]> SALOME platform Git repositories - modules/smesh.git/commitdiff
Salome HOME
PAL16617 (Modification/Transformation operations with copy don't create a new mesh)
authoreap <eap@opencascade.com>
Wed, 19 Dec 2007 15:01:13 +0000 (15:01 +0000)
committereap <eap@opencascade.com>
Wed, 19 Dec 2007 15:01:13 +0000 (15:01 +0000)
   PGroupIDs Transform (TIDSortedElemSet & theElements,
                        const gp_Trsf&     theTrsf,
                        const bool         theCopy,
-                       const bool         theMakeGroups);
+                       const bool         theMakeGroups,
+                       SMESH_Mesh*        theTargetMesh=0);

src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_MeshEditor.hxx

index 99f81e8444e657e018f676ddefd35d82ebbb0ba6..b858c372f1249ad88d97ff39fb0c5659a2cc07d2 100644 (file)
@@ -94,9 +94,12 @@ struct TNodeXYZ : public gp_XYZ {
 
 typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink;
 
+//=======================================================================
 /*!
  * \brief A sorted pair of nodes
  */
+//=======================================================================
+
 struct TLink: public NLink
 {
   TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 )
@@ -110,8 +113,8 @@ struct TLink: public NLink
 //purpose  :
 //=======================================================================
 
-SMESH_MeshEditor::SMESH_MeshEditor( SMESH_Mesh* theMesh ):
-myMesh( theMesh )
+SMESH_MeshEditor::SMESH_MeshEditor( SMESH_Mesh* theMesh )
+  :myMesh( theMesh ) // theMesh may be NULL
 {
 }
 
@@ -1171,7 +1174,7 @@ void SMESH_MeshEditor::AddToSameGroups (const SMDS_MeshElement* elemToAdd,
   set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
   for ( ; grIt != groups.end(); grIt++ ) {
     SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *grIt );
-    if ( group && group->SMDSGroup().Contains( elemInGroups ))
+    if ( group && group->Contains( elemInGroups ))
       group->SMDSGroup().Add( elemToAdd );
   }
 }
@@ -3221,16 +3224,17 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
       list<const SMDS_MeshElement*> & newVolumes = itElem->second;
       int iVol, volNb, nbVolumesByStep = newVolumes.size() / nbSteps;
 
-      set<const SMDS_MeshNode*> initNodeSet, faceNodeSet;
-      for ( iNode = 0; iNode < nbNodes; iNode++ )
+      set<const SMDS_MeshNode*> initNodeSet, topNodeSet, faceNodeSet;
+      for ( iNode = 0; iNode < nbNodes; iNode++ ) {
         initNodeSet.insert( vecNewNodes[ iNode ]->first );
-
+        topNodeSet .insert( vecNewNodes[ iNode ]->second.back() );
+      }
       for ( volNb = 0; volNb < nbVolumesByStep; volNb++ ) {
         list<const SMDS_MeshElement*>::iterator v = newVolumes.begin();
         iVol = 0;
         while ( iVol++ < volNb ) v++;
-        // find indices of free faces of a volume
-        list< int > fInd;
+        // find indices of free faces of a volume and their source edges
+        list< int > freeInd;
         list< const SMDS_MeshElement* > srcEdges; // source edges of free faces
         SMDS_VolumeTool vTool( *v );
         int iF, nbF = vTool.NbFaces();
@@ -3239,31 +3243,29 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
               vTool.GetFaceNodes( iF, faceNodeSet ) &&
               initNodeSet != faceNodeSet) // except an initial face
           {
-            fInd.push_back( iF );
+            if ( nbSteps == 1 && faceNodeSet == topNodeSet )
+              continue;
+            freeInd.push_back( iF );
             // find source edge of a free face iF
             vector<const SMDS_MeshNode*> commonNodes; // shared by the initial and free faces
             commonNodes.resize( initNodeSet.size(), NULL ); // avoid spoiling memory
             std::set_intersection( faceNodeSet.begin(), faceNodeSet.end(),
                                    initNodeSet.begin(), initNodeSet.end(),
                                    commonNodes.begin());
-            if (!commonNodes[ 1 + int((*v)->IsQuadratic()) ]) {
-#ifdef _DEBUG_
-              throw SALOME_Exception(LOCALIZED("Common nodes not found"));
-#else
-              srcEdges.push_back( NULL );
-#endif
-            }
             if ( (*v)->IsQuadratic() )
-              srcEdges.push_back(aMesh-> FindEdge (commonNodes[0],commonNodes[1],commonNodes[2]));
+              srcEdges.push_back(aMesh->FindEdge (commonNodes[0],commonNodes[1],commonNodes[2]));
             else
-              srcEdges.push_back(aMesh-> FindEdge (commonNodes[0],commonNodes[1]));
+              srcEdges.push_back(aMesh->FindEdge (commonNodes[0],commonNodes[1]));
 #ifdef _DEBUG_
             if ( !srcEdges.back() )
-              throw SALOME_Exception(LOCALIZED("Source edge not found"));
+            {
+              cout << "SMESH_MeshEditor::makeWalls(), no source edge found for a free face #"
+                   << iF << " of volume #" << vTool.ID() << endl;
+            }
 #endif
           }
         }
