Salome HOME
Copyright update 2020
[modules/smesh.git] / src / SMESH / SMESH_MeshEditor.cxx
index 12e01cd2adac78e1c810a8bb3c1b19d1bbafa2ab..ae3b70321c91196a98ba745dfa86b1466f83824d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2019  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2020  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
@@ -161,8 +161,7 @@ SMESH_MeshEditor::ElemFeatures::Init( const SMDS_MeshElement* elem, bool basicOn
         myIsQuad = elem->IsQuadratic();
         if ( myType == SMDSAbs_Volume && !basicOnly )
         {
-          vector<int> quant = static_cast<const SMDS_MeshVolume* >( elem )->GetQuantities();
-          myPolyhedQuantities.swap( quant );
+          myPolyhedQuantities = static_cast<const SMDS_MeshVolume* >( elem )->GetQuantities();
         }
       }
     }
@@ -297,6 +296,18 @@ SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
                                                  node[8], node[9], node[10],node[11],
                                                  node[12],node[13],node[14] );
       }
+      else if (nbnode == 18) {
+        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],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] );
+      }
       else if (nbnode == 20) {
         if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
                                                  node[4], node[5], node[6], node[7],
@@ -1093,19 +1104,37 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem)
       MESSAGE("Warning: bad volumic element");
       return false;
     }
-    const int nbFaces = aPolyedre->NbFaces();
+    SMDS_VolumeTool vTool( aPolyedre );
+    const int nbFaces = vTool.NbFaces();
+    vector<int> quantities( nbFaces );
     vector<const SMDS_MeshNode *> poly_nodes;
-    vector<int> quantities (nbFaces);
 
-    // reverse each face of the polyedre
-    for (int iface = 1; iface <= nbFaces; iface++) {
-      int inode, nbFaceNodes = aPolyedre->NbFaceNodes(iface);
-      quantities[iface - 1] = nbFaceNodes;
+    // check if all facets are oriented equally
+    bool sameOri = true;
+    vector<int>& facetOri = quantities; // keep orientation in quantities so far
+    for (int iface = 0; iface < nbFaces; iface++)
+    {
+      facetOri[ iface ] = vTool.IsFaceExternal( iface );
+      if ( facetOri[ iface ] != facetOri[ 0 ])
+        sameOri = false;
+    }
+
+    // reverse faces of the polyhedron
+    int neededOri = sameOri ? 1 - facetOri[0] : 1;
+    poly_nodes.reserve( vTool.NbNodes() );
+    for ( int iface = 0; iface < nbFaces; iface++ )
+    {
+      int             nbFaceNodes = vTool.NbFaceNodes( iface );
+      const SMDS_MeshNode** nodes = vTool.GetFaceNodes( iface );
+      bool toReverse = ( facetOri[ iface ] != neededOri );
 
-      for (inode = nbFaceNodes; inode >= 1; inode--) {
-        const SMDS_MeshNode* curNode = aPolyedre->GetFaceNode(iface, inode);
-        poly_nodes.push_back(curNode);
-      }
+      quantities[ iface ] = nbFaceNodes;
+
+      if ( toReverse )
+        for ( int inode = nbFaceNodes - 1; inode >= 0; inode-- )
+          poly_nodes.push_back( nodes[ inode ]);
+      else
+        poly_nodes.insert( poly_nodes.end(), nodes, nodes + nbFaceNodes );
     }
     return GetMeshDS()->ChangePolyhedronNodes( theElem, poly_nodes, quantities );
   }
@@ -5850,6 +5879,11 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet     theElemSets[2],
           }
           else
           {
+            if ( theParams.ToMakeBoundary() )
+            {
+              GetMeshDS()->Modified();
+              throw SALOME_Exception( SMESH_Comment("Can't extrude node #") << node->GetID() );
+            }
             break; // newNodesItVec will be shorter than nbNodes
           }
         }
@@ -6367,7 +6401,7 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
  *  \param [in] theValue - offset value
  *  \param [out] theTgtMesh - a mesh to add offset elements to
  *  \param [in] theMakeGroups - to generate groups
- *  \return PGroupIDs - IDs of created groups
+ *  \return PGroupIDs - IDs of created groups. NULL means failure
  */
 //================================================================================
 
@@ -6454,6 +6488,8 @@ SMESH_MeshEditor::PGroupIDs SMESH_MeshEditor::Offset( TIDSortedElemSet & theElem
   PGroupIDs newGroupIDs;
   if ( theMakeGroups )
     newGroupIDs = generateGroups( srcNodes, srcElems, "offset", theTgtMesh, false );
+  else
+    newGroupIDs.reset( new std::list< int > );
 
   return newGroupIDs;
 }
