From 53660eaf436e888915c430c2372390c2af5fbb74 Mon Sep 17 00:00:00 2001 From: eap Date: Wed, 19 Dec 2007 15:01:13 +0000 Subject: [PATCH] PAL16617 (Modification/Transformation operations with copy don't create a new mesh) 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 | 173 ++++++++++++++++++++------------- src/SMESH/SMESH_MeshEditor.hxx | 6 +- 2 files changed, 107 insertions(+), 72 deletions(-) diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 99f81e844..b858c372f 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -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::const_iterator grIt = groups.begin(); for ( ; grIt != groups.end(); grIt++ ) { SMESHDS_Group* group = dynamic_cast( *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 & newVolumes = itElem->second; int iVol, volNb, nbVolumesByStep = newVolumes.size() / nbSteps; - set initNodeSet, faceNodeSet; - for ( iNode = 0; iNode < nbNodes; iNode++ ) + set 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::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 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 iter_isnew = + pair 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 ); + 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(group->GetGroupDS()); newGroup = & groupDS->SMDSGroup(); newGroupIDs->push_back( id ); diff --git a/src/SMESH/SMESH_MeshEditor.hxx b/src/SMESH/SMESH_MeshEditor.hxx index 5c4d11b7c..fd5facec2 100644 --- a/src/SMESH/SMESH_MeshEditor.hxx +++ b/src/SMESH/SMESH_MeshEditor.hxx @@ -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 > TNodeOfNodeListMap; -- 2.30.2