X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH%2FSMESH_MeshEditor.cxx;h=794c69c5eef5b3b3cbe46080461a62ee65097199;hb=bd4cadfcf065d6c5079ca6edd42d3ffd69402a83;hp=a0434ebfc519dece8f71cd68fe7136356996b1d7;hpb=80ac3613f8288a4146f0d9b4763607bc7a02363d;p=modules%2Fsmesh.git diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index a0434ebfc..794c69c5e 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -1563,14 +1563,14 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems, const int theMethodFlags) { // std-like iterator on coordinates of nodes of mesh element - typedef SMDS_StdIterator< TNodeXYZ, SMDS_ElemIteratorPtr > NXyzIterator; + typedef SMDS_StdIterator< SMESH_TNodeXYZ, SMDS_ElemIteratorPtr > NXyzIterator; NXyzIterator xyzEnd; SMDS_VolumeTool volTool; SMESH_MesherHelper helper( *GetMesh()); - SMESHDS_SubMesh* subMesh = GetMeshDS()->MeshElements(1); - SMESHDS_SubMesh* fSubMesh = subMesh; + SMESHDS_SubMesh* subMesh = 0;//GetMeshDS()->MeshElements(1); + SMESHDS_SubMesh* fSubMesh = 0;//subMesh; SMESH_SequenceOfElemPtr newNodes, newElems; @@ -2681,6 +2681,9 @@ void SMESH_MeshEditor::GetLinkedNodes( const SMDS_MeshNode* theNode, while ( elemIt->more() ) { const SMDS_MeshElement* elem = elemIt->next(); + if(elem->GetType() == SMDSAbs_0DElement) + continue; + SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); if ( elem->GetType() == SMDSAbs_Volume ) { @@ -6241,7 +6244,7 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher const SMDS_MeshNode* closestNode = 0; list::iterator nIt = nodes.begin(); for ( ; nIt != nodes.end(); ++nIt ) { - double sqDist = thePnt.SquareDistance( SMESH_MeshEditor::TNodeXYZ( *nIt ) ); + double sqDist = thePnt.SquareDistance( SMESH_TNodeXYZ( *nIt ) ); if ( minSqDist > sqDist ) { closestNode = *nIt; minSqDist = sqDist; @@ -6461,7 +6464,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint() _refCount = 1; SMDS_ElemIteratorPtr nIt = elem->nodesIterator(); while ( nIt->more() ) - Add( SMESH_MeshEditor::TNodeXYZ( cast2Node( nIt->next() ))); + Add( SMESH_TNodeXYZ( cast2Node( nIt->next() ))); Enlarge( tolerance ); } @@ -6568,7 +6571,7 @@ double SMESH_ElementSearcherImpl::getTolerance() SMDS_NodeIteratorPtr nodeIt = _mesh->nodesIterator(); elemSize = 1; if ( meshInfo.NbNodes() > 2 ) - elemSize = SMESH_MeshEditor::TNodeXYZ( nodeIt->next() ).Distance( nodeIt->next() ); + elemSize = SMESH_TNodeXYZ( nodeIt->next() ).Distance( nodeIt->next() ); } else { @@ -6576,7 +6579,8 @@ double SMESH_ElementSearcherImpl::getTolerance() _mesh->elementsIterator( SMDSAbs_ElementType( complexType )); const SMDS_MeshElement* elem = elemIt->next(); SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); - SMESH_MeshEditor::TNodeXYZ n1( cast2Node( nodeIt->next() )); + SMESH_TNodeXYZ n1( cast2Node( nodeIt->next() )); + elemSize = 0; while ( nodeIt->more() ) { double dist = n1.Distance( cast2Node( nodeIt->next() )); @@ -6609,8 +6613,8 @@ bool SMESH_ElementSearcherImpl::getIntersParamOnLine(const gp_Lin& lin int nbNodes = face->IsQuadratic() ? face->NbNodes()/2 : face->NbNodes(); for ( int i = 0; i < nbNodes && nbInts < 2; ++i ) { - GC_MakeSegment edge( SMESH_MeshEditor::TNodeXYZ( face->GetNode( i )), - SMESH_MeshEditor::TNodeXYZ( face->GetNode( (i+1)%nbNodes) )); + GC_MakeSegment edge( SMESH_TNodeXYZ( face->GetNode( i )), + SMESH_TNodeXYZ( face->GetNode( (i+1)%nbNodes) )); anExtCC.Init( lineCurve, edge); if ( anExtCC.NbExtrema() > 0 && anExtCC.LowerDistance() <= tol) { @@ -6670,8 +6674,8 @@ void SMESH_ElementSearcherImpl::findOuterBoundary(const SMDS_MeshElement* outerF seamLinks.insert( link ); // link direction within the outerFace - gp_Vec n1n2( SMESH_MeshEditor::TNodeXYZ( link.node1()), - SMESH_MeshEditor::TNodeXYZ( link.node2())); + gp_Vec n1n2( SMESH_TNodeXYZ( link.node1()), + SMESH_TNodeXYZ( link.node2())); int i1 = outerFace->GetNodeIndex( link.node1() ); int i2 = outerFace->GetNodeIndex( link.node2() ); bool rev = ( abs(i2-i1) == 1 ? i1 > i2 : i2 > i1 ); @@ -6754,7 +6758,7 @@ FindElementsByPoint(const gp_Pnt& point, const SMDS_MeshNode* closeNode = _nodeSearcher->FindClosestTo( point ); if ( !closeNode ) return foundElements.size(); - if ( point.Distance( SMESH_MeshEditor::TNodeXYZ( closeNode )) > tolerance ) + if ( point.Distance( SMESH_TNodeXYZ( closeNode )) > tolerance ) return foundElements.size(); // to far from any node if ( type == SMDSAbs_Node ) @@ -6826,7 +6830,7 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point) // get face plane gp_XYZ fNorm; if ( !SMESH_Algo::FaceNormal( *face, fNorm, /*normalized=*/false)) continue; - gp_Pln facePlane( SMESH_MeshEditor::TNodeXYZ( (*face)->GetNode(0)), fNorm ); + gp_Pln facePlane( SMESH_TNodeXYZ( (*face)->GetNode(0)), fNorm ); // perform intersection IntAna_IntConicQuad intersection( line, IntAna_Quadric( facePlane )); @@ -7079,7 +7083,7 @@ bool SMESH_MeshEditor::isOut( const SMDS_MeshElement* element, const gp_Pnt& poi while ( nodeIt->more() ) { const SMDS_MeshNode* node = cast2Node( nodeIt->next() ); - xyz.push_back( TNodeXYZ(node) ); + xyz.push_back( SMESH_TNodeXYZ(node) ); nodeList.push_back(node); } @@ -10493,7 +10497,7 @@ namespace { gp_XYZ centerXYZ (0, 0, 0); SMDS_ElemIteratorPtr aNodeItr = theElem->nodesIterator(); while (aNodeItr->more()) - centerXYZ += SMESH_MeshEditor::TNodeXYZ(cast2Node( aNodeItr->next())); + centerXYZ += SMESH_TNodeXYZ(cast2Node( aNodeItr->next())); gp_Pnt aPnt = centerXYZ / theElem->NbNodes(); theClassifier.Perform(aPnt, theTol); @@ -10612,9 +10616,9 @@ bool SMESH_MeshEditor::DoubleNodesInRegion( const TIDSortedElemSet& theElems, bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector& theElems, bool createJointElems) { - MESSAGE("------------------------------------------------------"); - MESSAGE("SMESH_MeshEditor::CreateJointElementsOnGroupBoundaries"); - MESSAGE("------------------------------------------------------"); + MESSAGE("----------------------------------------------"); + MESSAGE("SMESH_MeshEditor::doubleNodesOnGroupBoundaries"); + MESSAGE("----------------------------------------------"); SMESHDS_Mesh *meshDS = this->myMesh->GetMeshDS(); meshDS->BuildDownWardConnectivity(false); @@ -10622,11 +10626,16 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorgetGrid(); // --- build the list of faces shared by 2 domains (group of elements), with their domain and volume indexes + // build the list of cells with only a node or an edge on the border, with their domain and volume indexes // build the list of nodes shared by 2 or more domains, with their domain indexes - std::map, DownIdCompare> faceDomains; // 2x(id domain --> id volume) - std::map > nodeDomains; //oldId -> (domainId -> newId) + std::map, DownIdCompare> faceDomains; // face --> (id domain --> id volume) + std::mapcelldom; // cell vtkId --> domain + std::map, DownIdCompare> cellDomains; // oldNode --> (id domain --> id cell) + std::map > nodeDomains; // oldId --> (domainId --> newId) faceDomains.clear(); + celldom.clear(); + cellDomains.clear(); nodeDomains.clear(); std::map emptyMap; emptyMap.clear(); @@ -10663,6 +10672,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector, DownIdCompare>::iterator itface; + + // --- explore the shared faces domain by domain, + // explore the nodes of the face and see if they belong to a cell in the domain, + // which has only a node or an edge on the border (not a shared face) + + for (int idomain = 0; idomain < theElems.size(); idomain++) + { + const TIDSortedElemSet& domain = theElems[idomain]; + itface = faceDomains.begin(); + for (; itface != faceDomains.end(); ++itface) + { + std::map domvol = itface->second; + if (!domvol.count(idomain)) + continue; + DownIdType face = itface->first; + //MESSAGE(" --- face " << face.cellId); + std::set oldNodes; + oldNodes.clear(); + grid->GetNodeIds(oldNodes, face.cellId, face.cellType); + std::set::iterator itn = oldNodes.begin(); + for (; itn != oldNodes.end(); ++itn) + { + int oldId = *itn; + //MESSAGE(" node " << oldId); + std::set cells; + cells.clear(); + vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId); + for (int i=0; iFindElement(GetMeshDS()->fromVtkToSmds(vtkId)); + if (!domain.count(anElem)) + continue; + int vtkType = grid->GetCellType(vtkId); + int downId = grid->CellIdToDownId(vtkId); + DownIdType aCell(downId, vtkType); + if (celldom.count(vtkId)) + continue; + cellDomains[aCell][idomain] = vtkId; + celldom[vtkId] = idomain; + } + } + } + } - // --- for each shared face, get the nodes + // --- explore the shared faces domain by domain, to duplicate the nodes in a coherent way + // for each shared face, get the nodes // for each node, for each domain of the face, create a clone of the node - std::map, DownIdCompare>::iterator itface = faceDomains.begin(); - for( ; itface != faceDomains.end();++itface ) + for (int idomain = 0; idomain < theElems.size(); idomain++) { - DownIdType face = itface->first; - std::map domvol = itface->second; - std::set oldNodes; - oldNodes.clear(); - grid->GetNodeIds(oldNodes, face.cellId, face.cellType); - std::set::iterator itn = oldNodes.begin(); - for (;itn != oldNodes.end(); ++itn) + itface = faceDomains.begin(); + for (; itface != faceDomains.end(); ++itface) { - int oldId = *itn; - if (!nodeDomains.count(oldId)) - nodeDomains[oldId] = emptyMap; // create an empty entry for node - std::map::iterator itdom = domvol.begin(); - for(; itdom != domvol.end(); ++itdom) + std::map domvol = itface->second; + if (!domvol.count(idomain)) + continue; + DownIdType face = itface->first; + //MESSAGE(" --- face " << face.cellId); + std::set oldNodes; + oldNodes.clear(); + grid->GetNodeIds(oldNodes, face.cellId, face.cellType); + std::set::iterator itn = oldNodes.begin(); + for (; itn != oldNodes.end(); ++itn) { - int idom = itdom->first; - if ( nodeDomains[oldId].empty() ) - nodeDomains[oldId][idom] = oldId; // keep the old node in the first domain - else + int oldId = *itn; + //MESSAGE(" node " << oldId); + if (!nodeDomains.count(oldId)) + nodeDomains[oldId] = emptyMap; // create an empty entry for node + if (nodeDomains[oldId].empty()) + nodeDomains[oldId][idomain] = oldId; // keep the old node in the first domain + std::map::iterator itdom = domvol.begin(); + for (; itdom != domvol.end(); ++itdom) { - double *coords = grid->GetPoint(oldId); - SMDS_MeshNode *newNode = meshDS->AddNode(coords[0], coords[1], coords[2]); - int newId = newNode->getVtkId(); - nodeDomains[oldId][idom] = newId; // cloned node for other domains + int idom = itdom->first; + //MESSAGE(" domain " << idom); + if (!nodeDomains[oldId].count(idom)) + { + double *coords = grid->GetPoint(oldId); + SMDS_MeshNode *newNode = meshDS->AddNode(coords[0], coords[1], coords[2]); + int newId = newNode->getVtkId(); + nodeDomains[oldId][idom] = newId; // cloned node for other domains + //MESSAGE(" newNode " << newId); + } } } } @@ -10719,7 +10784,6 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector::iterator itn; oldNodes.clear(); grid->GetNodeIds(oldNodes, face.cellId, face.cellType); - std::map localClonedNodeIds; std::map domvol = itface->second; std::map::iterator itdom = domvol.begin(); @@ -10727,24 +10791,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorsecond; itdom++; int dom2 = itdom->first; - - localClonedNodeIds.clear(); - for (itn = oldNodes.begin(); itn != oldNodes.end(); ++itn) - { - int oldId = *itn; - int refid = oldId; - if (nodeDomains[oldId].count(dom1)) - refid = nodeDomains[oldId][dom1]; - else - MESSAGE("--- problem domain node " << dom1 << " " << oldId); - int newid = oldId; - if (nodeDomains[oldId].count(dom2)) - newid = nodeDomains[oldId][dom2]; - else - MESSAGE("--- problem domain node " << dom2 << " " << oldId); - localClonedNodeIds[oldId] = newid; - } - meshDS->extrudeVolumeFromFace(vtkVolId, localClonedNodeIds); + meshDS->extrudeVolumeFromFace(vtkVolId, dom1, dom2, oldNodes, nodeDomains); } } @@ -10752,6 +10799,8 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorGetType() != elemType ) throw SALOME_Exception(LOCALIZED("wrong element type")); + if ( aroundElements && elemType == SMDSAbs_Volume ) + throw SALOME_Exception(LOCALIZED("wrong element type for aroundElements==true")); + if ( !targetMesh ) toCopyElements = toCopyExistingBondary = false; SMESH_MeshEditor tgtEditor( targetMesh ? targetMesh : myMesh ); SMESHDS_Mesh* aMesh = GetMeshDS(), *tgtMeshDS = tgtEditor.GetMeshDS(); + int nbAddedBnd = 0; + + // editor adding present bnd elements and optionally holding elements to add to the group + SMESH_MeshEditor* presentEditor; + SMESH_MeshEditor tgtEditor2( tgtEditor.GetMesh() ); + presentEditor = toAddExistingBondary ? &tgtEditor : &tgtEditor2; SMDS_VolumeTool vTool; - TIDSortedElemSet emptySet, avoidSet; + TIDSortedElemSet avoidSet; + const TIDSortedElemSet emptySet, *elemSet = aroundElements ? &elements : &emptySet; int inode; typedef vector TConnectivity; @@ -10895,7 +10962,9 @@ void SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, const SMDS_MeshElement* elem = eIt->next(); const int iQuad = elem->IsQuadratic(); + // ------------------------------------------------------------------------------------ // 1. For an elem, get present bnd elements and connectivities of missing bnd elements + // ------------------------------------------------------------------------------------ vector presentBndElems; vector missingBndElems; TConnectivity nodes; @@ -10947,7 +11016,7 @@ void SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, { nodes[0] = elem->GetNode(i); nodes[1] = elem->GetNode((i+1)%nbNodes); - if ( FindFaceInSet( nodes[0], nodes[1], emptySet, avoidSet)) + if ( FindFaceInSet( nodes[0], nodes[1], *elemSet, avoidSet)) continue; // not free link //if ( iQuad ) @@ -10960,7 +11029,9 @@ void SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, } } + // --------------------------------- // 2. Add missing boundary elements + // --------------------------------- if ( targetMesh != myMesh ) // instead of making a map of nodes in this mesh and targetMesh, // we create nodes with same IDs. We can renumber them later, if needed @@ -10970,16 +11041,28 @@ void SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, TConnectivity nodes( srcNodes.size() ); for ( inode = 0; inode < nodes.size(); ++inode ) nodes[inode] = getNodeWithSameID( tgtMeshDS, srcNodes[inode] ); + if ( aroundElements && tgtEditor.GetMeshDS()->FindElement( nodes, + missType, + /*noMedium=*/true)) + continue; tgtEditor.AddElement(nodes, missType, elem->IsPoly() && nodes.size()/(iQuad+1)>4); + ++nbAddedBnd; } else for ( int i = 0; i < missingBndElems.size(); ++i ) { - TConnectivity& nodes = missingBndElems[i]; + TConnectivity& nodes = missingBndElems[i]; + if ( aroundElements && tgtEditor.GetMeshDS()->FindElement( nodes, + missType, + /*noMedium=*/true)) + continue; tgtEditor.AddElement(nodes, missType, elem->IsPoly() && nodes.size()/(iQuad+1)>4); + ++nbAddedBnd; } + // ---------------------------------- // 3. Copy present boundary elements + // ---------------------------------- if ( toCopyExistingBondary ) for ( int i = 0 ; i < presentBndElems.size(); ++i ) { @@ -10987,13 +11070,19 @@ void SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, TConnectivity nodes( e->NbNodes() ); for ( inode = 0; inode < nodes.size(); ++inode ) nodes[inode] = getNodeWithSameID( tgtMeshDS, e->GetNode(inode) ); - tgtEditor.AddElement(nodes, missType, e->IsPoly()); - // leave only missing elements in tgtEditor.myLastCreatedElems - tgtEditor.myLastCreatedElems.Remove( tgtEditor.myLastCreatedElems.Size() ); + presentEditor->AddElement(nodes, missType, e->IsPoly()); + } + else // store present elements to add them to a group + for ( int i = 0 ; i < presentBndElems.size(); ++i ) + { + presentEditor->myLastCreatedElems.Append(presentBndElems[i]); } + } // loop on given elements - // 4. Fill group with missing boundary elements + // --------------------------------------------- + // 4. Fill group with boundary elements + // --------------------------------------------- if ( group ) { if ( SMESHDS_Group* g = dynamic_cast( group->GetGroupDS() )) @@ -11001,9 +11090,12 @@ void SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, g->SMDSGroup().Add( tgtEditor.myLastCreatedElems( i+1 )); } tgtEditor.myLastCreatedElems.Clear(); + tgtEditor2.myLastCreatedElems.Clear(); + // ----------------------- // 5. Copy given elements - if ( toCopyElements ) + // ----------------------- + if ( toCopyElements && targetMesh != myMesh ) { if (elements.empty()) eIt = aMesh->elementsIterator(elemType); @@ -11020,5 +11112,5 @@ void SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, tgtEditor.myLastCreatedElems.Clear(); } } - return; + return nbAddedBnd; }