X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH%2FSMESH_MeshEditor.cxx;h=81d71320ccbb23c62700a92e213c0965101c03b9;hp=b858c372f1249ad88d97ff39fb0c5659a2cc07d2;hb=34fb01e7b5b520e2193fd44c066322e970d471b1;hpb=79b1ac2b6df9117f16f11d444b1f165d477a1813 diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index b858c372f..81d71320c 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -1,6 +1,6 @@ -// SMESH SMESH : idl implementation based on 'SMESH' unit's classes +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // // This library is free software; you can redistribute it and/or @@ -17,15 +17,13 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// SMESH SMESH : idl implementation based on 'SMESH' unit's classes // File : SMESH_MeshEditor.cxx // Created : Mon Apr 12 16:10:22 2004 // Author : Edward AGAPOV (eap) - - +// #include "SMESH_MeshEditor.hxx" #include "SMDS_FaceOfNodes.hxx" @@ -61,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -92,22 +91,6 @@ struct TNodeXYZ : public gp_XYZ { TNodeXYZ( const SMDS_MeshNode* n ):gp_XYZ( n->X(), n->Y(), n->Z() ) {} }; -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 ) - { if ( n1->GetID() < n2->GetID() ) std::swap( first, second ); } - TLink(const NLink& link ):NLink( link ) - { if ( first->GetID() < second->GetID() ) std::swap( first, second ); } -}; - //======================================================================= //function : SMESH_MeshEditor //purpose : @@ -1171,11 +1154,13 @@ void SMESH_MeshEditor::AddToSameGroups (const SMDS_MeshElement* elemToAdd, SMESHDS_Mesh * aMesh) { const set& groups = aMesh->GetGroups(); - set::const_iterator grIt = groups.begin(); - for ( ; grIt != groups.end(); grIt++ ) { - SMESHDS_Group* group = dynamic_cast( *grIt ); - if ( group && group->Contains( elemInGroups )) - group->SMDSGroup().Add( elemToAdd ); + if (!groups.empty()) { + set::const_iterator grIt = groups.begin(); + for ( ; grIt != groups.end(); grIt++ ) { + SMESHDS_Group* group = dynamic_cast( *grIt ); + if ( group && group->Contains( elemInGroups )) + group->SMDSGroup().Add( elemToAdd ); + } } } @@ -1200,6 +1185,25 @@ void SMESH_MeshEditor::RemoveElemFromGroups (const SMDS_MeshElement* removeelem, } } +//======================================================================= +//function : ReplaceElemInGroups +//purpose : replace elemToRm by elemToAdd in the all groups +//======================================================================= + +void SMESH_MeshEditor::ReplaceElemInGroups (const SMDS_MeshElement* elemToRm, + const SMDS_MeshElement* elemToAdd, + SMESHDS_Mesh * aMesh) +{ + const set& groups = aMesh->GetGroups(); + if (!groups.empty()) { + set::const_iterator grIt = groups.begin(); + for ( ; grIt != groups.end(); grIt++ ) { + SMESHDS_Group* group = dynamic_cast( *grIt ); + if ( group && group->SMDSGroup().Remove( elemToRm ) && elemToAdd ) + group->SMDSGroup().Add( elemToAdd ); + } + } +} //======================================================================= //function : QuadToTri @@ -1460,10 +1464,10 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, // 1. map of elements with their linkIDs // 2. map of linkIDs with their elements - map< TLink, list< const SMDS_MeshElement* > > mapLi_listEl; - map< TLink, list< const SMDS_MeshElement* > >::iterator itLE; - map< const SMDS_MeshElement*, set< TLink > > mapEl_setLi; - map< const SMDS_MeshElement*, set< TLink > >::iterator itEL; + map< SMESH_TLink, list< const SMDS_MeshElement* > > mapLi_listEl; + map< SMESH_TLink, list< const SMDS_MeshElement* > >::iterator itLE; + map< const SMDS_MeshElement*, set< SMESH_TLink > > mapEl_setLi; + map< const SMDS_MeshElement*, set< SMESH_TLink > >::iterator itEL; TIDSortedElemSet::iterator itElem; for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { @@ -1482,7 +1486,7 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, // fill maps for ( i = 0; i < 3; i++ ) { - TLink link( aNodes[i], aNodes[i+1] ); + SMESH_TLink link( aNodes[i], aNodes[i+1] ); // check if elements sharing a link can be fused itLE = mapLi_listEl.find( link ); if ( itLE != mapLi_listEl.end() ) { @@ -1508,7 +1512,7 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, int nbElems = (*itLE).second.size(); if ( nbElems < 2 ) { const SMDS_MeshElement* elem = (*itLE).second.front(); - TLink link = (*itLE).first; + SMESH_TLink link = (*itLE).first; mapEl_setLi[ elem ].erase( link ); if ( mapEl_setLi[ elem ].empty() ) mapEl_setLi.erase( elem ); @@ -1534,11 +1538,11 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, // search elements to fuse starting from startElem or links of elements // fused earlyer - startLinks - list< TLink > startLinks; + list< SMESH_TLink > startLinks; while ( startElem || !startLinks.empty() ) { while ( !startElem && !startLinks.empty() ) { // Get an element to start, by a link - TLink linkId = startLinks.front(); + SMESH_TLink linkId = startLinks.front(); startLinks.pop_front(); itLE = mapLi_listEl.find( linkId ); if ( itLE != mapLi_listEl.end() ) { @@ -1554,15 +1558,15 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, if ( startElem ) { // Get candidates to be fused const SMDS_MeshElement *tr1 = startElem, *tr2 = 0, *tr3 = 0; - const TLink *link12, *link13; + const SMESH_TLink *link12, *link13; startElem = 0; ASSERT( mapEl_setLi.find( tr1 ) != mapEl_setLi.end() ); - set< TLink >& setLi = mapEl_setLi[ tr1 ]; + set< SMESH_TLink >& setLi = mapEl_setLi[ tr1 ]; ASSERT( !setLi.empty() ); - set< TLink >::iterator itLi; + set< SMESH_TLink >::iterator itLi; for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ ) { - const TLink & link = (*itLi); + const SMESH_TLink & link = (*itLi); itLE = mapLi_listEl.find( link ); if ( itLE == mapLi_listEl.end() ) continue; @@ -1583,10 +1587,10 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, } // add other links of elem to list of links to re-start from - set< TLink >& links = mapEl_setLi[ elem ]; - set< TLink >::iterator it; + set< SMESH_TLink >& links = mapEl_setLi[ elem ]; + set< SMESH_TLink >::iterator it; for ( it = links.begin(); it != links.end(); it++ ) { - const TLink& link2 = (*it); + const SMESH_TLink& link2 = (*it); if ( link2 != link ) startLinks.push_back( link2 ); } @@ -2047,8 +2051,8 @@ void SMESH_MeshEditor::GetLinkedNodes( const SMDS_MeshNode* theNode, iAfter = SMESH_MesherHelper::WrapIndex( iAfter, nb ); iBefore = SMESH_MesherHelper::WrapIndex( iBefore, nb ); } - linkedNodes.insert( elem->GetNode( iAfter )); - linkedNodes.insert( elem->GetNode( iBefore )); + linkedNodes.insert( elem->GetNodeWrap( iAfter )); + linkedNodes.insert( elem->GetNodeWrap( iBefore )); } } } @@ -2443,9 +2447,8 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, // fix nodes on mesh boundary if ( checkBoundaryNodes ) { - typedef pair TLink; - map< TLink, int > linkNbMap; // how many times a link encounters in elemsOnFace - map< TLink, int >::iterator link_nb; + map< NLink, int > linkNbMap; // how many times a link encounters in elemsOnFace + map< NLink, int >::iterator link_nb; // put all elements links to linkNbMap list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin(); for ( ; elemIt != elemsOnFace.end(); ++elemIt ) { @@ -2454,10 +2457,10 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, if(elem->IsQuadratic()) nbn = nbn/2; // loop on elem links: insert them in linkNbMap - const SMDS_MeshNode* curNode, *prevNode = elem->GetNode( nbn ); + const SMDS_MeshNode* curNode, *prevNode = elem->GetNodeWrap( nbn ); for ( int iN = 0; iN < nbn; ++iN ) { curNode = elem->GetNode( iN ); - TLink link; + NLink link; if ( curNode < prevNode ) link = make_pair( curNode , prevNode ); else link = make_pair( prevNode , curNode ); prevNode = curNode; @@ -2772,8 +2775,6 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, int iNode, nbSame = 0, iNotSameNode = 0, iSameNode = 0; vector sames(nbNodes); - - //bool issimple[nbNodes]; vector issimple(nbNodes); for ( iNode = 0; iNode < nbNodes; iNode++ ) { @@ -2783,12 +2784,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, if ( listNewNodes.empty() ) return; - if(listNewNodes.size()==nbSteps) { - issimple[iNode] = true; - } - else { - issimple[iNode] = false; - } + issimple[iNode] = (listNewNodes.size()==nbSteps); itNN[ iNode ] = listNewNodes.begin(); prevNod[ iNode ] = node; @@ -2833,11 +2829,8 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, //MESSAGE("Reversed elem " << elem ); i0 = 2; i2 = 0; - if ( nbSame > 0 ) { - int iAB = iAfterSame + iBeforeSame; - iBeforeSame = iAB - iBeforeSame; - iAfterSame = iAB - iAfterSame; - } + if ( nbSame > 0 ) + std::swap( iBeforeSame, iAfterSame ); } // make new elements @@ -2856,8 +2849,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, nextNod[ iNode ] = *itNN[ iNode ]; itNN[ iNode ]++; } - else if(!elem->IsQuadratic() || - elem->IsQuadratic() && elem->IsMediumNode(prevNod[iNode]) ) { + else if(!elem->IsQuadratic() || elem->IsMediumNode(prevNod[iNode]) ) { // we have to use each second node itNN[ iNode ]++; nextNod[ iNode ] = *itNN[ iNode ]; @@ -3285,7 +3277,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, const SMDS_MeshFace * f = aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ]); if ( !f ) myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] )); - else if ( nodes[ 1 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) + else if ( nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) aMesh->ChangeElementNodes( f, nodes, nbn ); break; } @@ -3293,7 +3285,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, const SMDS_MeshFace * f = aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ]); if ( !f ) myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] )); - else if ( nodes[ 1 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) + else if ( nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) aMesh->ChangeElementNodes( f, nodes, nbn ); break; } @@ -3305,7 +3297,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, if ( !f ) myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[1], nodes[3], nodes[5])); - else if ( nodes[ 2 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) + else if ( nodes[ 2 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) aMesh->ChangeElementNodes( f, nodes, nbn ); } else { /////// quadratic quadrangle @@ -3314,7 +3306,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, if ( !f ) myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6], nodes[1], nodes[3], nodes[5], nodes[7])); - else if ( nodes[ 2 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) + else if ( nodes[ 2 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) aMesh->ChangeElementNodes( f, nodes, nbn ); } } @@ -3323,7 +3315,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, const SMDS_MeshFace * f = aMesh->FindFace( polygon_nodes ); if ( !f ) myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes)); - else if ( nodes[ 1 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) + else if ( nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) aMesh->ChangeElementNodes( f, nodes, nbn ); } } @@ -3741,7 +3733,7 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, return newGroupIDs; } - +/* //======================================================================= //class : SMESH_MeshEditor_PathPoint //purpose : auxiliary class @@ -3785,6 +3777,7 @@ protected: double myAngle; double myPrm; }; +*/ //======================================================================= //function : ExtrusionAlongTrack @@ -3796,6 +3789,7 @@ SMESH_MeshEditor::Extrusion_Error const SMDS_MeshNode* theN1, const bool theHasAngles, list& theAngles, + const bool theLinearVariation, const bool theHasRefPoint, const gp_Pnt& theRefPoint, const bool theMakeGroups) @@ -3803,20 +3797,11 @@ SMESH_MeshEditor::Extrusion_Error myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - // source elements for each generated one - SMESH_SequenceOfElemPtr srcElems, srcNodes; - - int j, aNbTP, aNbE, aNb; - double aT1, aT2, aT, aAngle, aX, aY, aZ; + int aNbE; std::list aPrms; - std::list::iterator aItD; TIDSortedElemSet::iterator itElem; - Standard_Real aTx1, aTx2, aL2, aTolVec, aTolVec2; - gp_Pnt aP3D, aV0; - gp_Vec aVec; gp_XYZ aGC; - Handle(Geom_Curve) aC3D; TopoDS_Edge aTrackEdge; TopoDS_Vertex aV1, aV2; @@ -3825,11 +3810,6 @@ SMESH_MeshEditor::Extrusion_Error SMDSAbs_ElementType aTypeE; TNodeOfNodeListMap mapNewNodes; - TElemOfVecOfNnlmiMap mapElemNewNodes; - TElemOfElemListMap newElemsMap; - - aTolVec=1.e-7; - aTolVec2=aTolVec*aTolVec; // 1. Check data aNbE = theElements.size(); @@ -3840,7 +3820,7 @@ SMESH_MeshEditor::Extrusion_Error // 1.1 Track Pattern ASSERT( theTrack ); - SMESHDS_SubMesh* pSubMeshDS=theTrack->GetSubMeshDS(); + SMESHDS_SubMesh* pSubMeshDS = theTrack->GetSubMeshDS(); aItE = pSubMeshDS->GetElements(); while ( aItE->more() ) { @@ -3851,63 +3831,325 @@ SMESH_MeshEditor::Extrusion_Error return EXTR_PATH_NOT_EDGE; } + list fullList; + const TopoDS_Shape& aS = theTrack->GetSubShape(); - // Sub shape for the Pattern must be an Edge - if ( aS.ShapeType() != TopAbs_EDGE ) + // Sub shape for the Pattern must be an Edge or Wire + if( aS.ShapeType() == TopAbs_EDGE ) { + aTrackEdge = TopoDS::Edge( aS ); + // the Edge must not be degenerated + if ( BRep_Tool::Degenerated( aTrackEdge ) ) + return EXTR_BAD_PATH_SHAPE; + TopExp::Vertices( aTrackEdge, aV1, aV2 ); + aItN = theTrack->GetFather()->GetSubMesh( aV1 )->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* aN1 = aItN->next(); + aItN = theTrack->GetFather()->GetSubMesh( aV2 )->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* aN2 = aItN->next(); + // starting node must be aN1 or aN2 + if ( !( aN1 == theN1 || aN2 == theN1 ) ) + return EXTR_BAD_STARTING_NODE; + aItN = pSubMeshDS->GetNodes(); + while ( aItN->more() ) { + const SMDS_MeshNode* pNode = aItN->next(); + const SMDS_EdgePosition* pEPos = + static_cast( pNode->GetPosition().get() ); + double aT = pEPos->GetUParameter(); + aPrms.push_back( aT ); + } + Extrusion_Error err = MakeEdgePathPoints(aPrms, aTrackEdge, (aN1==theN1), fullList); + } + else if( aS.ShapeType() == TopAbs_WIRE ) { + list< SMESH_subMesh* > LSM; + TopTools_SequenceOfShape Edges; + SMESH_subMeshIteratorPtr itSM = theTrack->getDependsOnIterator(false,true); + while(itSM->more()) { + SMESH_subMesh* SM = itSM->next(); + LSM.push_back(SM); + const TopoDS_Shape& aS = SM->GetSubShape(); + Edges.Append(aS); + } + list< list > LLPPs; + int startNid = theN1->GetID(); + TColStd_MapOfInteger UsedNums; + int NbEdges = Edges.Length(); + int i = 1; + for(; i<=NbEdges; i++) { + int k = 0; + list< SMESH_subMesh* >::iterator itLSM = LSM.begin(); + for(; itLSM!=LSM.end(); itLSM++) { + k++; + if(UsedNums.Contains(k)) continue; + aTrackEdge = TopoDS::Edge( Edges.Value(k) ); + SMESH_subMesh* locTrack = *itLSM; + SMESHDS_SubMesh* locMeshDS = locTrack->GetSubMeshDS(); + TopExp::Vertices( aTrackEdge, aV1, aV2 ); + aItN = locTrack->GetFather()->GetSubMesh(aV1)->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* aN1 = aItN->next(); + aItN = locTrack->GetFather()->GetSubMesh(aV2)->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* aN2 = aItN->next(); + // starting node must be aN1 or aN2 + if ( !( aN1->GetID() == startNid || aN2->GetID() == startNid ) ) continue; + // 2. Collect parameters on the track edge + aPrms.clear(); + aItN = locMeshDS->GetNodes(); + while ( aItN->more() ) { + const SMDS_MeshNode* pNode = aItN->next(); + const SMDS_EdgePosition* pEPos = + static_cast( pNode->GetPosition().get() ); + double aT = pEPos->GetUParameter(); + aPrms.push_back( aT ); + } + list LPP; + Extrusion_Error err = MakeEdgePathPoints(aPrms, aTrackEdge, + (aN1->GetID()==startNid), LPP); + LLPPs.push_back(LPP); + UsedNums.Add(k); + // update startN for search following egde + if( aN1->GetID() == startNid ) startNid = aN2->GetID(); + else startNid = aN1->GetID(); + break; + } + } + list< list >::iterator itLLPP = LLPPs.begin(); + list firstList = *itLLPP; + list::iterator itPP = firstList.begin(); + for(; itPP!=firstList.end(); itPP++) { + fullList.push_back( *itPP ); + } + SMESH_MeshEditor_PathPoint PP1 = fullList.back(); + fullList.pop_back(); + itLLPP++; + for(; itLLPP!=LLPPs.end(); itLLPP++) { + list currList = *itLLPP; + itPP = currList.begin(); + SMESH_MeshEditor_PathPoint PP2 = currList.front(); + gp_Dir D1 = PP1.Tangent(); + gp_Dir D2 = PP2.Tangent(); + gp_Dir Dnew( gp_Vec( (D1.X()+D2.X())/2, (D1.Y()+D2.Y())/2, + (D1.Z()+D2.Z())/2 ) ); + PP1.SetTangent(Dnew); + fullList.push_back(PP1); + itPP++; + for(; itPP!=firstList.end(); itPP++) { + fullList.push_back( *itPP ); + } + PP1 = fullList.back(); + fullList.pop_back(); + } + // if wire not closed + fullList.push_back(PP1); + // else ??? + } + else { return EXTR_BAD_PATH_SHAPE; + } - aTrackEdge = TopoDS::Edge( aS ); - // the Edge must not be degenerated - if ( BRep_Tool::Degenerated( aTrackEdge ) ) - return EXTR_BAD_PATH_SHAPE; + return MakeExtrElements(theElements, fullList, theHasAngles, theAngles, theLinearVariation, + theHasRefPoint, theRefPoint, theMakeGroups); +} - TopExp::Vertices( aTrackEdge, aV1, aV2 ); - aT1=BRep_Tool::Parameter( aV1, aTrackEdge ); - aT2=BRep_Tool::Parameter( aV2, aTrackEdge ); - aItN = theTrack->GetFather()->GetSubMesh( aV1 )->GetSubMeshDS()->GetNodes(); - const SMDS_MeshNode* aN1 = aItN->next(); +//======================================================================= +//function : ExtrusionAlongTrack +//purpose : +//======================================================================= +SMESH_MeshEditor::Extrusion_Error + SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet & theElements, + SMESH_Mesh* theTrack, + const SMDS_MeshNode* theN1, + const bool theHasAngles, + list& theAngles, + const bool theLinearVariation, + const bool theHasRefPoint, + const gp_Pnt& theRefPoint, + const bool theMakeGroups) +{ + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); - aItN = theTrack->GetFather()->GetSubMesh( aV2 )->GetSubMeshDS()->GetNodes(); - const SMDS_MeshNode* aN2 = aItN->next(); + int aNbE; + std::list aPrms; + TIDSortedElemSet::iterator itElem; - // starting node must be aN1 or aN2 - if ( !( aN1 == theN1 || aN2 == theN1 ) ) - return EXTR_BAD_STARTING_NODE; + gp_XYZ aGC; + TopoDS_Edge aTrackEdge; + TopoDS_Vertex aV1, aV2; - aNbTP = pSubMeshDS->NbNodes() + 2; + SMDS_ElemIteratorPtr aItE; + SMDS_NodeIteratorPtr aItN; + SMDSAbs_ElementType aTypeE; - // 1.2. Angles - vector aAngles( aNbTP ); + TNodeOfNodeListMap mapNewNodes; - for ( j=0; j < aNbTP; ++j ) { - aAngles[j] = 0.; + // 1. Check data + aNbE = theElements.size(); + // nothing to do + if ( !aNbE ) + return EXTR_NO_ELEMENTS; + + // 1.1 Track Pattern + ASSERT( theTrack ); + + SMESHDS_Mesh* pMeshDS = theTrack->GetMeshDS(); + + aItE = pMeshDS->elementsIterator(); + while ( aItE->more() ) { + const SMDS_MeshElement* pE = aItE->next(); + aTypeE = pE->GetType(); + // Pattern must contain links only + if ( aTypeE != SMDSAbs_Edge ) + return EXTR_PATH_NOT_EDGE; } - if ( theHasAngles ) { - aItD = theAngles.begin(); - for ( j=1; (aItD != theAngles.end()) && (j fullList; + + const TopoDS_Shape& aS = theTrack->GetShapeToMesh(); + // Sub shape for the Pattern must be an Edge or Wire + if( aS.ShapeType() == TopAbs_EDGE ) { + aTrackEdge = TopoDS::Edge( aS ); + // the Edge must not be degenerated + if ( BRep_Tool::Degenerated( aTrackEdge ) ) + return EXTR_BAD_PATH_SHAPE; + TopExp::Vertices( aTrackEdge, aV1, aV2 ); + aItN = theTrack->GetSubMesh( aV1 )->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* aN1 = aItN->next(); + aItN = theTrack->GetSubMesh( aV2 )->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* aN2 = aItN->next(); + // starting node must be aN1 or aN2 + if ( !( aN1 == theN1 || aN2 == theN1 ) ) + return EXTR_BAD_STARTING_NODE; + aItN = pMeshDS->nodesIterator(); + while ( aItN->more() ) { + const SMDS_MeshNode* pNode = aItN->next(); + if( pNode==aN1 || pNode==aN2 ) continue; + const SMDS_EdgePosition* pEPos = + static_cast( pNode->GetPosition().get() ); + double aT = pEPos->GetUParameter(); + aPrms.push_back( aT ); + } + Extrusion_Error err = MakeEdgePathPoints(aPrms, aTrackEdge, (aN1==theN1), fullList); + } + else if( aS.ShapeType() == TopAbs_WIRE ) { + list< SMESH_subMesh* > LSM; + TopTools_SequenceOfShape Edges; + TopExp_Explorer eExp(aS, TopAbs_EDGE); + for(; eExp.More(); eExp.Next()) { + TopoDS_Edge E = TopoDS::Edge( eExp.Current() ); + if( BRep_Tool::Degenerated(E) ) continue; + SMESH_subMesh* SM = theTrack->GetSubMesh(E); + if(SM) { + LSM.push_back(SM); + Edges.Append(E); + } + } + list< list > LLPPs; + int startNid = theN1->GetID(); + TColStd_MapOfInteger UsedNums; + int NbEdges = Edges.Length(); + int i = 1; + for(; i<=NbEdges; i++) { + int k = 0; + list< SMESH_subMesh* >::iterator itLSM = LSM.begin(); + for(; itLSM!=LSM.end(); itLSM++) { + k++; + if(UsedNums.Contains(k)) continue; + aTrackEdge = TopoDS::Edge( Edges.Value(k) ); + SMESH_subMesh* locTrack = *itLSM; + SMESHDS_SubMesh* locMeshDS = locTrack->GetSubMeshDS(); + TopExp::Vertices( aTrackEdge, aV1, aV2 ); + aItN = locTrack->GetFather()->GetSubMesh(aV1)->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* aN1 = aItN->next(); + aItN = locTrack->GetFather()->GetSubMesh(aV2)->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* aN2 = aItN->next(); + // starting node must be aN1 or aN2 + if ( !( aN1->GetID() == startNid || aN2->GetID() == startNid ) ) continue; + // 2. Collect parameters on the track edge + aPrms.clear(); + aItN = locMeshDS->GetNodes(); + while ( aItN->more() ) { + const SMDS_MeshNode* pNode = aItN->next(); + const SMDS_EdgePosition* pEPos = + static_cast( pNode->GetPosition().get() ); + double aT = pEPos->GetUParameter(); + aPrms.push_back( aT ); + } + list LPP; + Extrusion_Error err = MakeEdgePathPoints(aPrms, aTrackEdge, + (aN1->GetID()==startNid), LPP); + LLPPs.push_back(LPP); + UsedNums.Add(k); + // update startN for search following egde + if( aN1->GetID() == startNid ) startNid = aN2->GetID(); + else startNid = aN1->GetID(); + break; + } } + list< list >::iterator itLLPP = LLPPs.begin(); + list firstList = *itLLPP; + list::iterator itPP = firstList.begin(); + for(; itPP!=firstList.end(); itPP++) { + fullList.push_back( *itPP ); + } + SMESH_MeshEditor_PathPoint PP1 = fullList.back(); + fullList.pop_back(); + itLLPP++; + for(; itLLPP!=LLPPs.end(); itLLPP++) { + list currList = *itLLPP; + itPP = currList.begin(); + SMESH_MeshEditor_PathPoint PP2 = currList.front(); + gp_Pnt P1 = PP1.Pnt(); + //cout<<" PP1: Pnt("<GetNodes(); - while ( aItN->more() ) { - const SMDS_MeshNode* pNode = aItN->next(); - const SMDS_EdgePosition* pEPos = - static_cast( pNode->GetPosition().get() ); - aT = pEPos->GetUParameter(); - aPrms.push_back( aT ); - } +//======================================================================= +//function : MakeEdgePathPoints +//purpose : auxilary for ExtrusionAlongTrack +//======================================================================= +SMESH_MeshEditor::Extrusion_Error +SMESH_MeshEditor::MakeEdgePathPoints(std::list& aPrms, + const TopoDS_Edge& aTrackEdge, + bool FirstIsStart, + list& LPP) +{ + Standard_Real aTx1, aTx2, aL2, aTolVec, aTolVec2; + aTolVec=1.e-7; + aTolVec2=aTolVec*aTolVec; + double aT1, aT2; + TopoDS_Vertex aV1, aV2; + TopExp::Vertices( aTrackEdge, aV1, aV2 ); + aT1=BRep_Tool::Parameter( aV1, aTrackEdge ); + aT2=BRep_Tool::Parameter( aV2, aTrackEdge ); + // 2. Collect parameters on the track edge + aPrms.push_front( aT1 ); + aPrms.push_back( aT2 ); // sort parameters aPrms.sort(); - if ( aN1 == theN1 ) { + if( FirstIsStart ) { if ( aT1 > aT2 ) { aPrms.reverse(); } @@ -3917,48 +4159,100 @@ SMESH_MeshEditor::Extrusion_Error aPrms.reverse(); } } - // 3. Path Points SMESH_MeshEditor_PathPoint aPP; - vector aPPs( aNbTP ); - // - aC3D = BRep_Tool::Curve( aTrackEdge, aTx1, aTx2 ); - // - aItD = aPrms.begin(); - for ( j=0; aItD != aPrms.end(); ++aItD, ++j ) { - aT = *aItD; + Handle(Geom_Curve) aC3D = BRep_Tool::Curve( aTrackEdge, aTx1, aTx2 ); + std::list::iterator aItD = aPrms.begin(); + for(; aItD != aPrms.end(); ++aItD) { + double aT = *aItD; + gp_Pnt aP3D; + gp_Vec aVec; aC3D->D1( aT, aP3D, aVec ); aL2 = aVec.SquareMagnitude(); if ( aL2 < aTolVec2 ) return EXTR_CANT_GET_TANGENT; - gp_Dir aTgt( aVec ); - aAngle = aAngles[j]; - aPP.SetPnt( aP3D ); aPP.SetTangent( aTgt ); - aPP.SetAngle( aAngle ); aPP.SetParameter( aT ); - aPPs[j]=aPP; + LPP.push_back(aPP); } +} + + +//======================================================================= +//function : MakeExtrElements +//purpose : auxilary for ExtrusionAlongTrack +//======================================================================= +SMESH_MeshEditor::Extrusion_Error +SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet& theElements, + list& fullList, + const bool theHasAngles, + list& theAngles, + const bool theLinearVariation, + const bool theHasRefPoint, + const gp_Pnt& theRefPoint, + const bool theMakeGroups) +{ + //cout<<"MakeExtrElements fullList.size() = "< aPPs(aNbTP); + // Angles + if( theHasAngles && theAngles.size()>0 && theLinearVariation ) { + LinearAngleVariation(aNbTP-1, theAngles); + } + vector aAngles( aNbTP ); + int j = 0; + for(; j::iterator aItD = theAngles.begin(); + for ( j=1; (aItD != theAngles.end()) && (j::iterator itPP = fullList.begin(); + for(; itPP!=fullList.end(); itPP++) { + j++; + SMESH_MeshEditor_PathPoint PP = *itPP; + PP.SetAngle(aAngles[j]); + aPPs[j] = PP; + } + + TNodeOfNodeListMap mapNewNodes; + TElemOfVecOfNnlmiMap mapElemNewNodes; + TElemOfElemListMap newElemsMap; + TIDSortedElemSet::iterator itElem; + double aX, aY, aZ; + int aNb; + SMDSAbs_ElementType aTypeE; + // source elements for each generated one + SMESH_SequenceOfElemPtr srcElems, srcNodes; // 3. Center of rotation aV0 - aV0 = theRefPoint; + gp_Pnt aV0 = theRefPoint; + gp_XYZ aGC; if ( !theHasRefPoint ) { aNb = 0; aGC.SetCoord( 0.,0.,0. ); - + itElem = theElements.begin(); for ( ; itElem != theElements.end(); itElem++ ) { const SMDS_MeshElement* elem = *itElem; - + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); while ( itN->more() ) { const SMDS_MeshNode* node = static_cast( itN->next() ); aX = node->X(); aY = node->Y(); aZ = node->Z(); - + if ( mapNewNodes.find( node ) == mapNewNodes.end() ) { list aLNx; mapNewNodes[node] = aLNx; @@ -4017,6 +4311,7 @@ SMESH_MeshEditor::Extrusion_Error const SMESH_MeshEditor_PathPoint& aPP0 = aPPs[0]; aP0x = aPP0.Pnt(); aDT0x= aPP0.Tangent(); + //cout<<"j = 0 PP: Pnt("<& Angles) +{ + int nbAngles = Angles.size(); + if( nbSteps > nbAngles ) { + vector theAngles(nbAngles); + list::iterator it = Angles.begin(); + int i = -1; + for(; it!=Angles.end(); it++) { + i++; + theAngles[i] = (*it); + } + list res; + double rAn2St = double( nbAngles ) / double( nbSteps ); + double angPrev = 0, angle; + for ( int iSt = 0; iSt < nbSteps; ++iSt ) { + double angCur = rAn2St * ( iSt+1 ); + double angCurFloor = floor( angCur ); + double angPrevFloor = floor( angPrev ); + if ( angPrevFloor == angCurFloor ) + angle = rAn2St * theAngles[ int( angCurFloor ) ]; + else { + int iP = int( angPrevFloor ); + double angPrevCeil = ceil(angPrev); + angle = ( angPrevCeil - angPrev ) * theAngles[ iP ]; + + int iC = int( angCurFloor ); + if ( iC < nbAngles ) + angle += ( angCur - angCurFloor ) * theAngles[ iC ]; + + iP = int( angPrevCeil ); + while ( iC-- > iP ) + angle += theAngles[ iC ]; + } + res.push_back(angle); + angPrev = angCur; + } + Angles.clear(); + it = res.begin(); + for(; it!=res.end(); it++) + Angles.push_back( *it ); + } +} + + //======================================================================= //function : Transform //purpose : @@ -4844,6 +5189,25 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) TNodeNodeMap::iterator nnIt = nodeNodeMap.find( n ); if ( nnIt != nodeNodeMap.end() ) { // n sticks n = (*nnIt).second; + // BUG 0020185: begin + { + bool stopRecur = false; + set nodesRecur; + nodesRecur.insert(n); + while (!stopRecur) { + TNodeNodeMap::iterator nnIt_i = nodeNodeMap.find( n ); + if ( nnIt_i != nodeNodeMap.end() ) { // n sticks + n = (*nnIt_i).second; + if (!nodesRecur.insert(n).second) { + // error: recursive dependancy + stopRecur = true; + } + } + else + stopRecur = true; + } + } + // BUG 0020185: end iRepl[ nbRepl++ ] = iCur; } curNodes[ iCur ] = n; @@ -6610,11 +6974,13 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode* theBetweenNode //======================================================================= int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, - SMESH_MesherHelper& theHelper, - const bool theForce3d) + SMESH_MesherHelper& theHelper, + const bool theForce3d) { int nbElem = 0; if( !theSm ) return nbElem; + + const bool notFromGroups = false; SMDS_ElemIteratorPtr ElemItr = theSm->GetElements(); while(ElemItr->more()) { @@ -6632,8 +6998,7 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, } SMDSAbs_ElementType aType = elem->GetType(); - theSm->RemoveElement(elem); - GetMeshDS()->SMDS_Mesh::RemoveFreeElement(elem); + GetMeshDS()->RemoveFreeElement(elem, theSm, notFromGroups); const SMDS_MeshElement* NewElem = 0; @@ -6664,14 +7029,14 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, switch(nbNodes) { case 4: - NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], id, true); + NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d); break; case 6: - NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], aNds[4], aNds[5], id, true); + NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], aNds[4], aNds[5], id, theForce3d); break; case 8: NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], - aNds[4], aNds[5], aNds[6], aNds[7], id, true); + aNds[4], aNds[5], aNds[6], aNds[7], id, theForce3d); break; default: continue; @@ -6681,13 +7046,9 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, default : continue; } + ReplaceElemInGroups( elem, NewElem, GetMeshDS()); if( NewElem ) - { - AddToSameGroups( NewElem, elem, GetMeshDS()); theSm->AddElement( NewElem ); - } - if ( NewElem != elem ) - RemoveElemFromGroups (elem, GetMeshDS()); } return nbElem; } @@ -6702,6 +7063,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) SMESH_MesherHelper aHelper(*myMesh); aHelper.SetIsQuadratic( true ); + const bool notFromGroups = false; int nbCheckedElems = 0; if ( myMesh->HasShapeToMesh() ) @@ -6719,8 +7081,9 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) } } int totalNbElems = meshDS->NbEdges() + meshDS->NbFaces() + meshDS->NbVolumes(); - if ( nbCheckedElems < totalNbElems ) // not all elements in submeshes + if ( nbCheckedElems < totalNbElems ) // not all elements are in submeshes { + SMESHDS_SubMesh *smDS = 0; SMDS_EdgeIteratorPtr aEdgeItr = meshDS->edgesIterator(); while(aEdgeItr->more()) { @@ -6731,13 +7094,10 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) const SMDS_MeshNode* n1 = edge->GetNode(0); const SMDS_MeshNode* n2 = edge->GetNode(1); - meshDS->SMDS_Mesh::RemoveFreeElement(edge); + meshDS->RemoveFreeElement(edge, smDS, notFromGroups); const SMDS_MeshEdge* NewEdge = aHelper.AddEdge(n1, n2, id, theForce3d); - if ( NewEdge ) - AddToSameGroups(NewEdge, edge, meshDS); - if ( NewEdge != edge ) - RemoveElemFromGroups (edge, meshDS); + ReplaceElemInGroups( edge, NewEdge, GetMeshDS()); } } SMDS_FaceIteratorPtr aFaceItr = meshDS->facesIterator(); @@ -6755,7 +7115,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) aNds[i] = face->GetNode(i); } - meshDS->SMDS_Mesh::RemoveFreeElement(face); + meshDS->RemoveFreeElement(face, smDS, notFromGroups); SMDS_MeshFace * NewFace = 0; switch(nbNodes) @@ -6769,10 +7129,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) default: continue; } - if ( NewFace ) - AddToSameGroups(NewFace, face, meshDS); - if ( NewFace != face ) - RemoveElemFromGroups (face, meshDS); + ReplaceElemInGroups( face, NewFace, GetMeshDS()); } SMDS_VolumeIteratorPtr aVolumeItr = meshDS->volumesIterator(); while(aVolumeItr->more()) @@ -6789,30 +7146,27 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) aNds[i] = volume->GetNode(i); } - meshDS->SMDS_Mesh::RemoveFreeElement(volume); + meshDS->RemoveFreeElement(volume, smDS, notFromGroups); SMDS_MeshVolume * NewVolume = 0; switch(nbNodes) { case 4: NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2], - aNds[3], id, true ); + aNds[3], id, theForce3d ); break; case 6: NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2], - aNds[3], aNds[4], aNds[5], id, true); + aNds[3], aNds[4], aNds[5], id, theForce3d); break; case 8: NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], - aNds[4], aNds[5], aNds[6], aNds[7], id, true); + aNds[4], aNds[5], aNds[6], aNds[7], id, theForce3d); break; default: continue; } - if ( NewVolume ) - AddToSameGroups(NewVolume, volume, meshDS); - if ( NewVolume != volume ) - RemoveElemFromGroups (volume, meshDS); + ReplaceElemInGroups(volume, NewVolume, meshDS); } } } @@ -6830,6 +7184,8 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh * theSm, { int nbElem = 0; SMESHDS_Mesh* meshDS = GetMeshDS(); + const bool notFromGroups = false; + while( theItr->more() ) { const SMDS_MeshElement* elem = theItr->next(); @@ -6855,15 +7211,10 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh * theSm, SMDSAbs_ElementType aType = elem->GetType(); //remove old quadratic element - meshDS->SMDS_Mesh::RemoveFreeElement( elem ); - if ( theSm ) - theSm->RemoveElement( elem ); + meshDS->RemoveFreeElement( elem, theSm, notFromGroups ); SMDS_MeshElement * NewElem = AddElement( aNds, aType, false, id ); - if ( NewElem ) - AddToSameGroups(NewElem, elem, meshDS); - if ( NewElem != elem ) - RemoveElemFromGroups (elem, meshDS); + ReplaceElemInGroups(elem, NewElem, meshDS); if( theSm && NewElem ) theSm->AddElement( NewElem ); @@ -6871,7 +7222,7 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh * theSm, vector::iterator nIt = mediumNodes.begin(); for ( ; nIt != mediumNodes.end(); ++nIt ) { const SMDS_MeshNode* n = *nIt; - if ( n->NbInverseNodes() == 0 ) { + if ( n->NbInverseElements() == 0 ) { if ( n->GetPosition()->GetShapeId() != theShapeID ) meshDS->RemoveFreeNode( n, meshDS->MeshElements ( n->GetPosition()->GetShapeId() )); @@ -6906,7 +7257,7 @@ bool SMESH_MeshEditor::ConvertFromQuadratic() int totalNbElems = GetMeshDS()->NbEdges() + GetMeshDS()->NbFaces() + GetMeshDS()->NbVolumes(); - if ( nbCheckedElems < totalNbElems ) // not all elements in submeshes + if ( nbCheckedElems < totalNbElems ) // not all elements are in submeshes { SMESHDS_SubMesh *aSM = 0; removeQuadElem( aSM, GetMeshDS()->elementsIterator(), 0 ); @@ -7541,8 +7892,8 @@ SMESH_MeshEditor::FindMatchingNodes(set& theSide1, if ( theSecondNode1 != theSecondNode2 ) nReplaceMap.insert( make_pair( theSecondNode1, theSecondNode2 )); - set< TLink > linkSet; // set of nodes where order of nodes is ignored - linkSet.insert( TLink( theFirstNode1, theSecondNode1 )); + set< SMESH_TLink > linkSet; // set of nodes where order of nodes is ignored + linkSet.insert( SMESH_TLink( theFirstNode1, theSecondNode1 )); list< NLink > linkList[2]; linkList[0].push_back( NLink( theFirstNode1, theSecondNode1 )); @@ -7633,10 +7984,9 @@ SMESH_MeshEditor::FindMatchingNodes(set& theSide1, return SEW_TOPO_DIFF_SETS_OF_ELEMENTS; } #ifdef DEBUG_MATCHING_NODES - cout << " Link 1: " << link[0].first->GetID() <<" "<< link[0].second->GetID() - << " F 1: " << face[0]; - cout << "| Link 2: " << link[1].first->GetID() <<" "<< link[1].second->GetID() - << " F 2: " << face[1] << " | Bind: "<GetID() <<" "<< link[0].second->GetID() + << " F 1: " << face[0] << "| Link 2: " << link[1].first->GetID() <<" " + << link[1].second->GetID() << " F 2: " << face[1] << " | Bind: " ) ; #endif int nbN = nbNodes[0]; { @@ -7644,7 +7994,7 @@ SMESH_MeshEditor::FindMatchingNodes(set& theSide1, list::iterator n2 = notLinkNodes[1].begin(); for ( int i = 0 ; i < nbN - 2; ++i ) { #ifdef DEBUG_MATCHING_NODES - cout << (*n1)->GetID() << " to " << (*n2)->GetID() << endl; + MESSAGE ( (*n1)->GetID() << " to " << (*n2)->GetID() ); #endif nReplaceMap.insert( make_pair( *(n1++), *(n2++) )); } @@ -7658,16 +8008,16 @@ SMESH_MeshEditor::FindMatchingNodes(set& theSide1, for ( int i = 0; i < nbN; i++ ) { const SMDS_MeshNode* n2 = f0->GetNode( i ); - pair< set< TLink >::iterator, bool > iter_isnew = - linkSet.insert( TLink( n1, n2 )); + pair< set< SMESH_TLink >::iterator, bool > iter_isnew = + linkSet.insert( SMESH_TLink( n1, n2 )); if ( !iter_isnew.second ) { // already in a set: no need to process linkSet.erase( iter_isnew.first ); } else // new in set == encountered for the first time: add { #ifdef DEBUG_MATCHING_NODES - cout << "Add link 1: " << n1->GetID() << " " << n2->GetID() << " "; - cout << " | link 2: " << nReplaceMap[n1]->GetID() << " " << nReplaceMap[n2]->GetID() << " " << endl; + MESSAGE ( "Add link 1: " << n1->GetID() << " " << n2->GetID() << " " + << " | link 2: " << nReplaceMap[n1]->GetID() << " " << nReplaceMap[n2]->GetID() << " " ); #endif linkList[0].push_back ( NLink( n1, n2 )); linkList[1].push_back ( NLink( nReplaceMap[n1], nReplaceMap[n2] )); @@ -7679,3 +8029,92 @@ SMESH_MeshEditor::FindMatchingNodes(set& theSide1, return SEW_OK; } + +/*! + \brief Creates a hole in a mesh by doubling the nodes of some particular elements + \param theNodes - identifiers of nodes to be doubled + \param theModifiedElems - identifiers of elements to be updated by the new (doubled) + nodes. If list of element identifiers is empty then nodes are doubled but + they not assigned to elements + \return TRUE if operation has been completed successfully, FALSE otherwise +*/ +bool SMESH_MeshEditor::DoubleNodes( const std::list< int >& theListOfNodes, + const std::list< int >& theListOfModifiedElems ) +{ + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + + if ( theListOfNodes.size() == 0 ) + return false; + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + if ( !aMeshDS ) + return false; + + // iterate through nodes and duplicate them + + std::map< const SMDS_MeshNode*, const SMDS_MeshNode* > anOldNodeToNewNode; + + std::list< int >::const_iterator aNodeIter; + for ( aNodeIter = theListOfNodes.begin(); aNodeIter != theListOfNodes.end(); ++aNodeIter ) + { + int aCurr = *aNodeIter; + SMDS_MeshNode* aNode = (SMDS_MeshNode*)aMeshDS->FindNode( aCurr ); + if ( !aNode ) + continue; + + // duplicate node + + const SMDS_MeshNode* aNewNode = aMeshDS->AddNode( aNode->X(), aNode->Y(), aNode->Z() ); + if ( aNewNode ) + { + anOldNodeToNewNode[ aNode ] = aNewNode; + myLastCreatedNodes.Append( aNewNode ); + } + } + + // Create map of new nodes for modified elements + + std::map< SMDS_MeshElement*, vector > anElemToNodes; + + std::list< int >::const_iterator anElemIter; + for ( anElemIter = theListOfModifiedElems.begin(); + anElemIter != theListOfModifiedElems.end(); ++anElemIter ) + { + int aCurr = *anElemIter; + SMDS_MeshElement* anElem = (SMDS_MeshElement*)aMeshDS->FindElement( aCurr ); + if ( !anElem ) + continue; + + vector aNodeArr( anElem->NbNodes() ); + + SMDS_ElemIteratorPtr anIter = anElem->nodesIterator(); + int ind = 0; + while ( anIter->more() ) + { + SMDS_MeshNode* aCurrNode = (SMDS_MeshNode*)anIter->next(); + if ( aCurr && anOldNodeToNewNode.find( aCurrNode ) != anOldNodeToNewNode.end() ) + { + const SMDS_MeshNode* aNewNode = anOldNodeToNewNode[ aCurrNode ]; + aNodeArr[ ind++ ] = aNewNode; + } + else + aNodeArr[ ind++ ] = aCurrNode; + } + anElemToNodes[ anElem ] = aNodeArr; + } + + // Change nodes of elements + + std::map< SMDS_MeshElement*, vector >::iterator + anElemToNodesIter = anElemToNodes.begin(); + for ( ; anElemToNodesIter != anElemToNodes.end(); ++anElemToNodesIter ) + { + const SMDS_MeshElement* anElem = anElemToNodesIter->first; + vector aNodeArr = anElemToNodesIter->second; + if ( anElem ) + aMeshDS->ChangeElementNodes( anElem, &aNodeArr[ 0 ], anElem->NbNodes() ); + } + + return true; +}