Salome HOME
Advanced feature for sewing - polygons creation instead of splitting.
authorjfa <jfa@opencascade.com>
Thu, 3 Mar 2005 13:03:05 +0000 (13:03 +0000)
committerjfa <jfa@opencascade.com>
Thu, 3 Mar 2005 13:03:05 +0000 (13:03 +0000)
idl/SMESH_Mesh.idl
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_MeshEditor.hxx
src/SMESHDS/SMESHDS_Mesh.cxx
src/SMESHDS/SMESHDS_Mesh.hxx
src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx
src/SMESHGUI/SMESHGUI_SewingDlg.cxx
src/SMESHGUI/SMESHGUI_SewingDlg.h
src/SMESH_I/SMESH_MeshEditor_i.cxx
src/SMESH_I/SMESH_MeshEditor_i.hxx

index fd0ad8e515de2277599998e1ce71965020fa04ea..10debd7fd23f435d95bd1fddec8f66ca19b47b1e 100644 (file)
@@ -657,7 +657,8 @@ module SMESH
                               in long LastNodeID1,
                               in long FirstNodeID2,
                               in long SecondNodeID2,
-                              in long LastNodeID2);
+                              in long LastNodeID2,
+                             in boolean CreatePoly);
 
     Sew_Error SewConformFreeBorders (in long FirstNodeID1,
                                      in long SecondNodeID1,
index 2067282e3bfbf2d39749f12b657881ab24e77006..1fdb16b7190d0a514b3bac57ab88f1854be33647 100644 (file)
 
 #include "SMESH_MeshEditor.hxx"
 
-#include "SMESH_ControlsDef.hxx"
-
 #include "SMDS_FaceOfNodes.hxx"
 #include "SMDS_VolumeTool.hxx"
+#include "SMDS_EdgePosition.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+
 #include "SMESHDS_Group.hxx"
 #include "SMESHDS_Mesh.hxx"
+
 #include "SMESH_subMesh.hxx"
 #include "SMESH_ControlsDef.hxx"
 
 #include <gp.hxx>
 #include <gp_Pln.hxx>
 #include <BRep_Tool.hxx>
-#include <SMDS_EdgePosition.hxx>
 #include <Geom_Curve.hxx>
 
-
 #include <map>
 
-#include "utilities.h"
-
 using namespace std;
 using namespace SMESH::Controls;
 
@@ -2365,7 +2363,7 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
     SMDS_ElemIteratorPtr itN = elem->nodesIterator();
     while ( itN->more() ) {
 
-      // check if a node has been already transormed
+      // check if a node has been already transformed
       const SMDS_MeshNode* node =
         static_cast<const SMDS_MeshNode*>( itN->next() );
       if (nodeMap.find( node ) != nodeMap.end() )
@@ -2431,6 +2429,82 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
     int nbNodes = elem->NbNodes();
     int elemType = elem->GetType();
 
+    if (elem->IsPoly()) {
+      // Polygon or Polyhedral Volume
+      switch ( elemType ) {
+      case SMDSAbs_Face:
+        {
+          vector<const SMDS_MeshNode*> poly_nodes (nbNodes);
+          int iNode = 0;
+          SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+          while (itN->more()) {
+            const SMDS_MeshNode* node =
+              static_cast<const SMDS_MeshNode*>(itN->next());
+            TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node);
+            if (nodeMapIt == nodeMap.end())
+              break; // not all nodes transformed
+            if (needReverse) {
+              // reverse mirrored faces and volumes
+              poly_nodes[nbNodes - iNode - 1] = (*nodeMapIt).second;
+            } else {
+              poly_nodes[iNode] = (*nodeMapIt).second;
+            }
+            iNode++;
+          }
+          if ( iNode != nbNodes )
+            continue; // not all nodes transformed
+
+          if ( theCopy ) {
+            aMesh->AddPolygonalFace(poly_nodes);
+          } else {
+            aMesh->ChangePolygonNodes(elem, poly_nodes);
+          }
+        }
+        break;
+      case SMDSAbs_Volume:
+        {
+          // ATTENTION: Reversing is not yet done!!!
+          const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
+            (const SMDS_PolyhedralVolumeOfNodes*) elem;
+          if (!aPolyedre) {
+            MESSAGE("Warning: bad volumic element");
+            continue;
+          }
+
+          vector<const SMDS_MeshNode*> poly_nodes;
+          vector<int> quantities;
+
+          bool allTransformed = true;
+          int nbFaces = aPolyedre->NbFaces();
+          for (int iface = 1; iface <= nbFaces && allTransformed; iface++) {
+            int nbFaceNodes = aPolyedre->NbFaceNodes(iface);
+            for (int inode = 1; inode <= nbFaceNodes && allTransformed; inode++) {
+              const SMDS_MeshNode* node = aPolyedre->GetFaceNode(iface, inode);
+              TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node);
+              if (nodeMapIt == nodeMap.end()) {
+                allTransformed = false; // not all nodes transformed
+              } else {
+                poly_nodes.push_back((*nodeMapIt).second);
+              }
+            }
+            quantities.push_back(nbFaceNodes);
+          }
+          if ( !allTransformed )
+            continue; // not all nodes transformed
+
+          if ( theCopy ) {
+            aMesh->AddPolyhedralVolume(poly_nodes, quantities);
+          } else {
+            aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
+          }
+        }
+        break;
+      default:;
+      }
+      continue;
+    }
+
+    // Regular elements
     int* i = index[ FORWARD ];
     if ( needReverse && nbNodes > 2) // reverse mirrored faces and volumes
       if ( elemType == SMDSAbs_Face )
