Salome HOME
0021130: EDF 1746 SMESH: Issue with export in STL format
[modules/smesh.git] / src / SMESH / SMESH_MeshEditor.cxx
index 198cf0f2da50310c81b584dadef6b9cf30c9d36e..e1756d3e1df46c0da2e2390de9585f100b268181 100644 (file)
@@ -135,27 +135,27 @@ SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
   case SMDSAbs_Face:
     if ( !isPoly ) {
       if      (nbnode == 3) {
-        if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], ID);
+        if ( ID >= 1 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], ID);
         else           e = mesh->AddFace      (node[0], node[1], node[2] );
       }
       else if (nbnode == 4) {
-        if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3], ID);
+        if ( ID >= 1 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3], ID);
         else           e = mesh->AddFace      (node[0], node[1], node[2], node[3] );
       }
       else if (nbnode == 6) {
-        if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
-                                              node[4], node[5], ID);
+        if ( ID >= 1 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
+                                               node[4], node[5], ID);
         else           e = mesh->AddFace      (node[0], node[1], node[2], node[3],
-                                              node[4], node[5] );
+                                               node[4], node[5] );
       }
       else if (nbnode == 8) {
-        if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
-                                              node[4], node[5], node[6], node[7], ID);
+        if ( ID >= 1 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
+                                               node[4], node[5], node[6], node[7], ID);
         else           e = mesh->AddFace      (node[0], node[1], node[2], node[3],
-                                              node[4], node[5], node[6], node[7] );
+                                               node[4], node[5], node[6], node[7] );
       }
     } else {
-      if ( ID >= 0 ) e = mesh->AddPolygonalFaceWithID(node, ID);
+      if ( ID >= 1 ) e = mesh->AddPolygonalFaceWithID(node, ID);
       else           e = mesh->AddPolygonalFace      (node    );
     }
     break;
@@ -163,90 +163,90 @@ SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
   case SMDSAbs_Volume:
     if ( !isPoly ) {
       if      (nbnode == 4) {
-        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], ID);
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], ID);
         else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3] );
       }
       else if (nbnode == 5) {
-        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                                node[4], ID);
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], ID);
         else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                                node[4] );
+                                                 node[4] );
       }
       else if (nbnode == 6) {
-        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                                node[4], node[5], ID);
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], ID);
         else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                                node[4], node[5] );
+                                                 node[4], node[5] );
       }
       else if (nbnode == 8) {
-        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                                node[4], node[5], node[6], node[7], ID);
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7], ID);
         else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                                node[4], node[5], node[6], node[7] );
+                                                 node[4], node[5], node[6], node[7] );
       }
       else if (nbnode == 10) {
-        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                                node[4], node[5], node[6], node[7],
-                                                node[8], node[9], ID);
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], ID);
         else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                                node[4], node[5], node[6], node[7],
-                                                node[8], node[9] );
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9] );
       }
       else if (nbnode == 13) {
-        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                                node[4], node[5], node[6], node[7],
-                                                node[8], node[9], node[10],node[11],
-                                                node[12],ID);
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12],ID);
         else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                                node[4], node[5], node[6], node[7],
-                                                node[8], node[9], node[10],node[11],
-                                                node[12] );
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12] );
       }
       else if (nbnode == 15) {
-        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                                node[4], node[5], node[6], node[7],
-                                                node[8], node[9], node[10],node[11],
-                                                node[12],node[13],node[14],ID);
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12],node[13],node[14],ID);
         else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                                node[4], node[5], node[6], node[7],
-                                                node[8], node[9], node[10],node[11],
-                                                node[12],node[13],node[14] );
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12],node[13],node[14] );
       }
       else if (nbnode == 20) {
-        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                                node[4], node[5], node[6], node[7],
-                                                node[8], node[9], node[10],node[11],
-                                                node[12],node[13],node[14],node[15],
-                                                node[16],node[17],node[18],node[19],ID);
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12],node[13],node[14],node[15],
+                                                 node[16],node[17],node[18],node[19],ID);
         else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                                node[4], node[5], node[6], node[7],
