X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH%2FSMESH_MeshEditor.cxx;h=a37950e411a9a58af2f95936f903fcfbbc46bed2;hp=9cc4d2378405173a2a3360dcedcb04904bf6e047;hb=1ea4e6ee790a9cca02f184dfb81c2cfb3775d3be;hpb=a0880e7c367025142b27c4669968a7611837c5a9 diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 9cc4d2378..a37950e41 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2016 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 @@ -1325,7 +1325,7 @@ int SMESH_MeshEditor::Reorient2DBy3D (TIDSortedElemSet & theFaces, if ( face->GetType() != SMDSAbs_Face ) continue; - const int nbCornersNodes = face->NbCornerNodes(); + const size_t nbCornersNodes = face->NbCornerNodes(); faceNodes.assign( face->begin_nodes(), face->end_nodes() ); checkedVolumes.clear(); @@ -1341,7 +1341,7 @@ int SMESH_MeshEditor::Reorient2DBy3D (TIDSortedElemSet & theFaces, // is volume adjacent? bool allNodesCommon = true; - for ( int iN = 1; iN < nbCornersNodes && allNodesCommon; ++iN ) + for ( size_t iN = 1; iN < nbCornersNodes && allNodesCommon; ++iN ) allNodesCommon = ( volume->GetNodeIndex( faceNodes[ iN ]) > -1 ); if ( !allNodesCommon ) continue; @@ -1361,7 +1361,7 @@ int SMESH_MeshEditor::Reorient2DBy3D (TIDSortedElemSet & theFaces, for ( int i = 0; i < 2; ++i ) { const SMDS_MeshNode* n = facetNodes[ i*iQ ]; - for ( int iN = 0; iN < nbCornersNodes; ++iN ) + for ( size_t iN = 0; iN < nbCornersNodes; ++iN ) if ( faceNodes[ iN ] == n ) { iNN[ i ] = iN; @@ -1601,13 +1601,13 @@ void SMESH_MeshEditor::QuadTo4Tri (TIDSortedElemSet & theElems) // create 4 triangles - GetMeshDS()->RemoveFreeElement( quad, subMeshDS, /*fromGroups=*/false ); - helper.SetIsQuadratic ( nodes.size() > 4 ); helper.SetIsBiQuadratic( nodes.size() == 9 ); if ( helper.GetIsQuadratic() ) helper.AddTLinks( static_cast< const SMDS_MeshFace*>( quad )); + GetMeshDS()->RemoveFreeElement( quad, subMeshDS, /*fromGroups=*/false ); + for ( int i = 0; i < 4; ++i ) { SMDS_MeshElement* tria = helper.AddFace( nodes[ i ], @@ -1925,7 +1925,7 @@ namespace if ( hasAdjacentSplits && method._nbSplits > 0 ) { bool facetCreated = true; - for ( int iF = 0; facetCreated && iF < triaSplitsByFace.size(); ++iF ) + for ( size_t iF = 0; facetCreated && iF < triaSplitsByFace.size(); ++iF ) { list< TTriangleFacet >::const_iterator facet = triaSplitsByFace[iF].begin(); for ( ; facetCreated && facet != triaSplitsByFace[iF].end(); ++facet ) @@ -2432,12 +2432,12 @@ void SMESH_MeshEditor::SplitVolumes (const TFacetOfElem & theElems, volNodes[ facet->_n3 ])); } } - for ( int i = 0; i < triangles.size(); ++i ) + for ( size_t i = 0; i < triangles.size(); ++i ) { - if ( !triangles[i] ) continue; + if ( !triangles[ i ]) continue; if ( fSubMesh ) - fSubMesh->AddElement( triangles[i]); - newElems.Append( triangles[i] ); + fSubMesh->AddElement( triangles[ i ]); + newElems.Append( triangles[ i ]); } ReplaceElemInGroups( face, triangles, GetMeshDS() ); GetMeshDS()->RemoveFreeElement( face, fSubMesh, /*fromGroups=*/false ); @@ -2455,7 +2455,7 @@ void SMESH_MeshEditor::SplitVolumes (const TFacetOfElem & theElems, GetMeshDS()->RemoveNode( volNodes[i] ); } } // loop on volumes to split - + myLastCreatedNodes = newNodes; myLastCreatedElems = newElems; } @@ -2530,7 +2530,7 @@ void SMESH_MeshEditor::GetHexaFacetsToSplit( TIDSortedElemSet& theHexas, set facetNodes; const SMDS_MeshElement* curHex; - const bool allHex = ( theHexas.size() == myMesh->NbHexas() ); + const bool allHex = ((int) theHexas.size() == myMesh->NbHexas() ); while ( startHex ) { @@ -2913,7 +2913,7 @@ void SMESH_MeshEditor::ReplaceElemInGroups (const SMDS_MeshElement* for ( ; grIt != groups.end(); grIt++ ) { SMESHDS_Group* group = dynamic_cast( *grIt ); if ( group && group->SMDSGroup().Remove( elemToRm ) ) - for ( int i = 0; i < elemToAdd.size(); ++i ) + for ( size_t i = 0; i < elemToAdd.size(); ++i ) group->SMDSGroup().Add( elemToAdd[ i ] ); } } @@ -2939,14 +2939,13 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, SMESH_MesherHelper helper( *GetMesh() ); TIDSortedElemSet::iterator itElem; - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { + for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) + { const SMDS_MeshElement* elem = *itElem; - if ( !elem || elem->GetType() != SMDSAbs_Face ) + if ( !elem || elem->GetGeomType() != SMDSGeom_QUADRANGLE ) continue; - bool isquad = elem->NbNodes()==4 || elem->NbNodes()==8; - if(!isquad) continue; - if(elem->NbNodes()==4) { + if ( elem->NbNodes() == 4 ) { // retrieve element nodes const SMDS_MeshNode* aNodes [4]; SMDS_ElemIteratorPtr itN = elem->nodesIterator(); @@ -2969,10 +2968,10 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, myLastCreatedElems.Append(newElem2); // put a new triangle on the same shape and add to the same groups if ( aShapeId ) - { - aMesh->SetMeshElementOnShape( newElem1, aShapeId ); - aMesh->SetMeshElementOnShape( newElem2, aShapeId ); - } + { + aMesh->SetMeshElementOnShape( newElem1, aShapeId ); + aMesh->SetMeshElementOnShape( newElem2, aShapeId ); + } AddToSameGroups( newElem1, elem, aMesh ); AddToSameGroups( newElem2, elem, aMesh ); aMesh->RemoveElement( elem ); @@ -2980,8 +2979,8 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, // Quadratic quadrangle - if( elem->NbNodes()==8 && elem->IsQuadratic() ) { - + else if ( elem->NbNodes() >= 8 ) + { // get surface elem is on int aShapeId = FindShape( elem ); if ( aShapeId != helper.GetSubShapeID() ) { @@ -2997,61 +2996,43 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, } } - const SMDS_MeshNode* aNodes [8]; - const SMDS_MeshNode* inFaceNode = 0; + const SMDS_MeshNode* aNodes [9]; aNodes[8] = 0; SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - int i = 0; - while ( itN->more() ) { - aNodes[ i++ ] = static_cast( itN->next() ); - if ( !inFaceNode && helper.GetNodeUVneedInFaceNode() && - aNodes[ i-1 ]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) - { - inFaceNode = aNodes[ i-1 ]; - } - } + for ( int i = 0; itN->more(); ++i ) + aNodes[ i ] = static_cast( itN->next() ); - // find middle point for (0,1,2,3) - // and create a node in this point; - gp_XYZ p( 0,0,0 ); - if ( surface.IsNull() ) { - for(i=0; i<4; i++) - p += gp_XYZ(aNodes[i]->X(), aNodes[i]->Y(), aNodes[i]->Z() ); - p /= 4; - } - else { - TopoDS_Face geomFace = TopoDS::Face( helper.GetSubShape() ); - gp_XY uv( 0,0 ); - for(i=0; i<4; i++) - uv += helper.GetNodeUV( geomFace, aNodes[i], inFaceNode ); - uv /= 4.; - p = surface->Value( uv.X(), uv.Y() ).XYZ(); + const SMDS_MeshNode* centrNode = aNodes[8]; + if ( centrNode == 0 ) + { + centrNode = helper.GetCentralNode( aNodes[0], aNodes[1], aNodes[2], aNodes[3], + aNodes[4], aNodes[5], aNodes[6], aNodes[7], + surface.IsNull() ); + myLastCreatedNodes.Append(centrNode); } - const SMDS_MeshNode* newN = aMesh->AddNode( p.X(), p.Y(), p.Z() ); - myLastCreatedNodes.Append(newN); // create a new element const SMDS_MeshElement* newElem1 = 0; const SMDS_MeshElement* newElem2 = 0; if ( the13Diag ) { newElem1 = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0], - aNodes[6], aNodes[7], newN ); + aNodes[6], aNodes[7], centrNode ); newElem2 = aMesh->AddFace(aNodes[2], aNodes[0], aNodes[1], - newN, aNodes[4], aNodes[5] ); + centrNode, aNodes[4], aNodes[5] ); } else { newElem1 = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1], - aNodes[7], aNodes[4], newN ); + aNodes[7], aNodes[4], centrNode ); newElem2 = aMesh->AddFace(aNodes[3], aNodes[1], aNodes[2], - newN, aNodes[5], aNodes[6] ); + centrNode, aNodes[5], aNodes[6] ); } myLastCreatedElems.Append(newElem1); myLastCreatedElems.Append(newElem2); // put a new triangle on the same shape and add to the same groups if ( aShapeId ) - { - aMesh->SetMeshElementOnShape( newElem1, aShapeId ); - aMesh->SetMeshElementOnShape( newElem2, aShapeId ); - } + { + aMesh->SetMeshElementOnShape( newElem1, aShapeId ); + aMesh->SetMeshElementOnShape( newElem2, aShapeId ); + } AddToSameGroups( newElem1, elem, aMesh ); AddToSameGroups( newElem2, elem, aMesh ); aMesh->RemoveElement( elem ); @@ -4006,7 +3987,7 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, Handle(Geom_Surface) surface; SMESHDS_SubMesh* faceSubMesh = 0; TopoDS_Face face; - double fToler2 = 0, f,l; + double fToler2 = 0; double u1 = 0, u2 = 0, v1 = 0, v2 = 0; bool isUPeriodic = false, isVPeriodic = false; if ( *fId ) @@ -4492,7 +4473,7 @@ namespace void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, const vector & newNodesItVec, list& newElems, - const int nbSteps, + const size_t nbSteps, SMESH_SequenceOfElemPtr& srcElements) { //MESSAGE("sweepElement " << nbSteps); @@ -4620,7 +4601,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, } // make new elements - for (int iStep = 0; iStep < nbSteps; iStep++ ) + for ( size_t iStep = 0; iStep < nbSteps; iStep++ ) { // get next nodes for ( iNode = 0; iNode < nbNodes; iNode++ ) @@ -5853,7 +5834,7 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet theElemSets[2], // source elements for each generated one SMESH_SequenceOfElemPtr srcElems, srcNodes; - SMESHDS_Mesh* aMesh = GetMeshDS(); + //SMESHDS_Mesh* aMesh = GetMeshDS(); setElemsFirst( theElemSets ); const int nbSteps = theParams.NbSteps(); @@ -5986,6 +5967,10 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], ASSERT( theTrack ); SMESHDS_SubMesh* pSubMeshDS = theTrack->GetSubMeshDS(); + if ( !pSubMeshDS ) + return ExtrusionAlongTrack( theElements, theTrack->GetFather(), theN1, + theHasAngles, theAngles, theLinearVariation, + theHasRefPoint, theRefPoint, theMakeGroups ); aItE = pSubMeshDS->GetElements(); while ( aItE->more() ) { @@ -6240,21 +6225,19 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], return EXTR_PATH_NOT_EDGE; TopTools_SequenceOfShape Edges; - double x1,x2,y1,y2,z1,z2; list< list > LLPPs; int startNid = theN1->GetID(); - for(int i = 1; i < aNodesList.size(); i++) { - x1 = aNodesList[i-1]->X();x2 = aNodesList[i]->X(); - y1 = aNodesList[i-1]->Y();y2 = aNodesList[i]->Y(); - z1 = aNodesList[i-1]->Z();z2 = aNodesList[i]->Z(); - TopoDS_Edge e = BRepBuilderAPI_MakeEdge(gp_Pnt(x1,y1,z1),gp_Pnt(x2,y2,z2)); + for ( size_t i = 1; i < aNodesList.size(); i++ ) + { + gp_Pnt p1 = SMESH_TNodeXYZ( aNodesList[i-1] ); + gp_Pnt p2 = SMESH_TNodeXYZ( aNodesList[i] ); + TopoDS_Edge e = BRepBuilderAPI_MakeEdge( p1, p2 ); list LPP; aPrms.clear(); MakeEdgePathPoints(aPrms, e, (aNodesList[i-1]->GetID()==startNid), LPP); LLPPs.push_back(LPP); - if( aNodesList[i-1]->GetID() == startNid ) startNid = aNodesList[i]->GetID(); - else startNid = aNodesList[i-1]->GetID(); - + if ( aNodesList[i-1]->GetID() == startNid ) startNid = aNodesList[i ]->GetID(); + else startNid = aNodesList[i-1]->GetID(); } list< list >::iterator itLLPP = LLPPs.begin(); @@ -6274,8 +6257,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], 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 ) ); + gp_Dir Dnew( 0.5 * ( D1.XYZ() + D2.XYZ() )); PP1.SetTangent(Dnew); fullList.push_back(PP1); itPP++; @@ -6288,7 +6270,8 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], fullList.push_back(PP1); } // Sub-shape for the Pattern must be an Edge or Wire - else if( aS.ShapeType() == TopAbs_EDGE ) { + else if ( aS.ShapeType() == TopAbs_EDGE ) + { aTrackEdge = TopoDS::Edge( aS ); // the Edge must not be degenerated if ( SMESH_Algo::isDegenerated( aTrackEdge ) ) @@ -6632,7 +6615,7 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet theElemSets // if current elem is quadratic and current node is not medium // we have to check - may be it is needed to insert additional nodes list< const SMDS_MeshNode* > & listNewNodes = nIt->second; - if ( listNewNodes.size() == aNbTP-1 ) + if ((int) listNewNodes.size() == aNbTP-1 ) { vector aNodes(2*(aNbTP-1)); gp_XYZ P(node->X(), node->Y(), node->Z()); @@ -6889,7 +6872,7 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, if ( !elem ) continue; SMDSAbs_GeometryType geomType = elem->GetGeomType(); - int nbNodes = elem->NbNodes(); + size_t nbNodes = elem->NbNodes(); if ( geomType == SMDSGeom_NONE ) continue; // node nodes.resize( nbNodes ); @@ -6927,7 +6910,7 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, const vector& i = needReverse ? iRev : iForw; // find transformed nodes - int iNode = 0; + size_t iNode = 0; SMDS_ElemIteratorPtr itN = elem->nodesIterator(); while ( itN->more() ) { const SMDS_MeshNode* node = static_cast( itN->next() ); @@ -7232,76 +7215,52 @@ int SMESH_MeshEditor::SimplifyFace (const vector& faceNod vector& quantities) const { int nbNodes = faceNodes.size(); - - if (nbNodes < 3) + while ( faceNodes[ 0 ] == faceNodes[ nbNodes-1 ] && nbNodes > 2 ) + --nbNodes; + if ( nbNodes < 3 ) return 0; + size_t prevNbQuant = quantities.size(); - set nodeSet; - - // get simple seq of nodes - vector simpleNodes( nbNodes ); - int iSimple = 0; - - simpleNodes[iSimple++] = faceNodes[0]; - for (int iCur = 1; iCur < nbNodes; iCur++) { - if (faceNodes[iCur] != simpleNodes[iSimple - 1]) { - simpleNodes[iSimple++] = faceNodes[iCur]; - nodeSet.insert( faceNodes[iCur] ); - } - } - int nbUnique = nodeSet.size(); - int nbSimple = iSimple; - if (simpleNodes[nbSimple - 1] == simpleNodes[0]) { - nbSimple--; - iSimple--; - } - - if (nbUnique < 3) - return 0; + vector< const SMDS_MeshNode* > simpleNodes; simpleNodes.reserve( nbNodes ); + map< const SMDS_MeshNode*, int > nodeIndices; // indices within simpleNodes + map< const SMDS_MeshNode*, int >::iterator nInd; - // separate loops - int nbNew = 0; - bool foundLoop = (nbSimple > nbUnique); - while (foundLoop) { - foundLoop = false; - set loopSet; - for (iSimple = 0; iSimple < nbSimple && !foundLoop; iSimple++) { - const SMDS_MeshNode* n = simpleNodes[iSimple]; - if (!loopSet.insert( n ).second) { - foundLoop = true; - - // separate loop - int iC = 0, curLast = iSimple; - for (; iC < curLast; iC++) { - if (simpleNodes[iC] == n) break; - } - int loopLen = curLast - iC; - if (loopLen > 2) { - // create sub-element - nbNew++; - quantities.push_back(loopLen); - for (; iC < curLast; iC++) { - poly_nodes.push_back(simpleNodes[iC]); - } - } - // shift the rest nodes (place from the first loop position) - for (iC = curLast + 1; iC < nbSimple; iC++) { - simpleNodes[iC - loopLen] = simpleNodes[iC]; + nodeIndices.insert( make_pair( faceNodes[0], 0 )); + simpleNodes.push_back( faceNodes[0] ); + for ( int iCur = 1; iCur < nbNodes; iCur++ ) + { + if ( faceNodes[ iCur ] != simpleNodes.back() ) + { + int index = simpleNodes.size(); + nInd = nodeIndices.insert( make_pair( faceNodes[ iCur ], index )).first; + int prevIndex = nInd->second; + if ( prevIndex < index ) + { + // a sub-loop found + int loopLen = index - prevIndex; + if ( loopLen > 2 ) + { + // store the sub-loop + quantities.push_back( loopLen ); + for ( int i = prevIndex; i < index; i++ ) + poly_nodes.push_back( simpleNodes[ i ]); } - nbSimple -= loopLen; - iSimple -= loopLen; + simpleNodes.resize( prevIndex+1 ); + } + else + { + simpleNodes.push_back( faceNodes[ iCur ]); } - } // for (iSimple = 0; iSimple < nbSimple; iSimple++) - } // while (foundLoop) + } + } - if (iSimple > 2) { - nbNew++; - quantities.push_back(iSimple); - for (int i = 0; i < iSimple; i++) - poly_nodes.push_back(simpleNodes[i]); + if ( simpleNodes.size() > 2 ) + { + quantities.push_back( simpleNodes.size() ); + poly_nodes.insert ( poly_nodes.end(), simpleNodes.begin(), simpleNodes.end() ); } - return nbNew; + return quantities.size() - prevNbQuant; } //======================================================================= @@ -7365,6 +7324,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) const SMDS_MeshElement* elem = *eIt; const int nbNodes = elem->NbNodes(); const int aShapeId = FindShape( elem ); + SMDSAbs_EntityType entity = elem->GetEntityType(); nodeSet.clear(); curNodes.resize( nbNodes ); @@ -7390,7 +7350,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) if ( nnIt_i != nodeNodeMap.end() ) { // n sticks n = (*nnIt_i).second; if (!nodesRecur.insert(n).second) { - // error: recursive dependancy + // error: recursive dependency stopRecur = true; } } @@ -7414,9 +7374,9 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) int nbUniqueNodes = nodeSet.size(); if ( nbNodes != nbUniqueNodes ) // some nodes stick { - if (elem->IsPoly()) // Polygons and Polyhedral volumes + if ( elem->IsPoly() ) // Polygons and Polyhedral volumes { - if (elem->GetType() == SMDSAbs_Face) // Polygon + if ( elem->GetType() == SMDSAbs_Face ) // Polygon { elemType.Init( elem ); const bool isQuad = elemType.myIsQuad; @@ -7451,7 +7411,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } elemType.SetPoly(( nbNewNodes / ( elemType.myIsQuad + 1 ) > 4 )); - SMDS_MeshElement* newElem = AddElement( face_nodes, elemType ); + SMDS_MeshElement* newElem = AddElement( face_nodes, elemType.SetID(-1)); if ( aShapeId ) aMesh->SetMeshElementOnShape(newElem, aShapeId); } @@ -7460,53 +7420,53 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } // Polygon - else if (elem->GetType() == SMDSAbs_Volume) // Polyhedral volume + else if ( elem->GetType() == SMDSAbs_Volume ) // Polyhedral volume { - if (nbUniqueNodes < 4) { + if ( nbUniqueNodes < 4 ) { rmElemIds.push_back(elem->GetID()); } else { // each face has to be analyzed in order to check volume validity const SMDS_VtkVolume* aPolyedre = dynamic_cast( elem ); - if (aPolyedre) + if ( aPolyedre ) { int nbFaces = aPolyedre->NbFaces(); vector poly_nodes; - vector quantities; + vector quantities; + vector faceNodes; - for (int iface = 1; iface <= nbFaces; iface++) { + for (int iface = 1; iface <= nbFaces; iface++) + { int nbFaceNodes = aPolyedre->NbFaceNodes(iface); - vector faceNodes (nbFaceNodes); - - for (int inode = 1; inode <= nbFaceNodes; inode++) { + faceNodes.resize( nbFaceNodes ); + for (int inode = 1; inode <= nbFaceNodes; inode++) + { const SMDS_MeshNode * faceNode = aPolyedre->GetFaceNode(iface, inode); TNodeNodeMap::iterator nnIt = nodeNodeMap.find(faceNode); - if (nnIt != nodeNodeMap.end()) { // faceNode sticks + if ( nnIt != nodeNodeMap.end() ) // faceNode sticks faceNode = (*nnIt).second; - } faceNodes[inode - 1] = faceNode; } - SimplifyFace(faceNodes, poly_nodes, quantities); } - if (quantities.size() > 3) { - // to be done: remove coincident faces + if ( quantities.size() > 3 ) { + // TODO: remove coincident faces } - if (quantities.size() > 3) + if ( quantities.size() > 3 ) { const SMDS_MeshElement* newElem = - aMesh->AddPolyhedralVolume(poly_nodes, quantities); - myLastCreatedElems.Append(newElem); + aMesh->AddPolyhedralVolume( poly_nodes, quantities ); + myLastCreatedElems.Append( newElem ); if ( aShapeId && newElem ) aMesh->SetMeshElementOnShape( newElem, aShapeId ); - rmElemIds.push_back(elem->GetID()); + rmElemIds.push_back( elem->GetID() ); } } else { - rmElemIds.push_back(elem->GetID()); + rmElemIds.push_back( elem->GetID() ); } } } @@ -7518,195 +7478,154 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) // Regular elements // TODO not all the possible cases are solved. Find something more generic? - switch ( nbNodes ) { - case 2: ///////////////////////////////////// EDGE - isOk = false; break; - case 3: ///////////////////////////////////// TRIANGLE - isOk = false; break; - case 4: - if ( elem->GetType() == SMDSAbs_Volume ) // TETRAHEDRON + switch ( entity ) { + case SMDSEntity_Edge: //////// EDGE + case SMDSEntity_Triangle: //// TRIANGLE + case SMDSEntity_Quad_Triangle: + case SMDSEntity_Tetra: + case SMDSEntity_Quad_Tetra: // TETRAHEDRON + { + isOk = false; + break; + } + case SMDSEntity_Quad_Edge: + { + isOk = false; // to linear EDGE ??????? + break; + } + case SMDSEntity_Quadrangle: //////////////////////////////////// QUADRANGLE + { + if ( nbUniqueNodes < 3 ) isOk = false; - else { //////////////////////////////////// QUADRANGLE - if ( nbUniqueNodes < 3 ) - isOk = false; - else if ( nbRepl == 2 && iRepl[ 1 ] - iRepl[ 0 ] == 2 ) - isOk = false; // opposite nodes stick - //MESSAGE("isOk " << isOk); + else if ( nbRepl == 1 && curNodes[ iRepl[0]] == curNodes[( iRepl[0]+2 )%4 ]) + isOk = false; // opposite nodes stick + break; + } + case SMDSEntity_Quad_Quadrangle: // Quadratic QUADRANGLE + { + // 1 5 2 + // +---+---+ + // | | + // 4+ +6 + // | | + // +---+---+ + // 0 7 3 + if (( nbUniqueNodes == 6 && nbRepl == 2 ) && + (( iRepl[0] == 1 && iRepl[1] == 4 && curNodes[1] == curNodes[0] ) || + ( iRepl[0] == 2 && iRepl[1] == 5 && curNodes[2] == curNodes[1] ) || + ( iRepl[0] == 3 && iRepl[1] == 6 && curNodes[3] == curNodes[2] ) || + ( iRepl[0] == 3 && iRepl[1] == 7 && curNodes[3] == curNodes[0] ))) + { + isOk = true; + } + break; + } + case SMDSEntity_BiQuad_Quadrangle: // Bi-Quadratic QUADRANGLE + { + // 1 5 2 + // +---+---+ + // | | + // 4+ 8+ +6 + // | | + // +---+---+ + // 0 7 3 + if (( nbUniqueNodes == 7 && nbRepl == 2 && iRepl[1] != 8 ) && + (( iRepl[0] == 1 && iRepl[1] == 4 && curNodes[1] == curNodes[0] ) || + ( iRepl[0] == 2 && iRepl[1] == 5 && curNodes[2] == curNodes[1] ) || + ( iRepl[0] == 3 && iRepl[1] == 6 && curNodes[3] == curNodes[2] ) || + ( iRepl[0] == 3 && iRepl[1] == 7 && curNodes[3] == curNodes[0] ))) + { + isOk = true; } break; - case 6: ///////////////////////////////////// PENTAHEDRON + } + case SMDSEntity_Penta: ///////////////////////////////////// PENTAHEDRON + { + isOk = false; if ( nbUniqueNodes == 4 ) { // ---------------------------------> tetrahedron - if (nbRepl == 3 && - iRepl[ 0 ] > 2 && iRepl[ 1 ] > 2 && iRepl[ 2 ] > 2 ) { - // all top nodes stick: reverse a bottom - uniqueNodes[ 0 ] = curNodes [ 1 ]; - uniqueNodes[ 1 ] = curNodes [ 0 ]; + if ( curNodes[3] == curNodes[4] && + curNodes[3] == curNodes[5] ) { + // top nodes stick + isOk = true; } - else if (nbRepl == 3 && - iRepl[ 0 ] < 3 && iRepl[ 1 ] < 3 && iRepl[ 2 ] < 3 ) { - // all bottom nodes stick: set a top before + else if ( curNodes[0] == curNodes[1] && + curNodes[0] == curNodes[2] ) { + // bottom nodes stick: set a top before uniqueNodes[ 3 ] = uniqueNodes [ 0 ]; - uniqueNodes[ 0 ] = curNodes [ 3 ]; + uniqueNodes[ 0 ] = curNodes [ 5 ]; uniqueNodes[ 1 ] = curNodes [ 4 ]; - uniqueNodes[ 2 ] = curNodes [ 5 ]; + uniqueNodes[ 2 ] = curNodes [ 3 ]; + isOk = true; } - else if (nbRepl == 4 && - iRepl[ 2 ] - iRepl [ 0 ] == 3 && iRepl[ 3 ] - iRepl [ 1 ] == 3 ) { - // a lateral face turns into a line: reverse a bottom - uniqueNodes[ 0 ] = curNodes [ 1 ]; - uniqueNodes[ 1 ] = curNodes [ 0 ]; + else if (( curNodes[0] == curNodes[3] ) + + ( curNodes[1] == curNodes[4] ) + + ( curNodes[2] == curNodes[5] ) == 2 ) { + // a lateral face turns into a line + isOk = true; } - else - isOk = false; } else if ( nbUniqueNodes == 5 ) { - // PENTAHEDRON --------------------> 2 tetrahedrons - if ( nbRepl == 2 && iRepl[ 1 ] - iRepl [ 0 ] == 3 ) { - // a bottom node sticks with a linked top one - // 1. - SMDS_MeshElement* newElem = - aMesh->AddVolume(curNodes[ 3 ], - curNodes[ 4 ], - curNodes[ 5 ], - curNodes[ iRepl[ 0 ] == 2 ? 1 : 2 ]); - myLastCreatedElems.Append(newElem); - if ( aShapeId ) - aMesh->SetMeshElementOnShape( newElem, aShapeId ); - // 2. : reverse a bottom - uniqueNodes[ 0 ] = curNodes [ 1 ]; - uniqueNodes[ 1 ] = curNodes [ 0 ]; - nbUniqueNodes = 4; - } - else - isOk = false; - } - else - isOk = false; - break; - case 8: { - if(elem->IsQuadratic()) { // Quadratic quadrangle - // 1 5 2 - // +---+---+ - // | | - // | | - // 4+ +6 - // | | - // | | - // +---+---+ - // 0 7 3 - isOk = false; - if(nbRepl==2) { - MESSAGE("nbRepl=2: " << iRepl[0] << " " << iRepl[1]); - } - if(nbRepl==3) { - MESSAGE("nbRepl=3: " << iRepl[0] << " " << iRepl[1] << " " << iRepl[2]); - nbUniqueNodes = 6; - if( iRepl[0]==0 && iRepl[1]==1 && iRepl[2]==4 ) { - uniqueNodes[0] = curNodes[0]; - uniqueNodes[1] = curNodes[2]; - uniqueNodes[2] = curNodes[3]; - uniqueNodes[3] = curNodes[5]; - uniqueNodes[4] = curNodes[6]; - uniqueNodes[5] = curNodes[7]; - isOk = true; - } - if( iRepl[0]==0 && iRepl[1]==3 && iRepl[2]==7 ) { - uniqueNodes[0] = curNodes[0]; - uniqueNodes[1] = curNodes[1]; - uniqueNodes[2] = curNodes[2]; - uniqueNodes[3] = curNodes[4]; - uniqueNodes[4] = curNodes[5]; - uniqueNodes[5] = curNodes[6]; - isOk = true; - } - if( iRepl[0]==0 && iRepl[1]==4 && iRepl[2]==7 ) { - uniqueNodes[0] = curNodes[1]; - uniqueNodes[1] = curNodes[2]; - uniqueNodes[2] = curNodes[3]; - uniqueNodes[3] = curNodes[5]; - uniqueNodes[4] = curNodes[6]; - uniqueNodes[5] = curNodes[0]; - isOk = true; - } - if( iRepl[0]==1 && iRepl[1]==2 && iRepl[2]==5 ) { - uniqueNodes[0] = curNodes[0]; - uniqueNodes[1] = curNodes[1]; - uniqueNodes[2] = curNodes[3]; - uniqueNodes[3] = curNodes[4]; - uniqueNodes[4] = curNodes[6]; - uniqueNodes[5] = curNodes[7]; - isOk = true; - } - if( iRepl[0]==1 && iRepl[1]==4 && iRepl[2]==5 ) { - uniqueNodes[0] = curNodes[0]; - uniqueNodes[1] = curNodes[2]; - uniqueNodes[2] = curNodes[3]; - uniqueNodes[3] = curNodes[1]; - uniqueNodes[4] = curNodes[6]; - uniqueNodes[5] = curNodes[7]; - isOk = true; - } - if( iRepl[0]==2 && iRepl[1]==3 && iRepl[2]==6 ) { - uniqueNodes[0] = curNodes[0]; - uniqueNodes[1] = curNodes[1]; - uniqueNodes[2] = curNodes[2]; - uniqueNodes[3] = curNodes[4]; - uniqueNodes[4] = curNodes[5]; - uniqueNodes[5] = curNodes[7]; - isOk = true; - } - if( iRepl[0]==2 && iRepl[1]==5 && iRepl[2]==6 ) { - uniqueNodes[0] = curNodes[0]; - uniqueNodes[1] = curNodes[1]; - uniqueNodes[2] = curNodes[3]; - uniqueNodes[3] = curNodes[4]; - uniqueNodes[4] = curNodes[2]; - uniqueNodes[5] = curNodes[7]; - isOk = true; - } - if( iRepl[0]==3 && iRepl[1]==6 && iRepl[2]==7 ) { - uniqueNodes[0] = curNodes[0]; - uniqueNodes[1] = curNodes[1]; - uniqueNodes[2] = curNodes[2]; - uniqueNodes[3] = curNodes[4]; - uniqueNodes[4] = curNodes[5]; - uniqueNodes[5] = curNodes[3]; - isOk = true; - } + // PENTAHEDRON --------------------> pyramid + if ( curNodes[0] == curNodes[3] ) + { + uniqueNodes[ 0 ] = curNodes[ 1 ]; + uniqueNodes[ 1 ] = curNodes[ 4 ]; + uniqueNodes[ 2 ] = curNodes[ 5 ]; + uniqueNodes[ 3 ] = curNodes[ 2 ]; + uniqueNodes[ 4 ] = curNodes[ 0 ]; + isOk = true; } - if(nbRepl==4) { - MESSAGE("nbRepl=4: " << iRepl[0] << " " << iRepl[1] << " " << iRepl[2] << " " << iRepl[3]); + if ( curNodes[1] == curNodes[4] ) + { + uniqueNodes[ 0 ] = curNodes[ 0 ]; + uniqueNodes[ 1 ] = curNodes[ 2 ]; + uniqueNodes[ 2 ] = curNodes[ 5 ]; + uniqueNodes[ 3 ] = curNodes[ 3 ]; + uniqueNodes[ 4 ] = curNodes[ 1 ]; + isOk = true; } - if(nbRepl==5) { - MESSAGE("nbRepl=5: " << iRepl[0] << " " << iRepl[1] << " " << iRepl[2] << " " << iRepl[3] << " " << iRepl[4]); + if ( curNodes[2] == curNodes[5] ) + { + uniqueNodes[ 0 ] = curNodes[ 0 ]; + uniqueNodes[ 1 ] = curNodes[ 3 ]; + uniqueNodes[ 2 ] = curNodes[ 4 ]; + uniqueNodes[ 3 ] = curNodes[ 1 ]; + uniqueNodes[ 4 ] = curNodes[ 2 ]; + isOk = true; } - break; } + break; + } + case SMDSEntity_Hexa: + { //////////////////////////////////// HEXAHEDRON isOk = false; SMDS_VolumeTool hexa (elem); hexa.SetExternalNormal(); if ( nbUniqueNodes == 4 && nbRepl == 4 ) { - //////////////////////// HEX ---> 1 tetrahedron + //////////////////////// HEX ---> tetrahedron for ( int iFace = 0; iFace < 6; iFace++ ) { const int *ind = hexa.GetFaceNodesIndices( iFace ); // indices of face nodes if (curNodes[ind[ 0 ]] == curNodes[ind[ 1 ]] && curNodes[ind[ 0 ]] == curNodes[ind[ 2 ]] && curNodes[ind[ 0 ]] == curNodes[ind[ 3 ]] ) { // one face turns into a point ... + int pickInd = ind[ 0 ]; int iOppFace = hexa.GetOppFaceIndex( iFace ); ind = hexa.GetFaceNodesIndices( iOppFace ); int nbStick = 0; + uniqueNodes.clear(); for ( iCur = 0; iCur < 4 && nbStick < 2; iCur++ ) { if ( curNodes[ind[ iCur ]] == curNodes[ind[ iCur + 1 ]] ) nbStick++; + else + uniqueNodes.push_back( curNodes[ind[ iCur ]]); } if ( nbStick == 1 ) { // ... and the opposite one - into a triangle. // set a top node - ind = hexa.GetFaceNodesIndices( iFace ); - uniqueNodes[ 3 ] = curNodes[ind[ 0 ]]; + uniqueNodes.push_back( curNodes[ pickInd ]); isOk = true; } break; @@ -7714,7 +7633,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } } else if ( nbUniqueNodes == 6 && nbRepl == 2 ) { - //////////////////////// HEX ---> 1 prism + //////////////////////// HEX ---> prism int nbTria = 0, iTria[3]; const int *ind; // indices of face nodes // look for triangular faces @@ -7729,7 +7648,6 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) // check if triangles are opposite if ( nbTria == 2 && iTria[0] == hexa.GetOppFaceIndex( iTria[1] )) { - isOk = true; // set nodes of the bottom triangle ind = hexa.GetFaceNodesIndices( iTria[ 0 ]); vector indB; @@ -7749,11 +7667,12 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) uniqueNodes[ iCur + 3 ] = curNodes[ indT[ j ]]; break; } + isOk = true; + break; } - break; } - else if (nbUniqueNodes == 5 && nbRepl == 4 ) { - //////////////////// HEXAHEDRON ---> 2 tetrahedrons + else if (nbUniqueNodes == 5 && nbRepl == 3 ) { + //////////////////// HEXAHEDRON ---> pyramid for ( int iFace = 0; iFace < 6; iFace++ ) { const int *ind = hexa.GetFaceNodesIndices( iFace ); // indices of face nodes if (curNodes[ind[ 0 ]] == curNodes[ind[ 1 ]] && @@ -7762,139 +7681,61 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) // one face turns into a point ... int iOppFace = hexa.GetOppFaceIndex( iFace ); ind = hexa.GetFaceNodesIndices( iOppFace ); - int nbStick = 0; - iUnique = 2; // reverse a tetrahedron 1 bottom - for ( iCur = 0; iCur < 4 && nbStick == 0; iCur++ ) { + uniqueNodes.clear(); + for ( iCur = 0; iCur < 4; iCur++ ) { if ( curNodes[ind[ iCur ]] == curNodes[ind[ iCur + 1 ]] ) - nbStick++; - else if ( iUnique >= 0 ) - uniqueNodes[ iUnique-- ] = curNodes[ind[ iCur ]]; + break; + else + uniqueNodes.push_back( curNodes[ind[ iCur ]]); } - if ( nbStick == 0 ) { + if ( uniqueNodes.size() == 4 ) { // ... and the opposite one is a quadrangle // set a top node const int* indTop = hexa.GetFaceNodesIndices( iFace ); - uniqueNodes[ 3 ] = curNodes[indTop[ 0 ]]; - nbUniqueNodes = 4; - // tetrahedron 2 - SMDS_MeshElement* newElem = - aMesh->AddVolume(curNodes[ind[ 0 ]], - curNodes[ind[ 3 ]], - curNodes[ind[ 2 ]], - curNodes[indTop[ 0 ]]); - myLastCreatedElems.Append(newElem); - if ( aShapeId ) - aMesh->SetMeshElementOnShape( newElem, aShapeId ); + uniqueNodes.push_back( curNodes[indTop[ 0 ]]); isOk = true; } break; } } } - else if ( nbUniqueNodes == 6 && nbRepl == 4 ) { - ////////////////// HEXAHEDRON ---> 2 tetrahedrons or 1 prism - // find indices of quad and tri faces - int iQuadFace[ 6 ], iTriFace[ 6 ], nbQuad = 0, nbTri = 0, iFace; - for ( iFace = 0; iFace < 6; iFace++ ) { + + if ( !isOk && nbUniqueNodes > 4 ) { + ////////////////// HEXAHEDRON ---> polyhedron + hexa.SetExternalNormal(); + vector poly_nodes; poly_nodes.reserve( 6 * 4 ); + vector quantities; quantities.reserve( 6 ); + for ( int iFace = 0; iFace < 6; iFace++ ) + { const int *ind = hexa.GetFaceNodesIndices( iFace ); // indices of face nodes + if ( curNodes[ind[0]] == curNodes[ind[2]] || + curNodes[ind[1]] == curNodes[ind[3]] ) + { + quantities.clear(); + break; // opposite nodes stick + } nodeSet.clear(); for ( iCur = 0; iCur < 4; iCur++ ) - nodeSet.insert( curNodes[ind[ iCur ]] ); - nbUniqueNodes = nodeSet.size(); - if ( nbUniqueNodes == 3 ) - iTriFace[ nbTri++ ] = iFace; - else if ( nbUniqueNodes == 4 ) - iQuadFace[ nbQuad++ ] = iFace; - } - if (nbQuad == 2 && nbTri == 4 && - hexa.GetOppFaceIndex( iQuadFace[ 0 ] ) == iQuadFace[ 1 ]) { - // 2 opposite quadrangles stuck with a diagonal; - // sample groups of merged indices: (0-4)(2-6) - // --------------------------------------------> 2 tetrahedrons - const int *ind1 = hexa.GetFaceNodesIndices( iQuadFace[ 0 ]); // indices of quad1 nodes - const int *ind2 = hexa.GetFaceNodesIndices( iQuadFace[ 1 ]); - int i0, i1d, i2, i3d, i0t, i2t; // d-daigonal, t-top - if (curNodes[ind1[ 0 ]] == curNodes[ind2[ 0 ]] && - curNodes[ind1[ 2 ]] == curNodes[ind2[ 2 ]]) { - // stuck with 0-2 diagonal - i0 = ind1[ 3 ]; - i1d = ind1[ 0 ]; - i2 = ind1[ 1 ]; - i3d = ind1[ 2 ]; - i0t = ind2[ 1 ]; - i2t = ind2[ 3 ]; - } - else if (curNodes[ind1[ 1 ]] == curNodes[ind2[ 3 ]] && - curNodes[ind1[ 3 ]] == curNodes[ind2[ 1 ]]) { - // stuck with 1-3 diagonal - i0 = ind1[ 0 ]; - i1d = ind1[ 1 ]; - i2 = ind1[ 2 ]; - i3d = ind1[ 3 ]; - i0t = ind2[ 0 ]; - i2t = ind2[ 1 ]; - } - else { - ASSERT(0); + { + if ( nodeSet.insert( curNodes[ind[ iCur ]] ).second ) + poly_nodes.push_back( curNodes[ind[ iCur ]]); } - // tetrahedron 1 - uniqueNodes[ 0 ] = curNodes [ i0 ]; - uniqueNodes[ 1 ] = curNodes [ i1d ]; - uniqueNodes[ 2 ] = curNodes [ i3d ]; - uniqueNodes[ 3 ] = curNodes [ i0t ]; - nbUniqueNodes = 4; - // tetrahedron 2 - SMDS_MeshElement* newElem = aMesh->AddVolume(curNodes[ i1d ], - curNodes[ i2 ], - curNodes[ i3d ], - curNodes[ i2t ]); - myLastCreatedElems.Append(newElem); - if ( aShapeId ) - aMesh->SetMeshElementOnShape( newElem, aShapeId ); - isOk = true; + if ( nodeSet.size() < 3 ) + poly_nodes.resize( poly_nodes.size() - nodeSet.size() ); + else + quantities.push_back( nodeSet.size() ); } - else if (( nbTri == 2 && nbQuad == 3 ) || // merged (0-4)(1-5) - ( nbTri == 4 && nbQuad == 2 )) { // merged (7-4)(1-5) - // --------------------------------------------> prism - // find 2 opposite triangles - nbUniqueNodes = 6; - for ( iFace = 0; iFace + 1 < nbTri; iFace++ ) { - if ( hexa.GetOppFaceIndex( iTriFace[ iFace ] ) == iTriFace[ iFace + 1 ]) { - // find indices of kept and replaced nodes - // and fill unique nodes of 2 opposite triangles - const int *ind1 = hexa.GetFaceNodesIndices( iTriFace[ iFace ]); - const int *ind2 = hexa.GetFaceNodesIndices( iTriFace[ iFace + 1 ]); - const SMDS_MeshNode** hexanodes = hexa.GetNodes(); - // fill unique nodes - iUnique = 0; - isOk = true; - for ( iCur = 0; iCur < 4 && isOk; iCur++ ) { - const SMDS_MeshNode* n = curNodes[ind1[ iCur ]]; - const SMDS_MeshNode* nInit = hexanodes[ind1[ iCur ]]; - if ( n == nInit ) { - // iCur of a linked node of the opposite face (make normals co-directed): - int iCurOpp = ( iCur == 1 || iCur == 3 ) ? 4 - iCur : iCur; - // check that correspondent corners of triangles are linked - if ( !hexa.IsLinked( ind1[ iCur ], ind2[ iCurOpp ] )) - isOk = false; - else { - uniqueNodes[ iUnique ] = n; - uniqueNodes[ iUnique + 3 ] = curNodes[ind2[ iCurOpp ]]; - iUnique++; - } - } - } - break; - } - } + if ( quantities.size() >= 4 ) + { + const SMDS_MeshElement* newElem = aMesh->AddPolyhedralVolume( poly_nodes, quantities ); + myLastCreatedElems.Append( newElem ); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + rmElemIds.push_back( elem->GetID() ); } - } // if ( nbUniqueNodes == 6 && nbRepl == 4 ) - else - { - MESSAGE("MergeNodes() removes hexahedron "<< elem); } break; - } // HEXAHEDRON + } // case HEXAHEDRON default: isOk = false; @@ -7902,7 +7743,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } // if ( nbNodes != nbUniqueNodes ) // some nodes stick - if ( isOk ) // the non-poly elem remains valid after sticking nodes + if ( isOk ) // a non-poly elem remains valid after sticking nodes { if ( nbNodes != nbUniqueNodes || !aMesh->ChangeElementNodes( elem, & curNodes[0], nbNodes )) @@ -8524,7 +8365,7 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode, // sew the border to the side 2 // ============================ - int nbNodes[] = { nSide[0].size(), nSide[1].size() }; + int nbNodes[] = { (int)nSide[0].size(), (int)nSide[1].size() }; int maxNbNodes = Max( nbNodes[0], nbNodes[1] ); bool toMergeConformal = ( nbNodes[0] == nbNodes[1] ); @@ -8997,8 +8838,8 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theElemen // create new elements i1 = 0; i2 = 1; - for ( iSplit = 0; iSplit < nbSplits - 1; iSplit++ ) { - SMDS_MeshElement* newElem = 0; + for ( iSplit = 0; iSplit < nbSplits - 1; iSplit++ ) + { if ( iSplit == iBestQuad ) newElems.push_back( aMesh->AddFace (linkNodes[ i1++ ], linkNodes[ i2++ ], @@ -11093,16 +10934,16 @@ bool SMESH_MeshEditor::DoubleNodesInRegion( const TIDSortedElemSet& theElems, return false; const double aTol = Precision::Confusion(); - auto_ptr< BRepClass3d_SolidClassifier> bsc3d; - auto_ptr<_FaceClassifier> aFaceClassifier; + SMESHUtils::Deleter< BRepClass3d_SolidClassifier> bsc3d; + SMESHUtils::Deleter<_FaceClassifier> aFaceClassifier; if ( theShape.ShapeType() == TopAbs_SOLID ) { - bsc3d.reset( new BRepClass3d_SolidClassifier(theShape));; + bsc3d._obj = new BRepClass3d_SolidClassifier( theShape ); bsc3d->PerformInfinitePoint(aTol); } else if (theShape.ShapeType() == TopAbs_FACE ) { - aFaceClassifier.reset( new _FaceClassifier(TopoDS::Face(theShape))); + aFaceClassifier._obj = new _FaceClassifier( TopoDS::Face( theShape )); } // iterates on indicated elements and get elements by back references from their nodes @@ -11125,7 +10966,7 @@ bool SMESH_MeshEditor::DoubleNodesInRegion( const TIDSortedElemSet& theElems, { const SMDS_MeshElement* curElem = backElemItr->next(); if ( curElem && theElems.find(curElem) == theElems.end() && - ( bsc3d.get() ? + ( bsc3d ? isInside( curElem, *bsc3d, aTol ) : isInside( curElem, *aFaceClassifier, aTol ))) anAffected.insert( curElem ); @@ -11217,83 +11058,84 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector volume to modify) - // with all the faces shared by 2 domains (group of elements) - // and corresponding volume of this domain, for each shared face. - // a volume has a face shared by 2 domains if it has a neighbor which is not in his domain. + // --- build a map (face to duplicate --> volume to modify) + // with all the faces shared by 2 domains (group of elements) + // and corresponding volume of this domain, for each shared face. + // a volume has a face shared by 2 domains if it has a neighbor which is not in his domain. - MESSAGE("... Neighbors of domain #" << idom); - const TIDSortedElemSet& domain = theElems[idom]; - TIDSortedElemSet::const_iterator elemItr = domain.begin(); - for (; elemItr != domain.end(); ++elemItr) + MESSAGE("... Neighbors of domain #" << idom); + const TIDSortedElemSet& domain = theElems[idom]; + TIDSortedElemSet::const_iterator elemItr = domain.begin(); + for (; elemItr != domain.end(); ++elemItr) + { + const SMDS_MeshElement* anElem = *elemItr; + if (!anElem) + continue; + int vtkId = anElem->getVtkId(); + //MESSAGE(" vtkId " << vtkId << " smdsId " << anElem->GetID()); + int neighborsVtkIds[NBMAXNEIGHBORS]; + int downIds[NBMAXNEIGHBORS]; + unsigned char downTypes[NBMAXNEIGHBORS]; + int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId); + for (int n = 0; n < nbNeighbors; n++) + { + int smdsId = meshDS->fromVtkToSmds(neighborsVtkIds[n]); + const SMDS_MeshElement* elem = meshDS->FindElement(smdsId); + if (elem && ! domain.count(elem)) // neighbor is in another domain : face is shared { - const SMDS_MeshElement* anElem = *elemItr; - if (!anElem) - continue; - int vtkId = anElem->getVtkId(); - //MESSAGE(" vtkId " << vtkId << " smdsId " << anElem->GetID()); - int neighborsVtkIds[NBMAXNEIGHBORS]; - int downIds[NBMAXNEIGHBORS]; - unsigned char downTypes[NBMAXNEIGHBORS]; - int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId); - for (int n = 0; n < nbNeighbors; n++) + bool ok = false; + for ( size_t idombis = 0; idombis < theElems.size() && !ok; idombis++) // check if the neighbor belongs to another domain of the list + { + // MESSAGE("Domain " << idombis); + const TIDSortedElemSet& domainbis = theElems[idombis]; + if ( domainbis.count(elem)) ok = true ; // neighbor is in a correct domain : face is kept + } + if ( ok || onAllBoundaries ) // the characteristics of the face is stored + { + DownIdType face(downIds[n], downTypes[n]); + if (!faceDomains[face].count(idom)) { - int smdsId = meshDS->fromVtkToSmds(neighborsVtkIds[n]); - const SMDS_MeshElement* elem = meshDS->FindElement(smdsId); - if (elem && ! domain.count(elem)) // neighbor is in another domain : face is shared - { - bool ok = false ; - for (int idombis = 0; idombis < theElems.size() && !ok; idombis++) // check if the neighbor belongs to another domain of the list - { - // MESSAGE("Domain " << idombis); - const TIDSortedElemSet& domainbis = theElems[idombis]; - if ( domainbis.count(elem)) ok = true ; // neighbor is in a correct domain : face is kept - } - if ( ok || onAllBoundaries ) // the characteristics of the face is stored - { - DownIdType face(downIds[n], downTypes[n]); - if (!faceDomains[face].count(idom)) - { - faceDomains[face][idom] = vtkId; // volume associated to face in this domain - celldom[vtkId] = idom; - //MESSAGE(" cell with a border " << vtkId << " domain " << idom); - } - if ( !ok ) - { - theRestDomElems.insert( elem ); - faceDomains[face][iRestDom] = neighborsVtkIds[n]; - celldom[neighborsVtkIds[n]] = iRestDom; - } - } - } + faceDomains[face][idom] = vtkId; // volume associated to face in this domain + celldom[vtkId] = idom; + //MESSAGE(" cell with a border " << vtkId << " domain " << idom); + } + if ( !ok ) + { + theRestDomElems.insert( elem ); + faceDomains[face][iRestDom] = neighborsVtkIds[n]; + celldom[neighborsVtkIds[n]] = iRestDom; } + } } + } } + } //MESSAGE("Number of shared faces " << faceDomains.size()); std::map, DownIdCompare>::iterator itface; @@ -11303,48 +11145,48 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector& 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); + vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId); + for (int i=0; i& domvol = itface->second; - if (!domvol.count(idomain)) + int vtkId = l.cells[i]; + const SMDS_MeshElement* anElem = GetMeshDS()->FindElement(GetMeshDS()->fromVtkToSmds(vtkId)); + if (!domain.count(anElem)) 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); - 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); - if (downId < 0) - { - MESSAGE("doubleNodesOnGroupBoundaries: internal algorithm problem"); - continue; // not OK at this stage of the algorithm: - //no cells created after BuildDownWardConnectivity - } - DownIdType aCell(downId, vtkType); - cellDomains[aCell][idomain] = vtkId; - celldom[vtkId] = idomain; - //MESSAGE(" cell " << vtkId << " domain " << idomain); - } - } + int vtkType = grid->GetCellType(vtkId); + int downId = grid->CellIdToDownId(vtkId); + if (downId < 0) + { + MESSAGE("doubleNodesOnGroupBoundaries: internal algorithm problem"); + continue; // not OK at this stage of the algorithm: + //no cells created after BuildDownWardConnectivity + } + DownIdType aCell(downId, vtkType); + cellDomains[aCell][idomain] = vtkId; + celldom[vtkId] = idomain; + //MESSAGE(" cell " << vtkId << " domain " << idomain); } + } } + } // --- explore the shared faces domain by domain, to duplicate the nodes in a coherent way // for each shared face, get the nodes @@ -11360,185 +11202,185 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector& 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; + if (nodeDomains[oldId].empty()) { - const 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) + nodeDomains[oldId][idomain] = oldId; // keep the old node in the first domain + //MESSAGE("-+-+-b oldNode " << oldId << " domain " << idomain); + } + std::map::const_iterator itdom = domvol.begin(); + for (; itdom != domvol.end(); ++itdom) + { + int idom = itdom->first; + //MESSAGE(" domain " << idom); + if (!nodeDomains[oldId].count(idom)) // --- node to clone + { + if (nodeDomains[oldId].size() >= 2) // a multiple node { - int oldId = *itn; - if (nodeDomains[oldId].empty()) - { - nodeDomains[oldId][idomain] = oldId; // keep the old node in the first domain - //MESSAGE("-+-+-b oldNode " << oldId << " domain " << idomain); - } - std::map::const_iterator itdom = domvol.begin(); - for (; itdom != domvol.end(); ++itdom) - { - int idom = itdom->first; - //MESSAGE(" domain " << idom); - if (!nodeDomains[oldId].count(idom)) // --- node to clone - { - if (nodeDomains[oldId].size() >= 2) // a multiple node - { - vector orderedDoms; - //MESSAGE("multiple node " << oldId); - if (mutipleNodes.count(oldId)) - orderedDoms = mutipleNodes[oldId]; - else - { - map::iterator it = nodeDomains[oldId].begin(); - for (; it != nodeDomains[oldId].end(); ++it) - orderedDoms.push_back(it->first); - } - orderedDoms.push_back(idom); // TODO order ==> push_front or back - //stringstream txt; - //for (int i=0; iGetPoint(oldId); - SMDS_MeshNode *newNode = meshDS->AddNode(coords[0], coords[1], coords[2]); - copyPosition( meshDS->FindNodeVtk( oldId ), newNode ); - int newId = newNode->getVtkId(); - nodeDomains[oldId][idom] = newId; // cloned node for other domains - //MESSAGE("-+-+-c oldNode " << oldId << " domain " << idomain << " newNode " << newId << " domain " << idom << " size=" < orderedDoms; + //MESSAGE("multiple node " << oldId); + if (mutipleNodes.count(oldId)) + orderedDoms = mutipleNodes[oldId]; + else + { + map::iterator it = nodeDomains[oldId].begin(); + for (; it != nodeDomains[oldId].end(); ++it) + orderedDoms.push_back(it->first); + } + orderedDoms.push_back(idom); // TODO order ==> push_front or back + //stringstream txt; + //for (int i=0; iGetPoint(oldId); + SMDS_MeshNode *newNode = meshDS->AddNode(coords[0], coords[1], coords[2]); + copyPosition( meshDS->FindNodeVtk( oldId ), newNode ); + int newId = newNode->getVtkId(); + nodeDomains[oldId][idom] = newId; // cloned node for other domains + //MESSAGE("-+-+-c oldNode " << oldId << " domain " << idomain << " newNode " << newId << " domain " << idom << " size=" < 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); + int nbMultipleNodes = 0; + std::set::iterator itn = oldNodes.begin(); + for (; itn != oldNodes.end(); ++itn) + { + int oldId = *itn; + if (mutipleNodes.count(oldId)) + nbMultipleNodes++; + } + if (nbMultipleNodes > 1) // check if an edge of the face is shared between 3 or more domains + { + //MESSAGE("multiple Nodes detected on a shared face"); + int downId = itface->first.cellId; + unsigned char cellType = itface->first.cellType; + // --- shared edge or shared face ? + if ((cellType == VTK_LINE) || (cellType == VTK_QUADRATIC_EDGE)) // shared edge (between two faces) { - 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); - int nbMultipleNodes = 0; - std::set::iterator itn = oldNodes.begin(); - for (; itn != oldNodes.end(); ++itn) - { - int oldId = *itn; - if (mutipleNodes.count(oldId)) - nbMultipleNodes++; - } - if (nbMultipleNodes > 1) // check if an edge of the face is shared between 3 or more domains + int nodes[3]; + int nbNodes = grid->getDownArray(cellType)->getNodes(downId, nodes); + for (int i=0; i< nbNodes; i=i+nbNodes-1) // i=0 , i=nbNodes-1 + if (mutipleNodes.count(nodes[i])) + if (!mutipleNodesToFace.count(nodes[i])) + mutipleNodesToFace[nodes[i]] = mutipleNodes[nodes[i]]; + } + else // shared face (between two volumes) + { + int nbEdges = grid->getDownArray(cellType)->getNumberOfDownCells(downId); + const int* downEdgeIds = grid->getDownArray(cellType)->getDownCells(downId); + const unsigned char* edgeType = grid->getDownArray(cellType)->getDownTypes(downId); + for (int ie =0; ie < nbEdges; ie++) + { + int nodes[3]; + int nbNodes = grid->getDownArray(edgeType[ie])->getNodes(downEdgeIds[ie], nodes); + if ( mutipleNodes.count(nodes[0]) && mutipleNodes.count( nodes[ nbNodes-1 ])) { - //MESSAGE("multiple Nodes detected on a shared face"); - int downId = itface->first.cellId; - unsigned char cellType = itface->first.cellType; - // --- shared edge or shared face ? - if ((cellType == VTK_LINE) || (cellType == VTK_QUADRATIC_EDGE)) // shared edge (between two faces) - { - int nodes[3]; - int nbNodes = grid->getDownArray(cellType)->getNodes(downId, nodes); - for (int i=0; i< nbNodes; i=i+nbNodes-1) // i=0 , i=nbNodes-1 - if (mutipleNodes.count(nodes[i])) - if (!mutipleNodesToFace.count(nodes[i])) - mutipleNodesToFace[nodes[i]] = mutipleNodes[nodes[i]]; - } - else // shared face (between two volumes) + vector vn0 = mutipleNodes[nodes[0]]; + vector vn1 = mutipleNodes[nodes[nbNodes - 1]]; + vector doms; + for ( size_t i0 = 0; i0 < vn0.size(); i0++ ) + for ( size_t i1 = 0; i1 < vn1.size(); i1++ ) + if ( vn0[i0] == vn1[i1] ) + doms.push_back( vn0[ i0 ]); + if ( doms.size() > 2 ) + { + //MESSAGE(" detect edgesMultiDomains " << nodes[0] << " " << nodes[nbNodes - 1]); + double *coords = grid->GetPoint(nodes[0]); + gp_Pnt p0(coords[0], coords[1], coords[2]); + coords = grid->GetPoint(nodes[nbNodes - 1]); + gp_Pnt p1(coords[0], coords[1], coords[2]); + gp_Pnt gref; + int vtkVolIds[1000]; // an edge can belong to a lot of volumes + map domvol; // domain --> a volume with the edge + map angleDom; // oriented angles between planes defined by edge and volume centers + int nbvol = grid->GetParentVolumes(vtkVolIds, downEdgeIds[ie], edgeType[ie]); + for ( size_t id = 0; id < doms.size(); id++ ) { - int nbEdges = grid->getDownArray(cellType)->getNumberOfDownCells(downId); - const int* downEdgeIds = grid->getDownArray(cellType)->getDownCells(downId); - const unsigned char* edgeType = grid->getDownArray(cellType)->getDownTypes(downId); - for (int ie =0; ie < nbEdges; ie++) + int idom = doms[id]; + const TIDSortedElemSet& domain = (idom == iRestDom) ? theRestDomElems : theElems[idom]; + for ( int ivol = 0; ivol < nbvol; ivol++ ) + { + int smdsId = meshDS->fromVtkToSmds(vtkVolIds[ivol]); + SMDS_MeshElement* elem = (SMDS_MeshElement*)meshDS->FindElement(smdsId); + if (domain.count(elem)) { - int nodes[3]; - int nbNodes = grid->getDownArray(edgeType[ie])->getNodes(downEdgeIds[ie], nodes); - if (mutipleNodes.count(nodes[0]) && mutipleNodes.count(nodes[nbNodes-1])) - { - vector vn0 = mutipleNodes[nodes[0]]; - vector vn1 = mutipleNodes[nodes[nbNodes - 1]]; - vector doms; - for (int i0 = 0; i0 < vn0.size(); i0++) - for (int i1 = 0; i1 < vn1.size(); i1++) - if (vn0[i0] == vn1[i1]) - doms.push_back(vn0[i0]); - if (doms.size() >2) - { - //MESSAGE(" detect edgesMultiDomains " << nodes[0] << " " << nodes[nbNodes - 1]); - double *coords = grid->GetPoint(nodes[0]); - gp_Pnt p0(coords[0], coords[1], coords[2]); - coords = grid->GetPoint(nodes[nbNodes - 1]); - gp_Pnt p1(coords[0], coords[1], coords[2]); - gp_Pnt gref; - int vtkVolIds[1000]; // an edge can belong to a lot of volumes - map domvol; // domain --> a volume with the edge - map angleDom; // oriented angles between planes defined by edge and volume centers - int nbvol = grid->GetParentVolumes(vtkVolIds, downEdgeIds[ie], edgeType[ie]); - for (int id=0; id < doms.size(); id++) - { - int idom = doms[id]; - const TIDSortedElemSet& domain = (idom == iRestDom) ? theRestDomElems : theElems[idom]; - for (int ivol=0; ivolfromVtkToSmds(vtkVolIds[ivol]); - SMDS_MeshElement* elem = (SMDS_MeshElement*)meshDS->FindElement(smdsId); - if (domain.count(elem)) - { - SMDS_VtkVolume* svol = dynamic_cast(elem); - domvol[idom] = svol; - //MESSAGE(" domain " << idom << " volume " << elem->GetID()); - double values[3]; - vtkIdType npts = 0; - vtkIdType* pts = 0; - grid->GetCellPoints(vtkVolIds[ivol], npts, pts); - SMDS_VtkVolume::gravityCenter(grid, pts, npts, values); - if (id ==0) - { - gref.SetXYZ(gp_XYZ(values[0], values[1], values[2])); - angleDom[idom] = 0; - } - else - { - gp_Pnt g(values[0], values[1], values[2]); - angleDom[idom] = OrientedAngle(p0, p1, gref, g); // -pisecond << " angle " << ib->first); - } - for (int ino = 0; ino < nbNodes; ino++) - vnodes.push_back(nodes[ino]); - edgesMultiDomains[vnodes] = vdom; // nodes vector --> ordered domains - } - } + SMDS_VtkVolume* svol = dynamic_cast(elem); + domvol[idom] = svol; + //MESSAGE(" domain " << idom << " volume " << elem->GetID()); + double values[3]; + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(vtkVolIds[ivol], npts, pts); + SMDS_VtkVolume::gravityCenter(grid, pts, npts, values); + if (id ==0) + { + gref.SetXYZ(gp_XYZ(values[0], values[1], values[2])); + angleDom[idom] = 0; + } + else + { + gp_Pnt g(values[0], values[1], values[2]); + angleDom[idom] = OrientedAngle(p0, p1, gref, g); // -pisecond << " angle " << ib->first); + } + for (int ino = 0; ino < nbNodes; ino++) + vnodes.push_back(nodes[ino]); + edgesMultiDomains[vnodes] = vdom; // nodes vector --> ordered domains + } } + } } + } } + } // --- iterate on shared faces (volumes to modify, face to extrude) // get node id's of the face (id SMDS = id VTK) @@ -11552,50 +11394,50 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectormyMesh->AddGroup(SMDSAbs_Face, joints2DName.c_str(), idg); - SMESHDS_Group *joints2DGrp = dynamic_cast(mapOfJunctionGroups[joints2DName]->GetGroupDS()); - string joints3DName = "joints3D"; - mapOfJunctionGroups[joints3DName] = this->myMesh->AddGroup(SMDSAbs_Volume, joints3DName.c_str(), idg); - SMESHDS_Group *joints3DGrp = dynamic_cast(mapOfJunctionGroups[joints3DName]->GetGroupDS()); - - itface = faceDomains.begin(); - for (; itface != faceDomains.end(); ++itface) - { - DownIdType face = itface->first; - std::set oldNodes; - std::set::iterator itn; - oldNodes.clear(); - grid->GetNodeIds(oldNodes, face.cellId, face.cellType); - - std::map domvol = itface->second; - std::map::iterator itdom = domvol.begin(); - int dom1 = itdom->first; - int vtkVolId = itdom->second; - itdom++; - int dom2 = itdom->first; - SMDS_MeshCell *vol = grid->extrudeVolumeFromFace(vtkVolId, dom1, dom2, oldNodes, nodeDomains, - nodeQuadDomains); - stringstream grpname; - grpname << "j_"; - if (dom1 < dom2) - grpname << dom1 << "_" << dom2; - else - grpname << dom2 << "_" << dom1; - string namegrp = grpname.str(); - if (!mapOfJunctionGroups.count(namegrp)) - mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(vol->GetType(), namegrp.c_str(), idg); - SMESHDS_Group *sgrp = dynamic_cast(mapOfJunctionGroups[namegrp]->GetGroupDS()); - if (sgrp) - sgrp->Add(vol->GetID()); - if (vol->GetType() == SMDSAbs_Volume) - joints3DGrp->Add(vol->GetID()); - else if (vol->GetType() == SMDSAbs_Face) - joints2DGrp->Add(vol->GetID()); - } - } + { + int idg; + string joints2DName = "joints2D"; + mapOfJunctionGroups[joints2DName] = this->myMesh->AddGroup(SMDSAbs_Face, joints2DName.c_str(), idg); + SMESHDS_Group *joints2DGrp = dynamic_cast(mapOfJunctionGroups[joints2DName]->GetGroupDS()); + string joints3DName = "joints3D"; + mapOfJunctionGroups[joints3DName] = this->myMesh->AddGroup(SMDSAbs_Volume, joints3DName.c_str(), idg); + SMESHDS_Group *joints3DGrp = dynamic_cast(mapOfJunctionGroups[joints3DName]->GetGroupDS()); + + itface = faceDomains.begin(); + for (; itface != faceDomains.end(); ++itface) + { + DownIdType face = itface->first; + std::set oldNodes; + std::set::iterator itn; + oldNodes.clear(); + grid->GetNodeIds(oldNodes, face.cellId, face.cellType); + + std::map domvol = itface->second; + std::map::iterator itdom = domvol.begin(); + int dom1 = itdom->first; + int vtkVolId = itdom->second; + itdom++; + int dom2 = itdom->first; + SMDS_MeshCell *vol = grid->extrudeVolumeFromFace(vtkVolId, dom1, dom2, oldNodes, nodeDomains, + nodeQuadDomains); + stringstream grpname; + grpname << "j_"; + if (dom1 < dom2) + grpname << dom1 << "_" << dom2; + else + grpname << dom2 << "_" << dom1; + string namegrp = grpname.str(); + if (!mapOfJunctionGroups.count(namegrp)) + mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(vol->GetType(), namegrp.c_str(), idg); + SMESHDS_Group *sgrp = dynamic_cast(mapOfJunctionGroups[namegrp]->GetGroupDS()); + if (sgrp) + sgrp->Add(vol->GetID()); + if (vol->GetType() == SMDSAbs_Volume) + joints3DGrp->Add(vol->GetID()); + else if (vol->GetType() == SMDSAbs_Face) + joints2DGrp->Add(vol->GetID()); + } + } // --- create volumes on multiple domain intersection if requested // iterate on mutipleNodesToFace @@ -11603,66 +11445,66 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector >::iterator itn = mutipleNodesToFace.begin(); + for (; itn != mutipleNodesToFace.end(); ++itn) { - // --- iterate on mutipleNodesToFace + int node = itn->first; + vector orderDom = itn->second; + vector orderedNodes; + for ( size_t idom = 0; idom < orderDom.size(); idom++ ) + orderedNodes.push_back( nodeDomains[ node ][ orderDom[ idom ]]); + SMDS_MeshFace* face = this->GetMeshDS()->AddFaceFromVtkIds(orderedNodes); - std::map >::iterator itn = mutipleNodesToFace.begin(); - for (; itn != mutipleNodesToFace.end(); ++itn) - { - int node = itn->first; - vector orderDom = itn->second; - vector orderedNodes; - for (int idom = 0; idom GetMeshDS()->AddFaceFromVtkIds(orderedNodes); - - stringstream grpname; - grpname << "m2j_"; - grpname << 0 << "_" << 0; - int idg; - string namegrp = grpname.str(); - if (!mapOfJunctionGroups.count(namegrp)) - mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Face, namegrp.c_str(), idg); - SMESHDS_Group *sgrp = dynamic_cast(mapOfJunctionGroups[namegrp]->GetGroupDS()); - if (sgrp) - sgrp->Add(face->GetID()); - } - - // --- iterate on edgesMultiDomains - - std::map, std::vector >::iterator ite = edgesMultiDomains.begin(); - for (; ite != edgesMultiDomains.end(); ++ite) - { - vector nodes = ite->first; - vector orderDom = ite->second; - vector orderedNodes; - if (nodes.size() == 2) - { - //MESSAGE(" use edgesMultiDomains " << nodes[0] << " " << nodes[1]); - for (int ino=0; ino < nodes.size(); ino++) - if (orderDom.size() == 3) - for (int idom = 0; idom =0; idom--) - orderedNodes.push_back( nodeDomains[nodes[ino]][orderDom[idom]] ); - SMDS_MeshVolume* vol = this->GetMeshDS()->AddVolumeFromVtkIds(orderedNodes); - - int idg; - string namegrp = "jointsMultiples"; - if (!mapOfJunctionGroups.count(namegrp)) - mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Volume, namegrp.c_str(), idg); - SMESHDS_Group *sgrp = dynamic_cast(mapOfJunctionGroups[namegrp]->GetGroupDS()); - if (sgrp) - sgrp->Add(vol->GetID()); - } + stringstream grpname; + grpname << "m2j_"; + grpname << 0 << "_" << 0; + int idg; + string namegrp = grpname.str(); + if (!mapOfJunctionGroups.count(namegrp)) + mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Face, namegrp.c_str(), idg); + SMESHDS_Group *sgrp = dynamic_cast(mapOfJunctionGroups[namegrp]->GetGroupDS()); + if (sgrp) + sgrp->Add(face->GetID()); + } + + // --- iterate on edgesMultiDomains + + std::map, std::vector >::iterator ite = edgesMultiDomains.begin(); + for (; ite != edgesMultiDomains.end(); ++ite) + { + vector nodes = ite->first; + vector orderDom = ite->second; + vector orderedNodes; + if (nodes.size() == 2) + { + //MESSAGE(" use edgesMultiDomains " << nodes[0] << " " << nodes[1]); + for ( size_t ino = 0; ino < nodes.size(); ino++ ) + if ( orderDom.size() == 3 ) + for ( size_t idom = 0; idom < orderDom.size(); idom++ ) + orderedNodes.push_back( nodeDomains[ nodes[ ino ]][ orderDom[ idom ]]); else - { - //INFOS("Quadratic multiple joints not implemented"); - // TODO quadratic nodes - } - } + for (int idom = orderDom.size()-1; idom >=0; idom--) + orderedNodes.push_back( nodeDomains[ nodes[ ino ]][ orderDom[ idom ]]); + SMDS_MeshVolume* vol = this->GetMeshDS()->AddVolumeFromVtkIds(orderedNodes); + + int idg; + string namegrp = "jointsMultiples"; + if (!mapOfJunctionGroups.count(namegrp)) + mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Volume, namegrp.c_str(), idg); + SMESHDS_Group *sgrp = dynamic_cast(mapOfJunctionGroups[namegrp]->GetGroupDS()); + if (sgrp) + sgrp->Add(vol->GetID()); + } + else + { + //INFOS("Quadratic multiple joints not implemented"); + // TODO quadratic nodes + } } + } // --- list the explicit faces and edges of the mesh that need to be modified, // i.e. faces and edges built with one or more duplicated nodes. @@ -11676,36 +11518,36 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector >::const_iterator itnod = nodeDomains.begin(); + for (; itnod != nodeDomains.end(); ++itnod) { - std::map >::const_iterator itnod = nodeDomains.begin(); - for (; itnod != nodeDomains.end(); ++itnod) - { - int oldId = itnod->first; - //MESSAGE(" node " << oldId); - vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId); - for (int i = 0; i < l.ncells; i++) + int oldId = itnod->first; + //MESSAGE(" node " << oldId); + vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId); + for (int i = 0; i < l.ncells; i++) + { + int vtkId = l.cells[i]; + int vtkType = grid->GetCellType(vtkId); + int downId = grid->CellIdToDownId(vtkId); + if (downId < 0) + continue; // new cells: not to be modified + DownIdType aCell(downId, vtkType); + int volParents[1000]; + int nbvol = grid->GetParentVolumes(volParents, vtkId); + for (int j = 0; j < nbvol; j++) + if (celldom.count(volParents[j]) && (celldom[volParents[j]] == idomain)) + if (!feDom.count(vtkId)) { - int vtkId = l.cells[i]; - int vtkType = grid->GetCellType(vtkId); - int downId = grid->CellIdToDownId(vtkId); - if (downId < 0) - continue; // new cells: not to be modified - DownIdType aCell(downId, vtkType); - int volParents[1000]; - int nbvol = grid->GetParentVolumes(volParents, vtkId); - for (int j = 0; j < nbvol; j++) - if (celldom.count(volParents[j]) && (celldom[volParents[j]] == idomain)) - if (!feDom.count(vtkId)) - { - feDom[vtkId] = idomain; - faceOrEdgeDom[aCell] = emptyMap; - faceOrEdgeDom[aCell][idomain] = vtkId; // affect face or edge to the first domain only - //MESSAGE("affect cell " << this->GetMeshDS()->fromVtkToSmds(vtkId) << " domain " << idomain - // << " type " << vtkType << " downId " << downId); - } + feDom[vtkId] = idomain; + faceOrEdgeDom[aCell] = emptyMap; + faceOrEdgeDom[aCell][idomain] = vtkId; // affect face or edge to the first domain only + //MESSAGE("affect cell " << this->GetMeshDS()->fromVtkToSmds(vtkId) << " domain " << idomain + // << " type " << vtkType << " downId " << downId); } - } + } } + } // --- iterate on shared faces (volumes to modify, face to extrude) // get node id's of the face @@ -11713,40 +11555,40 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector, DownIdCompare>* maps[3] = {&faceDomains, &cellDomains, &faceOrEdgeDom}; for (int m=0; m<3; m++) - { - std::map, DownIdCompare>* amap = maps[m]; - itface = (*amap).begin(); - for (; itface != (*amap).end(); ++itface) + { + std::map, DownIdCompare>* amap = maps[m]; + itface = (*amap).begin(); + for (; itface != (*amap).end(); ++itface) + { + DownIdType face = itface->first; + std::set oldNodes; + std::set::iterator itn; + oldNodes.clear(); + grid->GetNodeIds(oldNodes, face.cellId, face.cellType); + //MESSAGE("examine cell, downId " << face.cellId << " type " << int(face.cellType)); + std::map localClonedNodeIds; + + std::map domvol = itface->second; + std::map::iterator itdom = domvol.begin(); + for (; itdom != domvol.end(); ++itdom) + { + int idom = itdom->first; + int vtkVolId = itdom->second; + //MESSAGE("modify nodes of cell " << this->GetMeshDS()->fromVtkToSmds(vtkVolId) << " domain " << idom); + localClonedNodeIds.clear(); + for (itn = oldNodes.begin(); itn != oldNodes.end(); ++itn) { - DownIdType face = itface->first; - std::set oldNodes; - std::set::iterator itn; - oldNodes.clear(); - grid->GetNodeIds(oldNodes, face.cellId, face.cellType); - //MESSAGE("examine cell, downId " << face.cellId << " type " << int(face.cellType)); - std::map localClonedNodeIds; - - std::map domvol = itface->second; - std::map::iterator itdom = domvol.begin(); - for (; itdom != domvol.end(); ++itdom) - { - int idom = itdom->first; - int vtkVolId = itdom->second; - //MESSAGE("modify nodes of cell " << this->GetMeshDS()->fromVtkToSmds(vtkVolId) << " domain " << idom); - localClonedNodeIds.clear(); - for (itn = oldNodes.begin(); itn != oldNodes.end(); ++itn) - { - int oldId = *itn; - if (nodeDomains[oldId].count(idom)) - { - localClonedNodeIds[oldId] = nodeDomains[oldId][idom]; - //MESSAGE(" node " << oldId << " --> " << localClonedNodeIds[oldId]); - } - } - meshDS->ModifyCellNodes(vtkVolId, localClonedNodeIds); - } + int oldId = *itn; + if (nodeDomains[oldId].count(idom)) + { + localClonedNodeIds[oldId] = nodeDomains[oldId][idom]; + //MESSAGE(" node " << oldId << " --> " << localClonedNodeIds[oldId]); + } } + meshDS->ModifyCellNodes(vtkVolId, localClonedNodeIds); + } } + } // Remove empty groups (issue 0022812) std::map::iterator name_group = mapOfJunctionGroups.begin(); @@ -11793,137 +11635,137 @@ bool SMESH_MeshEditor::CreateFlatElementsOnFacesGroups(const std::vector mapOfJunctionGroups; mapOfJunctionGroups.clear(); - for (int idom = 0; idom < theElems.size(); idom++) + for ( size_t idom = 0; idom < theElems.size(); idom++ ) + { + const TIDSortedElemSet& domain = theElems[idom]; + TIDSortedElemSet::const_iterator elemItr = domain.begin(); + for ( ; elemItr != domain.end(); ++elemItr ) { - const TIDSortedElemSet& domain = theElems[idom]; - TIDSortedElemSet::const_iterator elemItr = domain.begin(); - for (; elemItr != domain.end(); ++elemItr) - { - SMDS_MeshElement* anElem = (SMDS_MeshElement*) *elemItr; - SMDS_MeshFace* aFace = dynamic_cast (anElem); - if (!aFace) - continue; - // MESSAGE("aFace=" << aFace->GetID()); - bool isQuad = aFace->IsQuadratic(); - vector ln0, ln1, ln2, ln3, ln4; - - // --- clone the nodes, create intermediate nodes for non medium nodes of a quad face - - SMDS_ElemIteratorPtr nodeIt = aFace->nodesIterator(); - while (nodeIt->more()) - { - const SMDS_MeshNode* node = static_cast (nodeIt->next()); - bool isMedium = isQuad && (aFace->IsMediumNode(node)); - if (isMedium) - ln2.push_back(node); - else - ln0.push_back(node); + SMDS_MeshElement* anElem = (SMDS_MeshElement*) *elemItr; + SMDS_MeshFace* aFace = dynamic_cast (anElem); + if (!aFace) + continue; + // MESSAGE("aFace=" << aFace->GetID()); + bool isQuad = aFace->IsQuadratic(); + vector ln0, ln1, ln2, ln3, ln4; - const SMDS_MeshNode* clone = 0; - if (!clonedNodes.count(node)) - { - clone = meshDS->AddNode(node->X(), node->Y(), node->Z()); - copyPosition( node, clone ); - clonedNodes[node] = clone; - } - else - clone = clonedNodes[node]; + // --- clone the nodes, create intermediate nodes for non medium nodes of a quad face - if (isMedium) - ln3.push_back(clone); - else - ln1.push_back(clone); + SMDS_ElemIteratorPtr nodeIt = aFace->nodesIterator(); + while (nodeIt->more()) + { + const SMDS_MeshNode* node = static_cast (nodeIt->next()); + bool isMedium = isQuad && (aFace->IsMediumNode(node)); + if (isMedium) + ln2.push_back(node); + else + ln0.push_back(node); - const SMDS_MeshNode* inter = 0; - if (isQuad && (!isMedium)) - { - if (!intermediateNodes.count(node)) - { - inter = meshDS->AddNode(node->X(), node->Y(), node->Z()); - copyPosition( node, inter ); - intermediateNodes[node] = inter; - } - else - inter = intermediateNodes[node]; - ln4.push_back(inter); - } - } + const SMDS_MeshNode* clone = 0; + if (!clonedNodes.count(node)) + { + clone = meshDS->AddNode(node->X(), node->Y(), node->Z()); + copyPosition( node, clone ); + clonedNodes[node] = clone; + } + else + clone = clonedNodes[node]; - // --- extrude the face + if (isMedium) + ln3.push_back(clone); + else + ln1.push_back(clone); - vector ln; - SMDS_MeshVolume* vol = 0; - vtkIdType aType = aFace->GetVtkType(); - switch (aType) + const SMDS_MeshNode* inter = 0; + if (isQuad && (!isMedium)) + { + if (!intermediateNodes.count(node)) { - case VTK_TRIANGLE: - vol = meshDS->AddVolume(ln0[2], ln0[1], ln0[0], ln1[2], ln1[1], ln1[0]); - // MESSAGE("vol prism " << vol->GetID()); - ln.push_back(ln1[0]); - ln.push_back(ln1[1]); - ln.push_back(ln1[2]); - break; - case VTK_QUAD: - vol = meshDS->AddVolume(ln0[3], ln0[2], ln0[1], ln0[0], ln1[3], ln1[2], ln1[1], ln1[0]); - // MESSAGE("vol hexa " << vol->GetID()); - ln.push_back(ln1[0]); - ln.push_back(ln1[1]); - ln.push_back(ln1[2]); - ln.push_back(ln1[3]); - break; - case VTK_QUADRATIC_TRIANGLE: - vol = meshDS->AddVolume(ln1[0], ln1[1], ln1[2], ln0[0], ln0[1], ln0[2], ln3[0], ln3[1], ln3[2], - ln2[0], ln2[1], ln2[2], ln4[0], ln4[1], ln4[2]); - // MESSAGE("vol quad prism " << vol->GetID()); - ln.push_back(ln1[0]); - ln.push_back(ln1[1]); - ln.push_back(ln1[2]); - ln.push_back(ln3[0]); - ln.push_back(ln3[1]); - ln.push_back(ln3[2]); - break; - case VTK_QUADRATIC_QUAD: -// vol = meshDS->AddVolume(ln0[0], ln0[1], ln0[2], ln0[3], ln1[0], ln1[1], ln1[2], ln1[3], -// ln2[0], ln2[1], ln2[2], ln2[3], ln3[0], ln3[1], ln3[2], ln3[3], -// ln4[0], ln4[1], ln4[2], ln4[3]); - vol = meshDS->AddVolume(ln1[0], ln1[1], ln1[2], ln1[3], ln0[0], ln0[1], ln0[2], ln0[3], - ln3[0], ln3[1], ln3[2], ln3[3], ln2[0], ln2[1], ln2[2], ln2[3], - ln4[0], ln4[1], ln4[2], ln4[3]); - // MESSAGE("vol quad hexa " << vol->GetID()); - ln.push_back(ln1[0]); - ln.push_back(ln1[1]); - ln.push_back(ln1[2]); - ln.push_back(ln1[3]); - ln.push_back(ln3[0]); - ln.push_back(ln3[1]); - ln.push_back(ln3[2]); - ln.push_back(ln3[3]); - break; - case VTK_POLYGON: - break; - default: - break; + inter = meshDS->AddNode(node->X(), node->Y(), node->Z()); + copyPosition( node, inter ); + intermediateNodes[node] = inter; } + else + inter = intermediateNodes[node]; + ln4.push_back(inter); + } + } - if (vol) - { - stringstream grpname; - grpname << "jf_"; - grpname << idom; - int idg; - string namegrp = grpname.str(); - if (!mapOfJunctionGroups.count(namegrp)) - mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Volume, namegrp.c_str(), idg); - SMESHDS_Group *sgrp = dynamic_cast(mapOfJunctionGroups[namegrp]->GetGroupDS()); - if (sgrp) - sgrp->Add(vol->GetID()); - } + // --- extrude the face - // --- modify the face + vector ln; + SMDS_MeshVolume* vol = 0; + vtkIdType aType = aFace->GetVtkType(); + switch (aType) + { + case VTK_TRIANGLE: + vol = meshDS->AddVolume(ln0[2], ln0[1], ln0[0], ln1[2], ln1[1], ln1[0]); + // MESSAGE("vol prism " << vol->GetID()); + ln.push_back(ln1[0]); + ln.push_back(ln1[1]); + ln.push_back(ln1[2]); + break; + case VTK_QUAD: + vol = meshDS->AddVolume(ln0[3], ln0[2], ln0[1], ln0[0], ln1[3], ln1[2], ln1[1], ln1[0]); + // MESSAGE("vol hexa " << vol->GetID()); + ln.push_back(ln1[0]); + ln.push_back(ln1[1]); + ln.push_back(ln1[2]); + ln.push_back(ln1[3]); + break; + case VTK_QUADRATIC_TRIANGLE: + vol = meshDS->AddVolume(ln1[0], ln1[1], ln1[2], ln0[0], ln0[1], ln0[2], ln3[0], ln3[1], ln3[2], + ln2[0], ln2[1], ln2[2], ln4[0], ln4[1], ln4[2]); + // MESSAGE("vol quad prism " << vol->GetID()); + ln.push_back(ln1[0]); + ln.push_back(ln1[1]); + ln.push_back(ln1[2]); + ln.push_back(ln3[0]); + ln.push_back(ln3[1]); + ln.push_back(ln3[2]); + break; + case VTK_QUADRATIC_QUAD: + // vol = meshDS->AddVolume(ln0[0], ln0[1], ln0[2], ln0[3], ln1[0], ln1[1], ln1[2], ln1[3], + // ln2[0], ln2[1], ln2[2], ln2[3], ln3[0], ln3[1], ln3[2], ln3[3], + // ln4[0], ln4[1], ln4[2], ln4[3]); + vol = meshDS->AddVolume(ln1[0], ln1[1], ln1[2], ln1[3], ln0[0], ln0[1], ln0[2], ln0[3], + ln3[0], ln3[1], ln3[2], ln3[3], ln2[0], ln2[1], ln2[2], ln2[3], + ln4[0], ln4[1], ln4[2], ln4[3]); + // MESSAGE("vol quad hexa " << vol->GetID()); + ln.push_back(ln1[0]); + ln.push_back(ln1[1]); + ln.push_back(ln1[2]); + ln.push_back(ln1[3]); + ln.push_back(ln3[0]); + ln.push_back(ln3[1]); + ln.push_back(ln3[2]); + ln.push_back(ln3[3]); + break; + case VTK_POLYGON: + break; + default: + break; + } - aFace->ChangeNodes(&ln[0], ln.size()); - } + if (vol) + { + stringstream grpname; + grpname << "jf_"; + grpname << idom; + int idg; + string namegrp = grpname.str(); + if (!mapOfJunctionGroups.count(namegrp)) + mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Volume, namegrp.c_str(), idg); + SMESHDS_Group *sgrp = dynamic_cast(mapOfJunctionGroups[namegrp]->GetGroupDS()); + if (sgrp) + sgrp->Add(vol->GetID()); + } + + // --- modify the face + + aFace->ChangeNodes(&ln[0], ln.size()); } + } return true; } @@ -11933,11 +11775,11 @@ bool SMESH_MeshEditor::CreateFlatElementsOnFacesGroups(const std::vector& nodesCoords, +void SMESH_MeshEditor::CreateHoleSkin(double radius, + const TopoDS_Shape& theShape, + SMESH_NodeSearcher* theNodeSearcher, + const char* groupName, + std::vector& nodesCoords, std::vector >& listOfListOfNodes) { MESSAGE("--------------------------------"); @@ -11955,28 +11797,28 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, SMESHDS_GroupBase* groupDS = 0; SMESH_Mesh::GroupIteratorPtr groupIt = this->myMesh->GetGroups(); while ( groupIt->more() ) - { + { + groupDS = 0; + SMESH_Group * group = groupIt->next(); + if ( !group ) continue; + groupDS = group->GetGroupDS(); + if ( !groupDS || groupDS->IsEmpty() ) continue; + std::string grpName = group->GetName(); + //MESSAGE("grpName=" << grpName); + if (grpName == groupName) + break; + else groupDS = 0; - SMESH_Group * group = groupIt->next(); - if ( !group ) continue; - groupDS = group->GetGroupDS(); - if ( !groupDS || groupDS->IsEmpty() ) continue; - std::string grpName = group->GetName(); - //MESSAGE("grpName=" << grpName); - if (grpName == groupName) - break; - else - groupDS = 0; - } + } bool isNodeGroup = false; bool isNodeCoords = false; if (groupDS) - { - if (groupDS->GetType() != SMDSAbs_Node) - return; - isNodeGroup = true; // a group of nodes exists and it is in this mesh - } + { + if (groupDS->GetType() != SMDSAbs_Node) + return; + isNodeGroup = true; // a group of nodes exists and it is in this mesh + } if (nodesCoords.size() > 0) isNodeCoords = true; // a list o nodes given by their coordinates @@ -11989,10 +11831,10 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, grpvName += "_vol"; SMESH_Group *grp = this->myMesh->AddGroup(SMDSAbs_Volume, grpvName.c_str(), idg); if (!grp) - { - MESSAGE("group not created " << grpvName); - return; - } + { + MESSAGE("group not created " << grpvName); + return; + } SMESHDS_Group *sgrp = dynamic_cast(grp->GetGroupDS()); int idgs; // --- group of SMDS faces on the skin @@ -12000,10 +11842,10 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, grpsName += "_skin"; SMESH_Group *grps = this->myMesh->AddGroup(SMDSAbs_Face, grpsName.c_str(), idgs); if (!grps) - { - MESSAGE("group not created " << grpsName); - return; - } + { + MESSAGE("group not created " << grpsName); + return; + } SMESHDS_Group *sgrps = dynamic_cast(grps->GetGroupDS()); int idgi; // --- group of SMDS faces internal (several shapes) @@ -12011,10 +11853,10 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, grpiName += "_internalFaces"; SMESH_Group *grpi = this->myMesh->AddGroup(SMDSAbs_Face, grpiName.c_str(), idgi); if (!grpi) - { - MESSAGE("group not created " << grpiName); - return; - } + { + MESSAGE("group not created " << grpiName); + return; + } SMESHDS_Group *sgrpi = dynamic_cast(grpi->GetGroupDS()); int idgei; // --- group of SMDS faces internal (several shapes) @@ -12022,10 +11864,10 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, grpeiName += "_internalEdges"; SMESH_Group *grpei = this->myMesh->AddGroup(SMDSAbs_Edge, grpeiName.c_str(), idgei); if (!grpei) - { - MESSAGE("group not created " << grpeiName); - return; - } + { + MESSAGE("group not created " << grpeiName); + return; + } SMESHDS_Group *sgrpei = dynamic_cast(grpei->GetGroupDS()); // --- build downward connectivity @@ -12043,157 +11885,157 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, gpnts.clear(); if (isNodeGroup) // --- a group of nodes is provided : find all the volumes using one or more of this nodes + { + MESSAGE("group of nodes provided"); + SMDS_ElemIteratorPtr elemIt = groupDS->GetElements(); + while ( elemIt->more() ) { - MESSAGE("group of nodes provided"); - SMDS_ElemIteratorPtr elemIt = groupDS->GetElements(); - while ( elemIt->more() ) - { - const SMDS_MeshElement* elem = elemIt->next(); - if (!elem) - continue; - const SMDS_MeshNode* node = dynamic_cast(elem); - if (!node) - continue; - SMDS_MeshElement* vol = 0; - SMDS_ElemIteratorPtr volItr = node->GetInverseElementIterator(SMDSAbs_Volume); - while (volItr->more()) - { - vol = (SMDS_MeshElement*)volItr->next(); - setOfInsideVol.insert(vol->getVtkId()); - sgrp->Add(vol->GetID()); - } - } + const SMDS_MeshElement* elem = elemIt->next(); + if (!elem) + continue; + const SMDS_MeshNode* node = dynamic_cast(elem); + if (!node) + continue; + SMDS_MeshElement* vol = 0; + SMDS_ElemIteratorPtr volItr = node->GetInverseElementIterator(SMDSAbs_Volume); + while (volItr->more()) + { + vol = (SMDS_MeshElement*)volItr->next(); + setOfInsideVol.insert(vol->getVtkId()); + sgrp->Add(vol->GetID()); + } } + } else if (isNodeCoords) + { + MESSAGE("list of nodes coordinates provided"); + size_t i = 0; + int k = 0; + while ( i < nodesCoords.size()-2 ) { - MESSAGE("list of nodes coordinates provided"); - int i = 0; - int k = 0; - while (i < nodesCoords.size()-2) - { - double x = nodesCoords[i++]; - double y = nodesCoords[i++]; - double z = nodesCoords[i++]; - gp_Pnt p = gp_Pnt(x, y ,z); - gpnts.push_back(p); - MESSAGE("TopoDS_Vertex " << k << " " << p.X() << " " << p.Y() << " " << p.Z()); - k++; - } + double x = nodesCoords[i++]; + double y = nodesCoords[i++]; + double z = nodesCoords[i++]; + gp_Pnt p = gp_Pnt(x, y ,z); + gpnts.push_back(p); + MESSAGE("TopoDS_Vertex " << k << " " << p.X() << " " << p.Y() << " " << p.Z()); + k++; } + } else // --- no group, no coordinates : use the vertices of the geom shape provided, and radius - { - MESSAGE("no group of nodes provided, using vertices from geom shape, and radius"); - TopTools_IndexedMapOfShape vertexMap; - TopExp::MapShapes( theShape, TopAbs_VERTEX, vertexMap ); - gp_Pnt p = gp_Pnt(0,0,0); - if (vertexMap.Extent() < 1) - return; + { + MESSAGE("no group of nodes provided, using vertices from geom shape, and radius"); + TopTools_IndexedMapOfShape vertexMap; + TopExp::MapShapes( theShape, TopAbs_VERTEX, vertexMap ); + gp_Pnt p = gp_Pnt(0,0,0); + if (vertexMap.Extent() < 1) + return; - for ( int i = 1; i <= vertexMap.Extent(); ++i ) - { - const TopoDS_Vertex& vertex = TopoDS::Vertex( vertexMap( i )); - p = BRep_Tool::Pnt(vertex); - gpnts.push_back(p); - MESSAGE("TopoDS_Vertex " << i << " " << p.X() << " " << p.Y() << " " << p.Z()); - } + for ( int i = 1; i <= vertexMap.Extent(); ++i ) + { + const TopoDS_Vertex& vertex = TopoDS::Vertex( vertexMap( i )); + p = BRep_Tool::Pnt(vertex); + gpnts.push_back(p); + MESSAGE("TopoDS_Vertex " << i << " " << p.X() << " " << p.Y() << " " << p.Z()); } + } if (gpnts.size() > 0) - { - int nodeId = 0; - const SMDS_MeshNode* startNode = theNodeSearcher->FindClosestTo(gpnts[0]); - if (startNode) - nodeId = startNode->GetID(); - MESSAGE("nodeId " << nodeId); + { + int nodeId = 0; + const SMDS_MeshNode* startNode = theNodeSearcher->FindClosestTo(gpnts[0]); + if (startNode) + nodeId = startNode->GetID(); + MESSAGE("nodeId " << nodeId); - double radius2 = radius*radius; - MESSAGE("radius2 " << radius2); + double radius2 = radius*radius; + MESSAGE("radius2 " << radius2); - // --- volumes on start node + // --- volumes on start node - setOfVolToCheck.clear(); - SMDS_MeshElement* startVol = 0; - SMDS_ElemIteratorPtr volItr = startNode->GetInverseElementIterator(SMDSAbs_Volume); - while (volItr->more()) - { - startVol = (SMDS_MeshElement*)volItr->next(); - setOfVolToCheck.insert(startVol->getVtkId()); - } - if (setOfVolToCheck.empty()) - { - MESSAGE("No volumes found"); - return; - } + setOfVolToCheck.clear(); + SMDS_MeshElement* startVol = 0; + SMDS_ElemIteratorPtr volItr = startNode->GetInverseElementIterator(SMDSAbs_Volume); + while (volItr->more()) + { + startVol = (SMDS_MeshElement*)volItr->next(); + setOfVolToCheck.insert(startVol->getVtkId()); + } + if (setOfVolToCheck.empty()) + { + MESSAGE("No volumes found"); + return; + } - // --- starting with central volumes then their neighbors, check if they are inside - // or outside the domain, until no more new neighbor volume is inside. - // Fill the group of inside volumes + // --- starting with central volumes then their neighbors, check if they are inside + // or outside the domain, until no more new neighbor volume is inside. + // Fill the group of inside volumes - std::map mapOfNodeDistance2; - mapOfNodeDistance2.clear(); - std::set setOfOutsideVol; - while (!setOfVolToCheck.empty()) + std::map mapOfNodeDistance2; + mapOfNodeDistance2.clear(); + std::set setOfOutsideVol; + while (!setOfVolToCheck.empty()) + { + std::set::iterator it = setOfVolToCheck.begin(); + int vtkId = *it; + MESSAGE("volume to check, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); + bool volInside = false; + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(vtkId, npts, pts); + for (int i=0; i::iterator it = setOfVolToCheck.begin(); - int vtkId = *it; - MESSAGE("volume to check, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); - bool volInside = false; - vtkIdType npts = 0; - vtkIdType* pts = 0; - grid->GetCellPoints(vtkId, npts, pts); - for (int i=0; iGetPoint(pts[i]); + gp_Pnt aPoint = gp_Pnt(coords[0], coords[1], coords[2]); + distance2 = 1.E40; + for ( size_t j = 0; j < gpnts.size(); j++ ) + { + double d2 = aPoint.SquareDistance( gpnts[ j ]); + if (d2 < distance2) { - double distance2 = 0; - if (mapOfNodeDistance2.count(pts[i])) - { - distance2 = mapOfNodeDistance2[pts[i]]; - MESSAGE("point " << pts[i] << " distance2 " << distance2); - } - else - { - double *coords = grid->GetPoint(pts[i]); - gp_Pnt aPoint = gp_Pnt(coords[0], coords[1], coords[2]); - distance2 = 1.E40; - for (int j=0; jAdd(meshDS->fromVtkToSmds(vtkId)); - break; - } - } - if (volInside) - { - setOfInsideVol.insert(vtkId); - MESSAGE(" volume inside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); - int neighborsVtkIds[NBMAXNEIGHBORS]; - int downIds[NBMAXNEIGHBORS]; - unsigned char downTypes[NBMAXNEIGHBORS]; - int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId); - for (int n = 0; n < nbNeighbors; n++) - if (!setOfInsideVol.count(neighborsVtkIds[n]) ||setOfOutsideVol.count(neighborsVtkIds[n])) - setOfVolToCheck.insert(neighborsVtkIds[n]); - } - else - { - setOfOutsideVol.insert(vtkId); - MESSAGE(" volume outside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); + break; } - setOfVolToCheck.erase(vtkId); + } + mapOfNodeDistance2[pts[i]] = distance2; + MESSAGE(" point " << pts[i] << " distance2 " << distance2 << " coords " << coords[0] << " " << coords[1] << " " << coords[2]); } + if (distance2 < radius2) + { + volInside = true; // one or more nodes inside the domain + sgrp->Add(meshDS->fromVtkToSmds(vtkId)); + break; + } + } + if (volInside) + { + setOfInsideVol.insert(vtkId); + MESSAGE(" volume inside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); + int neighborsVtkIds[NBMAXNEIGHBORS]; + int downIds[NBMAXNEIGHBORS]; + unsigned char downTypes[NBMAXNEIGHBORS]; + int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId); + for (int n = 0; n < nbNeighbors; n++) + if (!setOfInsideVol.count(neighborsVtkIds[n]) ||setOfOutsideVol.count(neighborsVtkIds[n])) + setOfVolToCheck.insert(neighborsVtkIds[n]); + } + else + { + setOfOutsideVol.insert(vtkId); + MESSAGE(" volume outside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); + } + setOfVolToCheck.erase(vtkId); } + } // --- for outside hexahedrons, check if they have more than one neighbor volume inside // If yes, add the volume to the inside set @@ -12201,52 +12043,52 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, bool addedInside = true; std::set setOfVolToReCheck; while (addedInside) + { + MESSAGE(" --------------------------- re check"); + addedInside = false; + std::set::iterator itv = setOfInsideVol.begin(); + for (; itv != setOfInsideVol.end(); ++itv) { - MESSAGE(" --------------------------- re check"); - addedInside = false; - std::set::iterator itv = setOfInsideVol.begin(); - for (; itv != setOfInsideVol.end(); ++itv) - { - int vtkId = *itv; - int neighborsVtkIds[NBMAXNEIGHBORS]; - int downIds[NBMAXNEIGHBORS]; - unsigned char downTypes[NBMAXNEIGHBORS]; - int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId); - for (int n = 0; n < nbNeighbors; n++) - if (!setOfInsideVol.count(neighborsVtkIds[n])) - setOfVolToReCheck.insert(neighborsVtkIds[n]); - } - setOfVolToCheck = setOfVolToReCheck; - setOfVolToReCheck.clear(); - while (!setOfVolToCheck.empty()) + int vtkId = *itv; + int neighborsVtkIds[NBMAXNEIGHBORS]; + int downIds[NBMAXNEIGHBORS]; + unsigned char downTypes[NBMAXNEIGHBORS]; + int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId); + for (int n = 0; n < nbNeighbors; n++) + if (!setOfInsideVol.count(neighborsVtkIds[n])) + setOfVolToReCheck.insert(neighborsVtkIds[n]); + } + setOfVolToCheck = setOfVolToReCheck; + setOfVolToReCheck.clear(); + while (!setOfVolToCheck.empty()) + { + std::set::iterator it = setOfVolToCheck.begin(); + int vtkId = *it; + if (grid->GetCellType(vtkId) == VTK_HEXAHEDRON) + { + MESSAGE("volume to recheck, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); + int countInside = 0; + int neighborsVtkIds[NBMAXNEIGHBORS]; + int downIds[NBMAXNEIGHBORS]; + unsigned char downTypes[NBMAXNEIGHBORS]; + int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId); + for (int n = 0; n < nbNeighbors; n++) + if (setOfInsideVol.count(neighborsVtkIds[n])) + countInside++; + MESSAGE("countInside " << countInside); + if (countInside > 1) { - std::set::iterator it = setOfVolToCheck.begin(); - int vtkId = *it; - if (grid->GetCellType(vtkId) == VTK_HEXAHEDRON) - { - MESSAGE("volume to recheck, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); - int countInside = 0; - int neighborsVtkIds[NBMAXNEIGHBORS]; - int downIds[NBMAXNEIGHBORS]; - unsigned char downTypes[NBMAXNEIGHBORS]; - int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId); - for (int n = 0; n < nbNeighbors; n++) - if (setOfInsideVol.count(neighborsVtkIds[n])) - countInside++; - MESSAGE("countInside " << countInside); - if (countInside > 1) - { - MESSAGE(" volume inside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); - setOfInsideVol.insert(vtkId); - sgrp->Add(meshDS->fromVtkToSmds(vtkId)); - addedInside = true; - } - else - setOfVolToReCheck.insert(vtkId); - } - setOfVolToCheck.erase(vtkId); + MESSAGE(" volume inside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); + setOfInsideVol.insert(vtkId); + sgrp->Add(meshDS->fromVtkToSmds(vtkId)); + addedInside = true; } + else + setOfVolToReCheck.insert(vtkId); + } + setOfVolToCheck.erase(vtkId); } + } // --- map of Downward faces at the boundary, inside the global volume // map of Downward faces on the skin of the global volume (equivalent to SMDS faces on the skin) @@ -12257,50 +12099,50 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, std::map skinFaces; // faces on the skin of the global volume --> corresponding cell std::set::iterator it = setOfInsideVol.begin(); for (; it != setOfInsideVol.end(); ++it) - { - int vtkId = *it; - //MESSAGE(" vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); - int neighborsVtkIds[NBMAXNEIGHBORS]; - int downIds[NBMAXNEIGHBORS]; - unsigned char downTypes[NBMAXNEIGHBORS]; - int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId, true); - for (int n = 0; n < nbNeighbors; n++) + { + int vtkId = *it; + //MESSAGE(" vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); + int neighborsVtkIds[NBMAXNEIGHBORS]; + int downIds[NBMAXNEIGHBORS]; + unsigned char downTypes[NBMAXNEIGHBORS]; + int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId, true); + for (int n = 0; n < nbNeighbors; n++) + { + int neighborDim = SMDS_Downward::getCellDimension(grid->GetCellType(neighborsVtkIds[n])); + if (neighborDim == 3) + { + if (! setOfInsideVol.count(neighborsVtkIds[n])) // neighbor volume is not inside : face is boundary { - int neighborDim = SMDS_Downward::getCellDimension(grid->GetCellType(neighborsVtkIds[n])); - if (neighborDim == 3) - { - if (! setOfInsideVol.count(neighborsVtkIds[n])) // neighbor volume is not inside : face is boundary - { - DownIdType face(downIds[n], downTypes[n]); - boundaryFaces[face] = vtkId; - } - // if the face between to volumes is in the mesh, get it (internal face between shapes) - int vtkFaceId = grid->getDownArray(downTypes[n])->getVtkCellId(downIds[n]); - if (vtkFaceId >= 0) - { - sgrpi->Add(meshDS->fromVtkToSmds(vtkFaceId)); - // find also the smds edges on this face - int nbEdges = grid->getDownArray(downTypes[n])->getNumberOfDownCells(downIds[n]); - const int* dEdges = grid->getDownArray(downTypes[n])->getDownCells(downIds[n]); - const unsigned char* dTypes = grid->getDownArray(downTypes[n])->getDownTypes(downIds[n]); - for (int i = 0; i < nbEdges; i++) - { - int vtkEdgeId = grid->getDownArray(dTypes[i])->getVtkCellId(dEdges[i]); - if (vtkEdgeId >= 0) - sgrpei->Add(meshDS->fromVtkToSmds(vtkEdgeId)); - } - } - } - else if (neighborDim == 2) // skin of the volume - { - DownIdType face(downIds[n], downTypes[n]); - skinFaces[face] = vtkId; - int vtkFaceId = grid->getDownArray(downTypes[n])->getVtkCellId(downIds[n]); - if (vtkFaceId >= 0) - sgrps->Add(meshDS->fromVtkToSmds(vtkFaceId)); - } + DownIdType face(downIds[n], downTypes[n]); + boundaryFaces[face] = vtkId; } + // if the face between to volumes is in the mesh, get it (internal face between shapes) + int vtkFaceId = grid->getDownArray(downTypes[n])->getVtkCellId(downIds[n]); + if (vtkFaceId >= 0) + { + sgrpi->Add(meshDS->fromVtkToSmds(vtkFaceId)); + // find also the smds edges on this face + int nbEdges = grid->getDownArray(downTypes[n])->getNumberOfDownCells(downIds[n]); + const int* dEdges = grid->getDownArray(downTypes[n])->getDownCells(downIds[n]); + const unsigned char* dTypes = grid->getDownArray(downTypes[n])->getDownTypes(downIds[n]); + for (int i = 0; i < nbEdges; i++) + { + int vtkEdgeId = grid->getDownArray(dTypes[i])->getVtkCellId(dEdges[i]); + if (vtkEdgeId >= 0) + sgrpei->Add(meshDS->fromVtkToSmds(vtkEdgeId)); + } + } + } + else if (neighborDim == 2) // skin of the volume + { + DownIdType face(downIds[n], downTypes[n]); + skinFaces[face] = vtkId; + int vtkFaceId = grid->getDownArray(downTypes[n])->getVtkCellId(downIds[n]); + if (vtkFaceId >= 0) + sgrps->Add(meshDS->fromVtkToSmds(vtkFaceId)); + } } + } // --- identify the edges constituting the wire of each subshape on the skin // define polylines with the nodes of edges, equivalent to wires @@ -12313,17 +12155,17 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, SMDS_ElemIteratorPtr itelem = sgrps->GetElements(); while (itelem->more()) + { + const SMDS_MeshElement *elem = itelem->next(); + int shapeId = elem->getshapeId(); + int vtkId = elem->getVtkId(); + if (!shapeIdToVtkIdSet.count(shapeId)) { - const SMDS_MeshElement *elem = itelem->next(); - int shapeId = elem->getshapeId(); - int vtkId = elem->getVtkId(); - if (!shapeIdToVtkIdSet.count(shapeId)) - { - shapeIdToVtkIdSet[shapeId] = emptySet; - shapeIds.insert(shapeId); - } - shapeIdToVtkIdSet[shapeId].insert(vtkId); + shapeIdToVtkIdSet[shapeId] = emptySet; + shapeIds.insert(shapeId); } + shapeIdToVtkIdSet[shapeId].insert(vtkId); + } std::map > shapeIdToEdges; // shapeId --> set of downward edges std::set emptyEdges; @@ -12331,124 +12173,124 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, std::map >::iterator itShape = shapeIdToVtkIdSet.begin(); for (; itShape != shapeIdToVtkIdSet.end(); ++itShape) - { - int shapeId = itShape->first; - MESSAGE(" --- Shape ID --- "<< shapeId); - shapeIdToEdges[shapeId] = emptyEdges; + { + int shapeId = itShape->first; + MESSAGE(" --- Shape ID --- "<< shapeId); + shapeIdToEdges[shapeId] = emptyEdges; - std::vector nodesEdges; + std::vector nodesEdges; - std::set::iterator its = itShape->second.begin(); - for (; its != itShape->second.end(); ++its) + std::set::iterator its = itShape->second.begin(); + for (; its != itShape->second.end(); ++its) + { + int vtkId = *its; + MESSAGE(" " << vtkId); + int neighborsVtkIds[NBMAXNEIGHBORS]; + int downIds[NBMAXNEIGHBORS]; + unsigned char downTypes[NBMAXNEIGHBORS]; + int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId); + for (int n = 0; n < nbNeighbors; n++) + { + if (neighborsVtkIds[n]<0) // only smds faces are considered as neighbors here + continue; + int smdsId = meshDS->fromVtkToSmds(neighborsVtkIds[n]); + const SMDS_MeshElement* elem = meshDS->FindElement(smdsId); + if ( shapeIds.count(elem->getshapeId()) && !sgrps->Contains(elem)) // edge : neighbor in the set of shape, not in the group { - int vtkId = *its; - MESSAGE(" " << vtkId); - int neighborsVtkIds[NBMAXNEIGHBORS]; - int downIds[NBMAXNEIGHBORS]; - unsigned char downTypes[NBMAXNEIGHBORS]; - int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId); - for (int n = 0; n < nbNeighbors; n++) - { - if (neighborsVtkIds[n]<0) // only smds faces are considered as neighbors here - continue; - int smdsId = meshDS->fromVtkToSmds(neighborsVtkIds[n]); - const SMDS_MeshElement* elem = meshDS->FindElement(smdsId); - if ( shapeIds.count(elem->getshapeId()) && !sgrps->Contains(elem)) // edge : neighbor in the set of shape, not in the group - { - DownIdType edge(downIds[n], downTypes[n]); - if (!shapeIdToEdges[shapeId].count(edge)) - { - shapeIdToEdges[shapeId].insert(edge); - int vtkNodeId[3]; - int nbNodes = grid->getDownArray(downTypes[n])->getNodes(downIds[n],vtkNodeId); - nodesEdges.push_back(vtkNodeId[0]); - nodesEdges.push_back(vtkNodeId[nbNodes-1]); - MESSAGE(" --- nodes " << vtkNodeId[0]+1 << " " << vtkNodeId[nbNodes-1]+1); - } - } - } + DownIdType edge(downIds[n], downTypes[n]); + if (!shapeIdToEdges[shapeId].count(edge)) + { + shapeIdToEdges[shapeId].insert(edge); + int vtkNodeId[3]; + int nbNodes = grid->getDownArray(downTypes[n])->getNodes(downIds[n],vtkNodeId); + nodesEdges.push_back(vtkNodeId[0]); + nodesEdges.push_back(vtkNodeId[nbNodes-1]); + MESSAGE(" --- nodes " << vtkNodeId[0]+1 << " " << vtkNodeId[nbNodes-1]+1); + } } + } + } - std::list order; - order.clear(); - if (nodesEdges.size() > 0) + std::list order; + order.clear(); + if (nodesEdges.size() > 0) + { + order.push_back(nodesEdges[0]); MESSAGE(" --- back " << order.back()+1); // SMDS id = VTK id + 1; + nodesEdges[0] = -1; + order.push_back(nodesEdges[1]); MESSAGE(" --- back " << order.back()+1); + nodesEdges[1] = -1; // do not reuse this edge + bool found = true; + while (found) + { + int nodeTofind = order.back(); // try first to push back + int i = 0; + for ( i = 0; i < (int)nodesEdges.size(); i++ ) + if (nodesEdges[i] == nodeTofind) + break; + if ( i == (int) nodesEdges.size() ) + found = false; // no follower found on back + else { - order.push_back(nodesEdges[0]); MESSAGE(" --- back " << order.back()+1); // SMDS id = VTK id + 1; - nodesEdges[0] = -1; - order.push_back(nodesEdges[1]); MESSAGE(" --- back " << order.back()+1); - nodesEdges[1] = -1; // do not reuse this edge - bool found = true; - while (found) + if (i%2) // odd ==> use the previous one + if (nodesEdges[i-1] < 0) + found = false; + else { - int nodeTofind = order.back(); // try first to push back - int i = 0; - for (i = 0; i use the previous one - if (nodesEdges[i-1] < 0) - found = false; - else - { - order.push_back(nodesEdges[i-1]); MESSAGE(" --- back " << order.back()+1); - nodesEdges[i-1] = -1; - } - else // even ==> use the next one - if (nodesEdges[i+1] < 0) - found = false; - else - { - order.push_back(nodesEdges[i+1]); MESSAGE(" --- back " << order.back()+1); - nodesEdges[i+1] = -1; - } - } - if (found) - continue; - // try to push front - found = true; - nodeTofind = order.front(); // try to push front - for (i = 0; i use the previous one - if (nodesEdges[i-1] < 0) - found = false; - else - { - order.push_front(nodesEdges[i-1]); MESSAGE(" --- front " << order.front()+1); - nodesEdges[i-1] = -1; - } - else // even ==> use the next one - if (nodesEdges[i+1] < 0) - found = false; - else - { - order.push_front(nodesEdges[i+1]); MESSAGE(" --- front " << order.front()+1); - nodesEdges[i+1] = -1; - } + order.push_back(nodesEdges[i-1]); MESSAGE(" --- back " << order.back()+1); + nodesEdges[i-1] = -1; + } + else // even ==> use the next one + if (nodesEdges[i+1] < 0) + found = false; + else + { + order.push_back(nodesEdges[i+1]); MESSAGE(" --- back " << order.back()+1); + nodesEdges[i+1] = -1; } } - - - std::vector nodes; - nodes.push_back(shapeId); - std::list::iterator itl = order.begin(); - for (; itl != order.end(); itl++) + if (found) + continue; + // try to push front + found = true; + nodeTofind = order.front(); // try to push front + for ( i = 0; i < (int)nodesEdges.size(); i++ ) + if ( nodesEdges[i] == nodeTofind ) + break; + if ( i == (int)nodesEdges.size() ) { - nodes.push_back((*itl) + 1); // SMDS id = VTK id + 1; - MESSAGE(" ordered node " << nodes[nodes.size()-1]); + found = false; // no predecessor found on front + continue; } - listOfListOfNodes.push_back(nodes); + if (i%2) // odd ==> use the previous one + if (nodesEdges[i-1] < 0) + found = false; + else + { + order.push_front(nodesEdges[i-1]); MESSAGE(" --- front " << order.front()+1); + nodesEdges[i-1] = -1; + } + else // even ==> use the next one + if (nodesEdges[i+1] < 0) + found = false; + else + { + order.push_front(nodesEdges[i+1]); MESSAGE(" --- front " << order.front()+1); + nodesEdges[i+1] = -1; + } + } + } + + + std::vector nodes; + nodes.push_back(shapeId); + std::list::iterator itl = order.begin(); + for (; itl != order.end(); itl++) + { + nodes.push_back((*itl) + 1); // SMDS id = VTK id + 1; + MESSAGE(" ordered node " << nodes[nodes.size()-1]); } + listOfListOfNodes.push_back(nodes); + } // partition geom faces with blocFissure // mesh blocFissure and geom faces of the skin (external wires given, triangle algo to choose) @@ -12623,10 +12465,10 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, if ( missType == SMDSAbs_Edge ) // boundary edges { nodes.resize( 2+iQuad ); - for ( int i = 0; i < nbFaceNodes; i += 1+iQuad) + for ( size_t i = 0; i < nbFaceNodes; i += 1+iQuad ) { - for ( int j = 0; j < nodes.size(); ++j ) - nodes[j] = nn[ i+j ]; + for ( size_t j = 0; j < nodes.size(); ++j ) + nodes[ j ] = nn[ i+j ]; if ( const SMDS_MeshElement* edge = aMesh->FindElement( nodes, SMDSAbs_Edge, /*noMedium=*/false )) presentBndElems.push_back( edge ); @@ -12713,14 +12555,14 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, ++nbAddedBnd; } else - for ( int i = 0; i < missingBndElems.size(); ++i ) + for ( size_t i = 0; i < missingBndElems.size(); ++i ) { - TConnectivity& nodes = missingBndElems[i]; + TConnectivity& nodes = missingBndElems[ i ]; if ( aroundElements && tgtEditor.GetMeshDS()->FindElement( nodes, missType, /*noMedium=*/false)) continue; - SMDS_MeshElement* newElem = + SMDS_MeshElement* newElem = tgtEditor.AddElement( nodes, elemKind.SetPoly( nodes.size()/(iQuad+1) > 4 )); nbAddedBnd += bool( newElem ); @@ -12757,18 +12599,18 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, // 3. Copy present boundary elements // ---------------------------------- if ( toCopyExistingBoundary ) - for ( int i = 0 ; i < presentBndElems.size(); ++i ) + for ( size_t i = 0 ; i < presentBndElems.size(); ++i ) { const SMDS_MeshElement* e = presentBndElems[i]; tgtNodes.resize( e->NbNodes() ); - for ( inode = 0; inode < nodes.size(); ++inode ) + for ( inode = 0; inode < tgtNodes.size(); ++inode ) tgtNodes[inode] = getNodeWithSameID( tgtMeshDS, e->GetNode(inode) ); presentEditor->AddElement( tgtNodes, elemToCopy.Init( e )); } else // store present elements to add them to a group - for ( int i = 0 ; i < presentBndElems.size(); ++i ) + for ( size_t i = 0 ; i < presentBndElems.size(); ++i ) { - presentEditor->myLastCreatedElems.Append( presentBndElems[i] ); + presentEditor->myLastCreatedElems.Append( presentBndElems[ i ]); } } // loop on given elements