@@ -3136,7 +3210,8 @@ SMESH_MeshEditor::Sew_Error
                                    const SMDS_MeshNode* theSideFirstNode,
                                    const SMDS_MeshNode* theSideSecondNode,
                                    const SMDS_MeshNode* theSideThirdNode,
-                                   bool                 theSideIsFreeBorder)
+                                   const bool           theSideIsFreeBorder,
+                                   const bool           toCreatePoly)
 {
   MESSAGE("::SewFreeBorder()");
   Sew_Error aResult = SEW_OK;
@@ -3482,12 +3557,12 @@ SMESH_MeshEditor::Sew_Error
           list<const SMDS_MeshNode*> & nodeList = (*insertMapIt).second;
           const SMDS_MeshNode* n12 = nodeList.front(); nodeList.pop_front();
           const SMDS_MeshNode* n22 = nodeList.front(); nodeList.pop_front();
-          InsertNodesIntoLink( elem, n12, n22, nodeList );
+          InsertNodesIntoLink( elem, n12, n22, nodeList, toCreatePoly );
           // 2. perform insertion into the link of adjacent faces
           while (true) {
             const SMDS_MeshElement* adjElem = findAdjacentFace( n12, n22, elem );
             if ( adjElem )
-              InsertNodesIntoLink( adjElem, n12, n22, nodeList );
+              InsertNodesIntoLink( adjElem, n12, n22, nodeList, toCreatePoly );
             else
               break;
           }
@@ -3530,14 +3605,14 @@ SMESH_MeshEditor::Sew_Error
       const SMDS_MeshNode* n1 = nodeList.front(); nodeList.pop_front();
       const SMDS_MeshNode* n2 = nodeList.front(); nodeList.pop_front();
 
-      InsertNodesIntoLink( elem, n1, n2, nodeList );
+      InsertNodesIntoLink( elem, n1, n2, nodeList, toCreatePoly );
 
       if ( !theSideIsFreeBorder ) {
         // look for and insert nodes into the faces adjacent to elem
         while (true) {
           const SMDS_MeshElement* adjElem = findAdjacentFace( n1, n2, elem );
           if ( adjElem )
-            InsertNodesIntoLink( adjElem, n1, n2, nodeList );
+            InsertNodesIntoLink( adjElem, n1, n2, nodeList, toCreatePoly );
           else
             break;
         }
@@ -3560,7 +3635,8 @@ SMESH_MeshEditor::Sew_Error
 void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
                                            const SMDS_MeshNode*        theBetweenNode1,
                                            const SMDS_MeshNode*        theBetweenNode2,
-                                           list<const SMDS_MeshNode*>& theNodesToInsert)
+                                           list<const SMDS_MeshNode*>& theNodesToInsert,
+                                           const bool                  toCreatePoly)
 {
   if ( theFace->GetType() != SMDSAbs_Face ) return;
 
@@ -3600,6 +3676,52 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     i4 = iNode;
   } 
 
