X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH%2FSMESH_MeshEditor.cxx;h=ae3b70321c91196a98ba745dfa86b1466f83824d;hb=29c693b1c362e8045aaab556ec5d8c612294e22e;hp=feacce4225860bfadc73811102350fac5d63728a;hpb=6d32f944a0a115b6419184c50b57bf7c4eef5786;p=modules%2Fsmesh.git diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index feacce422..ae3b70321 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -161,8 +161,7 @@ SMESH_MeshEditor::ElemFeatures::Init( const SMDS_MeshElement* elem, bool basicOn myIsQuad = elem->IsQuadratic(); if ( myType == SMDSAbs_Volume && !basicOnly ) { - vector quant = static_cast( elem )->GetQuantities(); - myPolyhedQuantities.swap( quant ); + myPolyhedQuantities = static_cast( elem )->GetQuantities(); } } } @@ -297,6 +296,18 @@ SMESH_MeshEditor::AddElement(const vector & node, node[8], node[9], node[10],node[11], node[12],node[13],node[14] ); } + else if (nbnode == 18) { + if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], + node[4], node[5], node[6], node[7], + node[8], node[9], node[10],node[11], + node[12],node[13],node[14], + node[15],node[16],node[17],ID ); + else e = mesh->AddVolume (node[0], node[1], node[2], node[3], + node[4], node[5], node[6], node[7], + node[8], node[9], node[10],node[11], + node[12],node[13],node[14], + node[15],node[16],node[17] ); + } else if (nbnode == 20) { if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], node[4], node[5], node[6], node[7], @@ -1093,19 +1104,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 +5879,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 +6401,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 +6488,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 +7489,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 +7626,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 +7708,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 +7719,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 +8064,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 +8115,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 +8146,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 @@ -9302,7 +9349,7 @@ void SMESH_MeshEditor::ConvertFromQuadratic(TIDSortedElemSet& theElements) const SMDS_MeshElement* eComplex = invIt2->next(); if ( eComplex->IsQuadratic() && !allMediumNodesIn( eComplex, mediumNodes)) { - int nbCommonNodes = SMESH_MeshAlgos::GetCommonNodes( e, eComplex ).size(); + int nbCommonNodes = SMESH_MeshAlgos::NbCommonNodes( e, eComplex ); if ( nbCommonNodes == e->NbNodes()) { complexFound = true; @@ -9844,10 +9891,10 @@ SMESH_MeshEditor::FindMatchingNodes(set& theSide1, set * faceSetPtr[] = { &theSide1, &theSide2 }; nReplaceMap.clear(); - if ( theFirstNode1 != theFirstNode2 ) - nReplaceMap.insert( make_pair( theFirstNode1, theFirstNode2 )); - if ( theSecondNode1 != theSecondNode2 ) - nReplaceMap.insert( make_pair( theSecondNode1, theSecondNode2 )); + //if ( theFirstNode1 != theFirstNode2 ) + nReplaceMap.insert( make_pair( theFirstNode1, theFirstNode2 )); + //if ( theSecondNode1 != theSecondNode2 ) + nReplaceMap.insert( make_pair( theSecondNode1, theSecondNode2 )); set< SMESH_TLink > linkSet; // set of nodes where order of nodes is ignored linkSet.insert( SMESH_TLink( theFirstNode1, theSecondNode1 )); @@ -11150,7 +11197,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorGetCellLinks()->GetLink(oldId); + vtkCellLinks::Link l = (static_cast (grid->GetCellLinks()))->GetLink(oldId); for (int i=0; iGetID()); double values[3] = { 0,0,0 }; vtkIdType npts = 0; - vtkIdType* pts = 0; + vtkIdType const *pts(nullptr); grid->GetCellPoints(vtkVolIds[ivol], npts, pts); for ( vtkIdType i = 0; i < npts; ++i ) { @@ -11512,7 +11559,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorfirst; //MESSAGE(" node " << oldId); - vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId); + vtkCellLinks::Link l = (static_cast< vtkCellLinks *>(grid->GetCellLinks()))->GetLink(oldId); for (int i = 0; i < l.ncells; i++) { int vtkId = l.cells[i]; @@ -11964,7 +12011,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, //MESSAGE("volume to check, vtkId " << vtkId << " smdsId " << meshDS->FromVtkToSmds(vtkId)); bool volInside = false; vtkIdType npts = 0; - vtkIdType* pts = 0; + vtkIdType const *pts(nullptr); grid->GetCellPoints(vtkId, npts, pts); for (int i=0; iFindElement( tgtNodes, - missType, - /*noMedium=*/false)) + missType, + /*noMedium=*/false)) continue; tgtEditor.AddElement( tgtNodes, elemKind.SetPoly( tgtNodes.size()/(iQuad+1) > 4 )); ++nbAddedBnd; @@ -12542,8 +12589,8 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, { TConnectivity& nodes = missingBndElems[ i ]; if ( /*aroundElements && */tgtEditor.GetMeshDS()->FindElement( nodes, - missType, - /*noMedium=*/false)) + missType, + /*noMedium=*/false)) continue; SMDS_MeshElement* newElem = tgtEditor.AddElement( nodes, elemKind.SetPoly( nodes.size()/(iQuad+1) > 4 ));