@@ -7453,6 +7489,8 @@ void SMESH_MeshEditor::FindEqualElements( TIDSortedElemSet &        theElements,
   while ( elemIt->more() )
   {
     const SMDS_MeshElement* curElem = elemIt->next();
+    if ( curElem->IsNull() )
+      continue;
     ComparableElement      compElem = curElem;
     // check uniqueness
     const ComparableElement& elemInSet = mapOfElements.Added( compElem );
@@ -9311,7 +9349,7 @@ void SMESH_MeshEditor::ConvertFromQuadratic(TIDSortedElemSet& theElements)
             const SMDS_MeshElement* eComplex = invIt2->next();
             if ( eComplex->IsQuadratic() && !allMediumNodesIn( eComplex, mediumNodes))
             {
-              int nbCommonNodes = SMESH_MeshAlgos::GetCommonNodes( e, eComplex ).size();
+              int nbCommonNodes = SMESH_MeshAlgos::NbCommonNodes( e, eComplex );
               if ( nbCommonNodes == e->NbNodes())
               {
                 complexFound = true;
@@ -9853,10 +9891,10 @@ SMESH_MeshEditor::FindMatchingNodes(set<const SMDS_MeshElement*>& theSide1,
   set<const SMDS_MeshElement*> * faceSetPtr[] = { &theSide1, &theSide2 };
 
   nReplaceMap.clear();
-  if ( theFirstNode1 != theFirstNode2 )
-    nReplaceMap.insert( make_pair( theFirstNode1, theFirstNode2 ));
-  if ( theSecondNode1 != theSecondNode2 )
-    nReplaceMap.insert( make_pair( theSecondNode1, theSecondNode2 ));
+  //if ( theFirstNode1 != theFirstNode2 )
+  nReplaceMap.insert( make_pair( theFirstNode1, theFirstNode2 ));
+  //if ( theSecondNode1 != theSecondNode2 )
+  nReplaceMap.insert( make_pair( theSecondNode1, theSecondNode2 ));
 
   set< SMESH_TLink > linkSet; // set of nodes where order of nodes is ignored
   linkSet.insert( SMESH_TLink( theFirstNode1, theSecondNode1 ));
@@ -11159,7 +11197,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
       {
         int oldId = *itn;
         //MESSAGE("     node " << oldId);
-        vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId);
+        vtkCellLinks::Link l = (static_cast <vtkCellLinks *>(grid->GetCellLinks()))->GetLink(oldId);
         for (int i=0; i<l.ncells; i++)
         {
           int vtkId = l.cells[i];
@@ -11338,7 +11376,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
                       //MESSAGE("  domain " << idom << " volume " << elem->GetID());
                       double values[3] = { 0,0,0 };
                       vtkIdType npts = 0;
-                      vtkIdType* pts = 0;
+                      vtkIdType const *pts(nullptr);
                       grid->GetCellPoints(vtkVolIds[ivol], npts, pts);
                       for ( vtkIdType i = 0; i < npts; ++i )
                       {
@@ -11521,7 +11559,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
     {
       int oldId = itnod->first;
       //MESSAGE("     node " << oldId);
-      vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId);
+      vtkCellLinks::Link l = (static_cast< vtkCellLinks *>(grid->GetCellLinks()))->GetLink(oldId);
       for (int i = 0; i < l.ncells; i++)
       {
         int vtkId = l.cells[i];
@@ -11973,7 +12011,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double                          radius,
       //MESSAGE("volume to check,  vtkId " << vtkId << " smdsId " << meshDS->FromVtkToSmds(vtkId));
       bool volInside = false;
       vtkIdType npts = 0;
-      vtkIdType* pts = 0;
+      vtkIdType const *pts(nullptr);
       grid->GetCellPoints(vtkId, npts, pts);
       for (int i=0; i<npts; i++)
       {
@@ -12540,8 +12578,8 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
         for ( inode = 0; inode < srcNodes.size(); ++inode )
           tgtNodes[inode] = getNodeWithSameID( tgtMeshDS, srcNodes[inode] );
         if ( /*aroundElements && */tgtEditor.GetMeshDS()->FindElement( tgtNodes,
-                                                                   missType,
-                                                                   /*noMedium=*/false))
+                                                                       missType,
+                                                                       /*noMedium=*/false))
           continue;
         tgtEditor.AddElement( tgtNodes, elemKind.SetPoly( tgtNodes.size()/(iQuad+1) > 4 ));
         ++nbAddedBnd;
@@ -12551,8 +12589,8 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
       {
         TConnectivity& nodes = missingBndElems[ i ];
         if ( /*aroundElements && */tgtEditor.GetMeshDS()->FindElement( nodes,
-                                                                   missType,
-                                                                   /*noMedium=*/false))
+                                                                       missType,
+                                                                       /*noMedium=*/false))
           continue;
         SMDS_MeshElement* newElem =
           tgtEditor.AddElement( nodes, elemKind.SetPoly( nodes.size()/(iQuad+1) > 4 ));