]> SALOME platform Git repositories - modules/smesh.git/blobdiff - src/SMESH/SMESH_MeshEditor.cxx
Salome HOME
Debug sewing. Enable polygons creation while sewing free border to side.
[modules/smesh.git] / src / SMESH / SMESH_MeshEditor.cxx
index 1fdb16b7190d0a514b3bac57ab88f1854be33647..007aac4517d3bfbd03c1990ea758267a4e645701 100644 (file)
@@ -975,12 +975,12 @@ bool SMESH_MeshEditor::TriToQuad (set<const SMDS_MeshElement*> &       theElems,
 }
 
 
-#define DUMPSO(txt) \
+/*#define DUMPSO(txt) \
 //  cout << txt << endl;
 //=============================================================================
-/*!
- *
- */
+//
+//
+//
 //=============================================================================
 static void swap( int i1, int i2, int idNodes[], gp_Pnt P[] )
 {
@@ -1252,7 +1252,7 @@ bool SMESH_MeshEditor::SortHexaNodes (const SMDS_Mesh * theMesh,
 //   }
 
   return true;
-}
+}*/
 
 //=======================================================================
 //function : laplacianSmooth
@@ -1274,6 +1274,8 @@ void laplacianSmooth(SMESHDS_Mesh *                       theMesh,
     if ( theElems.find( elem ) == theElems.end() )
       continue;
 
+    if (elem->IsPoly())
+      continue;
     int i = 0, iNode = 0;
     const SMDS_MeshNode* aNodes [4];
     SMDS_ElemIteratorPtr itN = elem->nodesIterator();
@@ -1858,7 +1860,8 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
           for (int inode = 0; inode < nbPolygonNodes; inode++) {
             polygon_nodes[inode] = nodes[inode];
           }
-          aMesh->AddPolygonalFace(polygon_nodes);
+          if (!hasFreeLinks || !aMesh->FindFace(polygon_nodes))
+            aMesh->AddPolygonalFace(polygon_nodes);
         }
         break;
       }
