Salome HOME
54522: Compound Mesh: bad groups with meshToAppendTo provided
authoreap <eap@opencascade.com>
Wed, 27 Mar 2019 11:51:54 +0000 (14:51 +0300)
committereap <eap@opencascade.com>
Wed, 27 Mar 2019 11:51:54 +0000 (14:51 +0300)
  Fix SMESH_Gen_i::ConcatenateCommon()

+ #16469: MakeSlot - add split faces to groups of initial faces

src/SMESH/SMESH_Mesh.cxx
src/SMESHUtils/SMESH_MeshAlgos.hxx
src/SMESHUtils/SMESH_Slot.cxx
src/SMESH_I/SMESH_Gen_i.cxx
src/SMESH_I/SMESH_MeshEditor_i.cxx

index 7cc790b..7201c52 100644 (file)
@@ -1192,7 +1192,7 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h
     return;
 
   bool toCallBack = true;
-  if ( _callUp && hyp && NbNodes() == 0 ) // for not loaded mesh
+  if ( _callUp && hyp && NbNodes() == 0 ) // for not loaded mesh (#16648)
   {
     _callUp->HypothesisModified( hyp->GetID() );
     toCallBack = ( NbNodes() > 0 );
index beebbe7..1ceb456 100644 (file)
@@ -505,9 +505,10 @@ namespace SMESH_MeshAlgos
    */
   // Implemented in ./SMESH_Slot.cxx
   SMESHUtils_EXPORT
-  std::vector< Edge > MakeSlot( SMDS_ElemIteratorPtr segmentIt,
-                                double               width,
-                                SMDS_Mesh*           mesh);
+  std::vector< Edge > MakeSlot( SMDS_ElemIteratorPtr             segmentIt,
+                                double                           width,
+                                SMDS_Mesh*                       mesh,
+                                std::vector< SMDS_MeshGroup* > & groupsToUpdate);
 
 } // namespace SMESH_MeshAlgos
 
index 3011026..3e5efd6 100644 (file)
@@ -25,6 +25,7 @@
 #include "ObjectPool.hxx"
 #include "SMDS_LinearEdge.hxx"
 #include "SMDS_Mesh.hxx"
+#include "SMDS_MeshGroup.hxx"
 
 #include <IntAna_IntConicQuad.hxx>
 #include <IntAna_Quadric.hxx>
@@ -290,6 +291,32 @@ namespace
 
     return faceNormals[ face->GetID() ];
   }
+
+  typedef std::vector< SMDS_MeshGroup* > TGroupVec;
+
+  //================================================================================
+  /*!
+   * \brief Fill theFaceID2Groups map for a given face
+   *  \param [in] theFace - the face
+   *  \param [in] theGroupsToUpdate - list of groups to treat
+   *  \param [out] theFaceID2Groups - the map to fill in
+   *  \param [out] theWorkGroups - a working buffer of groups
+   */
+  //================================================================================
+
+  void findGroups( const SMDS_MeshElement *                theFace,
+                   TGroupVec &                             theGroupsToUpdate,
+                   NCollection_DataMap< int, TGroupVec > & theFaceID2Groups,
+                   TGroupVec &                             theWorkGroups )
+  {
+    theWorkGroups.clear();
+    for ( size_t i = 0; i < theGroupsToUpdate.size(); ++i )
+      if ( theGroupsToUpdate[i]->Contains( theFace ))
+        theWorkGroups.push_back( theGroupsToUpdate[i] );
+
+    if ( !theWorkGroups.empty() )
+      theFaceID2Groups.Bind( theFace->GetID(), theWorkGroups );
+  }
 }
 
 //================================================================================
@@ -301,9 +328,10 @@ namespace
 //================================================================================
 
 std::vector< SMESH_MeshAlgos::Edge >
