mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-11-13 17:18:35 +05:00
IMP 23078: [CEA 1498] Sewing of meshes without having to set the nodes ids
This commit is contained in:
parent
8972ce9d84
commit
02ac54c6f3
@ -38,7 +38,7 @@ the meshed face boundary.
|
|||||||
|
|
||||||
\image html hypo_quad_params_dialog.png "Quadrangle parameters: Transition"
|
\image html hypo_quad_params_dialog.png "Quadrangle parameters: Transition"
|
||||||
|
|
||||||
<b>Quadrangle parameters</b> is a hypothesis for Quadrangle (Mapping) algorithm.
|
<b>Quadrangle parameters</b> is a hypothesis for \ref quad_ijk_algo_page.
|
||||||
|
|
||||||
<b>Transition</b> tab is used to define the algorithm of transition
|
<b>Transition</b> tab is used to define the algorithm of transition
|
||||||
between opposite sides of the face with a different number of
|
between opposite sides of the face with a different number of
|
||||||
|
@ -23,7 +23,9 @@ elements which will form your group:</li>
|
|||||||
</ul>
|
</ul>
|
||||||
<li><b>Name</b> field allows to enter the name of your new group.</li>
|
<li><b>Name</b> field allows to enter the name of your new group.</li>
|
||||||
<li><b>Color</b> - allows to assign to the group a certain color. The
|
<li><b>Color</b> - allows to assign to the group a certain color. The
|
||||||
chosen color is used to display the elements of the group.</li>
|
chosen color is used to display the elements of the group.<br>
|
||||||
|
Activation of <em>Auto Color</em> item in mesh context menu
|
||||||
|
switches on a random choice of a color for a new group.</li>
|
||||||
</ul>
|
</ul>
|
||||||
Mesh module distinguishes between the three Group types:
|
Mesh module distinguishes between the three Group types:
|
||||||
<b>Standalone Group</b>, <b>Group on Geometry</b> and <b>Group on Filter</b>.
|
<b>Standalone Group</b>, <b>Group on Geometry</b> and <b>Group on Filter</b>.
|
||||||
|
@ -16,17 +16,19 @@
|
|||||||
either \ref importing_exporting_meshes_page "imported" or manually
|
either \ref importing_exporting_meshes_page "imported" or manually
|
||||||
created);
|
created);
|
||||||
</li>
|
</li>
|
||||||
<li>\ref importing_exporting_meshes_page "importing and exporting meshes in various formats";</li>
|
<li>\ref importing_exporting_meshes_page "importing and exporting meshes"
|
||||||
|
in various formats;</li>
|
||||||
<li>\subpage modifying_meshes_page "modifying meshes" with a vast
|
<li>\subpage modifying_meshes_page "modifying meshes" with a vast
|
||||||
array of dedicated operations;</li>
|
array of dedicated operations;</li>
|
||||||
<li>\subpage grouping_elements_page "creating groups of mesh
|
<li>\subpage grouping_elements_page "creating groups" of mesh
|
||||||
elements";</li>
|
elements;</li>
|
||||||
<li>filtering mesh entities (nodes or elements) using
|
<li>filtering mesh entities (nodes or elements) using
|
||||||
\subpage filters_page "Filters" functionality for \ref
|
\subpage filters_page "Filters" functionality for \ref
|
||||||
grouping_elements_page "creating groups" and applying \ref
|
grouping_elements_page "creating groups" and applying \ref
|
||||||
modifying_meshes_page "mesh modifications";</li>
|
modifying_meshes_page "mesh modifications";</li>
|
||||||
<li>\subpage viewing_meshes_overview_page "viewing meshes" in
|
<li>\subpage viewing_meshes_overview_page "viewing meshes" in
|
||||||
the VTK viewer;</li>
|
the VTK viewer and \ref mesh_infos_page "getting info" on mesh
|
||||||
|
and its sub-objects;</li>
|
||||||
<li>applying to meshes \subpage quality_page "Quality Controls",
|
<li>applying to meshes \subpage quality_page "Quality Controls",
|
||||||
allowing to highlight important elements;</li>
|
allowing to highlight important elements;</li>
|
||||||
<li>taking various \subpage measurements_page "measurements" of the
|
<li>taking various \subpage measurements_page "measurements" of the
|
||||||
|
@ -21,10 +21,10 @@ then converted to the single node.
|
|||||||
processed.
|
processed.
|
||||||
<li>\b Tolerance is a maximum distance between nodes sufficient for
|
<li>\b Tolerance is a maximum distance between nodes sufficient for
|
||||||
merging.</li>
|
merging.</li>
|
||||||
<li>Activation of <b>No merge of corner and medium nodes</b> check-box
|
<li>Activation of <b>No merge of corner and medium nodes of quadratic
|
||||||
prevents merging medium nodes of quadratic elements with corner
|
cells</b> check-box prevents merging medium nodes of quadratic
|
||||||
nodes. This check-box is enabled provided that the selected mesh
|
elements with corner nodes. This check-box is enabled provided
|
||||||
includes quadratic elements.</li>
|
that the selected mesh includes quadratic elements.</li>
|
||||||
<li><b>Exclude Groups</b> group box allows to ignore the nodes which
|
<li><b>Exclude Groups</b> group box allows to ignore the nodes which
|
||||||
belong to the specified mesh groups.</li>
|
belong to the specified mesh groups.</li>
|
||||||
<li><b>Nodes to keep</b> group box allows to specify nodes to keep in
|
<li><b>Nodes to keep</b> group box allows to specify nodes to keep in
|
||||||
|
@ -14,14 +14,16 @@ in the toolbar.
|
|||||||
<em>"Mesh Information" button</em></center>
|
<em>"Mesh Information" button</em></center>
|
||||||
|
|
||||||
The <b>Mesh Information</b> dialog box provides three tab pages:
|
The <b>Mesh Information</b> dialog box provides three tab pages:
|
||||||
- <b>\ref advanced_mesh_infos_anchor "Base Info"</b> - to show base
|
- <b>\ref advanced_mesh_infos_anchor "Base Info"</b> - to show
|
||||||
information about the selected mesh object.
|
base and quantitative information about the selected mesh object.
|
||||||
- <b>\ref mesh_element_info_anchor "Element Info"</b> - to show
|
- <b>\ref mesh_element_info_anchor "Element Info"</b> - to show
|
||||||
detailed information about the selected mesh node or element.
|
detailed information about the selected mesh nodes or elements.
|
||||||
- <b>\ref mesh_addition_info_anchor "Additional Info"</b> - to show additional information available
|
- <b>\ref mesh_addition_info_anchor "Additional Info"</b> - to show
|
||||||
for the selected mesh, sub-mesh or group object.
|
additional information available for the selected mesh, sub-mesh or
|
||||||
|
group object.
|
||||||
- <b>\ref mesh_quality_info_anchor "Quality Info"</b> - to show
|
- <b>\ref mesh_quality_info_anchor "Quality Info"</b> - to show
|
||||||
overall quality information about the selected mesh, sub-mesh or group object.
|
overall quality information about the selected mesh, sub-mesh or group
|
||||||
|
object.
|
||||||
|
|
||||||
\anchor advanced_mesh_infos_anchor
|
\anchor advanced_mesh_infos_anchor
|
||||||
<h2>Base Information</h2>
|
<h2>Base Information</h2>
|
||||||
|
@ -27,7 +27,13 @@ the type of sewing operation you would like to perform.</li>
|
|||||||
\anchor free_borders_anchor
|
\anchor free_borders_anchor
|
||||||
<h2>Sew free borders</h2>
|
<h2>Sew free borders</h2>
|
||||||
|
|
||||||
This functionality allows you to unite two free borders of a 2D mesh.
|
This functionality allows you to unite free borders of a 2D mesh.
|
||||||
|
|
||||||
|
There are two working modes: \a Automatic and \a Manual. In the \b
|
||||||
|
Automatic mode, the program finds free borders coincident within a
|
||||||
|
certain tolerance and sew them. Optionally it is possible to adjust
|
||||||
|
the found free borders before sewing. In the \b Manual mode you are to
|
||||||
|
define borders to sew by picking three nodes of each border.
|
||||||
|
|
||||||
\image html sewing1.png
|
\image html sewing1.png
|
||||||
|
|
||||||
|
@ -26,8 +26,11 @@ information about the mesh.</li>
|
|||||||
<li>\subpage find_element_by_point_page "Find Element by Point" -
|
<li>\subpage find_element_by_point_page "Find Element by Point" -
|
||||||
allows to find all mesh elements, to which belongs a point with the
|
allows to find all mesh elements, to which belongs a point with the
|
||||||
given coordinates.</li>
|
given coordinates.</li>
|
||||||
<li><b>Auto Color</b> - switch on / off auto-assigning colors for the groups.</li>
|
<li><b>Auto Color</b> - switch on / off auto-assigning colors for the
|
||||||
<li>\subpage numbering_page "Numbering" - allows to display the ID
|
groups. If switched on, a default color of a new group in
|
||||||
|
\ref creating_groups_page "Create Group" dialog is chosen
|
||||||
|
randomly. </li>
|
||||||
|
<li>\subpage numbering_page "Numbering" - allows to display the ID
|
||||||
numbers of all meshing elements or nodes composing your mesh in the
|
numbers of all meshing elements or nodes composing your mesh in the
|
||||||
viewer.</li>
|
viewer.</li>
|
||||||
<li>\subpage display_mode_page "Display Mode" - allows to select between
|
<li>\subpage display_mode_page "Display Mode" - allows to select between
|
||||||
|
@ -29,13 +29,37 @@
|
|||||||
|
|
||||||
module SMESH
|
module SMESH
|
||||||
{
|
{
|
||||||
|
interface NumericalFunctor;
|
||||||
|
|
||||||
enum Bnd_Dimension { BND_2DFROM3D, BND_1DFROM3D, BND_1DFROM2D };
|
enum Bnd_Dimension { BND_2DFROM3D, BND_1DFROM3D, BND_1DFROM2D };
|
||||||
|
|
||||||
|
|
||||||
|
struct FreeBorder
|
||||||
|
{
|
||||||
|
SMESH::long_array nodeIDs; // all nodes defining a free border
|
||||||
|
// 1st and last node is same in a closed border
|
||||||
|
};
|
||||||
|
struct FreeBorderPart
|
||||||
|
{
|
||||||
|
short border; // border index within a sequence<FreeBorder>
|
||||||
|
long node1; // node index within the border-th FreeBorder
|
||||||
|
long node2;
|
||||||
|
long nodeLast;
|
||||||
|
};
|
||||||
|
typedef sequence<FreeBorder> ListOfFreeBorders;
|
||||||
|
typedef sequence<FreeBorderPart> FreeBordersGroup;
|
||||||
|
typedef sequence<FreeBordersGroup> ListOfFreeBorderGroups;
|
||||||
|
|
||||||
|
struct CoincidentFreeBorders
|
||||||
|
{
|
||||||
|
ListOfFreeBorders borders; // nodes of all free borders
|
||||||
|
ListOfFreeBorderGroups coincidentGroups; // groups of coincident parts of borders
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This interface makes modifications on the Mesh - removing elements and nodes etc.
|
* This interface makes modifications on the Mesh - removing elements and nodes etc.
|
||||||
*/
|
*/
|
||||||
interface NumericalFunctor;
|
|
||||||
|
|
||||||
interface SMESH_MeshEditor
|
interface SMESH_MeshEditor
|
||||||
{
|
{
|
||||||
/*!
|
/*!
|
||||||
@ -723,6 +747,21 @@ module SMESH
|
|||||||
short GetPointState(in double x, in double y, in double z)
|
short GetPointState(in double x, in double y, in double z)
|
||||||
raises (SALOME::SALOME_Exception);
|
raises (SALOME::SALOME_Exception);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Returns groups of FreeBorder's coincident within the given tolerance.
|
||||||
|
* If the tolerance <= 0.0 then one tenth of an average size of elements adjacent
|
||||||
|
* to free borders being compared is used.
|
||||||
|
*/
|
||||||
|
CoincidentFreeBorders FindCoincidentFreeBorders(in double tolerance);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Sew FreeBorder's of each group
|
||||||
|
*/
|
||||||
|
short SewCoincidentFreeBorders (in CoincidentFreeBorders freeBorders,
|
||||||
|
in boolean createPolygons,
|
||||||
|
in boolean createPolyedrs)
|
||||||
|
raises (SALOME::SALOME_Exception);
|
||||||
|
|
||||||
enum Sew_Error {
|
enum Sew_Error {
|
||||||
SEW_OK,
|
SEW_OK,
|
||||||
SEW_BORDER1_NOT_FOUND,
|
SEW_BORDER1_NOT_FOUND,
|
||||||
|
@ -559,22 +559,8 @@ bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
|
|||||||
if ( theEdgeNum < 0 || theEdgeNum > 3 || (nbNodes != 3 && nbNodes != 4) || theEdgeNum > nbNodes )
|
if ( theEdgeNum < 0 || theEdgeNum > 3 || (nbNodes != 3 && nbNodes != 4) || theEdgeNum > nbNodes )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
vector<int> anIds( nbNodes );
|
theNodeId1 = anElem->GetNode( theEdgeNum - 1 )->GetID();
|
||||||
SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
|
theNodeId2 = anElem->GetNode( theEdgeNum % nbNodes )->GetID();
|
||||||
int i = 0;
|
|
||||||
while( anIter->more() && i < nbNodes )
|
|
||||||
anIds[ i++ ] = anIter->next()->GetID();
|
|
||||||
|
|
||||||
if ( theEdgeNum < nbNodes - 1 )
|
|
||||||
{
|
|
||||||
theNodeId1 = anIds[ theEdgeNum ];
|
|
||||||
theNodeId2 = anIds[ theEdgeNum + 1 ];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
theNodeId1 = anIds[ nbNodes - 1 ];
|
|
||||||
theNodeId2 = anIds[ 0 ];
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ int SMDS_MeshNode::nbNodes =0;
|
|||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : SMDS_MeshNode
|
//function : SMDS_MeshNode
|
||||||
//purpose :
|
//purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
SMDS_MeshNode::SMDS_MeshNode() :
|
SMDS_MeshNode::SMDS_MeshNode() :
|
||||||
SMDS_MeshElement(-1, -1, 0),
|
SMDS_MeshElement(-1, -1, 0),
|
||||||
@ -83,31 +83,31 @@ SMDS_MeshNode::~SMDS_MeshNode()
|
|||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : RemoveInverseElement
|
//function : RemoveInverseElement
|
||||||
//purpose :
|
//purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * parent)
|
void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * parent)
|
||||||
{
|
{
|
||||||
//MESSAGE("RemoveInverseElement " << myID << " " << parent->GetID());
|
//MESSAGE("RemoveInverseElement " << myID << " " << parent->GetID());
|
||||||
const SMDS_MeshCell* cell = dynamic_cast<const SMDS_MeshCell*>(parent);
|
const SMDS_MeshCell* cell = dynamic_cast<const SMDS_MeshCell*>(parent);
|
||||||
MYASSERT(cell);
|
MYASSERT(cell);
|
||||||
SMDS_Mesh::_meshList[myMeshId]->getGrid()->RemoveReferenceToCell(myVtkID, cell->getVtkId());
|
SMDS_Mesh::_meshList[myMeshId]->getGrid()->RemoveReferenceToCell(myVtkID, cell->getVtkId());
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : Print
|
//function : Print
|
||||||
//purpose :
|
//purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
void SMDS_MeshNode::Print(ostream & OS) const
|
void SMDS_MeshNode::Print(ostream & OS) const
|
||||||
{
|
{
|
||||||
OS << "Node <" << myID << "> : X = " << X() << " Y = "
|
OS << "Node <" << myID << "> : X = " << X() << " Y = "
|
||||||
<< Y() << " Z = " << Z() << endl;
|
<< Y() << " Z = " << Z() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : SetPosition
|
//function : SetPosition
|
||||||
//purpose :
|
//purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos)
|
void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos)
|
||||||
@ -121,7 +121,7 @@ void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos)
|
|||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : GetPosition
|
//function : GetPosition
|
||||||
//purpose :
|
//purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
const SMDS_PositionPtr& SMDS_MeshNode::GetPosition() const
|
const SMDS_PositionPtr& SMDS_MeshNode::GetPosition() const
|
||||||
@ -178,10 +178,10 @@ public:
|
|||||||
int smdsId = myMesh->fromVtkToSmds(vtkId);
|
int smdsId = myMesh->fromVtkToSmds(vtkId);
|
||||||
const SMDS_MeshElement* elem = myMesh->FindElement(smdsId);
|
const SMDS_MeshElement* elem = myMesh->FindElement(smdsId);
|
||||||
if (!elem)
|
if (!elem)
|
||||||
{
|
{
|
||||||
MESSAGE("SMDS_MeshNode_MyInvIterator problem Null element");
|
MESSAGE("SMDS_MeshNode_MyInvIterator problem Null element");
|
||||||
throw SALOME_Exception("SMDS_MeshNode_MyInvIterator problem Null element");
|
throw SALOME_Exception("SMDS_MeshNode_MyInvIterator problem Null element");
|
||||||
}
|
}
|
||||||
//MESSAGE("vtkId " << vtkId << " smdsId " << smdsId << " " << elem->GetType());
|
//MESSAGE("vtkId " << vtkId << " smdsId " << smdsId << " " << elem->GetType());
|
||||||
iter++;
|
iter++;
|
||||||
return elem;
|
return elem;
|
||||||
@ -189,11 +189,11 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
SMDS_ElemIteratorPtr SMDS_MeshNode::
|
SMDS_ElemIteratorPtr SMDS_MeshNode::
|
||||||
GetInverseElementIterator(SMDSAbs_ElementType type) const
|
GetInverseElementIterator(SMDSAbs_ElementType type) const
|
||||||
{
|
{
|
||||||
vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
|
vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
|
||||||
//MESSAGE("myID " << myID << " ncells " << l.ncells);
|
//MESSAGE("myID " << myID << " ncells " << l.ncells);
|
||||||
return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(SMDS_Mesh::_meshList[myMeshId], l.cells, l.ncells, type));
|
return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(SMDS_Mesh::_meshList[myMeshId], l.cells, l.ncells, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same as GetInverseElementIterator but the create iterator only return
|
// Same as GetInverseElementIterator but the create iterator only return
|
||||||
@ -208,47 +208,47 @@ private:
|
|||||||
int iter;
|
int iter;
|
||||||
vector<SMDS_MeshElement*> myFiltCells;
|
vector<SMDS_MeshElement*> myFiltCells;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SMDS_MeshNode_MyIterator(SMDS_Mesh *mesh,
|
SMDS_MeshNode_MyIterator(SMDS_Mesh *mesh,
|
||||||
vtkIdType* cells,
|
vtkIdType* cells,
|
||||||
int ncells,
|
int ncells,
|
||||||
SMDSAbs_ElementType type):
|
SMDSAbs_ElementType type):
|
||||||
myMesh(mesh), myCells(cells), myNcells(ncells), myType(type), iter(0)
|
myMesh(mesh), myCells(cells), myNcells(ncells), myType(type), iter(0)
|
||||||
{
|
{
|
||||||
//MESSAGE("myNcells " << myNcells);
|
//MESSAGE("myNcells " << myNcells);
|
||||||
for (; iter<ncells; iter++)
|
for (; iter<ncells; iter++)
|
||||||
{
|
{
|
||||||
int vtkId = myCells[iter];
|
int vtkId = myCells[iter];
|
||||||
int smdsId = myMesh->fromVtkToSmds(vtkId);
|
int smdsId = myMesh->fromVtkToSmds(vtkId);
|
||||||
//MESSAGE("vtkId " << vtkId << " smdsId " << smdsId);
|
//MESSAGE("vtkId " << vtkId << " smdsId " << smdsId);
|
||||||
const SMDS_MeshElement* elem = myMesh->FindElement(smdsId);
|
const SMDS_MeshElement* elem = myMesh->FindElement(smdsId);
|
||||||
if (elem->GetType() == type)
|
if (elem->GetType() == type)
|
||||||
myFiltCells.push_back((SMDS_MeshElement*)elem);
|
myFiltCells.push_back((SMDS_MeshElement*)elem);
|
||||||
}
|
}
|
||||||
myNcells = myFiltCells.size();
|
myNcells = myFiltCells.size();
|
||||||
//MESSAGE("myNcells " << myNcells);
|
//MESSAGE("myNcells " << myNcells);
|
||||||
iter = 0;
|
iter = 0;
|
||||||
//MESSAGE("SMDS_MeshNode_MyIterator (filter) " << ncells << " " << myNcells);
|
//MESSAGE("SMDS_MeshNode_MyIterator (filter) " << ncells << " " << myNcells);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool more()
|
bool more()
|
||||||
{
|
{
|
||||||
return (iter< myNcells);
|
return (iter< myNcells);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SMDS_MeshElement* next()
|
const SMDS_MeshElement* next()
|
||||||
{
|
{
|
||||||
const SMDS_MeshElement* elem = myFiltCells[iter];
|
const SMDS_MeshElement* elem = myFiltCells[iter];
|
||||||
iter++;
|
iter++;
|
||||||
return elem;
|
return elem;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SMDS_ElemIteratorPtr SMDS_MeshNode::
|
SMDS_ElemIteratorPtr SMDS_MeshNode::
|
||||||
elementsIterator(SMDSAbs_ElementType type) const
|
elementsIterator(SMDSAbs_ElementType type) const
|
||||||
{
|
{
|
||||||
if(type==SMDSAbs_Node)
|
if(type==SMDSAbs_Node)
|
||||||
return SMDS_MeshElement::elementsIterator(SMDSAbs_Node);
|
return SMDS_MeshElement::elementsIterator(SMDSAbs_Node);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
|
vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
|
||||||
@ -258,7 +258,7 @@ SMDS_ElemIteratorPtr SMDS_MeshNode::
|
|||||||
|
|
||||||
int SMDS_MeshNode::NbNodes() const
|
int SMDS_MeshNode::NbNodes() const
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
double* SMDS_MeshNode::getCoord() const
|
double* SMDS_MeshNode::getCoord() const
|
||||||
@ -305,7 +305,7 @@ void SMDS_MeshNode::setXYZ(double x, double y, double z)
|
|||||||
|
|
||||||
SMDSAbs_ElementType SMDS_MeshNode::GetType() const
|
SMDSAbs_ElementType SMDS_MeshNode::GetType() const
|
||||||
{
|
{
|
||||||
return SMDSAbs_Node;
|
return SMDSAbs_Node;
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkIdType SMDS_MeshNode::GetVtkType() const
|
vtkIdType SMDS_MeshNode::GetVtkType() const
|
||||||
@ -358,11 +358,11 @@ int SMDS_MeshNode::NbInverseElements(SMDSAbs_ElementType type) const
|
|||||||
int nb = 0;
|
int nb = 0;
|
||||||
SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId];
|
SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId];
|
||||||
for (int i=0; i<l.ncells; i++)
|
for (int i=0; i<l.ncells; i++)
|
||||||
{
|
{
|
||||||
const SMDS_MeshElement* elem = mesh->FindElement(mesh->fromVtkToSmds(l.cells[i]));
|
const SMDS_MeshElement* elem = mesh->FindElement(mesh->fromVtkToSmds(l.cells[i]));
|
||||||
if (elem->GetType() == type)
|
if (elem->GetType() == type)
|
||||||
nb++;
|
nb++;
|
||||||
}
|
}
|
||||||
return nb;
|
return nb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,14 +371,14 @@ int SMDS_MeshNode::NbInverseElements(SMDSAbs_ElementType type) const
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2)
|
bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2)
|
||||||
{
|
{
|
||||||
return e1.getVtkId()<e2.getVtkId();
|
return e1.getVtkId()<e2.getVtkId();
|
||||||
/*if(e1.myX<e2.myX) return true;
|
/*if(e1.myX<e2.myX) return true;
|
||||||
else if(e1.myX==e2.myX)
|
else if(e1.myX==e2.myX)
|
||||||
{
|
{
|
||||||
if(e1.myY<e2.myY) return true;
|
if(e1.myY<e2.myY) return true;
|
||||||
else if(e1.myY==e2.myY) return (e1.myZ<e2.myZ);
|
else if(e1.myY==e2.myY) return (e1.myZ<e2.myZ);
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
else return false;*/
|
else return false;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8269,6 +8269,8 @@ bool SMESH_MeshEditor::CheckFreeBorderNodes(const SMDS_MeshNode* theNode1,
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : SewFreeBorder
|
//function : SewFreeBorder
|
||||||
//purpose :
|
//purpose :
|
||||||
|
//warning : for border-to-side sewing theSideSecondNode is considered as
|
||||||
|
// the last side node and theSideThirdNode is not used
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
SMESH_MeshEditor::Sew_Error
|
SMESH_MeshEditor::Sew_Error
|
||||||
|
@ -620,39 +620,26 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh,
|
|||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
|
|
||||||
// get all faces
|
// get all faces
|
||||||
list< const SMDS_MeshElement* > faces;
|
SMDS_ElemIteratorPtr fIt;
|
||||||
if ( nbElems > 0 ) {
|
if ( nbElems > 0 )
|
||||||
SMDS_ElemIteratorPtr fIt = fSubMesh->GetElements();
|
fIt = fSubMesh->GetElements();
|
||||||
while ( fIt->more() ) {
|
else
|
||||||
const SMDS_MeshElement* f = fIt->next();
|
fIt = aMeshDS->elementsIterator( SMDSAbs_Face );
|
||||||
if ( f && f->GetType() == SMDSAbs_Face )
|
|
||||||
faces.push_back( f );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SMDS_FaceIteratorPtr fIt = aMeshDS->facesIterator();
|
|
||||||
while ( fIt->more() )
|
|
||||||
faces.push_back( fIt->next() );
|
|
||||||
}
|
|
||||||
|
|
||||||
// put nodes of all faces into the nodePointIDMap and fill myElemPointIDs
|
// put nodes of all faces into the nodePointIDMap and fill myElemPointIDs
|
||||||
list< const SMDS_MeshElement* >::iterator fIt = faces.begin();
|
while ( fIt->more() )
|
||||||
for ( ; fIt != faces.end(); ++fIt )
|
|
||||||
{
|
{
|
||||||
|
const SMDS_MeshElement* face = fIt->next();
|
||||||
myElemPointIDs.push_back( TElemDef() );
|
myElemPointIDs.push_back( TElemDef() );
|
||||||
TElemDef& elemPoints = myElemPointIDs.back();
|
TElemDef& elemPoints = myElemPointIDs.back();
|
||||||
int nbNodes = (*fIt)->NbCornerNodes();
|
int nbNodes = face->NbCornerNodes();
|
||||||
for ( int i = 0;i < nbNodes; ++i )
|
for ( int i = 0;i < nbNodes; ++i )
|
||||||
{
|
{
|
||||||
const SMDS_MeshElement* node = (*fIt)->GetNode( i );
|
const SMDS_MeshElement* node = face->GetNode( i );
|
||||||
TNodePointIDMap::iterator nIdIt = nodePointIDMap.insert( make_pair( node, -1 )).first;
|
TNodePointIDMap::iterator nIdIt = nodePointIDMap.insert( make_pair( node, -1 )).first;
|
||||||
if ( nIdIt->second == -1 )
|
if ( nIdIt->second == -1 )
|
||||||
{
|
|
||||||
elemPoints.push_back( iPoint );
|
|
||||||
nIdIt->second = iPoint++;
|
nIdIt->second = iPoint++;
|
||||||
}
|
elemPoints.push_back( (*nIdIt).second );
|
||||||
else
|
|
||||||
elemPoints.push_back( (*nIdIt).second );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
myPoints.resize( iPoint );
|
myPoints.resize( iPoint );
|
||||||
|
@ -142,6 +142,8 @@ SET(_moc_HEADERS
|
|||||||
SMESHGUI_FieldSelectorWdg.h
|
SMESHGUI_FieldSelectorWdg.h
|
||||||
SMESHGUI_DisplayEntitiesDlg.h
|
SMESHGUI_DisplayEntitiesDlg.h
|
||||||
SMESHGUI_SplitBiQuad.h
|
SMESHGUI_SplitBiQuad.h
|
||||||
|
SMESHGUI_PreVisualObj.h
|
||||||
|
SMESHGUI_IdPreview.h
|
||||||
)
|
)
|
||||||
|
|
||||||
# header files / no moc processing
|
# header files / no moc processing
|
||||||
@ -251,6 +253,8 @@ SET(_other_SOURCES
|
|||||||
SMESHGUI_FieldSelectorWdg.cxx
|
SMESHGUI_FieldSelectorWdg.cxx
|
||||||
SMESHGUI_DisplayEntitiesDlg.cxx
|
SMESHGUI_DisplayEntitiesDlg.cxx
|
||||||
SMESHGUI_SplitBiQuad.cxx
|
SMESHGUI_SplitBiQuad.cxx
|
||||||
|
SMESHGUI_PreVisualObj.cxx
|
||||||
|
SMESHGUI_IdPreview.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
# sources / to compile
|
# sources / to compile
|
||||||
|
202
src/SMESHGUI/SMESHGUI_IdPreview.cxx
Normal file
202
src/SMESHGUI/SMESHGUI_IdPreview.cxx
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
|
||||||
|
//
|
||||||
|
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
|
||||||
|
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2.1 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
//
|
||||||
|
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "SMESHGUI_IdPreview.h"
|
||||||
|
|
||||||
|
#include <SALOME_Actor.h>
|
||||||
|
#include <SMDS_Mesh.hxx>
|
||||||
|
#include <SVTK_ViewWindow.h>
|
||||||
|
|
||||||
|
#include <TColStd_MapOfInteger.hxx>
|
||||||
|
#include <TColStd_MapIteratorOfMapOfInteger.hxx>
|
||||||
|
|
||||||
|
#include <vtkActor2D.h>
|
||||||
|
#include <vtkDataSetMapper.h>
|
||||||
|
#include <vtkLabeledDataMapper.h>
|
||||||
|
#include <vtkMaskPoints.h>
|
||||||
|
#include <vtkPointData.h>
|
||||||
|
#include <vtkProperty2D.h>
|
||||||
|
#include <vtkRenderer.h>
|
||||||
|
#include <vtkSelectVisiblePoints.h>
|
||||||
|
#include <vtkTextProperty.h>
|
||||||
|
#include <vtkUnstructuredGrid.h>
|
||||||
|
|
||||||
|
// Extracted from SMESHGUI_MergeDlg.cxx
|
||||||
|
|
||||||
|
SMESHGUI_IdPreview::SMESHGUI_IdPreview(SVTK_ViewWindow* theViewWindow):
|
||||||
|
myViewWindow(theViewWindow)
|
||||||
|
{
|
||||||
|
myIdGrid = vtkUnstructuredGrid::New();
|
||||||
|
|
||||||
|
// Create and display actor
|
||||||
|
vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
|
||||||
|
aMapper->SetInputData( myIdGrid );
|
||||||
|
|
||||||
|
myIdActor = SALOME_Actor::New();
|
||||||
|
myIdActor->SetInfinitive(true);
|
||||||
|
myIdActor->VisibilityOff();
|
||||||
|
myIdActor->PickableOff();
|
||||||
|
|
||||||
|
myIdActor->SetMapper( aMapper );
|
||||||
|
aMapper->Delete();
|
||||||
|
|
||||||
|
myViewWindow->AddActor(myIdActor);
|
||||||
|
|
||||||
|
//Definition of points numbering pipeline
|
||||||
|
myPointsNumDataSet = vtkUnstructuredGrid::New();
|
||||||
|
|
||||||
|
myPtsMaskPoints = vtkMaskPoints::New();
|
||||||
|
myPtsMaskPoints->SetInputData(myPointsNumDataSet);
|
||||||
|
myPtsMaskPoints->SetOnRatio(1);
|
||||||
|
|
||||||
|
myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New();
|
||||||
|
myPtsSelectVisiblePoints->SetInputConnection(myPtsMaskPoints->GetOutputPort());
|
||||||
|
myPtsSelectVisiblePoints->SelectInvisibleOff();
|
||||||
|
myPtsSelectVisiblePoints->SetTolerance(0.1);
|
||||||
|
|
||||||
|
myPtsLabeledDataMapper = vtkLabeledDataMapper::New();
|
||||||
|
myPtsLabeledDataMapper->SetInputConnection(myPtsSelectVisiblePoints->GetOutputPort());
|
||||||
|
myPtsLabeledDataMapper->SetLabelModeToLabelScalars();
|
||||||
|
|
||||||
|
vtkTextProperty* aPtsTextProp = vtkTextProperty::New();
|
||||||
|
aPtsTextProp->SetFontFamilyToTimes();
|
||||||
|
static int aPointsFontSize = 12;
|
||||||
|
aPtsTextProp->SetFontSize(aPointsFontSize);
|
||||||
|
aPtsTextProp->SetBold(1);
|
||||||
|
aPtsTextProp->SetItalic(0);
|
||||||
|
aPtsTextProp->SetShadow(0);
|
||||||
|
myPtsLabeledDataMapper->SetLabelTextProperty(aPtsTextProp);
|
||||||
|
aPtsTextProp->Delete();
|
||||||
|
|
||||||
|
myIsPointsLabeled = false;
|
||||||
|
|
||||||
|
myPointLabels = vtkActor2D::New();
|
||||||
|
myPointLabels->SetMapper(myPtsLabeledDataMapper);
|
||||||
|
myPointLabels->GetProperty()->SetColor(1,1,1);
|
||||||
|
myPointLabels->SetVisibility(myIsPointsLabeled);
|
||||||
|
|
||||||
|
AddToRender(myViewWindow->getRenderer());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMESHGUI_IdPreview::SetPointsData ( SMDS_Mesh* theMesh,
|
||||||
|
const TColStd_MapOfInteger & theNodesIdMap )
|
||||||
|
{
|
||||||
|
vtkPoints* aPoints = vtkPoints::New();
|
||||||
|
aPoints->SetNumberOfPoints(theNodesIdMap.Extent());
|
||||||
|
myIDs.clear();
|
||||||
|
|
||||||
|
TColStd_MapIteratorOfMapOfInteger idIter( theNodesIdMap );
|
||||||
|
for( int i = 0; idIter.More(); idIter.Next(), i++ )
|
||||||
|
{
|
||||||
|
const SMDS_MeshNode* aNode = theMesh->FindNode(idIter.Key());
|
||||||
|
aPoints->SetPoint( i, aNode->X(), aNode->Y(), aNode->Z() );
|
||||||
|
myIDs.push_back(idIter.Key());
|
||||||
|
}
|
||||||
|
|
||||||
|
myIdGrid->SetPoints(aPoints);
|
||||||
|
|
||||||
|
aPoints->Delete();
|
||||||
|
|
||||||
|
myIdActor->GetMapper()->Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMESHGUI_IdPreview::SetElemsData( const std::vector<int> & theElemsIdMap,
|
||||||
|
const std::list<gp_XYZ> & aGrCentersXYZ )
|
||||||
|
{
|
||||||
|
vtkPoints* aPoints = vtkPoints::New();
|
||||||
|
aPoints->SetNumberOfPoints( theElemsIdMap.size() );
|
||||||
|
myIDs = theElemsIdMap;
|
||||||
|
|
||||||
|
std::list<gp_XYZ>::const_iterator coordIt = aGrCentersXYZ.begin();
|
||||||
|
for( int i = 0; coordIt != aGrCentersXYZ.end(); coordIt++, i++ )
|
||||||
|
aPoints->SetPoint( i, coordIt->X(), coordIt->Y(), coordIt->Z() );
|
||||||
|
|
||||||
|
myIdGrid->SetPoints(aPoints);
|
||||||
|
aPoints->Delete();
|
||||||
|
|
||||||
|
myIdActor->GetMapper()->Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMESHGUI_IdPreview::AddToRender(vtkRenderer* theRenderer)
|
||||||
|
{
|
||||||
|
myIdActor->AddToRender(theRenderer);
|
||||||
|
|
||||||
|
myPtsSelectVisiblePoints->SetRenderer(theRenderer);
|
||||||
|
theRenderer->AddActor2D(myPointLabels);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMESHGUI_IdPreview::RemoveFromRender(vtkRenderer* theRenderer)
|
||||||
|
{
|
||||||
|
myIdActor->RemoveFromRender(theRenderer);
|
||||||
|
|
||||||
|
myPtsSelectVisiblePoints->SetRenderer(theRenderer);
|
||||||
|
theRenderer->RemoveActor(myPointLabels);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMESHGUI_IdPreview::SetPointsLabeled( bool theIsPointsLabeled, bool theIsActorVisible )
|
||||||
|
{
|
||||||
|
myIsPointsLabeled = theIsPointsLabeled && myIdGrid->GetNumberOfPoints();
|
||||||
|
|
||||||
|
if ( myIsPointsLabeled ) {
|
||||||
|
myPointsNumDataSet->ShallowCopy(myIdGrid);
|
||||||
|
vtkDataSet *aDataSet = myPointsNumDataSet;
|
||||||
|
int aNbElem = myIDs.size();
|
||||||
|
vtkIntArray *anArray = vtkIntArray::New();
|
||||||
|
anArray->SetNumberOfValues( aNbElem );
|
||||||
|
for ( int i = 0; i < aNbElem; i++ )
|
||||||
|
anArray->SetValue( i, myIDs[i] );
|
||||||
|
aDataSet->GetPointData()->SetScalars( anArray );
|
||||||
|
anArray->Delete();
|
||||||
|
myPtsMaskPoints->SetInputData( aDataSet );
|
||||||
|
myPointLabels->SetVisibility( theIsActorVisible );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
myPointLabels->SetVisibility( false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SMESHGUI_IdPreview::~SMESHGUI_IdPreview()
|
||||||
|
{
|
||||||
|
RemoveFromRender(myViewWindow->getRenderer());
|
||||||
|
|
||||||
|
myIdGrid->Delete();
|
||||||
|
|
||||||
|
myViewWindow->RemoveActor(myIdActor);
|
||||||
|
myIdActor->Delete();
|
||||||
|
|
||||||
|
//Deleting of points numbering pipeline
|
||||||
|
//---------------------------------------
|
||||||
|
myPointsNumDataSet->Delete();
|
||||||
|
|
||||||
|
//myPtsLabeledDataMapper->RemoveAllInputs(); //vtk 5.0 porting
|
||||||
|
myPtsLabeledDataMapper->Delete();
|
||||||
|
|
||||||
|
//myPtsSelectVisiblePoints->UnRegisterAllOutputs(); //vtk 5.0 porting
|
||||||
|
myPtsSelectVisiblePoints->Delete();
|
||||||
|
|
||||||
|
//myPtsMaskPoints->UnRegisterAllOutputs(); //vtk 5.0 porting
|
||||||
|
myPtsMaskPoints->Delete();
|
||||||
|
|
||||||
|
myPointLabels->Delete();
|
||||||
|
|
||||||
|
// myTimeStamp->Delete();
|
||||||
|
}
|
79
src/SMESHGUI/SMESHGUI_IdPreview.h
Normal file
79
src/SMESHGUI/SMESHGUI_IdPreview.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
|
||||||
|
//
|
||||||
|
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
|
||||||
|
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2.1 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
//
|
||||||
|
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SMESHGUI_IdPreview_H
|
||||||
|
#define SMESHGUI_IdPreview_H
|
||||||
|
|
||||||
|
#include "SMESH_SMESHGUI.hxx"
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <gp_XYZ.hxx>
|
||||||
|
|
||||||
|
class SALOME_Actor;
|
||||||
|
class SMDS_Mesh;
|
||||||
|
class SVTK_ViewWindow;
|
||||||
|
class TColStd_MapOfInteger;
|
||||||
|
class vtkActor2D;
|
||||||
|
class vtkLabeledDataMapper;
|
||||||
|
class vtkMaskPoints;
|
||||||
|
class vtkRenderer;
|
||||||
|
class vtkSelectVisiblePoints;
|
||||||
|
class vtkTextProperty;
|
||||||
|
class vtkUnstructuredGrid;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief To display in the viewer IDs of selected elements or nodes
|
||||||
|
*/
|
||||||
|
class SMESHGUI_IdPreview
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SMESHGUI_IdPreview(SVTK_ViewWindow* theViewWindow);
|
||||||
|
~SMESHGUI_IdPreview();
|
||||||
|
|
||||||
|
void SetPointsData( SMDS_Mesh* theMesh, const TColStd_MapOfInteger & theNodesIdMap );
|
||||||
|
void SetElemsData ( const std::vector<int> & theElemsIdMap,
|
||||||
|
const std::list<gp_XYZ> & theGrCentersXYZ );
|
||||||
|
void SetPointsLabeled( bool theIsPointsLabeled, bool theIsActorVisible = true );
|
||||||
|
|
||||||
|
void AddToRender ( vtkRenderer* theRenderer );
|
||||||
|
void RemoveFromRender( vtkRenderer* theRenderer );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
SVTK_ViewWindow* myViewWindow;
|
||||||
|
|
||||||
|
vtkUnstructuredGrid* myIdGrid;
|
||||||
|
SALOME_Actor* myIdActor;
|
||||||
|
|
||||||
|
vtkUnstructuredGrid* myPointsNumDataSet;
|
||||||
|
vtkMaskPoints* myPtsMaskPoints;
|
||||||
|
vtkSelectVisiblePoints* myPtsSelectVisiblePoints;
|
||||||
|
vtkLabeledDataMapper* myPtsLabeledDataMapper;
|
||||||
|
bool myIsPointsLabeled;
|
||||||
|
vtkActor2D* myPointLabels;
|
||||||
|
|
||||||
|
std::vector<int> myIDs;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -28,10 +28,11 @@
|
|||||||
#include "SMESHGUI_MergeDlg.h"
|
#include "SMESHGUI_MergeDlg.h"
|
||||||
|
|
||||||
#include "SMESHGUI.h"
|
#include "SMESHGUI.h"
|
||||||
#include "SMESHGUI_Utils.h"
|
#include "SMESHGUI_IdPreview.h"
|
||||||
#include "SMESHGUI_VTKUtils.h"
|
|
||||||
#include "SMESHGUI_MeshUtils.h"
|
#include "SMESHGUI_MeshUtils.h"
|
||||||
#include "SMESHGUI_SpinBox.h"
|
#include "SMESHGUI_SpinBox.h"
|
||||||
|
#include "SMESHGUI_Utils.h"
|
||||||
|
#include "SMESHGUI_VTKUtils.h"
|
||||||
|
|
||||||
#include <SMESH_Actor.h>
|
#include <SMESH_Actor.h>
|
||||||
#include <SMESH_TypeFilter.hxx>
|
#include <SMESH_TypeFilter.hxx>
|
||||||
@ -61,34 +62,20 @@
|
|||||||
#include CORBA_SERVER_HEADER(SMESH_Group)
|
#include CORBA_SERVER_HEADER(SMESH_Group)
|
||||||
#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
|
#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
|
||||||
|
|
||||||
// VTK includes
|
|
||||||
#include <vtkUnstructuredGrid.h>
|
|
||||||
#include <vtkRenderer.h>
|
|
||||||
#include <vtkActor2D.h>
|
|
||||||
#include <vtkPoints.h>
|
|
||||||
#include <vtkDataSetMapper.h>
|
|
||||||
#include <vtkMaskPoints.h>
|
|
||||||
#include <vtkSelectVisiblePoints.h>
|
|
||||||
#include <vtkLabeledDataMapper.h>
|
|
||||||
#include <vtkTextProperty.h>
|
|
||||||
#include <vtkIntArray.h>
|
|
||||||
#include <vtkProperty2D.h>
|
|
||||||
#include <vtkPointData.h>
|
|
||||||
|
|
||||||
// Qt includes
|
// Qt includes
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QButtonGroup>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QGridLayout>
|
||||||
#include <QGroupBox>
|
#include <QGroupBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QKeyEvent>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QListWidget>
|
#include <QListWidget>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QRadioButton>
|
#include <QRadioButton>
|
||||||
#include <QCheckBox>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QGridLayout>
|
|
||||||
#include <QKeyEvent>
|
|
||||||
#include <QButtonGroup>
|
|
||||||
|
|
||||||
#define SPACING 6
|
#define SPACING 6
|
||||||
#define MARGIN 11
|
#define MARGIN 11
|
||||||
@ -97,208 +84,27 @@ namespace
|
|||||||
{
|
{
|
||||||
enum ActionType { MERGE_NODES, MERGE_ELEMENTS, TYPE_AUTO=0, TYPE_MANUAL };
|
enum ActionType { MERGE_NODES, MERGE_ELEMENTS, TYPE_AUTO=0, TYPE_MANUAL };
|
||||||
}
|
}
|
||||||
namespace SMESH
|
|
||||||
|
|
||||||
|
QPixmap SMESHGUI_MergeDlg::IconFirst()
|
||||||
{
|
{
|
||||||
class TIdPreview
|
static const char * iconFirst[] = {
|
||||||
{ // to display in the viewer IDs of the selected elements
|
"18 10 2 1",
|
||||||
SVTK_ViewWindow* myViewWindow;
|
" g None",
|
||||||
|
". g #000000",
|
||||||
vtkUnstructuredGrid* myIdGrid;
|
" . . ",
|
||||||
SALOME_Actor* myIdActor;
|
" .. .. .. ",
|
||||||
|
" .. ... ... ",
|
||||||
vtkUnstructuredGrid* myPointsNumDataSet;
|
" .. .... .... ",
|
||||||
vtkMaskPoints* myPtsMaskPoints;
|
" .. ..... ..... ",
|
||||||
vtkSelectVisiblePoints* myPtsSelectVisiblePoints;
|
" .. ..... ..... ",
|
||||||
vtkLabeledDataMapper* myPtsLabeledDataMapper;
|
" .. .... .... ",
|
||||||
vtkTextProperty* aPtsTextProp;
|
" .. ... ... ",
|
||||||
bool myIsPointsLabeled;
|
" .. .. .. ",
|
||||||
vtkActor2D* myPointLabels;
|
" . . "};
|
||||||
|
return iconFirst;
|
||||||
std::vector<int> myIDs;
|
|
||||||
|
|
||||||
public:
|
|
||||||
TIdPreview(SVTK_ViewWindow* theViewWindow):
|
|
||||||
myViewWindow(theViewWindow)
|
|
||||||
{
|
|
||||||
myIdGrid = vtkUnstructuredGrid::New();
|
|
||||||
|
|
||||||
// Create and display actor
|
|
||||||
vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
|
|
||||||
aMapper->SetInputData( myIdGrid );
|
|
||||||
|
|
||||||
myIdActor = SALOME_Actor::New();
|
|
||||||
myIdActor->SetInfinitive(true);
|
|
||||||
myIdActor->VisibilityOff();
|
|
||||||
myIdActor->PickableOff();
|
|
||||||
|
|
||||||
myIdActor->SetMapper( aMapper );
|
|
||||||
aMapper->Delete();
|
|
||||||
|
|
||||||
myViewWindow->AddActor(myIdActor);
|
|
||||||
|
|
||||||
//Definition of points numbering pipeline
|
|
||||||
myPointsNumDataSet = vtkUnstructuredGrid::New();
|
|
||||||
|
|
||||||
myPtsMaskPoints = vtkMaskPoints::New();
|
|
||||||
myPtsMaskPoints->SetInputData(myPointsNumDataSet);
|
|
||||||
myPtsMaskPoints->SetOnRatio(1);
|
|
||||||
|
|
||||||
myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New();
|
|
||||||
myPtsSelectVisiblePoints->SetInputConnection(myPtsMaskPoints->GetOutputPort());
|
|
||||||
myPtsSelectVisiblePoints->SelectInvisibleOff();
|
|
||||||
myPtsSelectVisiblePoints->SetTolerance(0.1);
|
|
||||||
|
|
||||||
myPtsLabeledDataMapper = vtkLabeledDataMapper::New();
|
|
||||||
myPtsLabeledDataMapper->SetInputConnection(myPtsSelectVisiblePoints->GetOutputPort());
|
|
||||||
myPtsLabeledDataMapper->SetLabelModeToLabelScalars();
|
|
||||||
|
|
||||||
vtkTextProperty* aPtsTextProp = vtkTextProperty::New();
|
|
||||||
aPtsTextProp->SetFontFamilyToTimes();
|
|
||||||
static int aPointsFontSize = 12;
|
|
||||||
aPtsTextProp->SetFontSize(aPointsFontSize);
|
|
||||||
aPtsTextProp->SetBold(1);
|
|
||||||
aPtsTextProp->SetItalic(0);
|
|
||||||
aPtsTextProp->SetShadow(0);
|
|
||||||
myPtsLabeledDataMapper->SetLabelTextProperty(aPtsTextProp);
|
|
||||||
aPtsTextProp->Delete();
|
|
||||||
|
|
||||||
myIsPointsLabeled = false;
|
|
||||||
|
|
||||||
myPointLabels = vtkActor2D::New();
|
|
||||||
myPointLabels->SetMapper(myPtsLabeledDataMapper);
|
|
||||||
myPointLabels->GetProperty()->SetColor(1,1,1);
|
|
||||||
myPointLabels->SetVisibility(myIsPointsLabeled);
|
|
||||||
|
|
||||||
AddToRender(myViewWindow->getRenderer());
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetPointsData ( SMDS_Mesh* theMesh,
|
|
||||||
TColStd_MapOfInteger & theNodesIdMap )
|
|
||||||
{
|
|
||||||
vtkPoints* aPoints = vtkPoints::New();
|
|
||||||
aPoints->SetNumberOfPoints(theNodesIdMap.Extent());
|
|
||||||
myIDs.clear();
|
|
||||||
|
|
||||||
TColStd_MapIteratorOfMapOfInteger idIter( theNodesIdMap );
|
|
||||||
for( int i = 0; idIter.More(); idIter.Next(), i++ ) {
|
|
||||||
const SMDS_MeshNode* aNode = theMesh->FindNode(idIter.Key());
|
|
||||||
aPoints->SetPoint( i, aNode->X(), aNode->Y(), aNode->Z() );
|
|
||||||
myIDs.push_back(idIter.Key());
|
|
||||||
}
|
|
||||||
|
|
||||||
myIdGrid->SetPoints(aPoints);
|
|
||||||
|
|
||||||
aPoints->Delete();
|
|
||||||
|
|
||||||
myIdActor->GetMapper()->Update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetElemsData( TColStd_MapOfInteger & theElemsIdMap,
|
|
||||||
std::list<gp_XYZ> & aGrCentersXYZ )
|
|
||||||
{
|
|
||||||
vtkPoints* aPoints = vtkPoints::New();
|
|
||||||
aPoints->SetNumberOfPoints(theElemsIdMap.Extent());
|
|
||||||
myIDs.clear();
|
|
||||||
|
|
||||||
TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap );
|
|
||||||
for( ; idIter.More(); idIter.Next() ) {
|
|
||||||
myIDs.push_back(idIter.Key());
|
|
||||||
}
|
|
||||||
|
|
||||||
gp_XYZ aXYZ;
|
|
||||||
std::list<gp_XYZ>::iterator coordIt = aGrCentersXYZ.begin();
|
|
||||||
for( int i = 0; coordIt != aGrCentersXYZ.end(); coordIt++, i++ ) {
|
|
||||||
aXYZ = *coordIt;
|
|
||||||
aPoints->SetPoint( i, aXYZ.X(), aXYZ.Y(), aXYZ.Z() );
|
|
||||||
}
|
|
||||||
myIdGrid->SetPoints(aPoints);
|
|
||||||
aPoints->Delete();
|
|
||||||
|
|
||||||
myIdActor->GetMapper()->Update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddToRender(vtkRenderer* theRenderer)
|
|
||||||
{
|
|
||||||
myIdActor->AddToRender(theRenderer);
|
|
||||||
|
|
||||||
myPtsSelectVisiblePoints->SetRenderer(theRenderer);
|
|
||||||
theRenderer->AddActor2D(myPointLabels);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoveFromRender(vtkRenderer* theRenderer)
|
|
||||||
{
|
|
||||||
myIdActor->RemoveFromRender(theRenderer);
|
|
||||||
|
|
||||||
myPtsSelectVisiblePoints->SetRenderer(theRenderer);
|
|
||||||
theRenderer->RemoveActor(myPointLabels);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetPointsLabeled( bool theIsPointsLabeled, bool theIsActorVisible = true )
|
|
||||||
{
|
|
||||||
myIsPointsLabeled = theIsPointsLabeled && myIdGrid->GetNumberOfPoints();
|
|
||||||
|
|
||||||
if ( myIsPointsLabeled ) {
|
|
||||||
myPointsNumDataSet->ShallowCopy(myIdGrid);
|
|
||||||
vtkDataSet *aDataSet = myPointsNumDataSet;
|
|
||||||
int aNbElem = myIDs.size();
|
|
||||||
vtkIntArray *anArray = vtkIntArray::New();
|
|
||||||
anArray->SetNumberOfValues( aNbElem );
|
|
||||||
for ( int i = 0; i < aNbElem; i++ )
|
|
||||||
anArray->SetValue( i, myIDs[i] );
|
|
||||||
aDataSet->GetPointData()->SetScalars( anArray );
|
|
||||||
anArray->Delete();
|
|
||||||
myPtsMaskPoints->SetInputData( aDataSet );
|
|
||||||
myPointLabels->SetVisibility( theIsActorVisible );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
myPointLabels->SetVisibility( false );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~TIdPreview()
|
|
||||||
{
|
|
||||||
RemoveFromRender(myViewWindow->getRenderer());
|
|
||||||
|
|
||||||
myIdGrid->Delete();
|
|
||||||
|
|
||||||
myViewWindow->RemoveActor(myIdActor);
|
|
||||||
myIdActor->Delete();
|
|
||||||
|
|
||||||
//Deleting of points numbering pipeline
|
|
||||||
//---------------------------------------
|
|
||||||
myPointsNumDataSet->Delete();
|
|
||||||
|
|
||||||
//myPtsLabeledDataMapper->RemoveAllInputs(); //vtk 5.0 porting
|
|
||||||
myPtsLabeledDataMapper->Delete();
|
|
||||||
|
|
||||||
//myPtsSelectVisiblePoints->UnRegisterAllOutputs(); //vtk 5.0 porting
|
|
||||||
myPtsSelectVisiblePoints->Delete();
|
|
||||||
|
|
||||||
//myPtsMaskPoints->UnRegisterAllOutputs(); //vtk 5.0 porting
|
|
||||||
myPtsMaskPoints->Delete();
|
|
||||||
|
|
||||||
myPointLabels->Delete();
|
|
||||||
|
|
||||||
// myTimeStamp->Delete();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char * IconFirst[] = {
|
|
||||||
"18 10 2 1",
|
|
||||||
" g None",
|
|
||||||
". g #000000",
|
|
||||||
" . . ",
|
|
||||||
" .. .. .. ",
|
|
||||||
" .. ... ... ",
|
|
||||||
" .. .... .... ",
|
|
||||||
" .. ..... ..... ",
|
|
||||||
" .. ..... ..... ",
|
|
||||||
" .. .... .... ",
|
|
||||||
" .. ... ... ",
|
|
||||||
" .. .. .. ",
|
|
||||||
" . . "};
|
|
||||||
|
|
||||||
//=================================================================================
|
//=================================================================================
|
||||||
// class : SMESHGUI_MergeDlg()
|
// class : SMESHGUI_MergeDlg()
|
||||||
// purpose :
|
// purpose :
|
||||||
@ -313,7 +119,7 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
|
|||||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||||
setWindowTitle(myAction == MERGE_ELEMENTS ? tr("SMESH_MERGE_ELEMENTS") : tr("SMESH_MERGE_NODES"));
|
setWindowTitle(myAction == MERGE_ELEMENTS ? tr("SMESH_MERGE_ELEMENTS") : tr("SMESH_MERGE_NODES"));
|
||||||
|
|
||||||
myIdPreview = new SMESH::TIdPreview(SMESH::GetViewWindow( mySMESHGUI ));
|
myIdPreview = new SMESHGUI_IdPreview(SMESH::GetViewWindow( mySMESHGUI ));
|
||||||
|
|
||||||
SUIT_ResourceMgr* aResMgr = SMESH::GetResourceMgr( mySMESHGUI );
|
SUIT_ResourceMgr* aResMgr = SMESH::GetResourceMgr( mySMESHGUI );
|
||||||
QPixmap IconMergeNodes (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_MERGE_NODES")));
|
QPixmap IconMergeNodes (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_MERGE_NODES")));
|
||||||
@ -511,7 +317,7 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
|
|||||||
RemoveElemButton = new QPushButton(GroupEdit);
|
RemoveElemButton = new QPushButton(GroupEdit);
|
||||||
RemoveElemButton->setIcon(IconRemove);
|
RemoveElemButton->setIcon(IconRemove);
|
||||||
SetFirstButton = new QPushButton(GroupEdit);
|
SetFirstButton = new QPushButton(GroupEdit);
|
||||||
SetFirstButton->setIcon(QPixmap(IconFirst));
|
SetFirstButton->setIcon(IconFirst());
|
||||||
|
|
||||||
GroupEditLayout->addWidget(ListEdit, 0, 0, 2, 1);
|
GroupEditLayout->addWidget(ListEdit, 0, 0, 2, 1);
|
||||||
GroupEditLayout->addWidget(AddElemButton, 0, 1);
|
GroupEditLayout->addWidget(AddElemButton, 0, 1);
|
||||||
@ -645,8 +451,9 @@ void SMESHGUI_MergeDlg::Init()
|
|||||||
// function : FindGravityCenter()
|
// function : FindGravityCenter()
|
||||||
// purpose :
|
// purpose :
|
||||||
//=================================================================================
|
//=================================================================================
|
||||||
void SMESHGUI_MergeDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap,
|
void SMESHGUI_MergeDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap,
|
||||||
std::list< gp_XYZ > & theGrCentersXYZ)
|
std::vector<int>& theIDs,
|
||||||
|
std::list< gp_XYZ > & theGrCentersXYZ)
|
||||||
{
|
{
|
||||||
if (!myActor)
|
if (!myActor)
|
||||||
return;
|
return;
|
||||||
@ -658,11 +465,13 @@ void SMESHGUI_MergeDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap,
|
|||||||
|
|
||||||
int nbNodes;
|
int nbNodes;
|
||||||
|
|
||||||
|
theIDs.reserve( theElemsIdMap.Extent() );
|
||||||
TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap );
|
TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap );
|
||||||
for( ; idIter.More(); idIter.Next() ) {
|
for( ; idIter.More(); idIter.Next() ) {
|
||||||
const SMDS_MeshElement* anElem = aMesh->FindElement(idIter.Key());
|
const SMDS_MeshElement* anElem = aMesh->FindElement(idIter.Key());
|
||||||
if ( !anElem )
|
if ( !anElem )
|
||||||
continue;
|
continue;
|
||||||
|
theIDs.push_back( idIter.Key() );
|
||||||
|
|
||||||
gp_XYZ anXYZ(0., 0., 0.);
|
gp_XYZ anXYZ(0., 0., 0.);
|
||||||
SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator();
|
SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator();
|
||||||
@ -948,7 +757,7 @@ void SMESHGUI_MergeDlg::onDetect()
|
|||||||
|
|
||||||
SMESH::SMESH_IDSource_var src;
|
SMESH::SMESH_IDSource_var src;
|
||||||
if ( mySubMeshOrGroup->_is_nil() ) src = SMESH::SMESH_IDSource::_duplicate( myMesh );
|
if ( mySubMeshOrGroup->_is_nil() ) src = SMESH::SMESH_IDSource::_duplicate( myMesh );
|
||||||
else src = SMESH::SMESH_IDSource::_duplicate( mySubMeshOrGroup );
|
else src = SMESH::SMESH_IDSource::_duplicate( mySubMeshOrGroup );
|
||||||
|
|
||||||
switch (myAction) {
|
switch (myAction) {
|
||||||
case MERGE_NODES :
|
case MERGE_NODES :
|
||||||
@ -1034,8 +843,9 @@ void SMESHGUI_MergeDlg::onSelectGroup()
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::list< gp_XYZ > aGrCentersXYZ;
|
std::list< gp_XYZ > aGrCentersXYZ;
|
||||||
FindGravityCenter(anIndices, aGrCentersXYZ);
|
std::vector<int> anIDs;
|
||||||
myIdPreview->SetElemsData( anIndices, aGrCentersXYZ);
|
FindGravityCenter(anIndices, anIDs, aGrCentersXYZ);
|
||||||
|
myIdPreview->SetElemsData( anIDs, aGrCentersXYZ );
|
||||||
myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
|
myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1087,8 +897,9 @@ void SMESHGUI_MergeDlg::onSelectElementFromGroup()
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::list< gp_XYZ > aGrCentersXYZ;
|
std::list< gp_XYZ > aGrCentersXYZ;
|
||||||
FindGravityCenter(anIndices, aGrCentersXYZ);
|
std::vector<int> anIDs;
|
||||||
myIdPreview->SetElemsData(anIndices, aGrCentersXYZ);
|
FindGravityCenter(anIndices, anIDs, aGrCentersXYZ);
|
||||||
|
myIdPreview->SetElemsData(anIDs, aGrCentersXYZ);
|
||||||
myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
|
myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -38,25 +38,27 @@
|
|||||||
|
|
||||||
// STL includes
|
// STL includes
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
// IDL includes
|
// IDL includes
|
||||||
#include <SALOMEconfig.h>
|
#include <SALOMEconfig.h>
|
||||||
#include CORBA_SERVER_HEADER(SMESH_Mesh)
|
#include CORBA_SERVER_HEADER(SMESH_Mesh)
|
||||||
|
|
||||||
|
class LightApp_SelectionMgr;
|
||||||
|
class QButtonGroup;
|
||||||
|
class QCheckBox;
|
||||||
class QGroupBox;
|
class QGroupBox;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QLineEdit;
|
class QLineEdit;
|
||||||
|
class QListWidget;
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
class QRadioButton;
|
class QRadioButton;
|
||||||
class QCheckBox;
|
|
||||||
class QListWidget;
|
|
||||||
class QButtonGroup;
|
|
||||||
class SMESHGUI;
|
class SMESHGUI;
|
||||||
|
class SMESHGUI_IdPreview;
|
||||||
class SMESHGUI_SpinBox;
|
class SMESHGUI_SpinBox;
|
||||||
class SMESH_Actor;
|
class SMESH_Actor;
|
||||||
class SVTK_Selector;
|
|
||||||
class LightApp_SelectionMgr;
|
|
||||||
class SUIT_SelectionFilter;
|
class SUIT_SelectionFilter;
|
||||||
|
class SVTK_Selector;
|
||||||
class TColStd_MapOfInteger;
|
class TColStd_MapOfInteger;
|
||||||
|
|
||||||
namespace SMESH
|
namespace SMESH
|
||||||
@ -76,6 +78,8 @@ public:
|
|||||||
SMESHGUI_MergeDlg( SMESHGUI*, int );
|
SMESHGUI_MergeDlg( SMESHGUI*, int );
|
||||||
~SMESHGUI_MergeDlg();
|
~SMESHGUI_MergeDlg();
|
||||||
|
|
||||||
|
static QPixmap IconFirst();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Init();
|
void Init();
|
||||||
void enterEvent( QEvent* ); /* mouse enter the QWidget */
|
void enterEvent( QEvent* ); /* mouse enter the QWidget */
|
||||||
@ -84,7 +88,8 @@ private:
|
|||||||
bool isKeepNodesIDsSelection();
|
bool isKeepNodesIDsSelection();
|
||||||
bool isNewKeepNodesGroup( const char* entry );
|
bool isNewKeepNodesGroup( const char* entry );
|
||||||
|
|
||||||
void FindGravityCenter( TColStd_MapOfInteger&,
|
void FindGravityCenter( TColStd_MapOfInteger&,
|
||||||
|
std::vector<int>& ,
|
||||||
std::list<gp_XYZ>& );
|
std::list<gp_XYZ>& );
|
||||||
// add the centers of gravity of ElemsIdMap elements to the GrCentersXYZ list
|
// add the centers of gravity of ElemsIdMap elements to the GrCentersXYZ list
|
||||||
|
|
||||||
@ -103,7 +108,7 @@ private:
|
|||||||
SUIT_SelectionFilter* myMeshOrSubMeshOrGroupFilter;
|
SUIT_SelectionFilter* myMeshOrSubMeshOrGroupFilter;
|
||||||
SUIT_SelectionFilter* mySubMeshOrGroupFilter;
|
SUIT_SelectionFilter* mySubMeshOrGroupFilter;
|
||||||
|
|
||||||
SMESH::TIdPreview* myIdPreview;
|
SMESHGUI_IdPreview* myIdPreview;
|
||||||
|
|
||||||
int myAction;
|
int myAction;
|
||||||
bool myIsBusy;
|
bool myIsBusy;
|
||||||
|
142
src/SMESHGUI/SMESHGUI_PreVisualObj.cxx
Normal file
142
src/SMESHGUI/SMESHGUI_PreVisualObj.cxx
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
|
||||||
|
//
|
||||||
|
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
|
||||||
|
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2.1 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
//
|
||||||
|
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "SMESHGUI_PreVisualObj.h"
|
||||||
|
|
||||||
|
#include <SMDS_Mesh.hxx>
|
||||||
|
#include <SMESH_Actor.h>
|
||||||
|
|
||||||
|
SMESHGUI_PreVisualObj::SMESHGUI_PreVisualObj()
|
||||||
|
{
|
||||||
|
myMesh = new SMDS_Mesh();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SMESHGUI_PreVisualObj::Update( int theIsClear = true )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMESHGUI_PreVisualObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor )
|
||||||
|
{
|
||||||
|
if ( theFunctor ) theFunctor->SetMesh( GetMesh() );
|
||||||
|
}
|
||||||
|
|
||||||
|
int SMESHGUI_PreVisualObj::GetElemDimension( const int theObjId )
|
||||||
|
{
|
||||||
|
if ( const SMDS_MeshElement* anElem = myMesh->FindElement( theObjId ))
|
||||||
|
{
|
||||||
|
switch ( anElem->GetType() )
|
||||||
|
{
|
||||||
|
case SMDSAbs_Edge : return 1;
|
||||||
|
case SMDSAbs_Face : return 2;
|
||||||
|
case SMDSAbs_Volume: return 3;
|
||||||
|
// case SMDSAbs_0DElement : return 0;
|
||||||
|
// case SMDSAbs_Ball : return 0;
|
||||||
|
default : return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SMESHGUI_PreVisualObj::GetNbEntities( const SMDSAbs_ElementType theType ) const
|
||||||
|
{
|
||||||
|
myMesh->GetMeshInfo().NbElements( theType );
|
||||||
|
}
|
||||||
|
|
||||||
|
SMESH::SMESH_Mesh_ptr SMESHGUI_PreVisualObj::GetMeshServer()
|
||||||
|
{
|
||||||
|
return SMESH::SMESH_Mesh::_nil();
|
||||||
|
}
|
||||||
|
|
||||||
|
//=================================================================================
|
||||||
|
// function : GetEdgeNodes
|
||||||
|
// purpose : Retrieve ids of nodes from edge of elements ( edge is numbered from 1 )
|
||||||
|
//=================================================================================
|
||||||
|
|
||||||
|
bool SMESHGUI_PreVisualObj::GetEdgeNodes( const int theElemId,
|
||||||
|
const int theEdgeNum,
|
||||||
|
int& theNodeId1,
|
||||||
|
int& theNodeId2 ) const
|
||||||
|
{
|
||||||
|
const SMDS_MeshElement* e = myMesh->FindElement( theElemId );
|
||||||
|
if ( !e || e->GetType() != SMDSAbs_Face )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int nbNodes = e->NbCornerNodes();
|
||||||
|
if ( theEdgeNum < 0 || theEdgeNum > nbNodes )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
theNodeId1 = e->GetNode( theEdgeNum-1 )->GetID();
|
||||||
|
theNodeId2 = e->GetNode( theEdgeNum % nbNodes )->GetID();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SMESHGUI_PreVisualObj::IsValid() const
|
||||||
|
{
|
||||||
|
return GetNbEntities( SMDSAbs_All ) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkUnstructuredGrid* SMESHGUI_PreVisualObj::GetUnstructuredGrid()
|
||||||
|
{
|
||||||
|
return myMesh->getGrid();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vtkIdType SMESHGUI_PreVisualObj::GetNodeObjId( int theVTKID )
|
||||||
|
{
|
||||||
|
const SMDS_MeshNode* aNode = myMesh->FindNodeVtk( theVTKID );
|
||||||
|
return aNode ? aNode->GetID() : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkIdType SMESHGUI_PreVisualObj::GetNodeVTKId( int theObjID )
|
||||||
|
{
|
||||||
|
const SMDS_MeshNode* aNode = myMesh->FindNode( theObjID );
|
||||||
|
return aNode ? aNode->GetID() : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkIdType SMESHGUI_PreVisualObj::GetElemObjId( int theVTKID )
|
||||||
|
{
|
||||||
|
return this->GetMesh()->fromVtkToSmds(theVTKID);
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkIdType SMESHGUI_PreVisualObj::GetElemVTKId( int theObjID )
|
||||||
|
{
|
||||||
|
const SMDS_MeshElement* e = myMesh->FindElement(theObjID);
|
||||||
|
return e ? e->getVtkId() : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMESHGUI_PreVisualObj::ClearEntitiesFlags()
|
||||||
|
{
|
||||||
|
myEntitiesState = SMESH_Actor::eAllEntity;
|
||||||
|
myEntitiesFlag = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SMESHGUI_PreVisualObj::GetEntitiesFlag()
|
||||||
|
{
|
||||||
|
return myEntitiesFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int SMESHGUI_PreVisualObj::GetEntitiesState()
|
||||||
|
{
|
||||||
|
return myEntitiesState;
|
||||||
|
}
|
71
src/SMESHGUI/SMESHGUI_PreVisualObj.h
Normal file
71
src/SMESHGUI/SMESHGUI_PreVisualObj.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
|
||||||
|
//
|
||||||
|
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
|
||||||
|
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2.1 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
//
|
||||||
|
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||||
|
//
|
||||||
|
// File : SMESHGUI_PreVisualObj.h
|
||||||
|
// Module : SMESH
|
||||||
|
//
|
||||||
|
#ifndef SMESHGUI_PreVisualObj_H
|
||||||
|
#define SMESHGUI_PreVisualObj_H
|
||||||
|
|
||||||
|
#include "SMESH_SMESHGUI.hxx"
|
||||||
|
|
||||||
|
#include "SMESH_Object.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Incarnation of SMESH_VisualObj allowing usage of SMESH_Actor
|
||||||
|
* to show arbitrary mesh data. SMESHGUI_PreVisualObj encapsulates
|
||||||
|
* a instance of SMDS_Mesh that can be filled by its user.
|
||||||
|
* Main usage: to initialize a SMESH_Actor to display some preview
|
||||||
|
*/
|
||||||
|
class SMESHGUI_EXPORT SMESHGUI_PreVisualObj : public SMESH_VisualObj
|
||||||
|
{
|
||||||
|
mutable SMDS_Mesh* myMesh;
|
||||||
|
bool myEntitiesFlag;
|
||||||
|
unsigned int myEntitiesState;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SMESHGUI_PreVisualObj();
|
||||||
|
virtual SMDS_Mesh* GetMesh() const { return myMesh; }
|
||||||
|
|
||||||
|
virtual bool Update( int theIsClear );
|
||||||
|
virtual bool NulData() { return false; }
|
||||||
|
virtual void UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor );
|
||||||
|
virtual int GetElemDimension( const int theObjId );
|
||||||
|
virtual int GetNbEntities( const SMDSAbs_ElementType theType) const;
|
||||||
|
virtual bool IsValid() const;
|
||||||
|
virtual bool GetEdgeNodes( const int theElemId,
|
||||||
|
const int theEdgeNum,
|
||||||
|
int& theNodeId1,
|
||||||
|
int& theNodeId2 ) const;
|
||||||
|
|
||||||
|
virtual vtkIdType GetNodeObjId( int theVTKID );
|
||||||
|
virtual vtkIdType GetNodeVTKId( int theObjID );
|
||||||
|
virtual vtkIdType GetElemObjId( int theVTKID );
|
||||||
|
virtual vtkIdType GetElemVTKId( int theObjID );
|
||||||
|
virtual void ClearEntitiesFlags();
|
||||||
|
virtual bool GetEntitiesFlag();
|
||||||
|
virtual unsigned int GetEntitiesState();
|
||||||
|
|
||||||
|
virtual SMESH::SMESH_Mesh_ptr GetMeshServer();
|
||||||
|
virtual vtkUnstructuredGrid* GetUnstructuredGrid();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
@ -36,6 +36,9 @@
|
|||||||
// IDL includes
|
// IDL includes
|
||||||
#include <SALOMEconfig.h>
|
#include <SALOMEconfig.h>
|
||||||
#include CORBA_SERVER_HEADER(SMESH_Mesh)
|
#include CORBA_SERVER_HEADER(SMESH_Mesh)
|
||||||
|
#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class QButtonGroup;
|
class QButtonGroup;
|
||||||
class QGroupBox;
|
class QGroupBox;
|
||||||
@ -48,6 +51,10 @@ class SMESHGUI;
|
|||||||
class SMESH_Actor;
|
class SMESH_Actor;
|
||||||
class SVTK_Selector;
|
class SVTK_Selector;
|
||||||
class LightApp_SelectionMgr;
|
class LightApp_SelectionMgr;
|
||||||
|
class SMESHGUI_SpinBox;
|
||||||
|
class SalomeApp_IntSpinBox;
|
||||||
|
class QListWidget;
|
||||||
|
class QListWidgetItem;
|
||||||
|
|
||||||
//=================================================================================
|
//=================================================================================
|
||||||
// class : SMESHGUI_SewingDlg
|
// class : SMESHGUI_SewingDlg
|
||||||
@ -67,7 +74,8 @@ private:
|
|||||||
void keyPressEvent( QKeyEvent* );
|
void keyPressEvent( QKeyEvent* );
|
||||||
int GetConstructorId();
|
int GetConstructorId();
|
||||||
bool IsValid();
|
bool IsValid();
|
||||||
|
void UpdateButtons();
|
||||||
|
|
||||||
SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */
|
SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */
|
||||||
LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */
|
LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */
|
||||||
int myOk1, myOk2, myOk3, myOk4, myOk5, myOk6;
|
int myOk1, myOk2, myOk3, myOk4, myOk5, myOk6;
|
||||||
@ -114,13 +122,67 @@ private:
|
|||||||
QCheckBox* CheckBoxPolygons;
|
QCheckBox* CheckBoxPolygons;
|
||||||
QCheckBox* CheckBoxPolyedrs;
|
QCheckBox* CheckBoxPolyedrs;
|
||||||
|
|
||||||
|
QWidget* SewFreeBordersWidget;
|
||||||
|
QGroupBox* ModeGroup;
|
||||||
|
QButtonGroup* ModeButGrp;
|
||||||
|
//QPushButton* SelectMeshButton;
|
||||||
|
QLineEdit* LineEditMesh;
|
||||||
|
|
||||||
|
SMESHGUI_SpinBox* SpinBoxTolerance;
|
||||||
|
QCheckBox* AutoSewCheck;
|
||||||
|
|
||||||
|
QWidget* GroupCoincidentWidget;
|
||||||
|
QListWidget* ListCoincident;
|
||||||
|
QPushButton* DetectButton;
|
||||||
|
QPushButton* RemoveGroupButton;
|
||||||
|
QCheckBox* SelectAllCheck;
|
||||||
|
|
||||||
|
QListWidget* ListEdit;
|
||||||
|
QButtonGroup* MoveBorderEndsButGrp;
|
||||||
|
QLineEdit* BorderEndLine[2];
|
||||||
|
QPushButton* SwapBut;
|
||||||
|
QPushButton* SetFirstButton;
|
||||||
|
QPushButton* RemoveElemButton;
|
||||||
|
SalomeApp_IntSpinBox* StepSpin;
|
||||||
|
|
||||||
QString myHelpFileName;
|
QString myHelpFileName;
|
||||||
|
|
||||||
protected slots:
|
|
||||||
|
struct BorderGroupDisplayer;
|
||||||
|
std::vector< BorderGroupDisplayer* > myBorderDisplayers;
|
||||||
|
SMESH::CoincidentFreeBorders_var myBorders;
|
||||||
|
int myCurGroupIndex;
|
||||||
|
int myCurPartIndex;
|
||||||
|
int myStoredRepresentation;
|
||||||
|
unsigned int myStoredEntityMode;
|
||||||
|
|
||||||
|
bool haveBorders();
|
||||||
|
QString getGroupText( int groupIndex );
|
||||||
|
QString getPartText( const SMESH::FreeBorderPart& part );
|
||||||
|
void showGroup( QListWidgetItem* item );
|
||||||
|
bool setCurrentGroup();
|
||||||
|
bool setCurrentPart();
|
||||||
|
void onGroupChange(bool partChange=false);
|
||||||
|
void setDisplayMode();
|
||||||
|
void restoreDisplayMode();
|
||||||
|
|
||||||
|
|
||||||
|
protected slots:
|
||||||
virtual void reject();
|
virtual void reject();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void ConstructorsClicked( int );
|
void ConstructorsClicked( int );
|
||||||
|
void onModeChange( int );
|
||||||
|
void onAutoSew( int );
|
||||||
|
void onDetectClicked();
|
||||||
|
void onRemoveGroupClicked();
|
||||||
|
void onSelectGroup();
|
||||||
|
void onSelectAll(int);
|
||||||
|
void onSelectBorderPartFromGroup();
|
||||||
|
void onSetFirstClicked();
|
||||||
|
void onRemoveElemClicked();
|
||||||
|
void onMoveBorderEnd(int);
|
||||||
|
void onSwapClicked();
|
||||||
void ClickOnOk();
|
void ClickOnOk();
|
||||||
bool ClickOnApply();
|
bool ClickOnApply();
|
||||||
void ClickOnHelp();
|
void ClickOnHelp();
|
||||||
|
@ -5141,7 +5141,7 @@ Please select a group and try again</translation>
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>SEPARATE_CORNERS_AND_MEDIUM</source>
|
<source>SEPARATE_CORNERS_AND_MEDIUM</source>
|
||||||
<translation>No merge of corner and medium nodes</translation>
|
<translation>No merge of corner and medium nodes of quadratic cells</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>KEEP_NODES</source>
|
<source>KEEP_NODES</source>
|
||||||
@ -5155,10 +5155,6 @@ Please select a group and try again</translation>
|
|||||||
<source>SELECT</source>
|
<source>SELECT</source>
|
||||||
<translation>Select: </translation>
|
<translation>Select: </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source></source>
|
|
||||||
<translation></translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SMESHGUI_ExtrusionAlongPathDlg</name>
|
<name>SMESHGUI_ExtrusionAlongPathDlg</name>
|
||||||
@ -6665,6 +6661,42 @@ It is impossible to read point coordinates from file</translation>
|
|||||||
<source>SIDE_2</source>
|
<source>SIDE_2</source>
|
||||||
<translation>Side 2</translation>
|
<translation>Side 2</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>AUTO_SEWING</source>
|
||||||
|
<translation>Auto Sewing</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>COINCIDENT_FREE_BORDERS</source>
|
||||||
|
<translation>Coincident Free Borders</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>DETECT</source>
|
||||||
|
<translation>Detect</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>SELECT_ALL</source>
|
||||||
|
<translation>Select all</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>EDIT_SELECTED_GROUP</source>
|
||||||
|
<translation>Edit Selected Group</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>STEP</source>
|
||||||
|
<translation>Step</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>NO_BORDERS_TO_SEW</source>
|
||||||
|
<translation>No free borders to sew found</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>NOT_ALL_BORDERS_SEWED</source>
|
||||||
|
<translation>%1 of %2 groups of borders sewed</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>ALL_BORDERS_SEWED</source>
|
||||||
|
<translation>%1 group(s) of borders sewed</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SMESHGUI_ShapeByMeshDlg</name>
|
<name>SMESHGUI_ShapeByMeshDlg</name>
|
||||||
|
@ -79,6 +79,7 @@ SET(SMESHUtils_SOURCES
|
|||||||
SMESH_File.cxx
|
SMESH_File.cxx
|
||||||
SMESH_MeshAlgos.cxx
|
SMESH_MeshAlgos.cxx
|
||||||
SMESH_MAT2d.cxx
|
SMESH_MAT2d.cxx
|
||||||
|
SMESH_FreeBorders.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
# --- rules ---
|
# --- rules ---
|
||||||
|
507
src/SMESHUtils/SMESH_FreeBorders.cxx
Normal file
507
src/SMESHUtils/SMESH_FreeBorders.cxx
Normal file
@ -0,0 +1,507 @@
|
|||||||
|
// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2.1 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
//
|
||||||
|
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||||
|
//
|
||||||
|
// File : SMESH_FreeBorders.cxx
|
||||||
|
// Created : Tue Sep 8 17:08:39 2015
|
||||||
|
// Author : Edward AGAPOV (eap)
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
// Implementation of SMESH_MeshAlgos::FindCoincidentFreeBorders()
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
#include "SMESH_MeshAlgos.hxx"
|
||||||
|
|
||||||
|
#include "SMDS_LinearEdge.hxx"
|
||||||
|
#include "SMDS_Mesh.hxx"
|
||||||
|
#include "SMDS_SetIterator.hxx"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <limits>
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <NCollection_DataMap.hxx>
|
||||||
|
#include <gp_Pnt.hxx>
|
||||||
|
|
||||||
|
using namespace SMESH_MeshAlgos;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct BEdge;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Node on a free border
|
||||||
|
*/
|
||||||
|
struct BNode
|
||||||
|
{
|
||||||
|
const SMDS_MeshNode * myNode;
|
||||||
|
mutable std::vector< BEdge* > myLinkedEdges;
|
||||||
|
mutable std::vector< BEdge* > myCloseEdges;
|
||||||
|
|
||||||
|
BNode(const SMDS_MeshNode * node): myNode( node ) {}
|
||||||
|
void AddLinked( BEdge* e ) const;
|
||||||
|
void AddClose ( const BEdge* e ) const;
|
||||||
|
BEdge* FindCloseEdgeOfBorder( int borderID ) const;
|
||||||
|
bool operator<(const BNode& other) const { return myNode->GetID() < other.myNode->GetID(); }
|
||||||
|
};
|
||||||
|
/*!
|
||||||
|
* \brief Edge of a free border
|
||||||
|
*/
|
||||||
|
struct BEdge : public SMDS_LinearEdge
|
||||||
|
{
|
||||||
|
const BNode* myBNode1;
|
||||||
|
const BNode* myBNode2;
|
||||||
|
int myBorderID;
|
||||||
|
int myID; // within a border
|
||||||
|
BEdge* myPrev;
|
||||||
|
BEdge* myNext;
|
||||||
|
const SMDS_MeshElement* myFace;
|
||||||
|
std::set< int > myCloseBorders;
|
||||||
|
bool myInGroup;
|
||||||
|
|
||||||
|
BEdge():SMDS_LinearEdge( 0, 0 ), myBorderID(-1), myID(-1), myPrev(0), myNext(0), myInGroup(0) {}
|
||||||
|
|
||||||
|
void Set( const BNode * node1,
|
||||||
|
const BNode * node2,
|
||||||
|
const SMDS_MeshElement* face,
|
||||||
|
const int ID)
|
||||||
|
{
|
||||||
|
myBNode1 = node1;
|
||||||
|
myBNode2 = node2;
|
||||||
|
myNodes[0] = node1->myNode;
|
||||||
|
myNodes[1] = node2->myNode;
|
||||||
|
myFace = face;
|
||||||
|
setId( ID ); // mesh element ID
|
||||||
|
}
|
||||||
|
bool Contains( const BNode* n ) const
|
||||||
|
{
|
||||||
|
return ( n == myBNode1 || n == myBNode2 );
|
||||||
|
}
|
||||||
|
void AddLinked( BEdge* e )
|
||||||
|
{
|
||||||
|
if ( e->Contains( myBNode1 )) myPrev = e;
|
||||||
|
else myNext = e;
|
||||||
|
}
|
||||||
|
void RemoveLinked( BEdge* e )
|
||||||
|
{
|
||||||
|
if ( myPrev == e ) myPrev = 0;
|
||||||
|
if ( myNext == e ) myNext = 0;
|
||||||
|
}
|
||||||
|
void Reverse()
|
||||||
|
{
|
||||||
|
std::swap( myBNode1, myBNode2 );
|
||||||
|
myNodes[0] = myBNode1->myNode;
|
||||||
|
myNodes[1] = myBNode2->myNode;
|
||||||
|
}
|
||||||
|
void Orient()
|
||||||
|
{
|
||||||
|
if (( myPrev && !myPrev->Contains( myBNode1 )) ||
|
||||||
|
( myNext && !myNext->Contains( myBNode2 )))
|
||||||
|
std::swap( myPrev, myNext );
|
||||||
|
if ( myPrev && myPrev->myBNode2 != myBNode1 ) myPrev->Reverse();
|
||||||
|
if ( myNext && myNext->myBNode1 != myBNode2 ) myNext->Reverse();
|
||||||
|
}
|
||||||
|
void SetID( int id )
|
||||||
|
{
|
||||||
|
if ( myID < 0 )
|
||||||
|
{
|
||||||
|
myID = id;
|
||||||
|
if ( myNext )
|
||||||
|
myNext->SetID( id + 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void FindRangeOfSameCloseBorders(BEdge* eRange[2])
|
||||||
|
{
|
||||||
|
eRange[0] = this;
|
||||||
|
while ( eRange[0]->myPrev && eRange[0]->myPrev->myCloseBorders == this->myCloseBorders )
|
||||||
|
{
|
||||||
|
if ( eRange[0]->myPrev == this /*|| eRange[0]->myPrev->myInGroup*/ )
|
||||||
|
break;
|
||||||
|
eRange[0] = eRange[0]->myPrev;
|
||||||
|
}
|
||||||
|
eRange[1] = this;
|
||||||
|
if ( eRange[0]->myPrev != this ) // not closed range
|
||||||
|
while ( eRange[1]->myNext && eRange[1]->myNext->myCloseBorders == this->myCloseBorders )
|
||||||
|
{
|
||||||
|
if ( eRange[1]->myNext == this /*|| eRange[1]->myNext->myInGroup*/ )
|
||||||
|
break;
|
||||||
|
eRange[1] = eRange[1]->myNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void BNode::AddLinked( BEdge* e ) const
|
||||||
|
{
|
||||||
|
myLinkedEdges.reserve(2);
|
||||||
|
myLinkedEdges.push_back( e );
|
||||||
|
if ( myLinkedEdges.size() < 2 ) return;
|
||||||
|
|
||||||
|
if ( myLinkedEdges.size() == 2 )
|
||||||
|
{
|
||||||
|
myLinkedEdges[0]->AddLinked( myLinkedEdges[1] );
|
||||||
|
myLinkedEdges[1]->AddLinked( myLinkedEdges[0] );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for ( size_t i = 0; i < myLinkedEdges.size(); ++i )
|
||||||
|
for ( size_t j = 0; j < myLinkedEdges.size(); ++j )
|
||||||
|
if ( i != j )
|
||||||
|
myLinkedEdges[i]->RemoveLinked( myLinkedEdges[j] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void BNode::AddClose ( const BEdge* e ) const
|
||||||
|
{
|
||||||
|
if ( ! e->Contains( this ))
|
||||||
|
myCloseEdges.push_back( const_cast< BEdge* >( e ));
|
||||||
|
}
|
||||||
|
BEdge* BNode::FindCloseEdgeOfBorder( int borderID ) const
|
||||||
|
{
|
||||||
|
for ( size_t i = 0; i < myCloseEdges.size(); ++i )
|
||||||
|
if ( borderID == myCloseEdges[ i ]->myBorderID )
|
||||||
|
return myCloseEdges[ i ];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Accessor to SMDS_MeshElement* inherited by BEdge
|
||||||
|
struct ElemAcess
|
||||||
|
{
|
||||||
|
static const SMDS_MeshElement* value( std::vector< BEdge >::const_iterator it)
|
||||||
|
{
|
||||||
|
return & (*it);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/// Iterator over a vector of BEdge's
|
||||||
|
static SMDS_ElemIteratorPtr getElemIterator( const std::vector< BEdge > & bedges )
|
||||||
|
{
|
||||||
|
typedef SMDS_SetIterator
|
||||||
|
< const SMDS_MeshElement*, std::vector< BEdge >::const_iterator, ElemAcess > BEIter;
|
||||||
|
return SMDS_ElemIteratorPtr( new BEIter( bedges.begin(), bedges.end() ));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// struct needed for NCollection_Map
|
||||||
|
struct TLinkHasher
|
||||||
|
{
|
||||||
|
static int HashCode(const SMESH_TLink& link, int aLimit)
|
||||||
|
{
|
||||||
|
return ::HashCode( link.node1()->GetID() + link.node2()->GetID(), aLimit );
|
||||||
|
}
|
||||||
|
static Standard_Boolean IsEqual(const SMESH_TLink& l1, const SMESH_TLink& l2)
|
||||||
|
{
|
||||||
|
return ( l1.node1() == l2.node1() && l1.node2() == l2.node2() );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*
|
||||||
|
* Returns groups of TFreeBorder's coincident within the given tolerance.
|
||||||
|
* If the tolerance <= 0.0 then one tenth of an average size of elements adjacent
|
||||||
|
* to free borders being compared is used.
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
void SMESH_MeshAlgos::FindCoincidentFreeBorders(SMDS_Mesh& mesh,
|
||||||
|
double tolerance,
|
||||||
|
CoincidentFreeBorders & foundFreeBordes)
|
||||||
|
{
|
||||||
|
// find free links
|
||||||
|
typedef NCollection_DataMap<SMESH_TLink, const SMDS_MeshElement*, TLinkHasher > TLink2FaceMap;
|
||||||
|
TLink2FaceMap linkMap;
|
||||||
|
SMDS_FaceIteratorPtr faceIt = mesh.facesIterator();
|
||||||
|
while ( faceIt->more() )
|
||||||
|
{
|
||||||
|
const SMDS_MeshElement* face = faceIt->next();
|
||||||
|
if ( !face ) continue;
|
||||||
|
|
||||||
|
const SMDS_MeshNode* n0 = face->GetNode( face->NbNodes() - 1 );
|
||||||
|
SMDS_NodeIteratorPtr nodeIt = face->interlacedNodesIterator();
|
||||||
|
while ( nodeIt->more() )
|
||||||
|
{
|
||||||
|
const SMDS_MeshNode* n1 = nodeIt->next();
|
||||||
|
SMESH_TLink link( n0, n1 );
|
||||||
|
if ( !linkMap.Bind( link, face ))
|
||||||
|
linkMap.UnBind( link );
|
||||||
|
n0 = n1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( linkMap.IsEmpty() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// form free borders
|
||||||
|
std::set < BNode > bNodes;
|
||||||
|
std::vector< BEdge > bEdges( linkMap.Extent() );
|
||||||
|
|
||||||
|
TLink2FaceMap::Iterator linkIt( linkMap );
|
||||||
|
for ( int iEdge = 0; linkIt.More(); linkIt.Next(), ++iEdge )
|
||||||
|
{
|
||||||
|
const SMESH_TLink & link = linkIt.Key();
|
||||||
|
std::set< BNode >::iterator n1 = bNodes.insert( BNode( link.node1() )).first;
|
||||||
|
std::set< BNode >::iterator n2 = bNodes.insert( BNode( link.node2() )).first;
|
||||||
|
bEdges[ iEdge ].Set( &*n1, &*n2, linkIt.Value(), iEdge+1 );
|
||||||
|
n1->AddLinked( & bEdges[ iEdge ] );
|
||||||
|
n2->AddLinked( & bEdges[ iEdge ] );
|
||||||
|
}
|
||||||
|
linkMap.Clear();
|
||||||
|
|
||||||
|
// assign IDs to borders
|
||||||
|
std::vector< BEdge* > borders; // 1st of connected (via myPrev and myNext) edges
|
||||||
|
std::set< BNode >::iterator bn = bNodes.begin();
|
||||||
|
for ( ; bn != bNodes.end(); ++bn )
|
||||||
|
{
|
||||||
|
for ( size_t i = 0; i < bn->myLinkedEdges.size(); ++i )
|
||||||
|
{
|
||||||
|
if ( bn->myLinkedEdges[i]->myBorderID < 0 )
|
||||||
|
{
|
||||||
|
BEdge* be = bn->myLinkedEdges[i];
|
||||||
|
int borderID = borders.size();
|
||||||
|
borders.push_back( be );
|
||||||
|
for ( ; be && be->myBorderID < 0; be = be->myNext )
|
||||||
|
{
|
||||||
|
be->myBorderID = borderID;
|
||||||
|
be->Orient();
|
||||||
|
}
|
||||||
|
bool isClosed = ( be == bn->myLinkedEdges[i] );
|
||||||
|
be = bn->myLinkedEdges[i]->myPrev;
|
||||||
|
for ( ; be && be->myBorderID < 0; be = be->myPrev )
|
||||||
|
{
|
||||||
|
be->myBorderID = borderID;
|
||||||
|
be->Orient();
|
||||||
|
}
|
||||||
|
if ( !isClosed )
|
||||||
|
while ( borders.back()->myPrev )
|
||||||
|
borders.back() = borders.back()->myPrev;
|
||||||
|
|
||||||
|
borders.back()->SetID( 0 ); // set IDs to all edges of the border
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute tolerance of each border
|
||||||
|
double maxTolerance = tolerance;
|
||||||
|
std::vector< double > bordToler( borders.size(), tolerance );
|
||||||
|
if ( maxTolerance < std::numeric_limits< double >::min() )
|
||||||
|
{
|
||||||
|
// no tolerance provided by the user; compute tolerance of each border
|
||||||
|
// as one tenth of an average size of faces adjacent to a border
|
||||||
|
for ( size_t i = 0; i < borders.size(); ++i )
|
||||||
|
{
|
||||||
|
double avgFaceSize = 0;
|
||||||
|
int nbFaces = 0;
|
||||||
|
BEdge* be = borders[ i ];
|
||||||
|
do {
|
||||||
|
double facePerimeter = 0;
|
||||||
|
gp_Pnt p0 = SMESH_TNodeXYZ( be->myFace->GetNode( be->myFace->NbNodes() - 1 ));
|
||||||
|
SMDS_NodeIteratorPtr nodeIt = be->myFace->interlacedNodesIterator();
|
||||||
|
while ( nodeIt->more() )
|
||||||
|
{
|
||||||
|
gp_Pnt p1 = SMESH_TNodeXYZ( nodeIt->next() );
|
||||||
|
facePerimeter += p0.Distance( p1 );
|
||||||
|
p0 = p1;
|
||||||
|
}
|
||||||
|
avgFaceSize += ( facePerimeter / be->myFace->NbCornerNodes() );
|
||||||
|
nbFaces++;
|
||||||
|
|
||||||
|
be = be->myNext;
|
||||||
|
}
|
||||||
|
while ( be && be != borders[i] );
|
||||||
|
|
||||||
|
bordToler[ i ] = 0.1 * avgFaceSize / nbFaces;
|
||||||
|
maxTolerance = Max( maxTolerance, bordToler[ i ]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// for every border node find close border edges
|
||||||
|
SMESH_ElementSearcher* searcher =
|
||||||
|
GetElementSearcher( mesh, getElemIterator( bEdges ), maxTolerance );
|
||||||
|
SMESHUtils::Deleter< SMESH_ElementSearcher > searcherDeleter( searcher );
|
||||||
|
std::vector< const SMDS_MeshElement* > candidateEdges;
|
||||||
|
for ( bn = bNodes.begin(); bn != bNodes.end(); ++bn )
|
||||||
|
{
|
||||||
|
gp_Pnt point = SMESH_TNodeXYZ( bn->myNode );
|
||||||
|
searcher->FindElementsByPoint( point, SMDSAbs_Edge, candidateEdges );
|
||||||
|
if ( candidateEdges.size() <= bn->myLinkedEdges.size() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
double nodeTol = 0;
|
||||||
|
for ( size_t i = 0; i < bn->myLinkedEdges.size(); ++i )
|
||||||
|
nodeTol = Max( nodeTol, bordToler[ bn->myLinkedEdges[ i ]->myBorderID ]);
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < candidateEdges.size(); ++i )
|
||||||
|
{
|
||||||
|
const BEdge* be = static_cast< const BEdge* >( candidateEdges[ i ]);
|
||||||
|
double tol = Max( nodeTol, bordToler[ be->myBorderID ]);
|
||||||
|
if ( maxTolerance - tol < 1e-12 ||
|
||||||
|
!SMESH_MeshAlgos::IsOut( be, point, tol ))
|
||||||
|
bn->AddClose( be );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// for every border edge find close borders
|
||||||
|
|
||||||
|
std::vector< BEdge* > closeEdges;
|
||||||
|
for ( size_t i = 0; i < bEdges.size(); ++i )
|
||||||
|
{
|
||||||
|
BEdge& be = bEdges[i];
|
||||||
|
if ( be.myBNode1->myCloseEdges.empty() ||
|
||||||
|
be.myBNode2->myCloseEdges.empty() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
closeEdges.clear();
|
||||||
|
for ( size_t iE1 = 0; iE1 < be.myBNode1->myCloseEdges.size(); ++iE1 )
|
||||||
|
{
|
||||||
|
// find edges of the same border close to both nodes of the edge
|
||||||
|
BEdge* closeE1 = be.myBNode1->myCloseEdges[ iE1 ];
|
||||||
|
BEdge* closeE2 = be.myBNode2->FindCloseEdgeOfBorder( closeE1->myBorderID );
|
||||||
|
if ( !closeE2 )
|
||||||
|
continue;
|
||||||
|
// check that edges connecting closeE1 and closeE2 (if any) are also close to 'be'
|
||||||
|
if ( closeE1 != closeE2 )
|
||||||
|
{
|
||||||
|
bool coincide;
|
||||||
|
for ( int j = 0; j < 2; ++j ) // move closeE1 -> closeE2 or inversely
|
||||||
|
{
|
||||||
|
BEdge* ce = closeE1;
|
||||||
|
do {
|
||||||
|
coincide = ( ce->myBNode2->FindCloseEdgeOfBorder( be.myBorderID ));
|
||||||
|
ce = ce->myNext;
|
||||||
|
} while ( coincide && ce && ce != closeE2 );
|
||||||
|
|
||||||
|
if ( coincide && ce == closeE2 )
|
||||||
|
break;
|
||||||
|
if ( j == 0 )
|
||||||
|
std::swap( closeE1, closeE2 );
|
||||||
|
coincide = false;
|
||||||
|
}
|
||||||
|
if ( !coincide )
|
||||||
|
continue;
|
||||||
|
closeEdges.push_back( closeE1 );
|
||||||
|
closeEdges.push_back( closeE2 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
closeEdges.push_back( closeE1 );
|
||||||
|
}
|
||||||
|
be.myCloseBorders.insert( closeE1->myBorderID );
|
||||||
|
}
|
||||||
|
if ( !closeEdges.empty() )
|
||||||
|
{
|
||||||
|
be.myCloseBorders.insert( be.myBorderID );
|
||||||
|
// for ( size_t iB = 0; iB < closeEdges.size(); ++iB )
|
||||||
|
// closeEdges[ iB ]->myCloseBorders.insert( be.myCloseBorders.begin(),
|
||||||
|
// be.myCloseBorders.end() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill in CoincidentFreeBorders
|
||||||
|
|
||||||
|
// save nodes of free borders
|
||||||
|
foundFreeBordes._borders.resize( borders.size() );
|
||||||
|
for ( size_t i = 0; i < borders.size(); ++i )
|
||||||
|
{
|
||||||
|
BEdge* be = borders[i];
|
||||||
|
foundFreeBordes._borders[i].push_back( be->myBNode1->myNode );
|
||||||
|
do {
|
||||||
|
foundFreeBordes._borders[i].push_back( be->myBNode2->myNode );
|
||||||
|
be = be->myNext;
|
||||||
|
}
|
||||||
|
while ( be && be != borders[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// form groups of coincident parts of free borders
|
||||||
|
|
||||||
|
TFreeBorderPart part;
|
||||||
|
TCoincidentGroup group;
|
||||||
|
for ( size_t i = 0; i < borders.size(); ++i )
|
||||||
|
{
|
||||||
|
BEdge* be = borders[i];
|
||||||
|
|
||||||
|
// look for an edge close to other borders
|
||||||
|
do {
|
||||||
|
if ( !be->myInGroup && !be->myCloseBorders.empty() )
|
||||||
|
break;
|
||||||
|
be = be->myNext;
|
||||||
|
} while ( be && be != borders[i] );
|
||||||
|
|
||||||
|
if ( !be || be->myInGroup || be->myCloseBorders.empty() )
|
||||||
|
continue; // all edges of a border treated or are non-coincident
|
||||||
|
|
||||||
|
group.clear();
|
||||||
|
|
||||||
|
// look for the 1st and last edge of a coincident group
|
||||||
|
BEdge* beRange[2];
|
||||||
|
be->FindRangeOfSameCloseBorders( beRange );
|
||||||
|
BEdge* be1st = beRange[0];
|
||||||
|
|
||||||
|
// fill in a group
|
||||||
|
part._border = i;
|
||||||
|
part._node1 = beRange[0]->myID;
|
||||||
|
part._node2 = beRange[0]->myID + 1;
|
||||||
|
part._nodeLast = beRange[1]->myID + 1;
|
||||||
|
group.push_back( part );
|
||||||
|
|
||||||
|
be = beRange[0];
|
||||||
|
be->myInGroup = true;
|
||||||
|
while ( be != beRange[1] )
|
||||||
|
{
|
||||||
|
be->myInGroup = true;
|
||||||
|
be = be->myNext;
|
||||||
|
}
|
||||||
|
beRange[1]->myInGroup = true;
|
||||||
|
|
||||||
|
// add parts of other borders
|
||||||
|
std::set<int>::iterator closeBord = be1st->myCloseBorders.begin();
|
||||||
|
for ( ; closeBord != be1st->myCloseBorders.end(); ++closeBord )
|
||||||
|
{
|
||||||
|
be = be1st->myBNode2->FindCloseEdgeOfBorder( *closeBord );
|
||||||
|
if ( !be ) continue;
|
||||||
|
|
||||||
|
be->FindRangeOfSameCloseBorders( beRange );
|
||||||
|
|
||||||
|
// find out mutual orientation of borders
|
||||||
|
bool reverse = ( beRange[0]->myBNode1->FindCloseEdgeOfBorder( i ) != be1st &&
|
||||||
|
beRange[0]->myBNode2->FindCloseEdgeOfBorder( i ) != be1st );
|
||||||
|
|
||||||
|
// fill in a group
|
||||||
|
part._border = beRange[0]->myBorderID;
|
||||||
|
if ( reverse ) {
|
||||||
|
part._node1 = beRange[1]->myID + 1;
|
||||||
|
part._node2 = beRange[1]->myID;
|
||||||
|
part._nodeLast = beRange[0]->myID;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
part._node1 = beRange[0]->myID;
|
||||||
|
part._node2 = beRange[0]->myID + 1;
|
||||||
|
part._nodeLast = beRange[1]->myID + 1;
|
||||||
|
}
|
||||||
|
group.push_back( part );
|
||||||
|
|
||||||
|
be = beRange[0];
|
||||||
|
be->myInGroup = true;
|
||||||
|
while ( be != beRange[1] )
|
||||||
|
{
|
||||||
|
be->myInGroup = true;
|
||||||
|
be = be->myNext;
|
||||||
|
}
|
||||||
|
beRange[1]->myInGroup = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
foundFreeBordes._coincidentGroups.push_back( group );
|
||||||
|
|
||||||
|
} // loop on free borders
|
||||||
|
}
|
@ -439,8 +439,10 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
|
|||||||
bool _outerFacesFound;
|
bool _outerFacesFound;
|
||||||
set<const SMDS_MeshElement*> _outerFaces; // empty means "no internal faces at all"
|
set<const SMDS_MeshElement*> _outerFaces; // empty means "no internal faces at all"
|
||||||
|
|
||||||
SMESH_ElementSearcherImpl( SMDS_Mesh& mesh, SMDS_ElemIteratorPtr elemIt=SMDS_ElemIteratorPtr())
|
SMESH_ElementSearcherImpl( SMDS_Mesh& mesh,
|
||||||
: _mesh(&mesh),_meshPartIt(elemIt),_ebbTree(0),_nodeSearcher(0),_tolerance(-1),_outerFacesFound(false) {}
|
double tol=-1,
|
||||||
|
SMDS_ElemIteratorPtr elemIt=SMDS_ElemIteratorPtr())
|
||||||
|
: _mesh(&mesh),_meshPartIt(elemIt),_ebbTree(0),_nodeSearcher(0),_tolerance(tol),_outerFacesFound(false) {}
|
||||||
virtual ~SMESH_ElementSearcherImpl()
|
virtual ~SMESH_ElementSearcherImpl()
|
||||||
{
|
{
|
||||||
if ( _ebbTree ) delete _ebbTree; _ebbTree = 0;
|
if ( _ebbTree ) delete _ebbTree; _ebbTree = 0;
|
||||||
@ -1091,32 +1093,22 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin
|
|||||||
|
|
||||||
// get ordered nodes
|
// get ordered nodes
|
||||||
|
|
||||||
vector< gp_XYZ > xyz;
|
vector< SMESH_TNodeXYZ > xyz;
|
||||||
vector<const SMDS_MeshNode*> nodeList;
|
|
||||||
|
|
||||||
SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
|
SMDS_ElemIteratorPtr nodeIt = element->interlacedNodesElemIterator();
|
||||||
if ( element->IsQuadratic() ) {
|
|
||||||
nodeIt = element->interlacedNodesElemIterator();
|
|
||||||
// if (const SMDS_VtkFace* f=dynamic_cast<const SMDS_VtkFace*>(element))
|
|
||||||
// nodeIt = f->interlacedNodesElemIterator();
|
|
||||||
// else if (const SMDS_VtkEdge* e =dynamic_cast<const SMDS_VtkEdge*>(element))
|
|
||||||
// nodeIt = e->interlacedNodesElemIterator();
|
|
||||||
}
|
|
||||||
while ( nodeIt->more() )
|
while ( nodeIt->more() )
|
||||||
{
|
{
|
||||||
SMESH_TNodeXYZ node = nodeIt->next();
|
SMESH_TNodeXYZ node = nodeIt->next();
|
||||||
xyz.push_back( node );
|
xyz.push_back( node );
|
||||||
nodeList.push_back(node._node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int i, nbNodes = (int) nodeList.size(); // central node of biquadratic is missing
|
int i, nbNodes = (int) xyz.size(); // central node of biquadratic is missing
|
||||||
|
|
||||||
if ( element->GetType() == SMDSAbs_Face ) // --------------------------------------------------
|
if ( element->GetType() == SMDSAbs_Face ) // --------------------------------------------------
|
||||||
{
|
{
|
||||||
// compute face normal
|
// compute face normal
|
||||||
gp_Vec faceNorm(0,0,0);
|
gp_Vec faceNorm(0,0,0);
|
||||||
xyz.push_back( xyz.front() );
|
xyz.push_back( xyz.front() );
|
||||||
nodeList.push_back( nodeList.front() );
|
|
||||||
for ( i = 0; i < nbNodes; ++i )
|
for ( i = 0; i < nbNodes; ++i )
|
||||||
{
|
{
|
||||||
gp_Vec edge1( xyz[i+1], xyz[i]);
|
gp_Vec edge1( xyz[i+1], xyz[i]);
|
||||||
@ -1129,7 +1121,7 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin
|
|||||||
// degenerated face: point is out if it is out of all face edges
|
// degenerated face: point is out if it is out of all face edges
|
||||||
for ( i = 0; i < nbNodes; ++i )
|
for ( i = 0; i < nbNodes; ++i )
|
||||||
{
|
{
|
||||||
SMDS_LinearEdge edge( nodeList[i], nodeList[i+1] );
|
SMDS_LinearEdge edge( xyz[i]._node, xyz[i+1]._node );
|
||||||
if ( !IsOut( &edge, point, tol ))
|
if ( !IsOut( &edge, point, tol ))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1216,13 +1208,28 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin
|
|||||||
// (we consider quadratic edge as being composed of two straight parts)
|
// (we consider quadratic edge as being composed of two straight parts)
|
||||||
for ( i = 1; i < nbNodes; ++i )
|
for ( i = 1; i < nbNodes; ++i )
|
||||||
{
|
{
|
||||||
gp_Vec edge( xyz[i-1], xyz[i]);
|
gp_Vec edge( xyz[i-1], xyz[i] );
|
||||||
gp_Vec n1p ( xyz[i-1], point);
|
gp_Vec n1p ( xyz[i-1], point );
|
||||||
double dist = ( edge ^ n1p ).Magnitude() / edge.Magnitude();
|
// double dist = ( edge ^ n1p ).Magnitude() / edge.Magnitude();
|
||||||
if ( dist > tol )
|
// if ( dist > tol )
|
||||||
|
// continue;
|
||||||
|
// gp_Vec n2p( xyz[i], point );
|
||||||
|
// if ( fabs( edge.Magnitude() - n1p.Magnitude() - n2p.Magnitude()) > tol )
|
||||||
|
// continue;
|
||||||
|
double u = ( edge * n1p ) / edge.SquareMagnitude(); // param [0,1] on the edge
|
||||||
|
if ( u < 0. ) {
|
||||||
|
if ( n1p.SquareMagnitude() < tol * tol )
|
||||||
|
return false;
|
||||||
continue;
|
continue;
|
||||||
gp_Vec n2p( xyz[i], point );
|
}
|
||||||
if ( fabs( edge.Magnitude() - n1p.Magnitude() - n2p.Magnitude()) > tol )
|
if ( u > 1. ) {
|
||||||
|
if ( point.SquareDistance( xyz[i] ) < tol * tol )
|
||||||
|
return false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
gp_XYZ proj = ( 1. - u ) * xyz[i-1] + u * xyz[i]; // projection of the point on the edge
|
||||||
|
double dist2 = point.SquareDistance( proj );
|
||||||
|
if ( dist2 > tol * tol )
|
||||||
continue;
|
continue;
|
||||||
return false; // point is ON this part
|
return false; // point is ON this part
|
||||||
}
|
}
|
||||||
@ -1231,7 +1238,7 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin
|
|||||||
// Node or 0D element -------------------------------------------------------------------------
|
// Node or 0D element -------------------------------------------------------------------------
|
||||||
{
|
{
|
||||||
gp_Vec n2p ( xyz[0], point );
|
gp_Vec n2p ( xyz[0], point );
|
||||||
return n2p.Magnitude() <= tol;
|
return n2p.SquareMagnitude() <= tol * tol;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1650,9 +1657,10 @@ SMESH_NodeSearcher* SMESH_MeshAlgos::GetNodeSearcher(SMDS_Mesh& mesh)
|
|||||||
*/
|
*/
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
SMESH_ElementSearcher* SMESH_MeshAlgos::GetElementSearcher(SMDS_Mesh& mesh)
|
SMESH_ElementSearcher* SMESH_MeshAlgos::GetElementSearcher(SMDS_Mesh& mesh,
|
||||||
|
double tolerance)
|
||||||
{
|
{
|
||||||
return new SMESH_ElementSearcherImpl( mesh );
|
return new SMESH_ElementSearcherImpl( mesh, tolerance );
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@ -1662,7 +1670,8 @@ SMESH_ElementSearcher* SMESH_MeshAlgos::GetElementSearcher(SMDS_Mesh& mesh)
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
SMESH_ElementSearcher* SMESH_MeshAlgos::GetElementSearcher(SMDS_Mesh& mesh,
|
SMESH_ElementSearcher* SMESH_MeshAlgos::GetElementSearcher(SMDS_Mesh& mesh,
|
||||||
SMDS_ElemIteratorPtr elemIt)
|
SMDS_ElemIteratorPtr elemIt,
|
||||||
|
double tolerance)
|
||||||
{
|
{
|
||||||
return new SMESH_ElementSearcherImpl( mesh, elemIt );
|
return new SMESH_ElementSearcherImpl( mesh, tolerance, elemIt );
|
||||||
}
|
}
|
||||||
|
@ -156,10 +156,45 @@ namespace SMESH_MeshAlgos
|
|||||||
* \brief Return SMESH_ElementSearcher. The caller is responsible for deleting it
|
* \brief Return SMESH_ElementSearcher. The caller is responsible for deleting it
|
||||||
*/
|
*/
|
||||||
SMESHUtils_EXPORT
|
SMESHUtils_EXPORT
|
||||||
SMESH_ElementSearcher* GetElementSearcher( SMDS_Mesh& mesh );
|
SMESH_ElementSearcher* GetElementSearcher( SMDS_Mesh& mesh,
|
||||||
|
double tolerance=-1.);
|
||||||
SMESHUtils_EXPORT
|
SMESHUtils_EXPORT
|
||||||
SMESH_ElementSearcher* GetElementSearcher( SMDS_Mesh& mesh,
|
SMESH_ElementSearcher* GetElementSearcher( SMDS_Mesh& mesh,
|
||||||
SMDS_ElemIteratorPtr elemIt );
|
SMDS_ElemIteratorPtr elemIt,
|
||||||
}
|
double tolerance=-1. );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef std::vector<const SMDS_MeshNode*> TFreeBorder;
|
||||||
|
typedef std::vector<TFreeBorder> TFreeBorderVec;
|
||||||
|
struct TFreeBorderPart
|
||||||
|
{
|
||||||
|
int _border; // border index within a TFreeBorderVec
|
||||||
|
int _node1; // node index within the border-th TFreeBorder
|
||||||
|
int _node2;
|
||||||
|
int _nodeLast;
|
||||||
|
};
|
||||||
|
typedef std::vector<TFreeBorderPart> TCoincidentGroup;
|
||||||
|
typedef std::vector<TCoincidentGroup> TCoincidentGroupVec;
|
||||||
|
struct CoincidentFreeBorders
|
||||||
|
{
|
||||||
|
TFreeBorderVec _borders; // nodes of all free borders
|
||||||
|
TCoincidentGroupVec _coincidentGroups; // groups of coincident parts of borders
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Returns TFreeBorder's coincident within the given tolerance.
|
||||||
|
* If the tolerance <= 0.0 then one tenth of an average size of elements adjacent
|
||||||
|
* to free borders being compared is used.
|
||||||
|
*
|
||||||
|
* (Implemented in ./SMESH_FreeBorders.cxx)
|
||||||
|
*/
|
||||||
|
SMESHUtils_EXPORT
|
||||||
|
void FindCoincidentFreeBorders(SMDS_Mesh& mesh,
|
||||||
|
double tolerance,
|
||||||
|
CoincidentFreeBorders & foundFreeBordes);
|
||||||
|
|
||||||
|
|
||||||
|
} // SMESH_MeshAlgos
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -2414,6 +2414,7 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
|
|||||||
"Mirror","MirrorObject","Translate","TranslateObject","Rotate","RotateObject",
|
"Mirror","MirrorObject","Translate","TranslateObject","Rotate","RotateObject",
|
||||||
"FindCoincidentNodes","MergeNodes","FindEqualElements",
|
"FindCoincidentNodes","MergeNodes","FindEqualElements",
|
||||||
"MergeElements","MergeEqualElements","SewFreeBorders","SewConformFreeBorders",
|
"MergeElements","MergeEqualElements","SewFreeBorders","SewConformFreeBorders",
|
||||||
|
"FindCoincidentFreeBorders", "SewCoincidentFreeBorders",
|
||||||
"SewBorderToSide","SewSideElements","ChangeElemNodes","GetLastCreatedNodes",
|
"SewBorderToSide","SewSideElements","ChangeElemNodes","GetLastCreatedNodes",
|
||||||
"GetLastCreatedElems",
|
"GetLastCreatedElems",
|
||||||
"MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh","TranslateObjectMakeMesh",
|
"MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh","TranslateObjectMakeMesh",
|
||||||
|
@ -547,6 +547,39 @@ namespace SMESH
|
|||||||
DumpArray( theList, *this );
|
DumpArray( theList, *this );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
TPythonDump& TPythonDump::operator<<(const SMESH::CoincidentFreeBorders& theCFB)
|
||||||
|
{
|
||||||
|
// dump CoincidentFreeBorders as a list of lists, each enclosed list
|
||||||
|
// contains node IDs of a group of coincident free borders where
|
||||||
|
// each consequent triple of IDs describe a free border: (n1, n2, nLast)
|
||||||
|
// For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes
|
||||||
|
// two groups of coincident free borders, each group including two borders
|
||||||
|
|
||||||
|
myStream << "[";
|
||||||
|
for ( CORBA::ULong i = 0; i < theCFB.coincidentGroups.length(); ++i )
|
||||||
|
{
|
||||||
|
const SMESH::FreeBordersGroup& aGRP = theCFB.coincidentGroups[ i ];
|
||||||
|
if ( i ) myStream << ",";
|
||||||
|
myStream << "[";
|
||||||
|
for ( CORBA::ULong iP = 0; iP < aGRP.length(); ++iP )
|
||||||
|
{
|
||||||
|
const SMESH::FreeBorderPart& aPART = aGRP[ iP ];
|
||||||
|
if ( 0 <= aPART.border && aPART.border < theCFB.borders.length() )
|
||||||
|
{
|
||||||
|
if ( iP ) myStream << ", ";
|
||||||
|
const SMESH::FreeBorder& aBRD = theCFB.borders[ aPART.border ];
|
||||||
|
myStream << aBRD.nodeIDs[ aPART.node1 ] << ",";
|
||||||
|
myStream << aBRD.nodeIDs[ aPART.node2 ] << ",";
|
||||||
|
myStream << aBRD.nodeIDs[ aPART.nodeLast ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
myStream << "]";
|
||||||
|
}
|
||||||
|
myStream << "]";
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
const char* TPythonDump::NotPublishedObjectName()
|
const char* TPythonDump::NotPublishedObjectName()
|
||||||
{
|
{
|
||||||
return theNotPublishedObjectName;
|
return theNotPublishedObjectName;
|
||||||
|
@ -4572,6 +4572,182 @@ static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Se
|
|||||||
return SMESH::SMESH_MeshEditor::SEW_OK;
|
return SMESH::SMESH_MeshEditor::SEW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
/*!
|
||||||
|
* Returns groups of FreeBorder's coincident within the given tolerance.
|
||||||
|
* If the tolerance <= 0.0 then one tenth of an average size of elements adjacent
|
||||||
|
* to free borders being compared is used.
|
||||||
|
*/
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
SMESH::CoincidentFreeBorders*
|
||||||
|
SMESH_MeshEditor_i::FindCoincidentFreeBorders(CORBA::Double tolerance)
|
||||||
|
{
|
||||||
|
SMESH::CoincidentFreeBorders_var aCFB = new SMESH::CoincidentFreeBorders;
|
||||||
|
|
||||||
|
SMESH_TRY;
|
||||||
|
|
||||||
|
SMESH_MeshAlgos::CoincidentFreeBorders cfb;
|
||||||
|
SMESH_MeshAlgos::FindCoincidentFreeBorders( *getMeshDS(), tolerance, cfb );
|
||||||
|
|
||||||
|
// copy free borders
|
||||||
|
aCFB->borders.length( cfb._borders.size() );
|
||||||
|
for ( size_t i = 0; i < cfb._borders.size(); ++i )
|
||||||
|
{
|
||||||
|
SMESH_MeshAlgos::TFreeBorder& nodes = cfb._borders[i];
|
||||||
|
SMESH::FreeBorder& aBRD = aCFB->borders[i];
|
||||||
|
aBRD.nodeIDs.length( nodes.size() );
|
||||||
|
for ( size_t iN = 0; iN < nodes.size(); ++iN )
|
||||||
|
aBRD.nodeIDs[ iN ] = nodes[ iN ]->GetID();
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy coincident parts
|
||||||
|
aCFB->coincidentGroups.length( cfb._coincidentGroups.size() );
|
||||||
|
for ( size_t i = 0; i < cfb._coincidentGroups.size(); ++i )
|
||||||
|
{
|
||||||
|
SMESH_MeshAlgos::TCoincidentGroup& grp = cfb._coincidentGroups[i];
|
||||||
|
SMESH::FreeBordersGroup& aGRP = aCFB->coincidentGroups[i];
|
||||||
|
aGRP.length( grp.size() );
|
||||||
|
for ( size_t iP = 0; iP < grp.size(); ++iP )
|
||||||
|
{
|
||||||
|
SMESH_MeshAlgos::TFreeBorderPart& part = grp[ iP ];
|
||||||
|
SMESH::FreeBorderPart& aPART = aGRP[ iP ];
|
||||||
|
aPART.border = part._border;
|
||||||
|
aPART.node1 = part._node1;
|
||||||
|
aPART.node2 = part._node2;
|
||||||
|
aPART.nodeLast = part._nodeLast;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SMESH_CATCH( SMESH::doNothing );
|
||||||
|
|
||||||
|
TPythonDump() << "CoincidentFreeBorders = "
|
||||||
|
<< this << ".FindCoincidentFreeBorders( " << tolerance << " )";
|
||||||
|
|
||||||
|
return aCFB._retn();
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
/*!
|
||||||
|
* Sew FreeBorder's of each group
|
||||||
|
*/
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
CORBA::Short SMESH_MeshEditor_i::
|
||||||
|
SewCoincidentFreeBorders(const SMESH::CoincidentFreeBorders& freeBorders,
|
||||||
|
CORBA::Boolean createPolygons,
|
||||||
|
CORBA::Boolean createPolyhedra)
|
||||||
|
throw (SALOME::SALOME_Exception)
|
||||||
|
{
|
||||||
|
CORBA::Short nbSewed = 0;
|
||||||
|
|
||||||
|
SMESH_MeshAlgos::TFreeBorderVec groups;
|
||||||
|
SMESH_MeshAlgos::TFreeBorder borderNodes; // triples on nodes for every FreeBorderPart
|
||||||
|
|
||||||
|
// check the input
|
||||||
|
for ( CORBA::ULong i = 0; i < freeBorders.coincidentGroups.length(); ++i )
|
||||||
|
{
|
||||||
|
const SMESH::FreeBordersGroup& aGRP = freeBorders.coincidentGroups[ i ];
|
||||||
|
for ( CORBA::ULong iP = 0; iP < aGRP.length(); ++iP )
|
||||||
|
{
|
||||||
|
const SMESH::FreeBorderPart& aPART = aGRP[ iP ];
|
||||||
|
if ( aPART.border < 0 || aPART.border >= freeBorders.borders.length() )
|
||||||
|
THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::border index", SALOME::BAD_PARAM);
|
||||||
|
|
||||||
|
const SMESH::FreeBorder& aBRD = freeBorders.borders[ aPART.border ];
|
||||||
|
|
||||||
|
if ( aPART.node1 < 0 || aPART.node1 > aBRD.nodeIDs.length() )
|
||||||
|
THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::node1", SALOME::BAD_PARAM);
|
||||||
|
if ( aPART.node2 < 0 || aPART.node2 > aBRD.nodeIDs.length() )
|
||||||
|
THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::node2", SALOME::BAD_PARAM);
|
||||||
|
if ( aPART.nodeLast < 0 || aPART.nodeLast > aBRD.nodeIDs.length() )
|
||||||
|
THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::nodeLast", SALOME::BAD_PARAM);
|
||||||
|
|
||||||
|
// do not keep these nodes for further sewing as nodes can be removed by the sewing
|
||||||
|
const SMDS_MeshNode* n1 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node1 ]);
|
||||||
|
const SMDS_MeshNode* n2 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node2 ]);
|
||||||
|
const SMDS_MeshNode* n3 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.nodeLast ]);
|
||||||
|
if ( !n1)
|
||||||
|
THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::node1", SALOME::BAD_PARAM);
|
||||||
|
if ( !n2 )
|
||||||
|
THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::node2", SALOME::BAD_PARAM);
|
||||||
|
if ( !n3 )
|
||||||
|
THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::nodeLast", SALOME::BAD_PARAM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TIDSortedElemSet dummy;
|
||||||
|
|
||||||
|
::SMESH_MeshEditor::Sew_Error res, ok = ::SMESH_MeshEditor::SEW_OK;
|
||||||
|
for ( CORBA::ULong i = 0; i < freeBorders.coincidentGroups.length(); ++i )
|
||||||
|
{
|
||||||
|
const SMESH::FreeBordersGroup& aGRP = freeBorders.coincidentGroups[ i ];
|
||||||
|
if ( aGRP.length() < 2 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
//int n1bord2, n2bord2;
|
||||||
|
|
||||||
|
bool groupSewed = false;
|
||||||
|
for ( CORBA::ULong iP = 1; iP < aGRP.length(); ++iP )
|
||||||
|
{
|
||||||
|
const SMESH::FreeBorderPart& aPART_0 = aGRP[ 0 ];
|
||||||
|
const SMESH::FreeBorder& aBRD_0 = freeBorders.borders[ aPART_0.border ];
|
||||||
|
|
||||||
|
const SMDS_MeshNode* n0 = getMeshDS()->FindNode( aBRD_0.nodeIDs[ aPART_0.node1 ]);
|
||||||
|
const SMDS_MeshNode* n1 = getMeshDS()->FindNode( aBRD_0.nodeIDs[ aPART_0.node2 ]);
|
||||||
|
const SMDS_MeshNode* n2 = getMeshDS()->FindNode( aBRD_0.nodeIDs[ aPART_0.nodeLast ]);
|
||||||
|
|
||||||
|
const SMESH::FreeBorderPart& aPART = aGRP[ iP ];
|
||||||
|
const SMESH::FreeBorder& aBRD = freeBorders.borders[ aPART.border ];
|
||||||
|
|
||||||
|
const SMDS_MeshNode* n3 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node1 ]);
|
||||||
|
const SMDS_MeshNode* n4 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node2 ]);
|
||||||
|
const SMDS_MeshNode* n5 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.nodeLast ]);
|
||||||
|
|
||||||
|
if ( !n0 || !n1 || !n2 || !n3 || !n4 || !n5 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// if ( iP == 1 )
|
||||||
|
// {
|
||||||
|
// n1bord2 = aBRD.nodeIDs[ aPART.node1 ];
|
||||||
|
// n2bord2 = aBRD.nodeIDs[ aPART.node2 ];
|
||||||
|
// }
|
||||||
|
// else if ( !SMESH_MeshAlgos::FindFaceInSet( n0, n1, dummy, dummy ))
|
||||||
|
// {
|
||||||
|
// // a face including n0 and n1 was split;
|
||||||
|
// // find a new face starting at n0 in order to get a new n1
|
||||||
|
// const SMDS_MeshNode* n1test = getMeshDS()->FindNode( n1bord2 );
|
||||||
|
// const SMDS_MeshNode* n2test = getMeshDS()->FindNode( n2bord2 );
|
||||||
|
// if ( n1test && SMESH_MeshAlgos::FindFaceInSet( n0, n1test, dummy, dummy ))
|
||||||
|
// n1 = n1test;
|
||||||
|
// else if ( n2test && SMESH_MeshAlgos::FindFaceInSet( n0, n2test, dummy, dummy ))
|
||||||
|
// n1 = n2test;
|
||||||
|
// // else continue; ??????
|
||||||
|
// }
|
||||||
|
|
||||||
|
if ( iP > 1 )
|
||||||
|
{
|
||||||
|
n1 = n2; // at border-to-side sewing only last side node (n1) is needed
|
||||||
|
n2 = 0; // and n2 is not used
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1st border moves to 2nd
|
||||||
|
res = getEditor().SewFreeBorder( n3, n4, n5 ,// 1st
|
||||||
|
n0 ,n1 ,n2 ,// 2nd
|
||||||
|
/*2ndIsFreeBorder=*/ iP == 1,
|
||||||
|
createPolygons, createPolyhedra);
|
||||||
|
groupSewed = ( res == ok );
|
||||||
|
}
|
||||||
|
nbSewed += groupSewed;
|
||||||
|
}
|
||||||
|
|
||||||
|
TPythonDump() << "nbSewed = " << this << ".SewCoincidentFreeBorders( "
|
||||||
|
<< freeBorders << ", "
|
||||||
|
<< createPolygons << ", "
|
||||||
|
<< createPolyhedra << " )";
|
||||||
|
|
||||||
|
return nbSewed;
|
||||||
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : SewFreeBorders
|
//function : SewFreeBorders
|
||||||
//purpose :
|
//purpose :
|
||||||
@ -4621,14 +4797,14 @@ SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
|
|||||||
|
|
||||||
SMESH::SMESH_MeshEditor::Sew_Error error =
|
SMESH::SMESH_MeshEditor::Sew_Error error =
|
||||||
convError( getEditor().SewFreeBorder (aBorderFirstNode,
|
convError( getEditor().SewFreeBorder (aBorderFirstNode,
|
||||||
aBorderSecondNode,
|
aBorderSecondNode,
|
||||||
aBorderLastNode,
|
aBorderLastNode,
|
||||||
aSide2FirstNode,
|
aSide2FirstNode,
|
||||||
aSide2SecondNode,
|
aSide2SecondNode,
|
||||||
aSide2ThirdNode,
|
aSide2ThirdNode,
|
||||||
true,
|
true,
|
||||||
CreatePolygons,
|
CreatePolygons,
|
||||||
CreatePolyedrs) );
|
CreatePolyedrs) );
|
||||||
|
|
||||||
|
|
||||||
declareMeshModified( /*isReComputeSafe=*/false );
|
declareMeshModified( /*isReComputeSafe=*/false );
|
||||||
@ -4681,13 +4857,13 @@ SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
|
|||||||
|
|
||||||
SMESH::SMESH_MeshEditor::Sew_Error error =
|
SMESH::SMESH_MeshEditor::Sew_Error error =
|
||||||
convError( getEditor().SewFreeBorder (aBorderFirstNode,
|
convError( getEditor().SewFreeBorder (aBorderFirstNode,
|
||||||
aBorderSecondNode,
|
aBorderSecondNode,
|
||||||
aBorderLastNode,
|
aBorderLastNode,
|
||||||
aSide2FirstNode,
|
aSide2FirstNode,
|
||||||
aSide2SecondNode,
|
aSide2SecondNode,
|
||||||
aSide2ThirdNode,
|
aSide2ThirdNode,
|
||||||
true,
|
true,
|
||||||
false, false) );
|
false, false) );
|
||||||
|
|
||||||
declareMeshModified( /*isReComputeSafe=*/false );
|
declareMeshModified( /*isReComputeSafe=*/false );
|
||||||
return error;
|
return error;
|
||||||
@ -4743,14 +4919,14 @@ SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
|
|||||||
|
|
||||||
SMESH::SMESH_MeshEditor::Sew_Error error =
|
SMESH::SMESH_MeshEditor::Sew_Error error =
|
||||||
convError( getEditor().SewFreeBorder (aBorderFirstNode,
|
convError( getEditor().SewFreeBorder (aBorderFirstNode,
|
||||||
aBorderSecondNode,
|
aBorderSecondNode,
|
||||||
aBorderLastNode,
|
aBorderLastNode,
|
||||||
aSide2FirstNode,
|
aSide2FirstNode,
|
||||||
aSide2SecondNode,
|
aSide2SecondNode,
|
||||||
aSide2ThirdNode,
|
aSide2ThirdNode,
|
||||||
false,
|
false,
|
||||||
CreatePolygons,
|
CreatePolygons,
|
||||||
CreatePolyedrs) );
|
CreatePolyedrs) );
|
||||||
|
|
||||||
declareMeshModified( /*isReComputeSafe=*/false );
|
declareMeshModified( /*isReComputeSafe=*/false );
|
||||||
return error;
|
return error;
|
||||||
|
@ -538,6 +538,12 @@ public:
|
|||||||
CORBA::Short GetPointState(CORBA::Double x, CORBA::Double y, CORBA::Double z)
|
CORBA::Short GetPointState(CORBA::Double x, CORBA::Double y, CORBA::Double z)
|
||||||
throw (SALOME::SALOME_Exception);
|
throw (SALOME::SALOME_Exception);
|
||||||
|
|
||||||
|
SMESH::CoincidentFreeBorders* FindCoincidentFreeBorders(CORBA::Double tolerance);
|
||||||
|
CORBA::Short SewCoincidentFreeBorders(const SMESH::CoincidentFreeBorders& freeBorders,
|
||||||
|
CORBA::Boolean createPolygons,
|
||||||
|
CORBA::Boolean createPolyedrs)
|
||||||
|
throw (SALOME::SALOME_Exception);
|
||||||
|
|
||||||
SMESH::SMESH_MeshEditor::Sew_Error
|
SMESH::SMESH_MeshEditor::Sew_Error
|
||||||
SewFreeBorders(CORBA::Long FirstNodeID1,
|
SewFreeBorders(CORBA::Long FirstNodeID1,
|
||||||
CORBA::Long SecondNodeID1,
|
CORBA::Long SecondNodeID1,
|
||||||
@ -546,15 +552,13 @@ public:
|
|||||||
CORBA::Long SecondNodeID2,
|
CORBA::Long SecondNodeID2,
|
||||||
CORBA::Long LastNodeID2,
|
CORBA::Long LastNodeID2,
|
||||||
CORBA::Boolean CreatePolygons,
|
CORBA::Boolean CreatePolygons,
|
||||||
CORBA::Boolean CreatePolyedrs)
|
CORBA::Boolean CreatePolyedrs) throw (SALOME::SALOME_Exception);
|
||||||
throw (SALOME::SALOME_Exception);
|
|
||||||
SMESH::SMESH_MeshEditor::Sew_Error
|
SMESH::SMESH_MeshEditor::Sew_Error
|
||||||
SewConformFreeBorders(CORBA::Long FirstNodeID1,
|
SewConformFreeBorders(CORBA::Long FirstNodeID1,
|
||||||
CORBA::Long SecondNodeID1,
|
CORBA::Long SecondNodeID1,
|
||||||
CORBA::Long LastNodeID1,
|
CORBA::Long LastNodeID1,
|
||||||
CORBA::Long FirstNodeID2,
|
CORBA::Long FirstNodeID2,
|
||||||
CORBA::Long SecondNodeID2)
|
CORBA::Long SecondNodeID2) throw (SALOME::SALOME_Exception);
|
||||||
throw (SALOME::SALOME_Exception);
|
|
||||||
SMESH::SMESH_MeshEditor::Sew_Error
|
SMESH::SMESH_MeshEditor::Sew_Error
|
||||||
SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
|
SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
|
||||||
CORBA::Long SecondNodeIDOnFreeBorder,
|
CORBA::Long SecondNodeIDOnFreeBorder,
|
||||||
@ -562,16 +566,14 @@ public:
|
|||||||
CORBA::Long FirstNodeIDOnSide,
|
CORBA::Long FirstNodeIDOnSide,
|
||||||
CORBA::Long LastNodeIDOnSide,
|
CORBA::Long LastNodeIDOnSide,
|
||||||
CORBA::Boolean CreatePolygons,
|
CORBA::Boolean CreatePolygons,
|
||||||
CORBA::Boolean CreatePolyedrs)
|
CORBA::Boolean CreatePolyedrs) throw (SALOME::SALOME_Exception);
|
||||||
throw (SALOME::SALOME_Exception);
|
|
||||||
SMESH::SMESH_MeshEditor::Sew_Error
|
SMESH::SMESH_MeshEditor::Sew_Error
|
||||||
SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
|
SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
|
||||||
const SMESH::long_array& IDsOfSide2Elements,
|
const SMESH::long_array& IDsOfSide2Elements,
|
||||||
CORBA::Long NodeID1OfSide1ToMerge,
|
CORBA::Long NodeID1OfSide1ToMerge,
|
||||||
CORBA::Long NodeID1OfSide2ToMerge,
|
CORBA::Long NodeID1OfSide2ToMerge,
|
||||||
CORBA::Long NodeID2OfSide1ToMerge,
|
CORBA::Long NodeID2OfSide1ToMerge,
|
||||||
CORBA::Long NodeID2OfSide2ToMerge)
|
CORBA::Long NodeID2OfSide2ToMerge) throw (SALOME::SALOME_Exception);
|
||||||
throw (SALOME::SALOME_Exception);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Set new nodes for given element.
|
* Set new nodes for given element.
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include <SALOMEconfig.h>
|
#include <SALOMEconfig.h>
|
||||||
#include CORBA_SERVER_HEADER(SMESH_Mesh)
|
#include CORBA_SERVER_HEADER(SMESH_Mesh)
|
||||||
|
#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
|
||||||
#include CORBA_SERVER_HEADER(GEOM_Gen)
|
#include CORBA_SERVER_HEADER(GEOM_Gen)
|
||||||
#include CORBA_SERVER_HEADER(SALOMEDS)
|
#include CORBA_SERVER_HEADER(SALOMEDS)
|
||||||
|
|
||||||
@ -229,6 +230,9 @@ namespace SMESH
|
|||||||
TPythonDump&
|
TPythonDump&
|
||||||
operator<<(const SMESH::ListOfIDSources& theList);
|
operator<<(const SMESH::ListOfIDSources& theList);
|
||||||
|
|
||||||
|
TPythonDump&
|
||||||
|
operator<<(const SMESH::CoincidentFreeBorders& theCFB);
|
||||||
|
|
||||||
static const char* SMESHGenName() { return "smeshgen"; }
|
static const char* SMESHGenName() { return "smeshgen"; }
|
||||||
static const char* MeshEditorName() { return "mesh_editor"; }
|
static const char* MeshEditorName() { return "mesh_editor"; }
|
||||||
static const char* NotPublishedObjectName();
|
static const char* NotPublishedObjectName();
|
||||||
|
@ -4519,6 +4519,52 @@ class Mesh:
|
|||||||
def MergeEqualElements(self):
|
def MergeEqualElements(self):
|
||||||
self.editor.MergeEqualElements()
|
self.editor.MergeEqualElements()
|
||||||
|
|
||||||
|
## Returns groups of FreeBorder's coincident within the given tolerance.
|
||||||
|
# @param tolerance the tolerance. If the tolerance <= 0.0 then one tenth of an average
|
||||||
|
# size of elements adjacent to free borders being compared is used.
|
||||||
|
# @return SMESH.CoincidentFreeBorders structure
|
||||||
|
# @ingroup l2_modif_trsf
|
||||||
|
def FindCoincidentFreeBorders (self, tolerance=0.):
|
||||||
|
return self.editor.FindCoincidentFreeBorders( tolerance )
|
||||||
|
|
||||||
|
## Sew FreeBorder's of each group
|
||||||
|
# @param freeBorders either a SMESH.CoincidentFreeBorders structure or a list of lists
|
||||||
|
# where each enclosed list contains node IDs of a group of coincident free
|
||||||
|
# borders such that each consequent triple of IDs within a group describes
|
||||||
|
# a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
|
||||||
|
# last node of a border.
|
||||||
|
# For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
|
||||||
|
# groups of coincident free borders, each group including two borders.
|
||||||
|
# @param createPolygons if @c True faces adjacent to free borders are converted to
|
||||||
|
# polygons if a node of opposite border falls on a face edge, else such
|
||||||
|
# faces are split into several ones.
|
||||||
|
# @param createPolyhedra if @c True volumes adjacent to free borders are converted to
|
||||||
|
# polyhedra if a node of opposite border falls on a volume edge, else such
|
||||||
|
# volumes, if any, remain intact and the mesh becomes non-conformal.
|
||||||
|
# @return a number of successfully sewed groups
|
||||||
|
# @ingroup l2_modif_trsf
|
||||||
|
def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
|
||||||
|
if freeBorders and isinstance( freeBorders, list ):
|
||||||
|
# construct SMESH.CoincidentFreeBorders
|
||||||
|
if isinstance( freeBorders[0], int ):
|
||||||
|
freeBorders = [freeBorders]
|
||||||
|
borders = []
|
||||||
|
coincidentGroups = []
|
||||||
|
for nodeList in freeBorders:
|
||||||
|
if not nodeList or len( nodeList ) % 3:
|
||||||
|
raise ValueError, "Wrong number of nodes in this group: %s" % nodeList
|
||||||
|
group = []
|
||||||
|
while nodeList:
|
||||||
|
group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
|
||||||
|
borders.append( SMESH.FreeBorder( nodeList[:3] ))
|
||||||
|
nodeList = nodeList[3:]
|
||||||
|
pass
|
||||||
|
coincidentGroups.append( group )
|
||||||
|
pass
|
||||||
|
freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
|
||||||
|
|
||||||
|
return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
|
||||||
|
|
||||||
## Sews free borders
|
## Sews free borders
|
||||||
# @return SMESH::Sew_Error
|
# @return SMESH::Sew_Error
|
||||||
# @ingroup l2_modif_trsf
|
# @ingroup l2_modif_trsf
|
||||||
|
Loading…
Reference in New Issue
Block a user