@@ -2691,6 +2694,92 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
     int nbUniqueNodes = nodeSet.size();
     if ( nbNodes != nbUniqueNodes ) // some nodes stick
     {
+      // Polygons and Polyhedral volumes
+      if (elem->IsPoly()) {
+
+        if (elem->GetType() == SMDSAbs_Face) {
+          // Polygon
+          if (nbUniqueNodes < 3) {
+            isOk = false;
+          } else {
+            // get simple seq of nodes
+            const SMDS_MeshNode* simpleNodes[ nbNodes ];
+            int iSimple = 0;
+
+            simpleNodes[iSimple++] = curNodes[0];
+            for (iCur = 1; iCur < nbNodes; iCur++) {
+              if (curNodes[iCur] != simpleNodes[iSimple - 1]) {
+                simpleNodes[iSimple++] = curNodes[iCur];
+              }
+            }
+            int nbSimple = iSimple;
+            if (simpleNodes[nbSimple - 1] == simpleNodes[0]) {
+              nbSimple--;
+            }
+
+            // separate cycles
+            bool foundCycle = (nbSimple > nbUniqueNodes);
+            while (foundCycle) {
+              foundCycle = false;
+              set<const SMDS_MeshNode*> cycleSet;
+              for (iSimple = 0; iSimple < nbSimple && !foundCycle; iSimple++) {
+                const SMDS_MeshNode* n = simpleNodes[iSimple];
+                if (!cycleSet.insert( n ).second) {
+                  foundCycle = true;
+
+                  // separate cycle
+                  int iC = 0, curLast = iSimple;
+                  for (; iC < curLast; iC++) {
+                    if (simpleNodes[iC] == n) break;
+                  }
+                  int cycleLen = curLast - iC;
+                  if (cycleLen > 2) {
+                    // create sub-element
+                    vector<const SMDS_MeshNode *> poly_nodes (cycleLen);
+                    for (int ii = 0; iC < curLast; iC++) {
+                      poly_nodes[ii++] = simpleNodes[iC];
+                    }
+                    SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes);
+                    if (aShapeId)
+                      aMesh->SetMeshElementOnShape(newElem, aShapeId);
+                  }
+                  // put the rest nodes from the first cycle position
+                  for (iC = curLast + 1; iC < nbSimple; iC++) {
+                    simpleNodes[iC - cycleLen] = simpleNodes[iC];
+                  }
+                  nbSimple -= cycleLen;
+                }
+              } // for (iSimple = 0; iSimple < nbSimple; iSimple++)
+            } // while (foundCycle)
+
+            if (iSimple > 2) {
+              aMesh->ChangeElementNodes(elem, simpleNodes, nbSimple);
+            } else {
+              isOk = false;
+            }
+          }
+
+        } else if (elem->GetType() == SMDSAbs_Volume) {
+          // Polyhedral volume
+          if (nbUniqueNodes < 4) {
+            isOk = false;
+          } else {
+            // each face has to be analized in order to check volume validity
+            //aMesh->ChangeElementNodes(elem, uniqueNodes, nbUniqueNodes);
+            isOk = false;
+          }
+
+        } else {
+          isOk = false;
+        }
+
+        if (!isOk)
+          rmElemIds.push_back(elem->GetID());
+
+        continue;
+      }
+
+      // Regular elements
       switch ( nbNodes ) {
       case 2: ///////////////////////////////////// EDGE
         isOk = false; break;
@@ -3322,7 +3411,7 @@ SMESH_MeshEditor::Sew_Error
     LinkID_Gen aLinkID_Gen( GetMeshDS() );
     set<long> foundSideLinkIDs, checkedLinkIDs;
     SMDS_VolumeTool volume;
-    const SMDS_MeshNode* faceNodes[ 4 ];
+    //const SMDS_MeshNode* faceNodes[ 4 ];
 
     const SMDS_MeshNode*    sideNode;
     const SMDS_MeshElement* sideElem;
@@ -3350,6 +3439,7 @@ SMESH_MeshEditor::Sew_Error
         const SMDS_MeshElement* elem = invElemIt->next();
         // prepare data for a loop on links, of a face or a volume
         int iPrevNode, iNode = 0, nbNodes = elem->NbNodes();
+        const SMDS_MeshNode* faceNodes[ nbNodes ];
         bool isVolume = volume.Set( elem );
         const SMDS_MeshNode** nodes = isVolume ? volume.GetNodes() : faceNodes;
         if ( isVolume ) // --volume
@@ -3643,7 +3733,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
   // find indices of 2 link nodes and of the rest nodes
   int iNode = 0, il1, il2, i3, i4;
   il1 = il2 = i3 = i4 = -1;
-  const SMDS_MeshNode* nodes[ 8 ];
+  const SMDS_MeshNode* nodes[ theFace->NbNodes() ];
   SMDS_ElemIteratorPtr nodeIt = theFace->nodesIterator();
   while ( nodeIt->more() ) {
     const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
@@ -3662,11 +3752,12 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
 
   // arrange link nodes to go one after another regarding the face orientation
   bool reverse = ( Abs( il2 - il1 ) == 1 ? il2 < il1 : il1 < il2 );
+  list<const SMDS_MeshNode *> aNodesToInsert = theNodesToInsert;
   if ( reverse ) {
     iNode = il1;
     il1 = il2;
     il2 = iNode;
-    theNodesToInsert.reverse();
+    aNodesToInsert.reverse();
   }
   // check that not link nodes of a quadrangles are in good order
   int nbFaceNodes = theFace->NbNodes();
@@ -3679,7 +3770,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
   if (toCreatePoly || theFace->IsPoly()) {
 
     iNode = 0;
-    vector<const SMDS_MeshNode *> poly_nodes (nbFaceNodes + theNodesToInsert.size());
+    vector<const SMDS_MeshNode *> poly_nodes (nbFaceNodes + aNodesToInsert.size());
 
     // add nodes of face up to first node of link
     bool isFLN = false;
@@ -3693,8 +3784,8 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     }
 
     // add nodes to insert
-    list<const SMDS_MeshNode*>::iterator nIt = theNodesToInsert.begin();
-    for (; nIt != theNodesToInsert.end(); nIt++) {
+    list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
+    for (; nIt != aNodesToInsert.end(); nIt++) {
       poly_nodes[iNode++] = *nIt;
     }
 
@@ -3722,13 +3813,13 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     return;
   }
 
-  // put theNodesToInsert between theBetweenNode1 and theBetweenNode2
-  int nbLinkNodes = 2 + theNodesToInsert.size();
+  // put aNodesToInsert between theBetweenNode1 and theBetweenNode2
+  int nbLinkNodes = 2 + aNodesToInsert.size();
   const SMDS_MeshNode* linkNodes[ nbLinkNodes ];
   linkNodes[ 0 ] = nodes[ il1 ];
   linkNodes[ nbLinkNodes - 1 ] = nodes[ il2 ];
-  list<const SMDS_MeshNode*>::iterator nIt = theNodesToInsert.begin();
-  for ( iNode = 1; nIt != theNodesToInsert.end(); nIt++ ) {
+  list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
+  for ( iNode = 1; nIt != aNodesToInsert.end(); nIt++ ) {
     linkNodes[ iNode++ ] = *nIt;
   }
   // decide how to split a quadrangle: compare possible variants
@@ -3930,17 +4021,31 @@ SMESH_MeshEditor::Sew_Error
           bool isNewFace = setOfFaceNodeSet.insert( faceNodeSet ).second;
           if ( isNewFace ) {
             // no such a face is given but it still can exist, check it
-            if ( nbNodes == 3 )
+            if ( nbNodes == 3 ) {
               aFreeFace = aMesh->FindFace( fNodes[0],fNodes[1],fNodes[2] );
-            else
+            } else if ( nbNodes == 4 ) {
               aFreeFace = aMesh->FindFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] );
+            } else {
+              vector<const SMDS_MeshNode *> poly_nodes (nbNodes);
+              for (int inode = 0; inode < nbNodes; inode++) {
+                poly_nodes[inode] = fNodes[inode];
+              }
+              aFreeFace = aMesh->FindFace(poly_nodes);
+            }
           }
           if ( !aFreeFace ) {
             // create a temporary face
-            if ( nbNodes == 3 )
+            if ( nbNodes == 3 ) {
               aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2] );
-            else
+            } else if ( nbNodes == 4 ) {
               aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] );
+            } else {
+              vector<const SMDS_MeshNode *> poly_nodes (nbNodes);
+              for (int inode = 0; inode < nbNodes; inode++) {
+                poly_nodes[inode] = fNodes[inode];
+              }
+              aFreeFace = aTmpFacesMesh.AddPolygonalFace(poly_nodes);
+            }
           }
           if ( aFreeFace )
             freeFaceList.push_back( aFreeFace );