mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-11-11 16:19:16 +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"
|
||||
|
||||
<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
|
||||
between opposite sides of the face with a different number of
|
||||
|
@ -23,7 +23,9 @@ elements which will form your group:</li>
|
||||
</ul>
|
||||
<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
|
||||
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>
|
||||
Mesh module distinguishes between the three Group types:
|
||||
<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
|
||||
created);
|
||||
</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
|
||||
array of dedicated operations;</li>
|
||||
<li>\subpage grouping_elements_page "creating groups of mesh
|
||||
elements";</li>
|
||||
<li>\subpage grouping_elements_page "creating groups" of mesh
|
||||
elements;</li>
|
||||
<li>filtering mesh entities (nodes or elements) using
|
||||
\subpage filters_page "Filters" functionality for \ref
|
||||
grouping_elements_page "creating groups" and applying \ref
|
||||
modifying_meshes_page "mesh modifications";</li>
|
||||
<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",
|
||||
allowing to highlight important elements;</li>
|
||||
<li>taking various \subpage measurements_page "measurements" of the
|
||||
|
@ -21,10 +21,10 @@ then converted to the single node.
|
||||
processed.
|
||||
<li>\b Tolerance is a maximum distance between nodes sufficient for
|
||||
merging.</li>
|
||||
<li>Activation of <b>No merge of corner and medium nodes</b> check-box
|
||||
prevents merging medium nodes of quadratic elements with corner
|
||||
nodes. This check-box is enabled provided that the selected mesh
|
||||
includes quadratic elements.</li>
|
||||
<li>Activation of <b>No merge of corner and medium nodes of quadratic
|
||||
cells</b> check-box prevents merging medium nodes of quadratic
|
||||
elements with corner nodes. This check-box is enabled provided
|
||||
that the selected mesh includes quadratic elements.</li>
|
||||
<li><b>Exclude Groups</b> group box allows to ignore the nodes which
|
||||
belong to the specified mesh groups.</li>
|
||||
<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>
|
||||
|
||||
The <b>Mesh Information</b> dialog box provides three tab pages:
|
||||
- <b>\ref advanced_mesh_infos_anchor "Base Info"</b> - to show base
|
||||
information about the selected mesh object.
|
||||
- <b>\ref advanced_mesh_infos_anchor "Base Info"</b> - to show
|
||||
base and quantitative information about the selected mesh object.
|
||||
- <b>\ref mesh_element_info_anchor "Element Info"</b> - to show
|
||||
detailed information about the selected mesh node or element.
|
||||
- <b>\ref mesh_addition_info_anchor "Additional Info"</b> - to show additional information available
|
||||
for the selected mesh, sub-mesh or group object.
|
||||
detailed information about the selected mesh nodes or elements.
|
||||
- <b>\ref mesh_addition_info_anchor "Additional Info"</b> - to show
|
||||
additional information available for the selected mesh, sub-mesh or
|
||||
group object.
|
||||
- <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
|
||||
<h2>Base Information</h2>
|
||||
|
@ -27,7 +27,13 @@ the type of sewing operation you would like to perform.</li>
|
||||
\anchor free_borders_anchor
|
||||
<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
|
||||
|
||||
|
@ -26,8 +26,11 @@ information about the mesh.</li>
|
||||
<li>\subpage find_element_by_point_page "Find Element by Point" -
|
||||
allows to find all mesh elements, to which belongs a point with the
|
||||
given coordinates.</li>
|
||||
<li><b>Auto Color</b> - switch on / off auto-assigning colors for the groups.</li>
|
||||
<li>\subpage numbering_page "Numbering" - allows to display the ID
|
||||
<li><b>Auto Color</b> - switch on / off auto-assigning colors for the
|
||||
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
|
||||
viewer.</li>
|
||||
<li>\subpage display_mode_page "Display Mode" - allows to select between
|
||||
|
@ -29,13 +29,37 @@
|
||||
|
||||
module SMESH
|
||||
{
|
||||
interface NumericalFunctor;
|
||||
|
||||
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.
|
||||
*/
|
||||
interface NumericalFunctor;
|
||||
|
||||
interface SMESH_MeshEditor
|
||||
{
|
||||
/*!
|
||||
@ -723,6 +747,21 @@ module SMESH
|
||||
short GetPointState(in double x, in double y, in double z)
|
||||
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 {
|
||||
SEW_OK,
|
||||
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 )
|
||||
return false;
|
||||
|
||||
vector<int> anIds( nbNodes );
|
||||
SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
|
||||
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 ];
|
||||
}
|
||||
theNodeId1 = anElem->GetNode( theEdgeNum - 1 )->GetID();
|
||||
theNodeId2 = anElem->GetNode( theEdgeNum % nbNodes )->GetID();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ int SMDS_MeshNode::nbNodes =0;
|
||||
|
||||
//=======================================================================
|
||||
//function : SMDS_MeshNode
|
||||
//purpose :
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
SMDS_MeshNode::SMDS_MeshNode() :
|
||||
SMDS_MeshElement(-1, -1, 0),
|
||||
@ -83,31 +83,31 @@ SMDS_MeshNode::~SMDS_MeshNode()
|
||||
|
||||
//=======================================================================
|
||||
//function : RemoveInverseElement
|
||||
//purpose :
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * parent)
|
||||
{
|
||||
//MESSAGE("RemoveInverseElement " << myID << " " << parent->GetID());
|
||||
const SMDS_MeshCell* cell = dynamic_cast<const SMDS_MeshCell*>(parent);
|
||||
MYASSERT(cell);
|
||||
SMDS_Mesh::_meshList[myMeshId]->getGrid()->RemoveReferenceToCell(myVtkID, cell->getVtkId());
|
||||
//MESSAGE("RemoveInverseElement " << myID << " " << parent->GetID());
|
||||
const SMDS_MeshCell* cell = dynamic_cast<const SMDS_MeshCell*>(parent);
|
||||
MYASSERT(cell);
|
||||
SMDS_Mesh::_meshList[myMeshId]->getGrid()->RemoveReferenceToCell(myVtkID, cell->getVtkId());
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Print
|
||||
//purpose :
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void SMDS_MeshNode::Print(ostream & OS) const
|
||||
{
|
||||
OS << "Node <" << myID << "> : X = " << X() << " Y = "
|
||||
<< Y() << " Z = " << Z() << endl;
|
||||
OS << "Node <" << myID << "> : X = " << X() << " Y = "
|
||||
<< Y() << " Z = " << Z() << endl;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetPosition
|
||||
//purpose :
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos)
|
||||
@ -121,7 +121,7 @@ void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos)
|
||||
|
||||
//=======================================================================
|
||||
//function : GetPosition
|
||||
//purpose :
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
const SMDS_PositionPtr& SMDS_MeshNode::GetPosition() const
|
||||
@ -178,10 +178,10 @@ public:
|
||||
int smdsId = myMesh->fromVtkToSmds(vtkId);
|
||||
const SMDS_MeshElement* elem = myMesh->FindElement(smdsId);
|
||||
if (!elem)
|
||||
{
|
||||
MESSAGE("SMDS_MeshNode_MyInvIterator problem Null element");
|
||||
throw SALOME_Exception("SMDS_MeshNode_MyInvIterator problem Null element");
|
||||
}
|
||||
{
|
||||
MESSAGE("SMDS_MeshNode_MyInvIterator problem Null element");
|
||||
throw SALOME_Exception("SMDS_MeshNode_MyInvIterator problem Null element");
|
||||
}
|
||||
//MESSAGE("vtkId " << vtkId << " smdsId " << smdsId << " " << elem->GetType());
|
||||
iter++;
|
||||
return elem;
|
||||
@ -189,11 +189,11 @@ public:
|
||||
};
|
||||
|
||||
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);
|
||||
//MESSAGE("myID " << myID << " ncells " << l.ncells);
|
||||
return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(SMDS_Mesh::_meshList[myMeshId], l.cells, l.ncells, type));
|
||||
vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
|
||||
//MESSAGE("myID " << myID << " ncells " << l.ncells);
|
||||
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
|
||||
@ -208,47 +208,47 @@ private:
|
||||
int iter;
|
||||
vector<SMDS_MeshElement*> myFiltCells;
|
||||
|
||||
public:
|
||||
public:
|
||||
SMDS_MeshNode_MyIterator(SMDS_Mesh *mesh,
|
||||
vtkIdType* cells,
|
||||
int ncells,
|
||||
SMDSAbs_ElementType type):
|
||||
myMesh(mesh), myCells(cells), myNcells(ncells), myType(type), iter(0)
|
||||
{
|
||||
//MESSAGE("myNcells " << myNcells);
|
||||
for (; iter<ncells; iter++)
|
||||
{
|
||||
int vtkId = myCells[iter];
|
||||
int smdsId = myMesh->fromVtkToSmds(vtkId);
|
||||
//MESSAGE("vtkId " << vtkId << " smdsId " << smdsId);
|
||||
const SMDS_MeshElement* elem = myMesh->FindElement(smdsId);
|
||||
if (elem->GetType() == type)
|
||||
myFiltCells.push_back((SMDS_MeshElement*)elem);
|
||||
}
|
||||
myNcells = myFiltCells.size();
|
||||
//MESSAGE("myNcells " << myNcells);
|
||||
iter = 0;
|
||||
//MESSAGE("SMDS_MeshNode_MyIterator (filter) " << ncells << " " << myNcells);
|
||||
//MESSAGE("myNcells " << myNcells);
|
||||
for (; iter<ncells; iter++)
|
||||
{
|
||||
int vtkId = myCells[iter];
|
||||
int smdsId = myMesh->fromVtkToSmds(vtkId);
|
||||
//MESSAGE("vtkId " << vtkId << " smdsId " << smdsId);
|
||||
const SMDS_MeshElement* elem = myMesh->FindElement(smdsId);
|
||||
if (elem->GetType() == type)
|
||||
myFiltCells.push_back((SMDS_MeshElement*)elem);
|
||||
}
|
||||
myNcells = myFiltCells.size();
|
||||
//MESSAGE("myNcells " << myNcells);
|
||||
iter = 0;
|
||||
//MESSAGE("SMDS_MeshNode_MyIterator (filter) " << ncells << " " << myNcells);
|
||||
}
|
||||
|
||||
bool more()
|
||||
{
|
||||
return (iter< myNcells);
|
||||
return (iter< myNcells);
|
||||
}
|
||||
|
||||
const SMDS_MeshElement* next()
|
||||
{
|
||||
const SMDS_MeshElement* elem = myFiltCells[iter];
|
||||
iter++;
|
||||
return elem;
|
||||
const SMDS_MeshElement* elem = myFiltCells[iter];
|
||||
iter++;
|
||||
return elem;
|
||||
}
|
||||
};
|
||||
|
||||
SMDS_ElemIteratorPtr SMDS_MeshNode::
|
||||
elementsIterator(SMDSAbs_ElementType type) const
|
||||
elementsIterator(SMDSAbs_ElementType type) const
|
||||
{
|
||||
if(type==SMDSAbs_Node)
|
||||
return SMDS_MeshElement::elementsIterator(SMDSAbs_Node);
|
||||
return SMDS_MeshElement::elementsIterator(SMDSAbs_Node);
|
||||
else
|
||||
{
|
||||
vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
|
||||
@ -258,7 +258,7 @@ SMDS_ElemIteratorPtr SMDS_MeshNode::
|
||||
|
||||
int SMDS_MeshNode::NbNodes() const
|
||||
{
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
return SMDSAbs_Node;
|
||||
return SMDSAbs_Node;
|
||||
}
|
||||
|
||||
vtkIdType SMDS_MeshNode::GetVtkType() const
|
||||
@ -358,11 +358,11 @@ int SMDS_MeshNode::NbInverseElements(SMDSAbs_ElementType type) const
|
||||
int nb = 0;
|
||||
SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId];
|
||||
for (int i=0; i<l.ncells; i++)
|
||||
{
|
||||
const SMDS_MeshElement* elem = mesh->FindElement(mesh->fromVtkToSmds(l.cells[i]));
|
||||
if (elem->GetType() == type)
|
||||
nb++;
|
||||
}
|
||||
{
|
||||
const SMDS_MeshElement* elem = mesh->FindElement(mesh->fromVtkToSmds(l.cells[i]));
|
||||
if (elem->GetType() == type)
|
||||
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)
|
||||
{
|
||||
return e1.getVtkId()<e2.getVtkId();
|
||||
/*if(e1.myX<e2.myX) return true;
|
||||
else if(e1.myX==e2.myX)
|
||||
{
|
||||
if(e1.myY<e2.myY) return true;
|
||||
else if(e1.myY==e2.myY) return (e1.myZ<e2.myZ);
|
||||
else return false;
|
||||
}
|
||||
else return false;*/
|
||||
return e1.getVtkId()<e2.getVtkId();
|
||||
/*if(e1.myX<e2.myX) return true;
|
||||
else if(e1.myX==e2.myX)
|
||||
{
|
||||
if(e1.myY<e2.myY) return true;
|
||||
else if(e1.myY==e2.myY) return (e1.myZ<e2.myZ);
|
||||
else return false;
|
||||
}
|
||||
else return false;*/
|
||||
}
|
||||
|
||||
|
@ -8269,6 +8269,8 @@ bool SMESH_MeshEditor::CheckFreeBorderNodes(const SMDS_MeshNode* theNode1,
|
||||
//=======================================================================
|
||||
//function : SewFreeBorder
|
||||
//purpose :
|
||||
//warning : for border-to-side sewing theSideSecondNode is considered as
|
||||
// the last side node and theSideThirdNode is not used
|
||||
//=======================================================================
|
||||
|
||||
SMESH_MeshEditor::Sew_Error
|
||||
|
@ -620,39 +620,26 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh,
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
// get all faces
|
||||
list< const SMDS_MeshElement* > faces;
|
||||
if ( nbElems > 0 ) {
|
||||
SMDS_ElemIteratorPtr fIt = fSubMesh->GetElements();
|
||||
while ( fIt->more() ) {
|
||||
const SMDS_MeshElement* f = fIt->next();
|
||||
if ( f && f->GetType() == SMDSAbs_Face )
|
||||
faces.push_back( f );
|
||||
}
|
||||
}
|
||||
else {
|
||||
SMDS_FaceIteratorPtr fIt = aMeshDS->facesIterator();
|
||||
while ( fIt->more() )
|
||||
faces.push_back( fIt->next() );
|
||||
}
|
||||
SMDS_ElemIteratorPtr fIt;
|
||||
if ( nbElems > 0 )
|
||||
fIt = fSubMesh->GetElements();
|
||||
else
|
||||
fIt = aMeshDS->elementsIterator( SMDSAbs_Face );
|
||||
|
||||
// put nodes of all faces into the nodePointIDMap and fill myElemPointIDs
|
||||
list< const SMDS_MeshElement* >::iterator fIt = faces.begin();
|
||||
for ( ; fIt != faces.end(); ++fIt )
|
||||
while ( fIt->more() )
|
||||
{
|
||||
const SMDS_MeshElement* face = fIt->next();
|
||||
myElemPointIDs.push_back( TElemDef() );
|
||||
TElemDef& elemPoints = myElemPointIDs.back();
|
||||
int nbNodes = (*fIt)->NbCornerNodes();
|
||||
int nbNodes = face->NbCornerNodes();
|
||||
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;
|
||||
if ( nIdIt->second == -1 )
|
||||
{
|
||||
elemPoints.push_back( iPoint );
|
||||
nIdIt->second = iPoint++;
|
||||
}
|
||||
else
|
||||
elemPoints.push_back( (*nIdIt).second );
|
||||
elemPoints.push_back( (*nIdIt).second );
|
||||
}
|
||||
}
|
||||
myPoints.resize( iPoint );
|
||||
|
@ -142,6 +142,8 @@ SET(_moc_HEADERS
|
||||
SMESHGUI_FieldSelectorWdg.h
|
||||
SMESHGUI_DisplayEntitiesDlg.h
|
||||
SMESHGUI_SplitBiQuad.h
|
||||
SMESHGUI_PreVisualObj.h
|
||||
SMESHGUI_IdPreview.h
|
||||
)
|
||||
|
||||
# header files / no moc processing
|
||||
@ -251,6 +253,8 @@ SET(_other_SOURCES
|
||||
SMESHGUI_FieldSelectorWdg.cxx
|
||||
SMESHGUI_DisplayEntitiesDlg.cxx
|
||||
SMESHGUI_SplitBiQuad.cxx
|
||||
SMESHGUI_PreVisualObj.cxx
|
||||
SMESHGUI_IdPreview.cxx
|
||||
)
|
||||
|
||||
# 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.h"
|
||||
#include "SMESHGUI_Utils.h"
|
||||
#include "SMESHGUI_VTKUtils.h"
|
||||
#include "SMESHGUI_IdPreview.h"
|
||||
#include "SMESHGUI_MeshUtils.h"
|
||||
#include "SMESHGUI_SpinBox.h"
|
||||
#include "SMESHGUI_Utils.h"
|
||||
#include "SMESHGUI_VTKUtils.h"
|
||||
|
||||
#include <SMESH_Actor.h>
|
||||
#include <SMESH_TypeFilter.hxx>
|
||||
@ -61,34 +62,20 @@
|
||||
#include CORBA_SERVER_HEADER(SMESH_Group)
|
||||
#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
|
||||
#include <QApplication>
|
||||
#include <QButtonGroup>
|
||||
#include <QCheckBox>
|
||||
#include <QGridLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QKeyEvent>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QListWidget>
|
||||
#include <QPushButton>
|
||||
#include <QRadioButton>
|
||||
#include <QCheckBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QGridLayout>
|
||||
#include <QKeyEvent>
|
||||
#include <QButtonGroup>
|
||||
|
||||
#define SPACING 6
|
||||
#define MARGIN 11
|
||||
@ -97,208 +84,27 @@ namespace
|
||||
{
|
||||
enum ActionType { MERGE_NODES, MERGE_ELEMENTS, TYPE_AUTO=0, TYPE_MANUAL };
|
||||
}
|
||||
namespace SMESH
|
||||
|
||||
|
||||
QPixmap SMESHGUI_MergeDlg::IconFirst()
|
||||
{
|
||||
class TIdPreview
|
||||
{ // to display in the viewer IDs of the selected elements
|
||||
SVTK_ViewWindow* myViewWindow;
|
||||
|
||||
vtkUnstructuredGrid* myIdGrid;
|
||||
SALOME_Actor* myIdActor;
|
||||
|
||||
vtkUnstructuredGrid* myPointsNumDataSet;
|
||||
vtkMaskPoints* myPtsMaskPoints;
|
||||
vtkSelectVisiblePoints* myPtsSelectVisiblePoints;
|
||||
vtkLabeledDataMapper* myPtsLabeledDataMapper;
|
||||
vtkTextProperty* aPtsTextProp;
|
||||
bool myIsPointsLabeled;
|
||||
vtkActor2D* myPointLabels;
|
||||
|
||||
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",
|
||||
" . . ",
|
||||
" .. .. .. ",
|
||||
" .. ... ... ",
|
||||
" .. .... .... ",
|
||||
" .. ..... ..... ",
|
||||
" .. ..... ..... ",
|
||||
" .. .... .... ",
|
||||
" .. ... ... ",
|
||||
" .. .. .. ",
|
||||
" . . "};
|
||||
return iconFirst;
|
||||
}
|
||||
|
||||
static const char * IconFirst[] = {
|
||||
"18 10 2 1",
|
||||
" g None",
|
||||
". g #000000",
|
||||
" . . ",
|
||||
" .. .. .. ",
|
||||
" .. ... ... ",
|
||||
" .. .... .... ",
|
||||
" .. ..... ..... ",
|
||||
" .. ..... ..... ",
|
||||
" .. .... .... ",
|
||||
" .. ... ... ",
|
||||
" .. .. .. ",
|
||||
" . . "};
|
||||
|
||||
//=================================================================================
|
||||
// class : SMESHGUI_MergeDlg()
|
||||
// purpose :
|
||||
@ -313,7 +119,7 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
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 );
|
||||
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->setIcon(IconRemove);
|
||||
SetFirstButton = new QPushButton(GroupEdit);
|
||||
SetFirstButton->setIcon(QPixmap(IconFirst));
|
||||
SetFirstButton->setIcon(IconFirst());
|
||||
|
||||
GroupEditLayout->addWidget(ListEdit, 0, 0, 2, 1);
|
||||
GroupEditLayout->addWidget(AddElemButton, 0, 1);
|
||||
@ -645,8 +451,9 @@ void SMESHGUI_MergeDlg::Init()
|
||||
// function : FindGravityCenter()
|
||||
// purpose :
|
||||
//=================================================================================
|
||||
void SMESHGUI_MergeDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap,
|
||||
std::list< gp_XYZ > & theGrCentersXYZ)
|
||||
void SMESHGUI_MergeDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap,
|
||||
std::vector<int>& theIDs,
|
||||
std::list< gp_XYZ > & theGrCentersXYZ)
|
||||
{
|
||||
if (!myActor)
|
||||
return;
|
||||
@ -658,11 +465,13 @@ void SMESHGUI_MergeDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap,
|
||||
|
||||
int nbNodes;
|
||||
|
||||
theIDs.reserve( theElemsIdMap.Extent() );
|
||||
TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap );
|
||||
for( ; idIter.More(); idIter.Next() ) {
|
||||
const SMDS_MeshElement* anElem = aMesh->FindElement(idIter.Key());
|
||||
if ( !anElem )
|
||||
continue;
|
||||
theIDs.push_back( idIter.Key() );
|
||||
|
||||
gp_XYZ anXYZ(0., 0., 0.);
|
||||
SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator();
|
||||
@ -948,7 +757,7 @@ void SMESHGUI_MergeDlg::onDetect()
|
||||
|
||||
SMESH::SMESH_IDSource_var src;
|
||||
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) {
|
||||
case MERGE_NODES :
|
||||
@ -1034,8 +843,9 @@ void SMESHGUI_MergeDlg::onSelectGroup()
|
||||
}
|
||||
else {
|
||||
std::list< gp_XYZ > aGrCentersXYZ;
|
||||
FindGravityCenter(anIndices, aGrCentersXYZ);
|
||||
myIdPreview->SetElemsData( anIndices, aGrCentersXYZ);
|
||||
std::vector<int> anIDs;
|
||||
FindGravityCenter(anIndices, anIDs, aGrCentersXYZ);
|
||||
myIdPreview->SetElemsData( anIDs, aGrCentersXYZ );
|
||||
myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
|
||||
}
|
||||
else
|
||||
@ -1087,8 +897,9 @@ void SMESHGUI_MergeDlg::onSelectElementFromGroup()
|
||||
}
|
||||
else {
|
||||
std::list< gp_XYZ > aGrCentersXYZ;
|
||||
FindGravityCenter(anIndices, aGrCentersXYZ);
|
||||
myIdPreview->SetElemsData(anIndices, aGrCentersXYZ);
|
||||
std::vector<int> anIDs;
|
||||
FindGravityCenter(anIndices, anIDs, aGrCentersXYZ);
|
||||
myIdPreview->SetElemsData(anIDs, aGrCentersXYZ);
|
||||
myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
|
||||
}
|
||||
else
|
||||
|
@ -38,25 +38,27 @@
|
||||
|
||||
// STL includes
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
// IDL includes
|
||||
#include <SALOMEconfig.h>
|
||||
#include CORBA_SERVER_HEADER(SMESH_Mesh)
|
||||
|
||||
class LightApp_SelectionMgr;
|
||||
class QButtonGroup;
|
||||
class QCheckBox;
|
||||
class QGroupBox;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QListWidget;
|
||||
class QPushButton;
|
||||
class QRadioButton;
|
||||
class QCheckBox;
|
||||
class QListWidget;
|
||||
class QButtonGroup;
|
||||
class SMESHGUI;
|
||||
class SMESHGUI_IdPreview;
|
||||
class SMESHGUI_SpinBox;
|
||||
class SMESH_Actor;
|
||||
class SVTK_Selector;
|
||||
class LightApp_SelectionMgr;
|
||||
class SUIT_SelectionFilter;
|
||||
class SVTK_Selector;
|
||||
class TColStd_MapOfInteger;
|
||||
|
||||
namespace SMESH
|
||||
@ -76,6 +78,8 @@ public:
|
||||
SMESHGUI_MergeDlg( SMESHGUI*, int );
|
||||
~SMESHGUI_MergeDlg();
|
||||
|
||||
static QPixmap IconFirst();
|
||||
|
||||
private:
|
||||
void Init();
|
||||
void enterEvent( QEvent* ); /* mouse enter the QWidget */
|
||||
@ -84,7 +88,8 @@ private:
|
||||
bool isKeepNodesIDsSelection();
|
||||
bool isNewKeepNodesGroup( const char* entry );
|
||||
|
||||
void FindGravityCenter( TColStd_MapOfInteger&,
|
||||
void FindGravityCenter( TColStd_MapOfInteger&,
|
||||
std::vector<int>& ,
|
||||
std::list<gp_XYZ>& );
|
||||
// add the centers of gravity of ElemsIdMap elements to the GrCentersXYZ list
|
||||
|
||||
@ -103,7 +108,7 @@ private:
|
||||
SUIT_SelectionFilter* myMeshOrSubMeshOrGroupFilter;
|
||||
SUIT_SelectionFilter* mySubMeshOrGroupFilter;
|
||||
|
||||
SMESH::TIdPreview* myIdPreview;
|
||||
SMESHGUI_IdPreview* myIdPreview;
|
||||
|
||||
int myAction;
|
||||
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
|
||||
#include <SALOMEconfig.h>
|
||||
#include CORBA_SERVER_HEADER(SMESH_Mesh)
|
||||
#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
|
||||
|
||||
#include <vector>
|
||||
|
||||
class QButtonGroup;
|
||||
class QGroupBox;
|
||||
@ -48,6 +51,10 @@ class SMESHGUI;
|
||||
class SMESH_Actor;
|
||||
class SVTK_Selector;
|
||||
class LightApp_SelectionMgr;
|
||||
class SMESHGUI_SpinBox;
|
||||
class SalomeApp_IntSpinBox;
|
||||
class QListWidget;
|
||||
class QListWidgetItem;
|
||||
|
||||
//=================================================================================
|
||||
// class : SMESHGUI_SewingDlg
|
||||
@ -67,7 +74,8 @@ private:
|
||||
void keyPressEvent( QKeyEvent* );
|
||||
int GetConstructorId();
|
||||
bool IsValid();
|
||||
|
||||
void UpdateButtons();
|
||||
|
||||
SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */
|
||||
LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */
|
||||
int myOk1, myOk2, myOk3, myOk4, myOk5, myOk6;
|
||||
@ -114,13 +122,67 @@ private:
|
||||
QCheckBox* CheckBoxPolygons;
|
||||
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;
|
||||
|
||||
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();
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
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();
|
||||
bool ClickOnApply();
|
||||
void ClickOnHelp();
|
||||
|
@ -5141,7 +5141,7 @@ Please select a group and try again</translation>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
<source>KEEP_NODES</source>
|
||||
@ -5155,10 +5155,6 @@ Please select a group and try again</translation>
|
||||
<source>SELECT</source>
|
||||
<translation>Select: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source></source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SMESHGUI_ExtrusionAlongPathDlg</name>
|
||||
@ -6665,6 +6661,42 @@ It is impossible to read point coordinates from file</translation>
|
||||
<source>SIDE_2</source>
|
||||
<translation>Side 2</translation>
|
||||
</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>
|
||||
<name>SMESHGUI_ShapeByMeshDlg</name>
|
||||
|
@ -79,6 +79,7 @@ SET(SMESHUtils_SOURCES
|
||||
SMESH_File.cxx
|
||||
SMESH_MeshAlgos.cxx
|
||||
SMESH_MAT2d.cxx
|
||||
SMESH_FreeBorders.cxx
|
||||
)
|
||||
|
||||
# --- 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;
|
||||
set<const SMDS_MeshElement*> _outerFaces; // empty means "no internal faces at all"
|
||||
|
||||
SMESH_ElementSearcherImpl( SMDS_Mesh& mesh, SMDS_ElemIteratorPtr elemIt=SMDS_ElemIteratorPtr())
|
||||
: _mesh(&mesh),_meshPartIt(elemIt),_ebbTree(0),_nodeSearcher(0),_tolerance(-1),_outerFacesFound(false) {}
|
||||
SMESH_ElementSearcherImpl( SMDS_Mesh& mesh,
|
||||
double tol=-1,
|
||||
SMDS_ElemIteratorPtr elemIt=SMDS_ElemIteratorPtr())
|
||||
: _mesh(&mesh),_meshPartIt(elemIt),_ebbTree(0),_nodeSearcher(0),_tolerance(tol),_outerFacesFound(false) {}
|
||||
virtual ~SMESH_ElementSearcherImpl()
|
||||
{
|
||||
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
|
||||
|
||||
vector< gp_XYZ > xyz;
|
||||
vector<const SMDS_MeshNode*> nodeList;
|
||||
vector< SMESH_TNodeXYZ > xyz;
|
||||
|
||||
SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
|
||||
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();
|
||||
}
|
||||
SMDS_ElemIteratorPtr nodeIt = element->interlacedNodesElemIterator();
|
||||
while ( nodeIt->more() )
|
||||
{
|
||||
SMESH_TNodeXYZ node = nodeIt->next();
|
||||
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 ) // --------------------------------------------------
|
||||
{
|
||||
// compute face normal
|
||||
gp_Vec faceNorm(0,0,0);
|
||||
xyz.push_back( xyz.front() );
|
||||
nodeList.push_back( nodeList.front() );
|
||||
for ( i = 0; i < nbNodes; ++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
|
||||
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 ))
|
||||
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)
|
||||
for ( i = 1; i < nbNodes; ++i )
|
||||
{
|
||||
gp_Vec edge( xyz[i-1], xyz[i]);
|
||||
gp_Vec n1p ( xyz[i-1], point);
|
||||
double dist = ( edge ^ n1p ).Magnitude() / edge.Magnitude();
|
||||
if ( dist > tol )
|
||||
gp_Vec edge( xyz[i-1], xyz[i] );
|
||||
gp_Vec n1p ( xyz[i-1], point );
|
||||
// double dist = ( edge ^ n1p ).Magnitude() / edge.Magnitude();
|
||||
// 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;
|
||||
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;
|
||||
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 -------------------------------------------------------------------------
|
||||
{
|
||||
gp_Vec n2p ( xyz[0], point );
|
||||
return n2p.Magnitude() <= tol;
|
||||
return n2p.SquareMagnitude() <= tol * tol;
|
||||
}
|
||||
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,
|
||||
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
|
||||
*/
|
||||
SMESHUtils_EXPORT
|
||||
SMESH_ElementSearcher* GetElementSearcher( SMDS_Mesh& mesh );
|
||||
SMESH_ElementSearcher* GetElementSearcher( SMDS_Mesh& mesh,
|
||||
double tolerance=-1.);
|
||||
SMESHUtils_EXPORT
|
||||
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
|
||||
|
@ -2414,6 +2414,7 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
|
||||
"Mirror","MirrorObject","Translate","TranslateObject","Rotate","RotateObject",
|
||||
"FindCoincidentNodes","MergeNodes","FindEqualElements",
|
||||
"MergeElements","MergeEqualElements","SewFreeBorders","SewConformFreeBorders",
|
||||
"FindCoincidentFreeBorders", "SewCoincidentFreeBorders",
|
||||
"SewBorderToSide","SewSideElements","ChangeElemNodes","GetLastCreatedNodes",
|
||||
"GetLastCreatedElems",
|
||||
"MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh","TranslateObjectMakeMesh",
|
||||
|
@ -547,6 +547,39 @@ namespace SMESH
|
||||
DumpArray( theList, *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()
|
||||
{
|
||||
return theNotPublishedObjectName;
|
||||
|
@ -4572,6 +4572,182 @@ static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Se
|
||||
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
|
||||
//purpose :
|
||||
@ -4621,14 +4797,14 @@ SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
|
||||
|
||||
SMESH::SMESH_MeshEditor::Sew_Error error =
|
||||
convError( getEditor().SewFreeBorder (aBorderFirstNode,
|
||||
aBorderSecondNode,
|
||||
aBorderLastNode,
|
||||
aSide2FirstNode,
|
||||
aSide2SecondNode,
|
||||
aSide2ThirdNode,
|
||||
true,
|
||||
CreatePolygons,
|
||||
CreatePolyedrs) );
|
||||
aBorderSecondNode,
|
||||
aBorderLastNode,
|
||||
aSide2FirstNode,
|
||||
aSide2SecondNode,
|
||||
aSide2ThirdNode,
|
||||
true,
|
||||
CreatePolygons,
|
||||
CreatePolyedrs) );
|
||||
|
||||
|
||||
declareMeshModified( /*isReComputeSafe=*/false );
|
||||
@ -4681,13 +4857,13 @@ SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
|
||||
|
||||
SMESH::SMESH_MeshEditor::Sew_Error error =
|
||||
convError( getEditor().SewFreeBorder (aBorderFirstNode,
|
||||
aBorderSecondNode,
|
||||
aBorderLastNode,
|
||||
aSide2FirstNode,
|
||||
aSide2SecondNode,
|
||||
aSide2ThirdNode,
|
||||
true,
|
||||
false, false) );
|
||||
aBorderSecondNode,
|
||||
aBorderLastNode,
|
||||
aSide2FirstNode,
|
||||
aSide2SecondNode,
|
||||
aSide2ThirdNode,
|
||||
true,
|
||||
false, false) );
|
||||
|
||||
declareMeshModified( /*isReComputeSafe=*/false );
|
||||
return error;
|
||||
@ -4743,14 +4919,14 @@ SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
|
||||
|
||||
SMESH::SMESH_MeshEditor::Sew_Error error =
|
||||
convError( getEditor().SewFreeBorder (aBorderFirstNode,
|
||||
aBorderSecondNode,
|
||||
aBorderLastNode,
|
||||
aSide2FirstNode,
|
||||
aSide2SecondNode,
|
||||
aSide2ThirdNode,
|
||||
false,
|
||||
CreatePolygons,
|
||||
CreatePolyedrs) );
|
||||
aBorderSecondNode,
|
||||
aBorderLastNode,
|
||||
aSide2FirstNode,
|
||||
aSide2SecondNode,
|
||||
aSide2ThirdNode,
|
||||
false,
|
||||
CreatePolygons,
|
||||
CreatePolyedrs) );
|
||||
|
||||
declareMeshModified( /*isReComputeSafe=*/false );
|
||||
return error;
|
||||
|
@ -538,6 +538,12 @@ public:
|
||||
CORBA::Short GetPointState(CORBA::Double x, CORBA::Double y, CORBA::Double z)
|
||||
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
|
||||
SewFreeBorders(CORBA::Long FirstNodeID1,
|
||||
CORBA::Long SecondNodeID1,
|
||||
@ -546,15 +552,13 @@ public:
|
||||
CORBA::Long SecondNodeID2,
|
||||
CORBA::Long LastNodeID2,
|
||||
CORBA::Boolean CreatePolygons,
|
||||
CORBA::Boolean CreatePolyedrs)
|
||||
throw (SALOME::SALOME_Exception);
|
||||
CORBA::Boolean CreatePolyedrs) throw (SALOME::SALOME_Exception);
|
||||
SMESH::SMESH_MeshEditor::Sew_Error
|
||||
SewConformFreeBorders(CORBA::Long FirstNodeID1,
|
||||
CORBA::Long SecondNodeID1,
|
||||
CORBA::Long LastNodeID1,
|
||||
CORBA::Long FirstNodeID2,
|
||||
CORBA::Long SecondNodeID2)
|
||||
throw (SALOME::SALOME_Exception);
|
||||
CORBA::Long SecondNodeID2) throw (SALOME::SALOME_Exception);
|
||||
SMESH::SMESH_MeshEditor::Sew_Error
|
||||
SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
|
||||
CORBA::Long SecondNodeIDOnFreeBorder,
|
||||
@ -562,16 +566,14 @@ public:
|
||||
CORBA::Long FirstNodeIDOnSide,
|
||||
CORBA::Long LastNodeIDOnSide,
|
||||
CORBA::Boolean CreatePolygons,
|
||||
CORBA::Boolean CreatePolyedrs)
|
||||
throw (SALOME::SALOME_Exception);
|
||||
CORBA::Boolean CreatePolyedrs) throw (SALOME::SALOME_Exception);
|
||||
SMESH::SMESH_MeshEditor::Sew_Error
|
||||
SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
|
||||
const SMESH::long_array& IDsOfSide2Elements,
|
||||
CORBA::Long NodeID1OfSide1ToMerge,
|
||||
CORBA::Long NodeID1OfSide2ToMerge,
|
||||
CORBA::Long NodeID2OfSide1ToMerge,
|
||||
CORBA::Long NodeID2OfSide2ToMerge)
|
||||
throw (SALOME::SALOME_Exception);
|
||||
CORBA::Long NodeID2OfSide2ToMerge) throw (SALOME::SALOME_Exception);
|
||||
|
||||
/*!
|
||||
* Set new nodes for given element.
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include <SALOMEconfig.h>
|
||||
#include CORBA_SERVER_HEADER(SMESH_Mesh)
|
||||
#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
|
||||
#include CORBA_SERVER_HEADER(GEOM_Gen)
|
||||
#include CORBA_SERVER_HEADER(SALOMEDS)
|
||||
|
||||
@ -229,6 +230,9 @@ namespace SMESH
|
||||
TPythonDump&
|
||||
operator<<(const SMESH::ListOfIDSources& theList);
|
||||
|
||||
TPythonDump&
|
||||
operator<<(const SMESH::CoincidentFreeBorders& theCFB);
|
||||
|
||||
static const char* SMESHGenName() { return "smeshgen"; }
|
||||
static const char* MeshEditorName() { return "mesh_editor"; }
|
||||
static const char* NotPublishedObjectName();
|
||||
|
@ -4519,6 +4519,52 @@ class Mesh:
|
||||
def MergeEqualElements(self):
|
||||
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
|
||||
# @return SMESH::Sew_Error
|
||||
# @ingroup l2_modif_trsf
|
||||
|
Loading…
Reference in New Issue
Block a user