X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH%2FSMESH_MeshEditor.cxx;h=09bc9e4cb09faec258cfcbddba3373c2de1a74df;hb=db647c3bf2cc438899640070c9d6810e661ac2cc;hp=d7a64c1cdb0031a3a5ae3e89c61b5ce2e86e537e;hpb=47e62a030ce1fc5890a731d0a32c88d4e5408837;p=modules%2Fsmesh.git diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index d7a64c1cd..09bc9e4cb 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -47,6 +47,7 @@ #include "utilities.h" #include +#include #include #include #include @@ -54,7 +55,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -2781,27 +2784,30 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, TNodeOfNodeListMapItr nnIt = newNodesItVec[ iNode ]; const SMDS_MeshNode* node = nnIt->first; const list< const SMDS_MeshNode* > & listNewNodes = nnIt->second; - if ( listNewNodes.empty() ) + if ( listNewNodes.empty() ) { return; + } issimple[iNode] = (listNewNodes.size()==nbSteps); itNN[ iNode ] = listNewNodes.begin(); prevNod[ iNode ] = node; nextNod[ iNode ] = listNewNodes.front(); -//cout<<"iNode="<GetID() ); + //MESSAGE( " Too many same nodes of element " << elem->GetID() ); + INFOS( " Too many same nodes of element " << elem->GetID() ); return; } @@ -2811,9 +2817,10 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, // } int iBeforeSame = 0, iAfterSame = 0, iOpposSame = 0; + int nbBaseNodes = ( elem->IsQuadratic() ? nbNodes/2 : nbNodes ); if ( nbSame > 0 ) { - iBeforeSame = ( iSameNode == 0 ? nbNodes - 1 : iSameNode - 1 ); - iAfterSame = ( iSameNode + 1 == nbNodes ? 0 : iSameNode + 1 ); + iBeforeSame = ( iSameNode == 0 ? nbBaseNodes - 1 : iSameNode - 1 ); + iAfterSame = ( iSameNode + 1 == nbBaseNodes ? 0 : iSameNode + 1 ); iOpposSame = ( iSameNode - 2 < 0 ? iSameNode + 2 : iSameNode - 2 ); } @@ -2851,7 +2858,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, } else if(!elem->IsQuadratic() || elem->IsMediumNode(prevNod[iNode]) ) { // we have to use each second node - itNN[ iNode ]++; + //itNN[ iNode ]++; nextNod[ iNode ] = *itNN[ iNode ]; itNN[ iNode ]++; } @@ -2910,8 +2917,9 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, midlNod[0], nextNod[2], midlNod[1], prevNod[2]); } else if(nbSame==1) { // quadratic triangle - if(sames[0]==2) + if(sames[0]==2) { return; // medium node on axis + } else if(sames[0]==0) { aNewElem = aMesh->AddFace(prevNod[0], nextNod[1], prevNod[1], nextNod[2], midlNod[1], prevNod[2]); @@ -2921,8 +2929,9 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, midlNod[0], nextNod[2], prevNod[2]); } } - else + else { return; + } } break; } @@ -2957,38 +2966,140 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, } case 6: { // quadratic triangle // create pentahedron with 15 nodes - if(i0>0) { // reversed case - aNewElem = aMesh->AddVolume (prevNod[0], prevNod[2], prevNod[1], - nextNod[0], nextNod[2], nextNod[1], - prevNod[5], prevNod[4], prevNod[3], - nextNod[5], nextNod[4], nextNod[3], - midlNod[0], midlNod[2], midlNod[1]); - } - else { // not reversed case - aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2], - nextNod[0], nextNod[1], nextNod[2], - prevNod[3], prevNod[4], prevNod[5], - nextNod[3], nextNod[4], nextNod[5], - midlNod[0], midlNod[1], midlNod[2]); - } + if(nbSame==0) { + if(i0>0) { // reversed case + aNewElem = aMesh->AddVolume (prevNod[0], prevNod[2], prevNod[1], + nextNod[0], nextNod[2], nextNod[1], + prevNod[5], prevNod[4], prevNod[3], + nextNod[5], nextNod[4], nextNod[3], + midlNod[0], midlNod[2], midlNod[1]); + } + else { // not reversed case + aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2], + nextNod[0], nextNod[1], nextNod[2], + prevNod[3], prevNod[4], prevNod[5], + nextNod[3], nextNod[4], nextNod[5], + midlNod[0], midlNod[1], midlNod[2]); + } + } + else if(nbSame==1) { + // 2d order pyramid of 13 nodes + //SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, + // int n12,int n23,int n34,int n41, + // int n15,int n25,int n35,int n45, int ID); + int n5 = iSameNode; + int n1,n4,n41,n15,n45; + if(i0>0) { // reversed case + n1 = ( n5 + 1 == nbBaseNodes ? 0 : n5 + 1 ); + n4 = ( n5 == 0 ? nbBaseNodes - 1 : n5 - 1 ); + n41 = n1 + 3; + n15 = n5 + 3; + n45 = n4 + 3; + } + else { + n1 = ( n5 == 0 ? nbBaseNodes - 1 : n5 - 1 ); + n4 = ( n5 + 1 == nbBaseNodes ? 0 : n5 + 1 ); + n41 = n4 + 3; + n15 = n1 + 3; + n45 = n5 + 3; + } + aNewElem = aMesh->AddVolume(prevNod[n1], nextNod[n1], + nextNod[n4], prevNod[n4], prevNod[n5], + midlNod[n1], nextNod[n41], + midlNod[n4], prevNod[n41], + prevNod[n15], nextNod[n15], + nextNod[n45], prevNod[n45]); + } + else if(nbSame==2) { + // 2d order tetrahedron of 10 nodes + //SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, + // int n12,int n23,int n31, + // int n14,int n24,int n34, int ID); + int n1 = iNotSameNode; + int n2,n3,n12,n23,n31; + if(i0>0) { // reversed case + n2 = ( n1 == 0 ? nbBaseNodes - 1 : n1 - 1 ); + n3 = ( n1 + 1 == nbBaseNodes ? 0 : n1 + 1 ); + n12 = n2 + 3; + n23 = n3 + 3; + n31 = n1 + 3; + } + else { + n2 = ( n1 + 1 == nbBaseNodes ? 0 : n1 + 1 ); + n3 = ( n1 == 0 ? nbBaseNodes - 1 : n1 - 1 ); + n12 = n1 + 3; + n23 = n2 + 3; + n31 = n3 + 3; + } + aNewElem = aMesh->AddVolume (prevNod[n1], prevNod[n2], prevNod[n3], nextNod[n1], + prevNod[n12], prevNod[n23], prevNod[n31], + midlNod[n1], nextNod[n12], nextNod[n31]); + } break; } case 8: { // quadratic quadrangle - // create hexahedron with 20 nodes - if(i0>0) { // reversed case - aNewElem = aMesh->AddVolume (prevNod[0], prevNod[3], prevNod[2], prevNod[1], - nextNod[0], nextNod[3], nextNod[2], nextNod[1], - prevNod[7], prevNod[6], prevNod[5], prevNod[4], - nextNod[7], nextNod[6], nextNod[5], nextNod[4], - midlNod[0], midlNod[3], midlNod[2], midlNod[1]); - } - else { // not reversed case - aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2], prevNod[3], - nextNod[0], nextNod[1], nextNod[2], nextNod[3], - prevNod[4], prevNod[5], prevNod[6], prevNod[7], - nextNod[4], nextNod[5], nextNod[6], nextNod[7], - midlNod[0], midlNod[1], midlNod[2], midlNod[3]); - } + if(nbSame==0) { + // create hexahedron with 20 nodes + if(i0>0) { // reversed case + aNewElem = aMesh->AddVolume (prevNod[0], prevNod[3], prevNod[2], prevNod[1], + nextNod[0], nextNod[3], nextNod[2], nextNod[1], + prevNod[7], prevNod[6], prevNod[5], prevNod[4], + nextNod[7], nextNod[6], nextNod[5], nextNod[4], + midlNod[0], midlNod[3], midlNod[2], midlNod[1]); + } + else { // not reversed case + aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2], prevNod[3], + nextNod[0], nextNod[1], nextNod[2], nextNod[3], + prevNod[4], prevNod[5], prevNod[6], prevNod[7], + nextNod[4], nextNod[5], nextNod[6], nextNod[7], + midlNod[0], midlNod[1], midlNod[2], midlNod[3]); + } + } + else if(nbSame==1) { + // --- pyramid + pentahedron - can not be created since it is needed + // additional middle node ot the center of face + INFOS( " Sweep for face " << elem->GetID() << " can not be created" ); + return; + } + else if(nbSame==2) { + // 2d order Pentahedron with 15 nodes + //SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, + // int n12,int n23,int n31,int n45,int n56,int n64, + // int n14,int n25,int n36, int ID); + int n1,n2,n4,n5; + if ( prevNod[ iBeforeSame ] == nextNod[ iBeforeSame ] ) { + // iBeforeSame is same too + n1 = iBeforeSame; + n2 = iOpposSame; + n4 = iSameNode; + n5 = iAfterSame; + } + else { + // iAfterSame is same too + n1 = iSameNode; + n2 = iBeforeSame; + n4 = iAfterSame; + n5 = iOpposSame; + } + int n12,n45,n14,n25; + if(i0>0) { //reversed case + n12 = n1 + 4; + n45 = n5 + 4; + n14 = n4 + 4; + n25 = n2 + 4; + } + else { + n12 = n2 + 4; + n45 = n4 + 4; + n14 = n1 + 4; + n25 = n5 + 4; + } + aNewElem = aMesh->AddVolume (prevNod[n1], prevNod[n2], nextNod[n2], + prevNod[n4], prevNod[n5], nextNod[n5], + prevNod[n12], midlNod[n2], nextNod[n12], + prevNod[n45], midlNod[n5], nextNod[n45], + prevNod[n14], prevNod[n25], nextNod[n25]); + } break; } default: { @@ -3294,20 +3405,40 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, if(nbn==6) { /////// quadratic triangle const SMDS_MeshFace * f = aMesh->FindFace( nodes[0], nodes[2], nodes[4], nodes[1], nodes[3], nodes[5] ); - if ( !f ) + if ( !f ) { myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[1], nodes[3], nodes[5])); - else if ( nodes[ 2 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) - aMesh->ChangeElementNodes( f, nodes, nbn ); + } + else if ( nodes[ 2 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) { + const SMDS_MeshNode** tmpnodes = new const SMDS_MeshNode*[6]; + tmpnodes[0] = nodes[0]; + tmpnodes[1] = nodes[2]; + tmpnodes[2] = nodes[4]; + tmpnodes[3] = nodes[1]; + tmpnodes[4] = nodes[3]; + tmpnodes[5] = nodes[5]; + aMesh->ChangeElementNodes( f, tmpnodes, nbn ); + } } else { /////// quadratic quadrangle const SMDS_MeshFace * f = aMesh->FindFace( nodes[0], nodes[2], nodes[4], nodes[6], nodes[1], nodes[3], nodes[5], nodes[7] ); - if ( !f ) + 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->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) - aMesh->ChangeElementNodes( f, nodes, nbn ); + } + else if ( nodes[ 2 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) { + const SMDS_MeshNode** tmpnodes = new const SMDS_MeshNode*[8]; + tmpnodes[0] = nodes[0]; + tmpnodes[1] = nodes[2]; + tmpnodes[2] = nodes[4]; + tmpnodes[3] = nodes[6]; + tmpnodes[4] = nodes[1]; + tmpnodes[5] = nodes[3]; + tmpnodes[6] = nodes[5]; + tmpnodes[7] = nodes[7]; + aMesh->ChangeElementNodes( f, tmpnodes, nbn ); + } } } else { //////// polygon @@ -3428,20 +3559,25 @@ SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems, // loop on elem nodes SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while ( itN->more() ) - { + while ( itN->more() ) { // check if a node has been already sweeped const SMDS_MeshNode* node = cast2Node( itN->next() ); + + gp_XYZ aXYZ( node->X(), node->Y(), node->Z() ); + double coord[3]; + aXYZ.Coord( coord[0], coord[1], coord[2] ); + bool isOnAxis = ( aLine.SquareDistance( aXYZ ) <= aSqTol ); + TNodeOfNodeListMapItr nIt = mapNewNodes.find( node ); if ( nIt == mapNewNodes.end() ) { nIt = mapNewNodes.insert( make_pair( node, list() )).first; list& listNewNodes = nIt->second; // make new nodes - gp_XYZ aXYZ( node->X(), node->Y(), node->Z() ); - double coord[3]; - aXYZ.Coord( coord[0], coord[1], coord[2] ); - bool isOnAxis = ( aLine.SquareDistance( aXYZ ) <= aSqTol ); + //gp_XYZ aXYZ( node->X(), node->Y(), node->Z() ); + //double coord[3]; + //aXYZ.Coord( coord[0], coord[1], coord[2] ); + //bool isOnAxis = ( aLine.SquareDistance( aXYZ ) <= aSqTol ); const SMDS_MeshNode * newNode = node; for ( int i = 0; i < theNbSteps; i++ ) { if ( !isOnAxis ) { @@ -3462,10 +3598,17 @@ SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems, newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); myLastCreatedNodes.Append(newNode); srcNodes.Append( node ); + listNewNodes.push_back( newNode ); } - listNewNodes.push_back( newNode ); + else { + listNewNodes.push_back( newNode ); + if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { + listNewNodes.push_back( newNode ); + } + } } } + /* else { // if current elem is quadratic and current node is not medium // we have to check - may be it is needed to insert additional nodes @@ -3474,25 +3617,33 @@ SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems, if(listNewNodes.size()==theNbSteps) { listNewNodes.clear(); // make new nodes - gp_XYZ aXYZ( node->X(), node->Y(), node->Z() ); - double coord[3]; - aXYZ.Coord( coord[0], coord[1], coord[2] ); + //gp_XYZ aXYZ( node->X(), node->Y(), node->Z() ); + //double coord[3]; + //aXYZ.Coord( coord[0], coord[1], coord[2] ); const SMDS_MeshNode * newNode = node; - for(int i = 0; iAddNode( coord[0], coord[1], coord[2] ); - myLastCreatedNodes.Append(newNode); - listNewNodes.push_back( newNode ); - srcNodes.Append( node ); - aTrsf2.Transforms( coord[0], coord[1], coord[2] ); - newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); - myLastCreatedNodes.Append(newNode); - srcNodes.Append( node ); - listNewNodes.push_back( newNode ); + if ( !isOnAxis ) { + for(int i = 0; iAddNode( coord[0], coord[1], coord[2] ); + cout<<" 3 AddNode: "<AddNode( coord[0], coord[1], coord[2] ); + cout<<" 4 AddNode: "< nodes; const double precision = 1e-6; - myOctreeNode->NodesAround( &tgtNode, &nodes, precision ); + //myOctreeNode->NodesAround( &tgtNode, &nodes, precision ); double minSqDist = DBL_MAX; Bnd_B3d box; @@ -8040,89 +8191,166 @@ SMESH_MeshEditor::FindMatchingNodes(set& theSide1, /*! \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 + \param theElems - the list of elements (edges or faces) to be replicated + The nodes for duplication could be found from these elements + \param theNodesNot - list of nodes to NOT replicate + \param theAffectedElems - the list of elements (cells and edges) to which the + replicated nodes should be associated to. \return TRUE if operation has been completed successfully, FALSE otherwise */ -bool SMESH_MeshEditor::DoubleNodes( const std::list< int >& theListOfNodes, - const std::list< int >& theListOfModifiedElems ) +bool SMESH_MeshEditor::DoubleNodes( const TIDSortedElemSet& theElems, + const TIDSortedElemSet& theNodesNot, + const TIDSortedElemSet& theAffectedElems ) { myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - if ( theListOfNodes.size() == 0 ) + if ( theElems.size() == 0 ) return false; SMESHDS_Mesh* aMeshDS = GetMeshDS(); if ( !aMeshDS ) return false; - // iterate through nodes and duplicate them - + bool res = false; std::map< const SMDS_MeshNode*, const SMDS_MeshNode* > anOldNodeToNewNode; + // duplicate elements and nodes + res = doubleNodes( aMeshDS, theElems, theNodesNot, anOldNodeToNewNode, true ); + // replce nodes by duplications + res = doubleNodes( aMeshDS, theAffectedElems, theNodesNot, anOldNodeToNewNode, false ); + return res; +} - 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 ) +/*! + \brief Creates a hole in a mesh by doubling the nodes of some particular elements + \param theMeshDS - mesh instance + \param theElems - the elements replicated or modified (nodes should be changed) + \param theNodesNot - nodes to NOT replicate + \param theNodeNodeMap - relation of old node to new created node + \param theIsDoubleElem - flag os to replicate element or modify + \return TRUE if operation has been completed successfully, FALSE otherwise +*/ +bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh* theMeshDS, + const TIDSortedElemSet& theElems, + const TIDSortedElemSet& theNodesNot, + std::map< const SMDS_MeshNode*, + const SMDS_MeshNode* >& theNodeNodeMap, + const bool theIsDoubleElem ) +{ + // iterate on through element and duplicate them (by nodes duplication) + bool res = false; + TIDSortedElemSet::iterator elemItr = theElems.begin(); + for ( ; elemItr != theElems.end(); ++elemItr ) { - int aCurr = *anElemIter; - SMDS_MeshElement* anElem = (SMDS_MeshElement*)aMeshDS->FindElement( aCurr ); - if ( !anElem ) + const SMDS_MeshElement* anElem = *elemItr; + if (!anElem) continue; - vector aNodeArr( anElem->NbNodes() ); - + bool isDuplicate = false; + // duplicate nodes to duplicate element + std::vector newNodes( 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() ) + SMDS_MeshNode* aNewNode = aCurrNode; + if ( theNodeNodeMap.find( aCurrNode ) != theNodeNodeMap.end() ) + aNewNode = (SMDS_MeshNode*)theNodeNodeMap[ aCurrNode ]; + else if ( theIsDoubleElem && theNodesNot.find( aCurrNode ) == theNodesNot.end() ) { - const SMDS_MeshNode* aNewNode = anOldNodeToNewNode[ aCurrNode ]; - aNodeArr[ ind++ ] = aNewNode; + // duplicate node + aNewNode = theMeshDS->AddNode( aCurrNode->X(), aCurrNode->Y(), aCurrNode->Z() ); + theNodeNodeMap[ aCurrNode ] = aNewNode; + myLastCreatedNodes.Append( aNewNode ); } - else - aNodeArr[ ind++ ] = aCurrNode; + isDuplicate |= (aCurrNode == aNewNode); + newNodes[ ind++ ] = aNewNode; } - anElemToNodes[ anElem ] = aNodeArr; + if ( !isDuplicate ) + continue; + + if ( theIsDoubleElem ) + myLastCreatedElems.Append( AddElement(newNodes, anElem->GetType(), anElem->IsPoly()) ); + else + theMeshDS->ChangeElementNodes( anElem, &newNodes[ 0 ], anElem->NbNodes() ); + + res = true; } + return res; +} - // Change nodes of elements +/*! + \brief Check if element located inside shape + \return TRUE if IN or ON shape, FALSE otherwise +*/ - std::map< SMDS_MeshElement*, vector >::iterator - anElemToNodesIter = anElemToNodes.begin(); - for ( ; anElemToNodesIter != anElemToNodes.end(); ++anElemToNodesIter ) +static bool isInside(const SMDS_MeshElement* theElem, + BRepClass3d_SolidClassifier& theBsc3d, + const double theTol) +{ + gp_XYZ centerXYZ (0, 0, 0); + SMDS_ElemIteratorPtr aNodeItr = theElem->nodesIterator(); + while (aNodeItr->more()) { - const SMDS_MeshElement* anElem = anElemToNodesIter->first; - vector aNodeArr = anElemToNodesIter->second; - if ( anElem ) - aMeshDS->ChangeElementNodes( anElem, &aNodeArr[ 0 ], anElem->NbNodes() ); + SMDS_MeshNode* aNode = (SMDS_MeshNode*)aNodeItr->next(); + centerXYZ += gp_XYZ(aNode->X(), aNode->Y(), aNode->Z()); } + gp_Pnt aPnt(centerXYZ); + theBsc3d.Perform(aPnt, theTol); + TopAbs_State aState = theBsc3d.State(); + return (aState == TopAbs_IN || aState == TopAbs_ON ); +} - return true; +/*! + \brief Creates a hole in a mesh by doubling the nodes of some particular elements + \param theElems - group of of elements (edges or faces) to be replicated + \param theNodesNot - group of nodes not to replicated + \param theShape - shape to detect affected elements (element which geometric center + located on or inside shape). + The replicated nodes should be associated to affected elements. + \return TRUE if operation has been completed successfully, FALSE otherwise +*/ + +bool SMESH_MeshEditor::DoubleNodesInRegion( const TIDSortedElemSet& theElems, + const TIDSortedElemSet& theNodesNot, + const TopoDS_Shape& theShape ) +{ + SMESHDS_Mesh* aMesh = GetMeshDS(); + if (!aMesh) + return false; + if ( theShape.IsNull() ) + return false; + + const double aTol = Precision::Confusion(); + BRepClass3d_SolidClassifier bsc3d(theShape); + bsc3d.PerformInfinitePoint(aTol); + + // iterates on indicated elements and get elements by back references from their nodes + TIDSortedElemSet anAffected; + TIDSortedElemSet::iterator elemItr = theElems.begin(); + for ( ; elemItr != theElems.end(); ++elemItr ) + { + SMDS_MeshElement* anElem = (SMDS_MeshElement*)*elemItr; + if (!anElem) + continue; + + SMDS_ElemIteratorPtr nodeItr = anElem->nodesIterator(); + while ( nodeItr->more() ) + { + const SMDS_MeshNode* aNode = static_cast(nodeItr->next()); + if ( !aNode || theNodesNot.find(aNode) != theNodesNot.end() ) + continue; + SMDS_ElemIteratorPtr backElemItr = aNode->GetInverseElementIterator(); + while ( backElemItr->more() ) + { + SMDS_MeshElement* curElem = (SMDS_MeshElement*)backElemItr->next(); + if ( curElem && theElems.find(curElem) == theElems.end() && + isInside( curElem, bsc3d, aTol ) ) + anAffected.insert( curElem ); + } + } + } + return DoubleNodes( theElems, theNodesNot, anAffected ); }