-                                                node[8], node[9], node[10],node[11],
-                                                node[12],node[13],node[14],node[15],
-                                                node[16],node[17],node[18],node[19] );
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12],node[13],node[14],node[15],
+                                                 node[16],node[17],node[18],node[19] );
       }
     }
     break;
 
   case SMDSAbs_Edge:
     if ( nbnode == 2 ) {
-      if ( ID >= 0 ) e = mesh->AddEdgeWithID(node[0], node[1], ID);
+      if ( ID >= 1 ) e = mesh->AddEdgeWithID(node[0], node[1], ID);
       else           e = mesh->AddEdge      (node[0], node[1] );
     }
     else if ( nbnode == 3 ) {
-      if ( ID >= 0 ) e = mesh->AddEdgeWithID(node[0], node[1], node[2], ID);
+      if ( ID >= 1 ) e = mesh->AddEdgeWithID(node[0], node[1], node[2], ID);
       else           e = mesh->AddEdge      (node[0], node[1], node[2] );
     }
     break;
 
   case SMDSAbs_0DElement:
     if ( nbnode == 1 ) {
-      if ( ID >= 0 ) e = mesh->Add0DElementWithID(node[0], ID);
+      if ( ID >= 1 ) e = mesh->Add0DElementWithID(node[0], ID);
       else           e = mesh->Add0DElement      (node[0] );
     }
     break;
 
   case SMDSAbs_Node:
-    if ( ID >= 0 ) e = mesh->AddNodeWithID(node[0]->X(), node[0]->Y(), node[0]->Z(), ID);
+    if ( ID >= 1 ) e = mesh->AddNodeWithID(node[0]->X(), node[0]->Y(), node[0]->Z(), ID);
     else           e = mesh->AddNode      (node[0]->X(), node[0]->Y(), node[0]->Z());
     break;
 
@@ -1563,14 +1563,14 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems,
                                               const int                theMethodFlags)
 {
   // std-like iterator on coordinates of nodes of mesh element
-  typedef SMDS_StdIterator< TNodeXYZ, SMDS_ElemIteratorPtr > NXyzIterator;
+  typedef SMDS_StdIterator< SMESH_TNodeXYZ, SMDS_ElemIteratorPtr > NXyzIterator;
   NXyzIterator xyzEnd;
 
   SMDS_VolumeTool    volTool;
   SMESH_MesherHelper helper( *GetMesh());
 
-  SMESHDS_SubMesh* subMesh = GetMeshDS()->MeshElements(1);
-  SMESHDS_SubMesh* fSubMesh = subMesh;
+  SMESHDS_SubMesh* subMesh = 0;//GetMeshDS()->MeshElements(1);
+  SMESHDS_SubMesh* fSubMesh = 0;//subMesh;
   
   SMESH_SequenceOfElemPtr newNodes, newElems;
 
@@ -6241,7 +6241,7 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher
     const SMDS_MeshNode* closestNode = 0;
     list<const SMDS_MeshNode*>::iterator nIt = nodes.begin();
     for ( ; nIt != nodes.end(); ++nIt ) {
-      double sqDist = thePnt.SquareDistance( SMESH_MeshEditor::TNodeXYZ( *nIt ) );
+      double sqDist = thePnt.SquareDistance( SMESH_TNodeXYZ( *nIt ) );
       if ( minSqDist > sqDist ) {
         closestNode = *nIt;
         minSqDist = sqDist;
@@ -6296,7 +6296,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
   {
   public:
 
-    ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, double tolerance = NodeRadius );
+    ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, SMDS_ElemIteratorPtr theElemIt = SMDS_ElemIteratorPtr(), double tolerance = NodeRadius );
     void getElementsNearPoint( const gp_Pnt& point, TIDSortedElemSet& foundElems);
     void getElementsNearLine ( const gp_Ax1& line, TIDSortedElemSet& foundElems);
     ~ElementBndBoxTree();
@@ -6323,13 +6323,13 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
    */
   //================================================================================
 
-  ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, double tolerance)
+  ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, SMDS_ElemIteratorPtr theElemIt, double tolerance)
     :SMESH_Octree( new SMESH_Octree::Limit( MaxLevel, /*minSize=*/0. ))
   {
     int nbElems = mesh.GetMeshInfo().NbElements( elemType );
     _elements.reserve( nbElems );
 
-    SMDS_ElemIteratorPtr elemIt = mesh.elementsIterator( elemType );
+    SMDS_ElemIteratorPtr elemIt = theElemIt ? theElemIt : mesh.elementsIterator( elemType );
     while ( elemIt->more() )
       _elements.push_back( new ElementBox( elemIt->next(),tolerance  ));
 
@@ -6461,7 +6461,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
     _refCount = 1;
     SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
     while ( nIt->more() )
-      Add( SMESH_MeshEditor::TNodeXYZ( cast2Node( nIt->next() )));
+      Add( SMESH_TNodeXYZ( cast2Node( nIt->next() )));
     Enlarge( tolerance );
   }
 