+  if (toCreatePoly || theFace->IsPoly()) {
+
+    iNode = 0;
+    vector<const SMDS_MeshNode *> poly_nodes (nbFaceNodes + theNodesToInsert.size());
+
+    // add nodes of face up to first node of link
+    bool isFLN = false;
+    nodeIt = theFace->nodesIterator();
+    while ( nodeIt->more() && !isFLN ) {
+      const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+      poly_nodes[iNode++] = n;
+      if (n == nodes[il1]) {
+        isFLN = true;
+      }
+    }
+
+    // add nodes to insert
+    list<const SMDS_MeshNode*>::iterator nIt = theNodesToInsert.begin();
+    for (; nIt != theNodesToInsert.end(); nIt++) {
+      poly_nodes[iNode++] = *nIt;
+    }
+
+    // add nodes of face starting from last node of link
+    while ( nodeIt->more() ) {
+      const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+      poly_nodes[iNode++] = n;
+    }
+
+    // edit or replace the face
+    SMESHDS_Mesh *aMesh = GetMeshDS();
+
+    if (theFace->IsPoly()) {
+      aMesh->ChangePolygonNodes(theFace, poly_nodes);
+
+    } else {
+      int aShapeId = FindShape( theFace );
+
+      SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes);
+      if ( aShapeId && newElem )
+        aMesh->SetMeshElementOnShape( newElem, aShapeId );
+
+      aMesh->RemoveElement(theFace);
+    }
+    return;
+  }
+
   // put theNodesToInsert between theBetweenNode1 and theBetweenNode2
   int nbLinkNodes = 2 + theNodesToInsert.size();
   const SMDS_MeshNode* linkNodes[ nbLinkNodes ];
index 677d9c033596a54021628fd99c3ebe8e4c13fa25..638e6152b3d4b94e5bba691e4384a16eb07e14d6 100644 (file)
@@ -189,7 +189,8 @@ class SMESH_MeshEditor {
                            const SMDS_MeshNode* theSide2FirstNode,
                            const SMDS_MeshNode* theSide2SecondNode,
                            const SMDS_MeshNode* theSide2ThirdNode = 0,
-                           bool                 theSide2IsFreeBorder = true);
+                           const bool           theSide2IsFreeBorder = true,
+                           const bool           toCreatePoly = false);
   // Sew the free border to the side2 by replacing nodes in
   // elements on the free border with nodes of the elements
   // of the side 2. If nb of links in the free border and
@@ -226,9 +227,10 @@ class SMESH_MeshEditor {
   void InsertNodesIntoLink(const SMDS_MeshElement*          theFace,
                            const SMDS_MeshNode*             theBetweenNode1,
                            const SMDS_MeshNode*             theBetweenNode2,
-                           std::list<const SMDS_MeshNode*>& theNodesToInsert);
-  // insert theNodesToInsert into theFace between theBetweenNode1
-  // and theBetweenNode2 and split theElement.
+                           std::list<const SMDS_MeshNode*>& theNodesToInsert,
+                           const bool                       toCreatePoly = false);
+  // insert theNodesToInsert into theFace between theBetweenNode1 and theBetweenNode2.
+  // If toCreatePoly is true, replace theFace by polygon, else split theFace.
 
   static int SortQuadNodes (const SMDS_Mesh * theMesh,
                             int               theNodeIds[] );
index c0c758c7451c0591b13e9c977f4df0404c61988a..b72a6b6b31f950b981c48a1012a8081aa37de336 100644 (file)
@@ -181,6 +181,25 @@ bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
   return true;
 }
 