-        if ( fInd.empty() )
+        if ( freeInd.empty() )
           continue;
 
         // create faces for all steps;
@@ -3272,9 +3274,9 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
         for ( int iStep = 0; iStep < nbSteps; iStep++ )  {
           vTool.Set( *v );
           vTool.SetExternalNormal();
-          list< int >::iterator ind = fInd.begin();
+          list< int >::iterator ind = freeInd.begin();
           list< const SMDS_MeshElement* >::iterator srcEdge = srcEdges.begin();
-          for ( ; ind != fInd.end(); ++ind, ++srcEdge ) // loop on free faces
+          for ( ; ind != freeInd.end(); ++ind, ++srcEdge ) // loop on free faces
           {
             const SMDS_MeshNode** nodes = vTool.GetFaceNodes( *ind );
             int nbn = vTool.NbFaceNodes( *ind );
@@ -4132,7 +4134,8 @@ SMESH_MeshEditor::PGroupIDs
 SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
                              const gp_Trsf&     theTrsf,
                              const bool         theCopy,
-                             const bool         theMakeGroups)
+                             const bool         theMakeGroups,
+                             SMESH_Mesh*        theTargetMesh)
 {
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
@@ -4160,7 +4163,10 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
     groupPostfix = "transformed";
   }
 
-  SMESHDS_Mesh* aMesh = GetMeshDS();
+  SMESH_MeshEditor targetMeshEditor( theTargetMesh );
+  SMESHDS_Mesh* aTgtMesh = theTargetMesh ? theTargetMesh->GetMeshDS() : 0;
+  SMESHDS_Mesh* aMesh    = GetMeshDS();
+  
 
   // map old node to new one
   TNodeNodeMap nodeMap;
@@ -4185,9 +4191,9 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
 
       // check if a node has been already transformed
       const SMDS_MeshNode* node = cast2Node( itN->next() );
-      pair<TNodeNodeMap::iterator,bool> iter_isnew =
+      pair<TNodeNodeMap::iterator,bool> n2n_isnew =
         nodeMap.insert( make_pair ( node, node ));
-      if ( !iter_isnew.second )
+      if ( !n2n_isnew.second )
         continue;
 
       double coord[3];
@@ -4195,9 +4201,15 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
       coord[1] = node->Y();
       coord[2] = node->Z();
       theTrsf.Transforms( coord[0], coord[1], coord[2] );
-      if ( theCopy ) {
+      if ( theTargetMesh ) {
+        const SMDS_MeshNode * newNode = aTgtMesh->AddNode( coord[0], coord[1], coord[2] );
+        n2n_isnew.first->second = newNode;
+        myLastCreatedNodes.Append(newNode);
+        srcNodes.Append( node );
+      }
+      else if ( theCopy ) {
         const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
-        iter_isnew.first->second = newNode;
+        n2n_isnew.first->second = newNode;
         myLastCreatedNodes.Append(newNode);
         srcNodes.Append( node );
       }
@@ -4209,7 +4221,7 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
       }
 
       // keep inverse elements
