X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH%2FSMESH_MeshEditor.cxx;h=f7fcec03e8fd5a6fdd42a1e261cdb4f0329a30f3;hp=146e8c12a2eccbbaa4df2033f7a1ea46c680b1b9;hb=5504d02a2237b17b8459bcd3b1fb2a89468598cd;hpb=8682ebb1ebbf9c8392c8fa4adcce76d37e171859 diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 146e8c12a..f7fcec03e 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 @@ -26,22 +26,21 @@ #include "SMESH_MeshEditor.hxx" -#include "SMDS_FaceOfNodes.hxx" -#include "SMDS_VolumeTool.hxx" +#include "SMDS_Downward.hxx" #include "SMDS_EdgePosition.hxx" +#include "SMDS_FaceOfNodes.hxx" #include "SMDS_FacePosition.hxx" -#include "SMDS_SpacePosition.hxx" -#include "SMDS_MeshGroup.hxx" #include "SMDS_LinearEdge.hxx" -#include "SMDS_Downward.hxx" +#include "SMDS_MeshGroup.hxx" #include "SMDS_SetIterator.hxx" - +#include "SMDS_SpacePosition.hxx" +#include "SMDS_VolumeTool.hxx" #include "SMESHDS_Group.hxx" #include "SMESHDS_Mesh.hxx" - #include "SMESH_Algo.hxx" #include "SMESH_ControlsDef.hxx" #include "SMESH_Group.hxx" +#include "SMESH_Mesh.hxx" #include "SMESH_MeshAlgos.hxx" #include "SMESH_MesherHelper.hxx" #include "SMESH_OctreeNode.hxx" @@ -73,6 +72,7 @@ #include #include #include +#include #include #include #include @@ -125,6 +125,18 @@ SMESH_MeshEditor::SMESH_MeshEditor( SMESH_Mesh* theMesh ) { } +//================================================================================ +/*! + * \brief Return mesh DS + */ +//================================================================================ + +SMESHDS_Mesh * SMESH_MeshEditor::GetMeshDS() +{ + return myMesh->GetMeshDS(); +} + + //================================================================================ /*! * \brief Clears myLastCreatedNodes and myLastCreatedElems @@ -683,7 +695,6 @@ static bool getNodesFromTwoTria(const SMDS_MeshElement * theTria1, bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1, const SMDS_MeshElement * theTria2 ) { - MESSAGE("InverseDiag"); myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); @@ -888,8 +899,6 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshNode * theNode1, myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - MESSAGE( "::InverseDiag()" ); - const SMDS_MeshElement *tr1, *tr2; if ( !findTriangles( theNode1, theNode2, tr1, tr2 )) return false; @@ -1011,8 +1020,6 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1, myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - MESSAGE( "::DeleteDiag()" ); - const SMDS_MeshElement *tr1, *tr2; if ( !findTriangles( theNode1, theNode2, tr1, tr2 )) return false; @@ -1105,7 +1112,6 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1, bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) { - MESSAGE("Reorient"); myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); @@ -1325,7 +1331,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 +1347,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 +1367,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; @@ -1518,7 +1524,7 @@ void SMESH_MeshEditor::QuadTo4Tri (TIDSortedElemSet & theElems) gp_XY uv [9]; uv[8] = gp_XY(0,0); gp_XYZ xyz[9]; vector< const SMDS_MeshNode* > nodes; - SMESHDS_SubMesh* subMeshDS; + SMESHDS_SubMesh* subMeshDS = 0; TopoDS_Face F; Handle(Geom_Surface) surface; TopLoc_Location loc; @@ -1601,13 +1607,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 +1931,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 ) @@ -2130,7 +2136,7 @@ namespace // No adjacent prisms. Select a variant with a best aspect ratio. - double badness[2] = { 0, 0 }; + double badness[2] = { 0., 0. }; static SMESH::Controls::NumericalFunctorPtr aspectRatio( new SMESH::Controls::AspectRatio); const SMDS_MeshNode** nodes = vol.GetNodes(); for ( int variant = 0; variant < nbVariants; ++variant ) @@ -2432,12 +2438,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 +2461,7 @@ void SMESH_MeshEditor::SplitVolumes (const TFacetOfElem & theElems, GetMeshDS()->RemoveNode( volNodes[i] ); } } // loop on volumes to split - + myLastCreatedNodes = newNodes; myLastCreatedElems = newElems; } @@ -2530,7 +2536,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 +2919,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 ] ); } } @@ -2931,22 +2937,19 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - MESSAGE( "::QuadToTri()" ); - SMESHDS_Mesh * aMesh = GetMeshDS(); Handle(Geom_Surface) surface; 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 +2972,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 +2983,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 +3000,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 ); @@ -3172,8 +3157,6 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - MESSAGE( "::TriToQuad()" ); - if ( !theCrit.get() ) return false; @@ -3278,7 +3261,7 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, if ( startElem ) { // Get candidates to be fused const SMDS_MeshElement *tr1 = startElem, *tr2 = 0, *tr3 = 0; - const SMESH_TLink *link12, *link13; + const SMESH_TLink *link12 = 0, *link13 = 0; startElem = 0; ASSERT( mapEl_setLi.find( tr1 ) != mapEl_setLi.end() ); set< SMESH_TLink >& setLi = mapEl_setLi[ tr1 ]; @@ -3957,8 +3940,6 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - MESSAGE((theSmoothMethod==LAPLACIAN ? "LAPLACIAN" : "CENTROIDAL") << "--::Smooth()"); - if ( theTgtAspectRatio < 1.0 ) theTgtAspectRatio = 1.0; @@ -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,10 +4473,9 @@ 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); SMESHDS_Mesh* aMesh = GetMeshDS(); const int nbNodes = elem->NbNodes(); @@ -4620,7 +4600,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++ ) @@ -4816,7 +4796,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, else if(nbSame==1) { // ---> pyramid + pentahedron - can not be created since it is needed // additional middle node at the center of face - INFOS( " Sweep for face " << elem->GetID() << " can not be created" ); + //INFOS( " Sweep for face " << elem->GetID() << " can not be created" ); return; } else if( nbSame == 2 ) { @@ -5387,7 +5367,6 @@ SMESH_MeshEditor::RotationSweep(TIDSortedElemSet theElemSets[2], // source elements for each generated one SMESH_SequenceOfElemPtr srcElems, srcNodes; - MESSAGE( "RotationSweep()"); gp_Trsf aTrsf; aTrsf.SetRotation( theAxis, theAngle ); gp_Trsf aTrsf2; @@ -5501,11 +5480,14 @@ SMESH_MeshEditor::RotationSweep(TIDSortedElemSet theElemSets[2], //purpose : standard construction //======================================================================= -SMESH_MeshEditor::ExtrusParam::ExtrusParam( const gp_Vec& theStep, - const int theNbSteps, - const int theFlags, - const double theTolerance): +SMESH_MeshEditor::ExtrusParam::ExtrusParam( const gp_Vec& theStep, + const int theNbSteps, + const std::list& theScales, + const gp_XYZ* theBasePoint, + const int theFlags, + const double theTolerance): myDir( theStep ), + myBaseP( Precision::Infinite(), 0, 0 ), myFlags( theFlags ), myTolerance( theTolerance ), myElemsToUse( NULL ) @@ -5515,6 +5497,37 @@ SMESH_MeshEditor::ExtrusParam::ExtrusParam( const gp_Vec& theStep, for (int i=1; i<=theNbSteps; i++ ) mySteps->Append( stepSize ); + int nbScales = theScales.size(); + if ( nbScales > 0 ) + { + if ( IsLinearVariation() && nbScales < theNbSteps ) + { + myScales.reserve( theNbSteps ); + std::list::const_iterator scale = theScales.begin(); + double prevScale = 1.0; + for ( int iSc = 1; scale != theScales.end(); ++scale, ++iSc ) + { + int iStep = int( iSc / double( nbScales ) * theNbSteps + 0.5 ); + int stDelta = Max( 1, iStep - myScales.size()); + double scDelta = ( *scale - prevScale ) / stDelta; + for ( int iStep = 0; iStep < stDelta; ++iStep ) + { + myScales.push_back( prevScale + scDelta ); + prevScale = myScales.back(); + } + prevScale = *scale; + } + } + else + { + myScales.assign( theScales.begin(), theScales.end() ); + } + } + if ( theBasePoint ) + { + myBaseP = *theBasePoint; + } + if (( theFlags & EXTRUSION_FLAG_SEW ) && ( theTolerance > 0 )) { @@ -5583,12 +5596,38 @@ SMESH_MeshEditor::ExtrusParam::ExtrusParam( const double theStepSize, //======================================================================= //function : ExtrusParam::SetElementsToUse //purpose : stores elements to use for extrusion by normal, depending on -// state of EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY flag +// state of EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY flag; +// define myBaseP for scaling //======================================================================= -void SMESH_MeshEditor::ExtrusParam::SetElementsToUse( const TIDSortedElemSet& elems ) +void SMESH_MeshEditor::ExtrusParam::SetElementsToUse( const TIDSortedElemSet& elems, + const TIDSortedElemSet& nodes ) { myElemsToUse = ToUseInpElemsOnly() ? & elems : 0; + + if ( Precision::IsInfinite( myBaseP.X() )) // myBaseP not defined + { + myBaseP.SetCoord( 0.,0.,0. ); + TIDSortedElemSet newNodes; + + const TIDSortedElemSet* elemSets[] = { &elems, &nodes }; + for ( int is2ndSet = 0; is2ndSet < 2; ++is2ndSet ) + { + const TIDSortedElemSet& elements = *( elemSets[ is2ndSet ]); + TIDSortedElemSet::const_iterator itElem = elements.begin(); + for ( ; itElem != elements.end(); itElem++ ) + { + const SMDS_MeshElement* elem = *itElem; + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + while ( itN->more() ) { + const SMDS_MeshElement* node = itN->next(); + if ( newNodes.insert( node ).second ) + myBaseP += SMESH_TNodeXYZ( node ); + } + } + } + myBaseP /= newNodes.size(); + } } //======================================================================= @@ -5658,6 +5697,41 @@ makeNodesByDir( SMESHDS_Mesh* mesh, const SMDS_MeshNode * newNode = mesh->AddNode( p.X(), p.Y(), p.Z() ); newNodes.push_back( newNode ); } + + if ( !myScales.empty() ) + { + if ( makeMediumNodes && myMediumScales.empty() ) + { + myMediumScales.resize( myScales.size() ); + double prevFactor = 1.; + for ( size_t i = 0; i < myScales.size(); ++i ) + { + myMediumScales[i] = 0.5 * ( prevFactor + myScales[i] ); + prevFactor = myScales[i]; + } + } + typedef std::vector::iterator ScaleIt; + ScaleIt scales[] = { myScales.begin(), myMediumScales.begin() }; + + size_t iSc = 0, nbScales = myScales.size() + myMediumScales.size(); + + gp_XYZ center = myBaseP; + std::list::iterator nIt = newNodes.begin(); + size_t iN = 0; + for ( beginStepIter( makeMediumNodes ); moreSteps() && ( iN < nbScales ); ++nIt, ++iN ) + { + center += myDir.XYZ() * nextStep(); + + iSc += int( makeMediumNodes ); + ScaleIt& scale = scales[ iSc % 2 ]; + + gp_XYZ xyz = SMESH_TNodeXYZ( *nIt ); + xyz = ( *scale * ( xyz - center )) + center; + mesh->MoveNode( *nIt, xyz.X(), xyz.Y(), xyz.Z() ); + + ++scale; + } + } return nbNodes; } @@ -5832,7 +5906,7 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet theElems[2], const int theFlags, const double theTolerance) { - ExtrusParam aParams( theStep, theNbSteps, theFlags, theTolerance ); + ExtrusParam aParams( theStep, theNbSteps, std::list(), 0, theFlags, theTolerance ); return ExtrusionSweep( theElems, aParams, newElemsMap ); } @@ -5853,16 +5927,12 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet theElemSets[2], // source elements for each generated one SMESH_SequenceOfElemPtr srcElems, srcNodes; - SMESHDS_Mesh* aMesh = GetMeshDS(); - setElemsFirst( theElemSets ); const int nbSteps = theParams.NbSteps(); - theParams.SetElementsToUse( theElemSets[0] ); + theParams.SetElementsToUse( theElemSets[0], theElemSets[1] ); - TNodeOfNodeListMap mapNewNodes; - //TNodeOfNodeVecMap mapNewNodes; + TNodeOfNodeListMap mapNewNodes; TElemOfVecOfNnlmiMap mapElemNewNodes; - //TElemOfVecOfMapNodesMap mapElemNewNodes; const bool isQuadraticMesh = bool( myMesh->NbEdges(ORDER_QUADRATIC) + myMesh->NbFaces(ORDER_QUADRATIC) + @@ -5958,7 +6028,6 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], const gp_Pnt& theRefPoint, const bool theMakeGroups) { - MESSAGE("ExtrusionAlongTrack"); myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); @@ -5986,6 +6055,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 +6313,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 +6345,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 +6358,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 ) ) @@ -6389,7 +6460,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], SMESH_MeshEditor_PathPoint PP2 = currList.front(); gp_Dir D1 = PP1.Tangent(); gp_Dir D2 = PP2.Tangent(); - gp_Dir Dnew( ( D1.XYZ() + D2.XYZ() ) / 2 ); + gp_Dir Dnew( D1.XYZ() + D2.XYZ() ); PP1.SetTangent(Dnew); fullList.push_back(PP1); fullList.splice( fullList.end(), currList, ++currList.begin(), currList.end() ); @@ -6454,7 +6525,7 @@ SMESH_MeshEditor::MakeEdgePathPoints(std::list& aPrms, aL2 = aVec.SquareMagnitude(); if ( aL2 < aTolVec2 ) return EXTR_CANT_GET_TANGENT; - gp_Dir aTgt( aVec ); + gp_Dir aTgt( FirstIsStart ? aVec : -aVec ); aPP.SetPnt( aP3D ); aPP.SetTangent( aTgt ); aPP.SetParameter( aT ); @@ -6479,9 +6550,11 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet theElemSets const bool theMakeGroups) { const int aNbTP = fullList.size(); + // Angles if( theHasAngles && !theAngles.empty() && theLinearVariation ) LinearAngleVariation(aNbTP-1, theAngles); + // fill vector of path points with angles vector aPPs; list::iterator itPP = fullList.begin(); @@ -6511,10 +6584,10 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet theElemSets { TIDSortedElemSet& theElements = theElemSets[ is2ndSet ]; itElem = theElements.begin(); - for ( ; itElem != theElements.end(); itElem++ ) { + for ( ; itElem != theElements.end(); itElem++ ) + { const SMDS_MeshElement* elem = *itElem; - - SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); while ( itN->more() ) { const SMDS_MeshElement* node = itN->next(); if ( newNodes.insert( node ).second ) @@ -6528,19 +6601,15 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet theElemSets // 4. Processing the elements SMESHDS_Mesh* aMesh = GetMeshDS(); + list emptyList; setElemsFirst( theElemSets ); for ( int is2ndSet = 0; is2ndSet < 2; ++is2ndSet ) { TIDSortedElemSet& theElements = theElemSets[ is2ndSet ]; - for ( itElem = theElements.begin(); itElem != theElements.end(); itElem++ ) { - // check element type + for ( itElem = theElements.begin(); itElem != theElements.end(); itElem++ ) + { const SMDS_MeshElement* elem = *itElem; - if ( !elem ) - continue; - // SMDSAbs_ElementType aTypeE = elem->GetType(); - // if ( aTypeE != SMDSAbs_Face && aTypeE != SMDSAbs_Edge ) - // continue; vector & newNodesItVec = mapElemNewNodes[ elem ]; newNodesItVec.reserve( elem->NbNodes() ); @@ -6552,13 +6621,11 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet theElemSets { ++nodeIndex; // check if a node has been already processed - const SMDS_MeshNode* node = - static_cast( itN->next() ); - TNodeOfNodeListMap::iterator nIt = mapNewNodes.find( node ); - if ( nIt == mapNewNodes.end() ) { - nIt = mapNewNodes.insert( make_pair( node, list() )).first; - list& listNewNodes = nIt->second; - + const SMDS_MeshNode* node = cast2Node( itN->next() ); + TNodeOfNodeListMap::iterator nIt = mapNewNodes.insert( make_pair( node, emptyList )).first; + list& listNewNodes = nIt->second; + if ( listNewNodes.empty() ) + { // make new nodes Standard_Real aAngle1x, aAngleT1T0, aTolAng; gp_Pnt aP0x, aP1x, aPN0, aPN1, aV0x, aV1x; @@ -6573,7 +6640,6 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet theElemSets const SMESH_MeshEditor_PathPoint& aPP0 = aPPs[0]; aP0x = aPP0.Pnt(); aDT0x= aPP0.Tangent(); - //cout<<"j = 0 PP: Pnt("< aTolAng) { + if (fabs(aAngleT1T0) > aTolAng) + { aDT1T0=aDT1x^aDT0x; anAxT1T0.SetLocation( aV1x ); anAxT1T0.SetDirection( aDT1T0 ); @@ -6611,13 +6678,11 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet theElemSets } // make new node - //MESSAGE("elem->IsQuadratic " << elem->IsQuadratic() << " " << elem->IsMediumNode(node)); - if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { + if ( elem->IsQuadratic() && !elem->IsMediumNode(node) ) + { // create additional node - double x = ( aPN1.X() + aPN0.X() )/2.; - double y = ( aPN1.Y() + aPN0.Y() )/2.; - double z = ( aPN1.Z() + aPN0.Z() )/2.; - const SMDS_MeshNode* newNode = aMesh->AddNode(x,y,z); + gp_XYZ midP = 0.5 * ( aPN1.XYZ() + aPN0.XYZ() ); + const SMDS_MeshNode* newNode = aMesh->AddNode( midP.X(), midP.Y(), midP.Z() ); myLastCreatedNodes.Append(newNode); srcNodes.Append( node ); listNewNodes.push_back( newNode ); @@ -6633,42 +6698,40 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet theElemSets aDT0x = aDT1x; } } - - else { + else if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) + { // if current elem is quadratic and current node is not medium // we have to check - may be it is needed to insert additional nodes - if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { - list< const SMDS_MeshNode* > & listNewNodes = nIt->second; - if(listNewNodes.size()==aNbTP-1) { - vector aNodes(2*(aNbTP-1)); - gp_XYZ P(node->X(), node->Y(), node->Z()); - list< const SMDS_MeshNode* >::iterator it = listNewNodes.begin(); - int i; - for(i=0; iX() + P.X() )/2.; - double y = ( N->Y() + P.Y() )/2.; - double z = ( N->Z() + P.Z() )/2.; - const SMDS_MeshNode* newN = aMesh->AddNode(x,y,z); - srcNodes.Append( node ); - myLastCreatedNodes.Append(newN); - aNodes[2*i] = newN; - aNodes[2*i+1] = N; - P = gp_XYZ(N->X(),N->Y(),N->Z()); - } - listNewNodes.clear(); - for(i=0; i<2*(aNbTP-1); i++) { - listNewNodes.push_back(aNodes[i]); - } + list< const SMDS_MeshNode* > & listNewNodes = nIt->second; + if ((int) listNewNodes.size() == aNbTP-1 ) + { + vector aNodes(2*(aNbTP-1)); + gp_XYZ P(node->X(), node->Y(), node->Z()); + list< const SMDS_MeshNode* >::iterator it = listNewNodes.begin(); + int i; + for(i=0; iX() + P.X() )/2.; + double y = ( N->Y() + P.Y() )/2.; + double z = ( N->Z() + P.Z() )/2.; + const SMDS_MeshNode* newN = aMesh->AddNode(x,y,z); + srcNodes.Append( node ); + myLastCreatedNodes.Append(newN); + aNodes[2*i] = newN; + aNodes[2*i+1] = N; + P = gp_XYZ(N->X(),N->Y(),N->Z()); + } + listNewNodes.clear(); + for(i=0; i<2*(aNbTP-1); i++) { + listNewNodes.push_back(aNodes[i]); } } } newNodesItVec.push_back( nIt ); } + // make new elements - //sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], - // newNodesItVec[0]->second.size(), myLastCreatedElems ); sweepElement( elem, newNodesItVec, newElemsMap[elem], aNbTP-1, srcElems ); } } @@ -6684,24 +6747,23 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet theElemSets //======================================================================= //function : LinearAngleVariation -//purpose : auxilary for ExtrusionAlongTrack +//purpose : spread values over nbSteps //======================================================================= -void SMESH_MeshEditor::LinearAngleVariation(const int nbSteps, + +void SMESH_MeshEditor::LinearAngleVariation(const int nbSteps, list& Angles) { int nbAngles = Angles.size(); - if( nbSteps > nbAngles ) { + if( nbSteps > nbAngles && nbAngles > 0 ) + { vector theAngles(nbAngles); - list::iterator it = Angles.begin(); - int i = -1; - for(; it!=Angles.end(); it++) { - i++; - theAngles[i] = (*it); - } + theAngles.assign( Angles.begin(), Angles.end() ); + list res; double rAn2St = double( nbAngles ) / double( nbSteps ); double angPrev = 0, angle; - for ( int iSt = 0; iSt < nbSteps; ++iSt ) { + for ( int iSt = 0; iSt < nbSteps; ++iSt ) + { double angCur = rAn2St * ( iSt+1 ); double angCurFloor = floor( angCur ); double angPrevFloor = floor( angPrev ); @@ -6723,10 +6785,7 @@ void SMESH_MeshEditor::LinearAngleVariation(const int nbSteps, res.push_back(angle); angPrev = angCur; } - Angles.clear(); - it = res.begin(); - for(; it!=res.end(); it++) - Angles.push_back( *it ); + Angles.swap( res ); } } @@ -6757,37 +6816,29 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, string groupPostfix; switch ( theTrsf.Form() ) { case gp_PntMirror: - MESSAGE("gp_PntMirror"); needReverse = true; groupPostfix = "mirrored"; break; case gp_Ax1Mirror: - MESSAGE("gp_Ax1Mirror"); groupPostfix = "mirrored"; break; case gp_Ax2Mirror: - MESSAGE("gp_Ax2Mirror"); needReverse = true; groupPostfix = "mirrored"; break; case gp_Rotation: - MESSAGE("gp_Rotation"); groupPostfix = "rotated"; break; case gp_Translation: - MESSAGE("gp_Translation"); groupPostfix = "translated"; break; case gp_Scale: - MESSAGE("gp_Scale"); groupPostfix = "scaled"; break; case gp_CompoundTrsf: // different scale by axis - MESSAGE("gp_CompoundTrsf"); groupPostfix = "scaled"; break; default: - MESSAGE("default"); needReverse = false; groupPostfix = "transformed"; } @@ -6897,7 +6948,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 ); @@ -6935,7 +6986,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() ); @@ -7240,76 +7291,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; } //======================================================================= @@ -7320,7 +7347,6 @@ int SMESH_MeshEditor::SimplifyFace (const vector& faceNod void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) { - MESSAGE("MergeNodes"); myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); @@ -7373,6 +7399,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 ); @@ -7398,7 +7425,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; } } @@ -7422,9 +7449,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; @@ -7459,7 +7486,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); } @@ -7468,53 +7495,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() ); } } } @@ -7526,195 +7553,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; @@ -7722,7 +7708,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 @@ -7737,7 +7723,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; @@ -7757,11 +7742,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 ]] && @@ -7770,139 +7756,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; @@ -7910,7 +7818,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 )) @@ -7963,10 +7871,6 @@ public: const SMDS_MeshElement* Get() const { return myElem; } - void Set(const SMDS_MeshElement* e) const - { myElem = e; } - - private: mutable const SMDS_MeshElement* myElem; }; @@ -8291,7 +8195,6 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode, myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - MESSAGE("::SewFreeBorder()"); Sew_Error aResult = SEW_OK; // ==================================== @@ -8399,7 +8302,7 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode, //const SMDS_MeshNode* faceNodes[ 4 ]; const SMDS_MeshNode* sideNode; - const SMDS_MeshElement* sideElem; + const SMDS_MeshElement* sideElem = 0; const SMDS_MeshNode* prevSideNode = theSideFirstNode; const SMDS_MeshNode* prevBordNode = theBordFirstNode; nBordIt = bordNodes.begin(); @@ -8424,7 +8327,7 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode, { const SMDS_MeshElement* elem = invElemIt->next(); // prepare data for a loop on links coming to prevSideNode, of a face or a volume - int iPrevNode, iNode = 0, nbNodes = elem->NbNodes(); + int iPrevNode = 0, iNode = 0, nbNodes = elem->NbNodes(); vector< const SMDS_MeshNode* > faceNodes( nbNodes, (const SMDS_MeshNode*)0 ); bool isVolume = volume.Set( elem ); const SMDS_MeshNode** nodes = isVolume ? volume.GetNodes() : & faceNodes[0]; @@ -8536,7 +8439,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] ); @@ -8972,7 +8875,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theElemen } // decide how to split a quadrangle: compare possible variants // and choose which of splits to be a quadrangle - int i1, i2, iSplit, nbSplits = nbLinkNodes - 1, iBestQuad; + int i1, i2, iSplit, nbSplits = nbLinkNodes - 1, iBestQuad = 0; if ( nbFaceNodes == 3 ) { iBestQuad = nbSplits; i4 = i3; @@ -9009,8 +8912,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++ ], @@ -9928,7 +9831,6 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet& theSide1, myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - MESSAGE ("::::SewSideElements()"); if ( theSide1.size() != theSide2.size() ) return SEW_DIFF_NB_OF_ELEMENTS; @@ -10607,7 +10509,7 @@ void SMESH_MeshEditor::DoubleElements( const TIDSortedElemSet& theElements ) // get an element type and an iterator over elements - SMDSAbs_ElementType type; + SMDSAbs_ElementType type = SMDSAbs_All; SMDS_ElemIteratorPtr elemIt; vector< const SMDS_MeshElement* > allElems; if ( theElements.empty() ) @@ -10709,7 +10611,6 @@ bool SMESH_MeshEditor::doubleNodes(SMESHDS_Mesh* theMeshDS, TNodeNodeMap& theNodeNodeMap, const bool theIsDoubleElem ) { - MESSAGE("doubleNodes"); // iterate through element and duplicate them (by nodes duplication) bool res = false; std::vector newNodes; @@ -10774,7 +10675,6 @@ bool SMESH_MeshEditor::doubleNodes(SMESHDS_Mesh* theMeshDS, bool SMESH_MeshEditor::DoubleNodes( const std::list< int >& theListOfNodes, const std::list< int >& theListOfModifiedElems ) { - MESSAGE("DoubleNodes"); myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); @@ -10848,10 +10748,9 @@ bool SMESH_MeshEditor::DoubleNodes( const std::list< int >& theListOfNodes, const SMDS_MeshElement* anElem = anElemToNodesIter->first; vector aNodeArr = anElemToNodesIter->second; if ( anElem ) - { - MESSAGE("ChangeElementNodes"); + { aMeshDS->ChangeElementNodes( anElem, &aNodeArr[ 0 ], anElem->NbNodes() ); - } + } } return true; @@ -10951,15 +10850,13 @@ bool SMESH_MeshEditor::AffectedElemGroupsInRegion( const TIDSortedElemSet& theEl // --- iterates on elements to be replicated and get elements by back references from their nodes TIDSortedElemSet::const_iterator elemItr = theElems.begin(); - int ielem; - for ( ielem=1; elemItr != theElems.end(); ++elemItr ) + for ( ; elemItr != theElems.end(); ++elemItr ) { SMDS_MeshElement* anElem = (SMDS_MeshElement*)*elemItr; if (!anElem || (anElem->GetType() != SMDSAbs_Face)) continue; gp_XYZ normal; SMESH_MeshAlgos::FaceNormal( anElem, normal, /*normalized=*/true ); - MESSAGE("element " << ielem++ << " normal " << normal.X() << " " << normal.Y() << " " << normal.Z()); std::set nodesElem; nodesElem.clear(); SMDS_ElemIteratorPtr nodeItr = anElem->nodesIterator(); @@ -10971,7 +10868,6 @@ bool SMESH_MeshEditor::AffectedElemGroupsInRegion( const TIDSortedElemSet& theEl std::set::iterator nodit = nodesElem.begin(); for (; nodit != nodesElem.end(); nodit++) { - MESSAGE(" noeud "); const SMDS_MeshNode* aNode = *nodit; if ( !aNode || theNodesNot.find(aNode) != theNodesNot.end() ) continue; @@ -10981,7 +10877,6 @@ bool SMESH_MeshEditor::AffectedElemGroupsInRegion( const TIDSortedElemSet& theEl SMDS_ElemIteratorPtr backElemItr = aNode->GetInverseElementIterator(); while ( backElemItr->more() ) { - MESSAGE(" backelem "); const SMDS_MeshElement* curElem = backElemItr->next(); if (alreadyCheckedElems.find(curElem) != alreadyCheckedElems.end()) continue; @@ -11003,10 +10898,8 @@ bool SMESH_MeshEditor::AffectedElemGroupsInRegion( const TIDSortedElemSet& theEl p.SetCoord( x/nb -aNode->X(), y/nb -aNode->Y(), z/nb -aNode->Z() ); - MESSAGE(" check " << p.X() << " " << p.Y() << " " << p.Z()); if (normal*p > 0) { - MESSAGE(" --- inserted") theAffectedElems.insert( curElem ); } else if (curElem->GetType() == SMDSAbs_Edge) @@ -11032,7 +10925,6 @@ bool SMESH_MeshEditor::AffectedElemGroupsInRegion( const TIDSortedElemSet& theEl } if (onside) { - MESSAGE(" --- edge onside inserted") theAffectedElems.insert(anEdge); } } @@ -11054,24 +10946,20 @@ bool SMESH_MeshEditor::AffectedElemGroupsInRegion( const TIDSortedElemSet& theEl // iterates on indicated elements and get elements by back references from their nodes TIDSortedElemSet::const_iterator elemItr = theElems.begin(); - int ielem; - for ( ielem = 1; elemItr != theElems.end(); ++elemItr ) + for ( ; elemItr != theElems.end(); ++elemItr ) { - MESSAGE("element " << ielem++); SMDS_MeshElement* anElem = (SMDS_MeshElement*)*elemItr; if (!anElem) continue; SMDS_ElemIteratorPtr nodeItr = anElem->nodesIterator(); while ( nodeItr->more() ) { - MESSAGE(" noeud "); const SMDS_MeshNode* aNode = cast2Node(nodeItr->next()); if ( !aNode || theNodesNot.find(aNode) != theNodesNot.end() ) continue; SMDS_ElemIteratorPtr backElemItr = aNode->GetInverseElementIterator(); while ( backElemItr->more() ) { - MESSAGE(" backelem "); const SMDS_MeshElement* curElem = backElemItr->next(); if ( curElem && theElems.find(curElem) == theElems.end() && ( bsc3d.get() ? @@ -11105,16 +10993,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 @@ -11137,7 +11025,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 ); @@ -11157,10 +11045,6 @@ bool SMESH_MeshEditor::DoubleNodesInRegion( const TIDSortedElemSet& theElems, */ double SMESH_MeshEditor::OrientedAngle(const gp_Pnt& p0, const gp_Pnt& p1, const gp_Pnt& g1, const gp_Pnt& g2) { -// MESSAGE(" p0: " << p0.X() << " " << p0.Y() << " " << p0.Z()); -// MESSAGE(" p1: " << p1.X() << " " << p1.Y() << " " << p1.Z()); -// MESSAGE(" g1: " << g1.X() << " " << g1.Y() << " " << g1.Z()); -// MESSAGE(" g2: " << g2.X() << " " << g2.Y() << " " << g2.Z()); gp_Vec vref(p0, p1); gp_Vec v1(p0, g1); gp_Vec v2(p0, g2); @@ -11229,83 +11113,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; @@ -11315,48 +11200,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 @@ -11372,185 +11257,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) @@ -11564,50 +11449,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 @@ -11615,66 +11500,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. @@ -11688,36 +11573,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 @@ -11725,40 +11610,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(); @@ -11805,137 +11690,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; } @@ -11945,11 +11830,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("--------------------------------"); @@ -11967,28 +11852,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 @@ -12001,10 +11886,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 @@ -12012,10 +11897,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) @@ -12023,10 +11908,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) @@ -12034,10 +11919,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 @@ -12055,157 +11940,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 @@ -12213,52 +12098,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) @@ -12269,50 +12154,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 @@ -12325,17 +12210,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; @@ -12343,125 +12228,125 @@ 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) // mesh volume around blocFissure (skin triangles and quadrangle given, tetra algo to choose) @@ -12635,10 +12520,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 ); @@ -12725,14 +12610,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 ); @@ -12769,18 +12654,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