@@ -6477,6 +6477,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
 struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
 {
   SMESHDS_Mesh*                _mesh;
+  SMDS_ElemIteratorPtr         _meshPartIt;
   ElementBndBoxTree*           _ebbTree;
   SMESH_NodeSearcherImpl*      _nodeSearcher;
   SMDSAbs_ElementType          _elementType;
@@ -6484,8 +6485,8 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
   bool                         _outerFacesFound;
   set<const SMDS_MeshElement*> _outerFaces; // empty means "no internal faces at all"
 
-  SMESH_ElementSearcherImpl( SMESHDS_Mesh& mesh )
-    : _mesh(&mesh),_ebbTree(0),_nodeSearcher(0), _tolerance(-1), _outerFacesFound(false) {}
+  SMESH_ElementSearcherImpl( SMESHDS_Mesh& mesh, SMDS_ElemIteratorPtr elemIt=SMDS_ElemIteratorPtr())
+    : _mesh(&mesh),_meshPartIt(elemIt),_ebbTree(0),_nodeSearcher(0),_tolerance(-1),_outerFacesFound(false) {}
   ~SMESH_ElementSearcherImpl()
   {
     if ( _ebbTree )      delete _ebbTree;      _ebbTree      = 0;
@@ -6567,7 +6568,7 @@ double SMESH_ElementSearcherImpl::getTolerance()
         SMDS_NodeIteratorPtr nodeIt = _mesh->nodesIterator();
         elemSize = 1;
         if ( meshInfo.NbNodes() > 2 )
-          elemSize = SMESH_MeshEditor::TNodeXYZ( nodeIt->next() ).Distance( nodeIt->next() );
+          elemSize = SMESH_TNodeXYZ( nodeIt->next() ).Distance( nodeIt->next() );
       }
       else
       {
@@ -6575,7 +6576,8 @@ double SMESH_ElementSearcherImpl::getTolerance()
             _mesh->elementsIterator( SMDSAbs_ElementType( complexType ));
         const SMDS_MeshElement* elem = elemIt->next();
         SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
-        SMESH_MeshEditor::TNodeXYZ n1( cast2Node( nodeIt->next() ));
+        SMESH_TNodeXYZ n1( cast2Node( nodeIt->next() ));
+        elemSize = 0;
         while ( nodeIt->more() )
         {
           double dist = n1.Distance( cast2Node( nodeIt->next() ));
@@ -6608,8 +6610,8 @@ bool SMESH_ElementSearcherImpl::getIntersParamOnLine(const gp_Lin&           lin
   int nbNodes = face->IsQuadratic() ? face->NbNodes()/2 : face->NbNodes();
   for ( int i = 0; i < nbNodes && nbInts < 2; ++i )
   {
-    GC_MakeSegment edge( SMESH_MeshEditor::TNodeXYZ( face->GetNode( i )),
-                         SMESH_MeshEditor::TNodeXYZ( face->GetNode( (i+1)%nbNodes) )); 
+    GC_MakeSegment edge( SMESH_TNodeXYZ( face->GetNode( i )),
+                         SMESH_TNodeXYZ( face->GetNode( (i+1)%nbNodes) )); 
     anExtCC.Init( lineCurve, edge);
     if ( anExtCC.NbExtrema() > 0 && anExtCC.LowerDistance() <= tol)
     {
@@ -6669,8 +6671,8 @@ void SMESH_ElementSearcherImpl::findOuterBoundary(const SMDS_MeshElement* outerF
       seamLinks.insert( link );
 
       // link direction within the outerFace
-      gp_Vec n1n2( SMESH_MeshEditor::TNodeXYZ( link.node1()),
-                   SMESH_MeshEditor::TNodeXYZ( link.node2()));
+      gp_Vec n1n2( SMESH_TNodeXYZ( link.node1()),
+                   SMESH_TNodeXYZ( link.node2()));
       int i1 = outerFace->GetNodeIndex( link.node1() );
       int i2 = outerFace->GetNodeIndex( link.node2() );
       bool rev = ( abs(i2-i1) == 1 ? i1 > i2 : i2 > i1 );
@@ -6753,7 +6755,7 @@ FindElementsByPoint(const gp_Pnt&                      point,
     const SMDS_MeshNode* closeNode = _nodeSearcher->FindClosestTo( point );
     if ( !closeNode ) return foundElements.size();
 
-    if ( point.Distance( SMESH_MeshEditor::TNodeXYZ( closeNode )) > tolerance )
+    if ( point.Distance( SMESH_TNodeXYZ( closeNode )) > tolerance )
       return foundElements.size(); // to far from any node
 
     if ( type == SMDSAbs_Node )
@@ -6773,7 +6775,7 @@ FindElementsByPoint(const gp_Pnt&                      point,
     if ( !_ebbTree || _elementType != type )
     {
       if ( _ebbTree ) delete _ebbTree;
-      _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, tolerance );
+      _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, _meshPartIt, tolerance );
     }
     TIDSortedElemSet suspectElems;
     _ebbTree->getElementsNearPoint( point, suspectElems );
@@ -6797,7 +6799,7 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point)
   if ( !_ebbTree || _elementType != SMDSAbs_Face )
   {
     if ( _ebbTree ) delete _ebbTree;
-    _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = SMDSAbs_Face );
+    _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = SMDSAbs_Face, _meshPartIt );
   }
   // Algo: analyse transition of a line starting at the point through mesh boundary;
   // try three lines parallel to axis of the coordinate system and perform rough
@@ -6825,7 +6827,7 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point)
       // get face plane
       gp_XYZ fNorm;
       if ( !SMESH_Algo::FaceNormal( *face, fNorm, /*normalized=*/false)) continue;
-      gp_Pln facePlane( SMESH_MeshEditor::TNodeXYZ( (*face)->GetNode(0)), fNorm );
+      gp_Pln facePlane( SMESH_TNodeXYZ( (*face)->GetNode(0)), fNorm );
 
       // perform intersection
       IntAna_IntConicQuad intersection( line, IntAna_Quadric( facePlane ));
@@ -7021,7 +7023,7 @@ void SMESH_ElementSearcherImpl::GetElementsNearLine( const gp_Ax1&
   if ( !_ebbTree || _elementType != type )
   {
     if ( _ebbTree ) delete _ebbTree;
-    _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type );
+    _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, _meshPartIt );
   }
   TIDSortedElemSet suspectFaces; // elements possibly intersecting the line
   _ebbTree->getElementsNearLine( line, suspectFaces );
@@ -7039,6 +7041,17 @@ SMESH_ElementSearcher* SMESH_MeshEditor::GetElementSearcher()
   return new SMESH_ElementSearcherImpl( *GetMeshDS() );
 }
 
+//=======================================================================
+/*!
+ * \brief Return SMESH_ElementSearcher
+ */
+//=======================================================================
+
+SMESH_ElementSearcher* SMESH_MeshEditor::GetElementSearcher(SMDS_ElemIteratorPtr elemIt)
+{
+  return new SMESH_ElementSearcherImpl( *GetMeshDS(), elemIt );
+}
+
 //=======================================================================
 /*!
  * \brief Return true if the point is IN or ON of the element
@@ -7067,7 +7080,7 @@ bool SMESH_MeshEditor::isOut( const SMDS_MeshElement* element, const gp_Pnt& poi
   while ( nodeIt->more() )
     {
       const SMDS_MeshNode* node = cast2Node( nodeIt->next() );
-      xyz.push_back( TNodeXYZ(node) );
+      xyz.push_back( SMESH_TNodeXYZ(node) );
       nodeList.push_back(node);
     }
 
@@ -10481,7 +10494,7 @@ namespace {
     gp_XYZ centerXYZ (0, 0, 0);
     SMDS_ElemIteratorPtr aNodeItr = theElem->nodesIterator();
     while (aNodeItr->more())
-      centerXYZ += SMESH_MeshEditor::TNodeXYZ(cast2Node( aNodeItr->next()));
+      centerXYZ += SMESH_TNodeXYZ(cast2Node( aNodeItr->next()));
 
     gp_Pnt aPnt = centerXYZ / theElem->NbNodes();
     theClassifier.Perform(aPnt, theTol);