-SMESH_MeshAlgos::MakeSlot( SMDS_ElemIteratorPtr theSegmentIt,
-                           double               theWidth,
-                           SMDS_Mesh*           theMesh)
+SMESH_MeshAlgos::MakeSlot( SMDS_ElemIteratorPtr             theSegmentIt,
+                           double                           theWidth,
+                           SMDS_Mesh*                       theMesh,
+                           std::vector< SMDS_MeshGroup* > & theGroupsToUpdate)
 {
   std::vector< Edge > bndEdges;
 
@@ -352,6 +380,9 @@ SMESH_MeshAlgos::MakeSlot( SMDS_ElemIteratorPtr theSegmentIt,
   std::vector< SMESH_NodeXYZ > facePoints(4);
   std::vector< Intersector::TFace > cutFacePoints;
 
+  NCollection_DataMap< int, TGroupVec > faceID2Groups;
+  TGroupVec groupVec;
+
   std::vector< gp_Ax1 > planeNormalVec(2);
   gp_Ax1 * planeNormal = & planeNormalVec[0];
   
@@ -551,6 +582,9 @@ SMESH_MeshAlgos::MakeSlot( SMDS_ElemIteratorPtr theSegmentIt,
           Edge e = { intPoints[iE].myNode.Node(), intPoints[iE-1].myNode.Node(), 0 };
           segment->AddEdge( e, tol );
           bndEdges.push_back( e );
+
+          findGroups( face, theGroupsToUpdate, faceID2Groups, groupVec );
+
         }
       }  // loop on faces sharing an edge
 
@@ -664,6 +698,8 @@ SMESH_MeshAlgos::MakeSlot( SMDS_ElemIteratorPtr theSegmentIt,
       Edge e = { intPoints[0].myNode.Node(), intPoints[1].myNode.Node(), 0 };
       bndEdges.push_back( e );
 
+      findGroups( face, theGroupsToUpdate, faceID2Groups, groupVec );
+
       // add cut points to an adjacent face at ends of poly-line
       // if they fall onto face edges
       if (( i == 0                       && intPoints[0].myEdgeIndex >= 0 ) ||
@@ -687,6 +723,8 @@ SMESH_MeshAlgos::MakeSlot( SMDS_ElemIteratorPtr theSegmentIt,
               meshIntersector.Cut( faces[iF],
                                    intPoints[iE].myNode, intPoints[iE].myEdgeIndex,
                                    intPoints[iE].myNode, intPoints[iE].myEdgeIndex );
+
+              findGroups( faces[iF], theGroupsToUpdate, faceID2Groups, groupVec );
             }
         }
       }
@@ -702,6 +740,18 @@ SMESH_MeshAlgos::MakeSlot( SMDS_ElemIteratorPtr theSegmentIt,
   TNodeIntPairVec new2OldNodes;
   meshIntersector.MakeNewFaces( new2OldFaces, new2OldNodes, /*sign=*/1, /*optimize=*/true );
 
+  // add new faces to theGroupsToUpdate
+  for ( size_t i = 0; i < new2OldFaces.size(); ++i )
+  {
+    const SMDS_MeshElement* newFace = new2OldFaces[i].first;
+    const int             oldFaceID = new2OldFaces[i].second;
+    if ( !newFace ) continue;
+
+    if ( TGroupVec* groups = const_cast< TGroupVec* >( faceID2Groups.Seek( oldFaceID )))
+      for ( size_t iG = 0; iG < groups->size(); ++iG )
+        (*groups)[ iG ]->Add( newFace );
+  }
+
   // remove poly-line edges
   for ( size_t i = 0; i < polySegments.size(); ++i )
   {
index ba4898e..e090b4b 100644 (file)
@@ -2509,6 +2509,22 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
   TGroupsMap       groupsMap;
   TListOfNewGroups listOfNewGroups;
 
+  if ( !CORBA::is_nil( theMeshToAppendTo ))
+  {
+    // fill groupsMap with existing groups
+    SMESH::ListOfGroups_var groups = theMeshToAppendTo->GetGroups();
+    for ( CORBA::ULong i = 0; i < groups->length(); ++i )
+    {
+      SMESH::SMESH_Group_var group = SMESH::SMESH_Group::_narrow( groups[ i ]);
+      if ( !group->_is_nil() )
+      {
+        CORBA::String_var  name = group->GetName();
+        SMESH::ElementType type = group->GetType();
+        groupsMap[ TNameAndType( name.in(), type ) ].push_back( group );
+      }
+    }
+  }
+
   ::SMESH_MeshEditor               newEditor( &locMesh );
   ::SMESH_MeshEditor::ElemFeatures elemType;
 
index ba435e4..dec18fa 100644 (file)
@@ -7513,9 +7513,18 @@ SMESH::ListOfEdges* SMESH_MeshEditor_i::MakeSlot(SMESH::SMESH_GroupBase_ptr theS
 
   SMESHDS_Mesh* meshDS = getMeshDS();
 
+  // get standalone face groups to be updated
+  std::vector< SMDS_MeshGroup* > faceGroups;
+  const std::set<SMESHDS_GroupBase*>& allGroups = meshDS->GetGroups();
+  std::set<SMESHDS_GroupBase*>::const_iterator grIt = allGroups.begin();
+  for ( ; grIt != allGroups.end(); ++grIt )
+    if ( const SMESHDS_Group* gr = dynamic_cast< const SMESHDS_Group* >( *grIt ))
+      if ( gr->GetType() == SMDSAbs_Face )
+        faceGroups.push_back( & const_cast< SMESHDS_Group* >( gr )->SMDSGroup() );
+
   std::vector< SMESH_MeshAlgos::Edge > edges =
     SMESH_MeshAlgos::MakeSlot( SMESH_Mesh_i::GetElements( theSegments, SMESH::EDGE ),
-                               theWidth, meshDS );
+                               theWidth, meshDS, faceGroups );
 
   resultEdges->length( edges.size() );
   for ( size_t i = 0; i < edges.size(); ++i )