-      if ( !theCopy && needReverse ) {
+      if ( !theCopy && !theTargetMesh && needReverse ) {
         SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
         while ( invElemIt->more() ) {
           const SMDS_MeshElement* iel = invElemIt->next();
@@ -4220,7 +4232,7 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
   }
 
   // either create new elements or reverse mirrored ones
-  if ( !theCopy && !needReverse)
+  if ( !theCopy && !needReverse && !theTargetMesh )
     return PGroupIDs();
 
   TIDSortedElemSet::iterator invElemIt = inverseElemSet.begin();
@@ -4280,7 +4292,11 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
           if ( iNode != nbNodes )
             continue; // not all nodes transformed
 
-          if ( theCopy ) {
+          if ( theTargetMesh ) {
+            myLastCreatedElems.Append(aTgtMesh->AddPolygonalFace(poly_nodes));
+            srcElems.Append( elem );
+          }
+          else if ( theCopy ) {
             myLastCreatedElems.Append(aMesh->AddPolygonalFace(poly_nodes));
             srcElems.Append( elem );
           }
@@ -4320,7 +4336,11 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
           if ( !allTransformed )
             continue; // not all nodes transformed
 
-          if ( theCopy ) {
+          if ( theTargetMesh ) {
+            myLastCreatedElems.Append(aTgtMesh->AddPolyhedralVolume(poly_nodes, quantities));
+            srcElems.Append( elem );
+          }
+          else if ( theCopy ) {
             myLastCreatedElems.Append(aMesh->AddPolyhedralVolume(poly_nodes, quantities));
             srcElems.Append( elem );
           }
@@ -4329,18 +4349,18 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
           }
         }
         break;
-      default:;
-      }
-      continue;
+    default:;
     }
+    continue;
+  }
 
