54522: Compound Mesh: bad groups with meshToAppendTo provided

Fix SMESH_Gen_i::ConcatenateCommon()

+ #16469: MakeSlot - add split faces to groups of initial faces
This commit is contained in:
eap 2019-03-27 14:51:54 +03:00
parent 1fb3ff621a
commit 90538c5190
5 changed files with 84 additions and 8 deletions

View 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 );

View File

@ -507,7 +507,8 @@ namespace SMESH_MeshAlgos
SMESHUtils_EXPORT
std::vector< Edge > MakeSlot( SMDS_ElemIteratorPtr segmentIt,
double width,
SMDS_Mesh* mesh);
SMDS_Mesh* mesh,
std::vector< SMDS_MeshGroup* > & groupsToUpdate);
} // namespace SMESH_MeshAlgos

View 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 );
}
}
//================================================================================
@ -303,7 +330,8 @@ namespace
std::vector< SMESH_MeshAlgos::Edge >
SMESH_MeshAlgos::MakeSlot( SMDS_ElemIteratorPtr theSegmentIt,
double theWidth,
SMDS_Mesh* theMesh)
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 )
{

View 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;

View 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 )