+//=======================================================================
+//function : ChangePolygonNodes
+//purpose  : 
+//=======================================================================
+bool SMESHDS_Mesh::ChangePolygonNodes
+                   (const SMDS_MeshElement * elem,
+                    std::vector<const SMDS_MeshNode*> nodes)
+{
+  ASSERT(nodes.size() > 3);
+
+  int nb = nodes.size();
+  const SMDS_MeshNode* nodes_array [nb];
+  for (int inode = 0; inode < nb; inode++) {
+    nodes_array[inode] = nodes[inode];
+  }
+
+  return ChangeElementNodes(elem, nodes_array, nb);
+}
+
 //=======================================================================
 //function : ChangePolyhedronNodes
 //purpose  : 
index 115ab375621be7a9ef05625e4f4f3556d2d1c85d..5da0423b05e2279bb6aa290da0b91ca0e43f4132 100644 (file)
@@ -186,6 +186,8 @@ public:
   bool ChangeElementNodes(const SMDS_MeshElement * elem,
                           const SMDS_MeshNode    * nodes[],
                           const int                nbnodes);
+  bool ChangePolygonNodes(const SMDS_MeshElement * elem,
+                          std::vector<const SMDS_MeshNode*> nodes);
   bool ChangePolyhedronNodes(const SMDS_MeshElement * elem,
                              std::vector<const SMDS_MeshNode*> nodes,
                              std::vector<int>                  quantities);
index ffdfb5113920c58200e0f37de5e05274bfdf975e..266320ba40fa83e88eec4c9232840df38cb7f817 100644 (file)
@@ -593,10 +593,13 @@ void SMESHGUI_AddMeshElementDlg::SelectionIntoArgument()
   myBusy = true;
   myEditCurrentArgument->setText( aString );
   myBusy = false;
-  if (myIsPoly && myElementType == SMDSAbs_Face && nbNodes>=3 ) {
-  } else if (myIsPoly && myElementType == SMDSAbs_Volume && nbNodes>=4){
-  } else if (myNbNodes != nbNodes)
+  if (myIsPoly && myElementType == SMDSAbs_Face && nbNodes >= 3 ) {
+    myNbNodes = nbNodes;
+  } else if (myIsPoly && myElementType == SMDSAbs_Volume && nbNodes >= 4) {
+    myNbNodes = nbNodes;
+  } else if (myNbNodes != nbNodes) {
     return;
+  }
 
   // OK
 
index 0cfe1f64399924850ba5c01a2ae18731409c2881..5a0e1375ced6eaf9791b0b41fa18e8c7acf78258 100644 (file)
@@ -245,6 +245,11 @@ SMESHGUI_SewingDlg::SMESHGUI_SewingDlg( QWidget* parent, const char* name, SALOM
   CheckBoxMerge->setText( tr( "MERGE_EQUAL_ELEMENTS"  ) );
   GroupArgumentsLayout->addWidget( CheckBoxMerge, 2, 0 );
   
+  // Control for the polygons creation instead of splitting
+  CheckBoxPoly = new QCheckBox( GroupArguments, "CheckBoxPoly" );
+  CheckBoxPoly->setText( tr( "CREATE_POLYGONS_INSTEAD_SPLITTING"  ) );
+  GroupArgumentsLayout->addWidget( CheckBoxPoly, 3, 0 );
+  
 
   SMESHGUI_SewingDlgLayout->addWidget( GroupArguments, 1, 0 );
   
@@ -320,6 +325,7 @@ void SMESHGUI_SewingDlg::Init()
   myActor     = 0;
   myMesh = SMESH::SMESH_Mesh::_nil();
   CheckBoxMerge->setChecked(false);
+  CheckBoxPoly->setChecked(false);
   SelectionIntoArgument();
 }
 
@@ -355,6 +361,9 @@ void SMESHGUI_SewingDlg::ConstructorsClicked(int constructorId)
       LineEdit6->setEnabled(true);
     }
   