-    // Regular elements
-    int* i = index[ FORWARD ];
-    if ( needReverse && nbNodes > 2) // reverse mirrored faces and volumes
-      if ( elemType == SMDSAbs_Face )
-        i = index[ REV_FACE ];
-      else
-        i = index[ nbNodes - 4 ];
+  // Regular elements
+  int* i = index[ FORWARD ];
+  if ( needReverse && nbNodes > 2) // reverse mirrored faces and volumes
+    if ( elemType == SMDSAbs_Face )
+      i = index[ REV_FACE ];
+    else
+      i = index[ nbNodes - 4 ];
 
     if(elem->IsQuadratic()) {
       static int anIds[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
@@ -4392,14 +4412,20 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
     if ( iNode != nbNodes )
       continue; // not all nodes transformed
 
-    if ( theCopy ) {
+    if ( theTargetMesh ) {
+      if ( SMDS_MeshElement* copy =
+           targetMeshEditor.AddElement( nodes, elem->GetType(), elem->IsPoly() )) {
+        myLastCreatedElems.Append( copy );
+        srcElems.Append( elem );
+      }
+    }
+    else if ( theCopy ) {
       if ( SMDS_MeshElement* copy = AddElement( nodes, elem->GetType(), elem->IsPoly() )) {
         myLastCreatedElems.Append( copy );
         srcElems.Append( elem );
       }
     }
-    else
-    {
+    else {
       // reverse element as it was reversed by transformation
       if ( nbNodes > 2 )
         aMesh->ChangeElementNodes( elem, &nodes[0], nbNodes );
@@ -4408,8 +4434,9 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
 
   PGroupIDs newGroupIDs;
 
-  if ( theCopy && theMakeGroups )
-    newGroupIDs = generateGroups( srcNodes, srcElems, groupPostfix );
+  if ( theMakeGroups && theCopy ||
+       theMakeGroups && theTargetMesh )
+    newGroupIDs = generateGroups( srcNodes, srcElems, groupPostfix, theTargetMesh );
 
   return newGroupIDs;
 }
@@ -4426,24 +4453,27 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
 SMESH_MeshEditor::PGroupIDs
 SMESH_MeshEditor::generateGroups(const SMESH_SequenceOfElemPtr& nodeGens,
                                  const SMESH_SequenceOfElemPtr& elemGens,
-                                 const std::string&             postfix)
+                                 const std::string&             postfix,
+                                 SMESH_Mesh*                    targetMesh)
 {
   PGroupIDs newGroupIDs( new list<int> );
+  SMESH_Mesh* mesh = targetMesh ? targetMesh : GetMesh();
+
   // Sort existing groups by types and collect their names
 
-  // store an old group and a generated new one
-  typedef pair< SMESHDS_Group*, SMDS_MeshGroup* > TOldNewGroup;
+  // to store an old group and a generated new one
+  typedef pair< SMESHDS_GroupBase*, SMDS_MeshGroup* > TOldNewGroup;
   vector< list< TOldNewGroup > > groupsByType( SMDSAbs_NbElementTypes );
   // group names
   set< string > groupNames;
-
+  //
   SMDS_MeshGroup* nullNewGroup = (SMDS_MeshGroup*) 0;
   SMESH_Mesh::GroupIteratorPtr groupIt = GetMesh()->GetGroups();
   while ( groupIt->more() ) {
     SMESH_Group * group = groupIt->next();
     if ( !group ) continue;
-    SMESHDS_Group* groupDS = dynamic_cast< SMESHDS_Group* >( group->GetGroupDS() );
-    if ( !groupDS ) continue;
+    SMESHDS_GroupBase* groupDS = group->GetGroupDS();
+    if ( !groupDS || groupDS->IsEmpty() ) continue;
     groupNames.insert( group->GetName() );
     groupDS->SetStoreName( group->GetName() );
     groupsByType[ groupDS->GetType() ].push_back( make_pair( groupDS, nullNewGroup ));
@@ -4470,7 +4500,7 @@ SMESH_MeshEditor::generateGroups(const SMESH_SequenceOfElemPtr& nodeGens,
       list< TOldNewGroup > & groupsOldNew = groupsByType[ sourceElem->GetType() ];
       if ( groupsOldNew.empty() ) {
         while ( iElem < gens.Length() && gens( iElem+1 ) == sourceElem )
-          ++iElem;
+          ++iElem; // skip all elements made by sourceElem
         continue;
       }
       // collect all elements made by sourceElem
@@ -4491,32 +4521,35 @@ SMESH_MeshEditor::generateGroups(const SMESH_SequenceOfElemPtr& nodeGens,
       list< TOldNewGroup >::iterator gOldNew, gLast = groupsOldNew.end();
       for ( gOldNew = groupsOldNew.begin(); gOldNew != gLast; ++gOldNew )
       {
-        SMESHDS_Group* oldGroup = gOldNew->first;
-        if ( oldGroup->SMDSGroup().Contains( sourceElem )) // sourceElem in oldGroup
+        SMESHDS_GroupBase* oldGroup = gOldNew->first;
+        if ( oldGroup->Contains( sourceElem )) // sourceElem in oldGroup
         {
           SMDS_MeshGroup* & newGroup = gOldNew->second;
           if ( !newGroup )// create a new group
           {
             // make a name
             string name = oldGroup->GetStoreName();
-            name += "_";
-            name += postfix;
-            int nb = 0;
-            while ( !groupNames.insert( name ).second ) // name exists
-            {
-              if ( nb == 0 ) {
-                name += "_1";
-              }
-              else {
-                TCollection_AsciiString nbStr(++nb);
-                name.resize( name.rfind('_') );
-                name += nbStr.ToCString();
+            if ( !targetMesh ) {
+              name += "_";
+              name += postfix;
+              int nb = 0;
+              while ( !groupNames.insert( name ).second ) // name exists
+              {
+                if ( nb == 0 ) {
+                  name += "_1";
+                }
+                else {
+                  TCollection_AsciiString nbStr(nb+1);
+                  name.resize( name.rfind('_')+1 );
+                  name += nbStr.ToCString();
+                }
+                ++nb;
               }
             }
             // make a group
             int id;
-            SMESH_Group* group = GetMesh()->AddGroup( resultElems.back()->GetType(),
-                                                      name.c_str(), id );
+            SMESH_Group* group = mesh->AddGroup( resultElems.back()->GetType(),
+                                                 name.c_str(), id );
             SMESHDS_Group* groupDS = static_cast<SMESHDS_Group*>(group->GetGroupDS());
             newGroup = & groupDS->SMDSGroup();
             newGroupIDs->push_back( id );
index 5c4d11b7c289d0464a5f0ab40591024dd0eaa6ff..fd5facec2e6ad444d12fdf27b580aacc74318918 100644 (file)
@@ -296,7 +296,8 @@ public:
   PGroupIDs Transform (TIDSortedElemSet & theElements,
                        const gp_Trsf&     theTrsf,
                        const bool         theCopy,
-                       const bool         theMakeGroups);
+                       const bool         theMakeGroups,
+                       SMESH_Mesh*        theTargetMesh=0);
   // Move or copy theElements applying theTrsf to their nodes
 
   typedef std::list< std::list< const SMDS_MeshNode* > > TListOfListOfNodes;
@@ -531,7 +532,8 @@ private:
    */
   PGroupIDs generateGroups(const SMESH_SequenceOfElemPtr& nodeGens,
                            const SMESH_SequenceOfElemPtr& elemGens,
-                           const std::string&             postfix);
+                           const std::string&             postfix,
+                           SMESH_Mesh*                    targetMesh=0);
 
 
   typedef std::map<const SMDS_MeshNode*, std::list<const SMDS_MeshNode*> > TNodeOfNodeListMap;