X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH%2FSMESH_MeshEditor.cxx;h=0673fc64edc86cca16612d6475a9109515e1987f;hb=95aa1f92b91de619f549d1cb4d142718d5e2ab34;hp=feacce4225860bfadc73811102350fac5d63728a;hpb=6d32f944a0a115b6419184c50b57bf7c4eef5786;p=modules%2Fsmesh.git diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index feacce422..0673fc64e 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -1093,19 +1093,37 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) MESSAGE("Warning: bad volumic element"); return false; } - const int nbFaces = aPolyedre->NbFaces(); + SMDS_VolumeTool vTool( aPolyedre ); + const int nbFaces = vTool.NbFaces(); + vector quantities( nbFaces ); vector poly_nodes; - vector quantities (nbFaces); - // reverse each face of the polyedre - for (int iface = 1; iface <= nbFaces; iface++) { - int inode, nbFaceNodes = aPolyedre->NbFaceNodes(iface); - quantities[iface - 1] = nbFaceNodes; + // check if all facets are oriented equally + bool sameOri = true; + vector& facetOri = quantities; // keep orientation in quantities so far + for (int iface = 0; iface < nbFaces; iface++) + { + facetOri[ iface ] = vTool.IsFaceExternal( iface ); + if ( facetOri[ iface ] != facetOri[ 0 ]) + sameOri = false; + } - for (inode = nbFaceNodes; inode >= 1; inode--) { - const SMDS_MeshNode* curNode = aPolyedre->GetFaceNode(iface, inode); - poly_nodes.push_back(curNode); - } + // reverse faces of the polyhedron + int neededOri = sameOri ? 1 - facetOri[0] : 1; + poly_nodes.reserve( vTool.NbNodes() ); + for ( int iface = 0; iface < nbFaces; iface++ ) + { + int nbFaceNodes = vTool.NbFaceNodes( iface ); + const SMDS_MeshNode** nodes = vTool.GetFaceNodes( iface ); + bool toReverse = ( facetOri[ iface ] != neededOri ); + + quantities[ iface ] = nbFaceNodes; + + if ( toReverse ) + for ( int inode = nbFaceNodes - 1; inode >= 0; inode-- ) + poly_nodes.push_back( nodes[ inode ]); + else + poly_nodes.insert( poly_nodes.end(), nodes, nodes + nbFaceNodes ); } return GetMeshDS()->ChangePolyhedronNodes( theElem, poly_nodes, quantities ); } @@ -5850,6 +5868,11 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet theElemSets[2], } else { + if ( theParams.ToMakeBoundary() ) + { + GetMeshDS()->Modified(); + throw SALOME_Exception( SMESH_Comment("Can't extrude node #") << node->GetID() ); + } break; // newNodesItVec will be shorter than nbNodes } } @@ -6367,7 +6390,7 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, * \param [in] theValue - offset value * \param [out] theTgtMesh - a mesh to add offset elements to * \param [in] theMakeGroups - to generate groups - * \return PGroupIDs - IDs of created groups + * \return PGroupIDs - IDs of created groups. NULL means failure */ //================================================================================ @@ -6454,6 +6477,8 @@ SMESH_MeshEditor::PGroupIDs SMESH_MeshEditor::Offset( TIDSortedElemSet & theElem PGroupIDs newGroupIDs; if ( theMakeGroups ) newGroupIDs = generateGroups( srcNodes, srcElems, "offset", theTgtMesh, false ); + else + newGroupIDs.reset( new std::list< int > ); return newGroupIDs; } @@ -7453,6 +7478,8 @@ void SMESH_MeshEditor::FindEqualElements( TIDSortedElemSet & theElements, while ( elemIt->more() ) { const SMDS_MeshElement* curElem = elemIt->next(); + if ( curElem->IsNull() ) + continue; ComparableElement compElem = curElem; // check uniqueness const ComparableElement& elemInSet = mapOfElements.Added( compElem ); @@ -7588,35 +7615,37 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode* theFirst theNodes.push_back( theSecondNode ); const SMDS_MeshNode *nIgnore = theFirstNode, *nStart = theSecondNode; - TIDSortedElemSet foundElems; + //TIDSortedElemSet foundElems; bool needTheLast = ( theLastNode != 0 ); + vector nodes; + while ( nStart != theLastNode ) { if ( nStart == theFirstNode ) return !needTheLast; - // find all free border faces sharing form nStart + // find all free border faces sharing nStart list< const SMDS_MeshElement* > curElemList; list< const SMDS_MeshNode* > nStartList; SMDS_ElemIteratorPtr invElemIt = nStart->GetInverseElementIterator(SMDSAbs_Face); while ( invElemIt->more() ) { const SMDS_MeshElement* e = invElemIt->next(); - if ( e == curElem || foundElems.insert( e ).second ) { + //if ( e == curElem || foundElems.insert( e ).second ) // e can encounter twice in border + { // get nodes - int iNode = 0, nbNodes = e->NbNodes(); - vector nodes( nbNodes+1 ); nodes.assign( SMDS_MeshElement::iterator( e->interlacedNodesIterator() ), SMDS_MeshElement::iterator() ); nodes.push_back( nodes[ 0 ]); // check 2 links + int iNode = 0, nbNodes = nodes.size() - 1; for ( iNode = 0; iNode < nbNodes; iNode++ ) - if (((nodes[ iNode ] == nStart && nodes[ iNode + 1] != nIgnore ) || - (nodes[ iNode + 1] == nStart && nodes[ iNode ] != nIgnore )) && - ControlFreeBorder( &nodes[ iNode ], e->GetID() )) + if ((( nodes[ iNode ] == nStart && nodes[ iNode + 1] != nIgnore ) || + ( nodes[ iNode + 1] == nStart && nodes[ iNode ] != nIgnore )) && + ( ControlFreeBorder( &nodes[ iNode ], e->GetID() ))) { - nStartList.push_back( nodes[ iNode + ( nodes[ iNode ] == nStart ? 1 : 0 )]); + nStartList.push_back( nodes[ iNode + ( nodes[ iNode ] == nStart )]); curElemList.push_back( e ); } } @@ -7668,7 +7697,7 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode* theFirst else if ( !contNodes[0].empty() && !contNodes[1].empty() ) { // choice: clear a worse one int iLongest = ( contNodes[0].size() < contNodes[1].size() ? 1 : 0 ); - int iWorse = ( needTheLast ? 1 - iLongest : iLongest ); + int iWorse = ( needTheLast ? 1 - iLongest : iLongest ); contNodes[ iWorse ].clear(); contFaces[ iWorse ].clear(); } @@ -7679,13 +7708,11 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode* theFirst // push_back the best free border cNL = & contNodes[ contNodes[0].empty() ? 1 : 0 ]; cFL = & contFaces[ contFaces[0].empty() ? 1 : 0 ]; - theNodes.pop_back(); // remove nIgnore + //theNodes.pop_back(); // remove nIgnore theNodes.pop_back(); // remove nStart - theFaces.pop_back(); // remove curElem - list< const SMDS_MeshNode* >::iterator nIt = cNL->begin(); - list< const SMDS_MeshElement* >::iterator fIt = cFL->begin(); - for ( ; nIt != cNL->end(); nIt++ ) theNodes.push_back( *nIt ); - for ( ; fIt != cFL->end(); fIt++ ) theFaces.push_back( *fIt ); + //theFaces.pop_back(); // remove curElem + theNodes.splice( theNodes.end(), *cNL ); + theFaces.splice( theFaces.end(), *cFL ); return true; } // several continuations found @@ -8026,6 +8053,10 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode, nIt[0] = nSide[0].begin(); eIt[0] = eSide[0].begin(); nIt[1] = nSide[1].begin(); eIt[1] = eSide[1].begin(); + // element can be split while iterating on border if it has two edges in the border + std::map< const SMDS_MeshElement* , const SMDS_MeshElement* > elemReplaceMap; + std::map< const SMDS_MeshElement* , const SMDS_MeshElement* >::iterator elemReplaceMapIt; + TElemOfNodeListMap insertMap; TElemOfNodeListMap::iterator insertMapIt; // insertMap is @@ -8073,12 +8104,15 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode, const SMDS_MeshNode* nIns = *nIt [ 1 - intoBord ]; if ( intoBord == 1 ) { // move node of the border to be on a link of elem of the side - gp_XYZ p1 (n1->X(), n1->Y(), n1->Z()); - gp_XYZ p2 (n2->X(), n2->Y(), n2->Z()); + SMESH_NodeXYZ p1( n1 ), p2( n2 ); double ratio = du / ( param[ 1 ][ i[1] ] - param[ 1 ][ i[1]-1 ]); gp_XYZ p = p2 * ( 1 - ratio ) + p1 * ratio; GetMeshDS()->MoveNode( nIns, p.X(), p.Y(), p.Z() ); } + elemReplaceMapIt = elemReplaceMap.find( elem ); + if ( elemReplaceMapIt != elemReplaceMap.end() ) + elem = elemReplaceMapIt->second; + insertMapIt = insertMap.find( elem ); bool notFound = ( insertMapIt == insertMap.end() ); bool otherLink = ( !notFound && (*insertMapIt).second.front() != n1 ); @@ -8101,8 +8135,10 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode, UpdateVolumes(n12, n22, nodeList); } // 3. find an element appeared on n1 and n2 after the insertion - insertMap.erase( elem ); - elem = findAdjacentFace( n1, n2, 0 ); + insertMap.erase( insertMapIt ); + const SMDS_MeshElement* elem2 = findAdjacentFace( n1, n2, 0 ); + elemReplaceMap.insert( std::make_pair( elem, elem2 )); + elem = elem2; } if ( notFound || otherLink ) { // add element and nodes of the side into the insertMap