From 90538c51905cda57f579f1c2a04ca715bf6ab905 Mon Sep 17 00:00:00 2001 From: eap Date: Wed, 27 Mar 2019 14:51:54 +0300 Subject: [PATCH] 54522: Compound Mesh: bad groups with meshToAppendTo provided Fix SMESH_Gen_i::ConcatenateCommon() + #16469: MakeSlot - add split faces to groups of initial faces --- src/SMESH/SMESH_Mesh.cxx | 2 +- src/SMESHUtils/SMESH_MeshAlgos.hxx | 7 ++-- src/SMESHUtils/SMESH_Slot.cxx | 56 ++++++++++++++++++++++++++++-- src/SMESH_I/SMESH_Gen_i.cxx | 16 +++++++++ src/SMESH_I/SMESH_MeshEditor_i.cxx | 11 +++++- 5 files changed, 84 insertions(+), 8 deletions(-) diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 7cc790b44..7201c5280 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -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 ); diff --git a/src/SMESHUtils/SMESH_MeshAlgos.hxx b/src/SMESHUtils/SMESH_MeshAlgos.hxx index beebbe796..1ceb456db 100644 --- a/src/SMESHUtils/SMESH_MeshAlgos.hxx +++ b/src/SMESHUtils/SMESH_MeshAlgos.hxx @@ -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 diff --git a/src/SMESHUtils/SMESH_Slot.cxx b/src/SMESHUtils/SMESH_Slot.cxx index 301102626..3e5efd6c3 100644 --- a/src/SMESHUtils/SMESH_Slot.cxx +++ b/src/SMESHUtils/SMESH_Slot.cxx @@ -25,6 +25,7 @@ #include "ObjectPool.hxx" #include "SMDS_LinearEdge.hxx" #include "SMDS_Mesh.hxx" +#include "SMDS_MeshGroup.hxx" #include #include @@ -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 ) { diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index ba4898e97..e090b4be1 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -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; diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index ba435e4aa..dec18fa04 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -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& allGroups = meshDS->GetGroups(); + std::set::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 ) -- 2.39.2