+  if (constructorId != 0 && CheckBoxPoly->isVisible())
+    CheckBoxPoly->hide();
+       
   switch(constructorId)
     {
     case 0 :
@@ -362,6 +371,9 @@ void SMESHGUI_SewingDlg::ConstructorsClicked(int constructorId)
        GroupArguments->setTitle( tr( "SEW_FREE_BORDERS" ) );
        SubGroup1->setTitle( tr( "BORDER_1" ) );
        SubGroup2->setTitle( tr( "BORDER_2" ) );
+
+        if (!CheckBoxPoly->isVisible())
+          CheckBoxPoly->show();
        
        break;
       }
@@ -449,6 +461,7 @@ bool SMESHGUI_SewingDlg::ClickOnApply()
   if ( IsValid() )
     {
       bool toMerge = CheckBoxMerge->isChecked();
+      bool toCreatePoly = CheckBoxPoly->isChecked();
     
       try
        {
@@ -464,7 +477,8 @@ bool SMESHGUI_SewingDlg::ClickOnApply()
                                                  LineEdit3->text().toLong(),
                                                  LineEdit4->text().toLong(),
                                                  LineEdit5->text().toLong(),
-                                                 LineEdit6->text().toLong());
+                                                 LineEdit6->text().toLong(),
+                                                  toCreatePoly);
          else if (aConstructorId == 1)
            anError = aMeshEditor->SewConformFreeBorders(LineEdit1->text().toLong(),
                                                         LineEdit2->text().toLong(),
index b5433bb2d33a22f58702a2c91286edbc6e7919ac..80740d79da5570495c8f281db54ae7013cc12217 100644 (file)
@@ -111,6 +111,7 @@ private:
     QLineEdit* LineEdit5;
     QLineEdit* LineEdit6;
     QCheckBox* CheckBoxMerge;
+    QCheckBox* CheckBoxPoly;
    
 private slots:
 
index 0f46b537eecdf5808bb48321f6d58a095823ec50..d1b0e9f1dd7ef60307fa1c4deb76b89531188d0d 100644 (file)
@@ -916,7 +916,8 @@ SMESH::SMESH_MeshEditor::Sew_Error
                                      CORBA::Long LastNodeID1,
                                      CORBA::Long FirstNodeID2,
                                      CORBA::Long SecondNodeID2,
-                                     CORBA::Long LastNodeID2)
+                                     CORBA::Long LastNodeID2,
+                                     CORBA::Boolean CreatePoly)
 {
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
@@ -943,7 +944,8 @@ SMESH::SMESH_MeshEditor::Sew_Error
                                             aSide2FirstNode,
                                             aSide2SecondNode,
                                             aSide2ThirdNode,
-                                            true));
+                                            true,
+                                            CreatePoly) );
 }
 
 //=======================================================================
@@ -982,7 +984,8 @@ SMESH::SMESH_MeshEditor::Sew_Error
                                             aSide2FirstNode,
                                             aSide2SecondNode,
                                             aSide2ThirdNode,
-                                            true ));
+                                            true,
+                                            false) );
 }
 
 //=======================================================================
@@ -1021,7 +1024,8 @@ SMESH::SMESH_MeshEditor::Sew_Error
                                             aSide2FirstNode,
                                             aSide2SecondNode,
                                             aSide2ThirdNode,
-                                            false));
+                                            false,
+                                            false) );
 }
 
 //=======================================================================
index 7325f53e4590fab1e28544438ec7ebcfb5a39858..73e26d2ac5025069fd785115979d35dc49ebf0dc 100644 (file)
@@ -164,7 +164,8 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
                    CORBA::Long LastNodeID1,
                    CORBA::Long FirstNodeID2,
                    CORBA::Long SecondNodeID2,
-                   CORBA::Long LastNodeID2);
+                   CORBA::Long LastNodeID2,
+                   CORBA::Boolean CreatePoly);
   SMESH::SMESH_MeshEditor::Sew_Error
     SewConformFreeBorders(CORBA::Long FirstNodeID1,
                           CORBA::Long SecondNodeID1,