X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH%2FSMESH_MeshEditor.cxx;h=1f343b1c4233af0670e82e8529895fbedee6afb6;hp=0f2f1ad710c39fa4159264fa4c5290fa8a0d5230;hb=2b69ded6e7adc32dafb69e39d78b654425a815b6;hpb=eb75a450cceabb83064e079ca4f907bde33b38de diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 0f2f1ad71..1f343b1c4 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 @@ -462,27 +474,22 @@ int SMESH_MeshEditor::Remove (const list< int >& theIDs, //================================================================================ /*! - * \brief Create 0D elements on all nodes of the given object except those - * nodes on which a 0D element already exists. + * \brief Create 0D elements on all nodes of the given object. * \param elements - Elements on whose nodes to create 0D elements; if empty, * the all mesh is treated * \param all0DElems - returns all 0D elements found or created on nodes of \a elements + * \param duplicateElements - to add one more 0D element to a node or not */ //================================================================================ void SMESH_MeshEditor::Create0DElementsOnAllNodes( const TIDSortedElemSet& elements, - TIDSortedElemSet& all0DElems ) + TIDSortedElemSet& all0DElems, + const bool duplicateElements ) { SMDS_ElemIteratorPtr elemIt; - vector< const SMDS_MeshElement* > allNodes; if ( elements.empty() ) { - allNodes.reserve( GetMeshDS()->NbNodes() ); elemIt = GetMeshDS()->elementsIterator( SMDSAbs_Node ); - while ( elemIt->more() ) - allNodes.push_back( elemIt->next() ); - - elemIt = elemSetIterator( allNodes ); } else { @@ -497,12 +504,13 @@ void SMESH_MeshEditor::Create0DElementsOnAllNodes( const TIDSortedElemSet& eleme { const SMDS_MeshNode* n = cast2Node( nodeIt->next() ); SMDS_ElemIteratorPtr it0D = n->GetInverseElementIterator( SMDSAbs_0DElement ); - if ( it0D->more() ) - all0DElems.insert( it0D->next() ); - else { + if ( duplicateElements || !it0D->more() ) + { myLastCreatedElems.Append( GetMeshDS()->Add0DElement( n )); all0DElems.insert( myLastCreatedElems.Last() ); } + while ( it0D->more() ) + all0DElems.insert( it0D->next() ); } } } @@ -683,7 +691,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 +895,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 +1016,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 +1108,6 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1, bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) { - MESSAGE("Reorient"); myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); @@ -1166,7 +1168,7 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) * \brief Reorient faces. * \param theFaces - the faces to reorient. If empty the whole mesh is meant * \param theDirection - desired direction of normal of \a theFace - * \param theFace - one of \a theFaces that sould be oriented according to + * \param theFace - one of \a theFaces that should be oriented according to * \a theDirection and whose orientation defines orientation of other faces * \return number of reoriented faces. */ @@ -1518,7 +1520,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; @@ -2130,7 +2132,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 ) @@ -2396,7 +2398,7 @@ void SMESH_MeshEditor::SplitVolumes (const TFacetOfElem & theElems, } else { - // among possible triangles create ones discribed by split method + // among possible triangles create ones described by split method const int* nInd = volTool.GetFaceNodesIndices( iF ); int nbVariants = ( nbNodes == 4 ? 2 : nbNodes ); int iCom = 0; // common node of triangle faces to split into @@ -2522,7 +2524,7 @@ void SMESH_MeshEditor::GetHexaFacetsToSplit( TIDSortedElemSet& theHexas, // Fill theFacets starting from facetID of startHex - // facets used for seach of volumes adjacent to already treated ones + // facets used for searching of volumes adjacent to already treated ones typedef pair< TFacetOfElem::iterator, int > TElemFacets; typedef map< TVolumeFaceKey, TElemFacets > TFacetMap; TFacetMap facetsToCheck; @@ -2931,8 +2933,6 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - MESSAGE( "::QuadToTri()" ); - SMESHDS_Mesh * aMesh = GetMeshDS(); Handle(Geom_Surface) surface; @@ -3153,8 +3153,6 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - MESSAGE( "::TriToQuad()" ); - if ( !theCrit.get() ) return false; @@ -3259,7 +3257,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 ]; @@ -3938,8 +3936,6 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - MESSAGE((theSmoothMethod==LAPLACIAN ? "LAPLACIAN" : "CENTROIDAL") << "--::Smooth()"); - if ( theTgtAspectRatio < 1.0 ) theTgtAspectRatio = 1.0; @@ -3998,11 +3994,11 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, fToler2 = BRep_Tool::Tolerance( face ); fToler2 *= fToler2 * 10.; isUPeriodic = surface->IsUPeriodic(); - if ( isUPeriodic ) - surface->UPeriod(); + // if ( isUPeriodic ) + // surface->UPeriod(); isVPeriodic = surface->IsVPeriodic(); - if ( isVPeriodic ) - surface->VPeriod(); + // if ( isVPeriodic ) + // surface->VPeriod(); surface->Bounds( u1, u2, v1, v2 ); helper.SetSubShape( face ); } @@ -4061,9 +4057,9 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, { // check if all faces around the node are on faceSubMesh // because a node on edge may be bound to face - SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(SMDSAbs_Face); bool all = true; if ( faceSubMesh ) { + SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(SMDSAbs_Face); while ( eIt->more() && all ) { const SMDS_MeshElement* e = eIt->next(); all = faceSubMesh->Contains( e ); @@ -4346,18 +4342,18 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, } } if ( maxRatio <= theTgtAspectRatio ) { - MESSAGE("-- quality achived --"); + //MESSAGE("-- quality achieved --"); break; } if (it+1 == theNbIterations) { - MESSAGE("-- Iteration limit exceeded --"); + //MESSAGE("-- Iteration limit exceeded --"); } } // smoothing iterations - MESSAGE(" Face id: " << *fId << - " Nb iterstions: " << it << - " Displacement: " << maxDisplacement << - " Aspect Ratio " << maxRatio); + // MESSAGE(" Face id: " << *fId << + // " Nb iterstions: " << it << + // " Displacement: " << maxDisplacement << + // " Aspect Ratio " << maxRatio); // --------------------------------------- // new nodes positions are computed, @@ -4476,7 +4472,6 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, const size_t nbSteps, SMESH_SequenceOfElemPtr& srcElements) { - //MESSAGE("sweepElement " << nbSteps); SMESHDS_Mesh* aMesh = GetMeshDS(); const int nbNodes = elem->NbNodes(); @@ -4573,7 +4568,11 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, std::swap( itNN[0], itNN[1] ); std::swap( prevNod[0], prevNod[1] ); std::swap( nextNod[0], nextNod[1] ); +#if defined(__APPLE__) + std::swap( isSingleNode[0], isSingleNode[1] ); +#else isSingleNode.swap( isSingleNode[0], isSingleNode[1] ); +#endif if ( nbSame > 0 ) sames[0] = 1 - sames[0]; iNotSameNode = 1 - iNotSameNode; @@ -5368,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; @@ -5482,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 ) @@ -5496,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 )) { @@ -5564,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(); + } } //======================================================================= @@ -5639,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; } @@ -5813,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 ); } @@ -5834,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) + @@ -5939,7 +6028,6 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], const gp_Pnt& theRefPoint, const bool theMakeGroups) { - MESSAGE("ExtrusionAlongTrack"); myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); @@ -6007,7 +6095,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], aPrms.push_back( aT ); } //Extrusion_Error err = - MakeEdgePathPoints(aPrms, aTrackEdge, (aN1==theN1), fullList); + makeEdgePathPoints(aPrms, aTrackEdge, (aN1==theN1), fullList); } else if( aS.ShapeType() == TopAbs_WIRE ) { list< SMESH_subMesh* > LSM; TopTools_SequenceOfShape Edges; @@ -6052,7 +6140,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], } list LPP; //Extrusion_Error err = - MakeEdgePathPoints(aPrms, aTrackEdge,(aN1->GetID()==startNid), LPP); + makeEdgePathPoints(aPrms, aTrackEdge,(aN1->GetID()==startNid), LPP); LLPPs.push_back(LPP); UsedNums.Add(k); // update startN for search following egde @@ -6095,7 +6183,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], return EXTR_BAD_PATH_SHAPE; } - return MakeExtrElements(theElements, fullList, theHasAngles, theAngles, theLinearVariation, + return makeExtrElements(theElements, fullList, theHasAngles, theAngles, theLinearVariation, theHasRefPoint, theRefPoint, theMakeGroups); } @@ -6234,7 +6322,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], TopoDS_Edge e = BRepBuilderAPI_MakeEdge( p1, p2 ); list LPP; aPrms.clear(); - MakeEdgePathPoints(aPrms, e, (aNodesList[i-1]->GetID()==startNid), LPP); + 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(); @@ -6292,7 +6380,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], aPrms.push_back( aT ); } //Extrusion_Error err = - MakeEdgePathPoints(aPrms, aTrackEdge, (aN1==theN1), fullList); + makeEdgePathPoints(aPrms, aTrackEdge, (aN1==theN1), fullList); } else if( aS.ShapeType() == TopAbs_WIRE ) { list< SMESH_subMesh* > LSM; @@ -6351,7 +6439,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], } list LPP; //Extrusion_Error err = - MakeEdgePathPoints(aPrms, aTrackEdge, aN1isOK, LPP); + makeEdgePathPoints(aPrms, aTrackEdge, aN1isOK, LPP); LLPPs.push_back(LPP); UsedNums.Add(k); // update startN for search following egde @@ -6387,17 +6475,17 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2], return EXTR_BAD_PATH_SHAPE; } - return MakeExtrElements(theElements, fullList, theHasAngles, theAngles, theLinearVariation, + return makeExtrElements(theElements, fullList, theHasAngles, theAngles, theLinearVariation, theHasRefPoint, theRefPoint, theMakeGroups); } //======================================================================= -//function : MakeEdgePathPoints -//purpose : auxilary for ExtrusionAlongTrack +//function : makeEdgePathPoints +//purpose : auxiliary for ExtrusionAlongTrack //======================================================================= SMESH_MeshEditor::Extrusion_Error -SMESH_MeshEditor::MakeEdgePathPoints(std::list& aPrms, +SMESH_MeshEditor::makeEdgePathPoints(std::list& aPrms, const TopoDS_Edge& aTrackEdge, bool FirstIsStart, list& LPP) @@ -6448,11 +6536,11 @@ SMESH_MeshEditor::MakeEdgePathPoints(std::list& aPrms, //======================================================================= -//function : MakeExtrElements -//purpose : auxilary for ExtrusionAlongTrack +//function : makeExtrElements +//purpose : auxiliary for ExtrusionAlongTrack //======================================================================= SMESH_MeshEditor::Extrusion_Error -SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet theElemSets[2], +SMESH_MeshEditor::makeExtrElements(TIDSortedElemSet theElemSets[2], list& fullList, const bool theHasAngles, list& theAngles, @@ -6465,7 +6553,7 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet theElemSets // Angles if( theHasAngles && !theAngles.empty() && theLinearVariation ) - LinearAngleVariation(aNbTP-1, theAngles); + linearAngleVariation(aNbTP-1, theAngles); // fill vector of path points with angles vector aPPs; @@ -6658,25 +6746,24 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet theElemSets //======================================================================= -//function : LinearAngleVariation -//purpose : auxilary for ExtrusionAlongTrack +//function : linearAngleVariation +//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 ); @@ -6698,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 ); } } @@ -6732,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"; } @@ -7182,7 +7258,7 @@ void SMESH_MeshEditor::FindCoincidentNodes (TIDSortedNodeSet & theNodes, } else while ( nIt->more() ) - theNodes.insert( theNodes.end(),nIt->next() ); + theNodes.insert( theNodes.end(), nIt->next() ); } else if ( theSeparateCornersAndMedium ) // separate corners from medium nodes { @@ -7215,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; + vector< const SMDS_MeshNode* > simpleNodes; simpleNodes.reserve( nbNodes ); + map< const SMDS_MeshNode*, int > nodeIndices; // indices within simpleNodes + map< const SMDS_MeshNode*, int >::iterator nInd; - // 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; - - // 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; } //======================================================================= @@ -7293,17 +7345,18 @@ int SMESH_MeshEditor::SimplifyFace (const vector& faceNod // in all elements. //======================================================================= -void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) +void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes, + const bool theAvoidMakingHoles) { - MESSAGE("MergeNodes"); myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - SMESHDS_Mesh* aMesh = GetMeshDS(); + SMESHDS_Mesh* mesh = GetMeshDS(); TNodeNodeMap nodeNodeMap; // node to replace - new node set elems; // all elements with changed nodes list< int > rmElemIds, rmNodeIds; + vector< ElemFeatures > newElemDefs; // Fill nodeNodeMap and elems @@ -7317,17 +7370,6 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) { const SMDS_MeshNode* nToRemove = *nIt; nodeNodeMap.insert( make_pair( nToRemove, nToKeep )); - if ( nToRemove != nToKeep ) - { - rmNodeIds.push_back( nToRemove->GetID() ); - AddToSameGroups( nToKeep, nToRemove, aMesh ); - // set _alwaysComputed to a sub-mesh of VERTEX to enable mesh computing - // after MergeNodes() w/o creating node in place of merged ones. - const SMDS_PositionPtr& pos = nToRemove->GetPosition(); - if ( pos && pos->GetTypeOfPosition() == SMDS_TOP_VERTEX ) - if ( SMESH_subMesh* sm = myMesh->GetSubMeshContaining( nToRemove->getshapeId() )) - sm->SetIsAlwaysComputed( true ); - } SMDS_ElemIteratorPtr invElemIt = nToRemove->GetInverseElementIterator(); while ( invElemIt->more() ) { const SMDS_MeshElement* elem = invElemIt->next(); @@ -7335,587 +7377,570 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } } } - // Change element nodes or remove an element - set nodeSet; - vector< const SMDS_MeshNode*> curNodes, uniqueNodes; - vector iRepl; - ElemFeatures elemType; + // Apply recursive replacements (BUG 0020185) + TNodeNodeMap::iterator nnIt = nodeNodeMap.begin(); + for ( ; nnIt != nodeNodeMap.end(); ++nnIt ) + { + const SMDS_MeshNode* nToKeep = nnIt->second; + TNodeNodeMap::iterator nnIt_i = nodeNodeMap.find( nToKeep ); + while ( nnIt_i != nodeNodeMap.end() && nnIt_i->second != nnIt->second ) + nToKeep = nnIt_i->second; + nnIt->second = nToKeep; + } + + if ( theAvoidMakingHoles ) + { + // find elements whose topology changes + + vector pbElems; + set::iterator eIt = elems.begin(); + for ( ; eIt != elems.end(); ++eIt ) + { + const SMDS_MeshElement* elem = *eIt; + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + while ( itN->more() ) + { + const SMDS_MeshNode* n = static_cast( itN->next() ); + TNodeNodeMap::iterator nnIt = nodeNodeMap.find( n ); + if ( nnIt != nodeNodeMap.end() && elem->GetNodeIndex( nnIt->second ) >= 0 ) + { + // several nodes of elem stick + pbElems.push_back( elem ); + break; + } + } + } + // exclude from merge nodes causing spoiling element + for ( size_t iLoop = 0; iLoop < pbElems.size(); ++iLoop ) // avoid infinite cycle + { + bool nodesExcluded = false; + for ( size_t i = 0; i < pbElems.size(); ++i ) + { + size_t prevNbMergeNodes = nodeNodeMap.size(); + if ( !applyMerge( pbElems[i], newElemDefs, nodeNodeMap, /*noHoles=*/true ) && + prevNbMergeNodes < nodeNodeMap.size() ) + nodesExcluded = true; + } + if ( !nodesExcluded ) + break; + } + } + + for ( nnIt = nodeNodeMap.begin(); nnIt != nodeNodeMap.end(); ++nnIt ) + { + const SMDS_MeshNode* nToRemove = nnIt->first; + const SMDS_MeshNode* nToKeep = nnIt->second; + if ( nToRemove != nToKeep ) + { + rmNodeIds.push_back( nToRemove->GetID() ); + AddToSameGroups( nToKeep, nToRemove, mesh ); + // set _alwaysComputed to a sub-mesh of VERTEX to enable further mesh computing + // w/o creating node in place of merged ones. + const SMDS_PositionPtr& pos = nToRemove->GetPosition(); + if ( pos && pos->GetTypeOfPosition() == SMDS_TOP_VERTEX ) + if ( SMESH_subMesh* sm = myMesh->GetSubMeshContaining( nToRemove->getshapeId() )) + sm->SetIsAlwaysComputed( true ); + } + } + + // Change element nodes or remove an element set::iterator eIt = elems.begin(); for ( ; eIt != elems.end(); eIt++ ) { const SMDS_MeshElement* elem = *eIt; - const int nbNodes = elem->NbNodes(); - const int aShapeId = FindShape( elem ); + SMESHDS_SubMesh* sm = mesh->MeshElements( elem->getshapeId() ); - nodeSet.clear(); - curNodes.resize( nbNodes ); - uniqueNodes.resize( nbNodes ); - iRepl.resize( nbNodes ); - int iUnique = 0, iCur = 0, nbRepl = 0; + bool keepElem = applyMerge( elem, newElemDefs, nodeNodeMap, /*noHoles=*/false ); + if ( !keepElem ) + rmElemIds.push_back( elem->GetID() ); - // get new seq of nodes - SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while ( itN->more() ) - { - const SMDS_MeshNode* n = static_cast( itN->next() ); - - TNodeNodeMap::iterator nnIt = nodeNodeMap.find( n ); - if ( nnIt != nodeNodeMap.end() ) { // n sticks - n = (*nnIt).second; - { ////////// BUG 0020185: begin - bool stopRecur = false; - set nodesRecur; - nodesRecur.insert(n); - while (!stopRecur) { - TNodeNodeMap::iterator nnIt_i = nodeNodeMap.find( n ); - if ( nnIt_i != nodeNodeMap.end() ) { // n sticks - n = (*nnIt_i).second; - if (!nodesRecur.insert(n).second) { - // error: recursive dependancy - stopRecur = true; - } - } - else - stopRecur = true; - } - } ////////// BUG 0020185: end + for ( size_t i = 0; i < newElemDefs.size(); ++i ) + { + if ( i > 0 || !mesh->ChangeElementNodes( elem, + & newElemDefs[i].myNodes[0], + newElemDefs[i].myNodes.size() )) + { + if ( i == 0 ) + { + newElemDefs[i].SetID( elem->GetID() ); + mesh->RemoveFreeElement(elem, sm, /*fromGroups=*/false); + if ( !keepElem ) rmElemIds.pop_back(); + } + else + { + newElemDefs[i].SetID( -1 ); + } + SMDS_MeshElement* newElem = this->AddElement( newElemDefs[i].myNodes, newElemDefs[i] ); + if ( sm && newElem ) + sm->AddElement( newElem ); + if ( elem != newElem ) + ReplaceElemInGroups( elem, newElem, mesh ); } - curNodes[ iCur ] = n; - bool isUnique = nodeSet.insert( n ).second; - if ( isUnique ) - uniqueNodes[ iUnique++ ] = n; - else - iRepl[ nbRepl++ ] = iCur; - iCur++; } + } - // Analyse element topology after replacement + // Remove bad elements, then equal nodes (order important) + Remove( rmElemIds, false ); + Remove( rmNodeIds, true ); + + return; +} + +//======================================================================= +//function : applyMerge +//purpose : Compute new connectivity of an element after merging nodes +// \param [in] elems - the element +// \param [out] newElemDefs - definition(s) of result element(s) +// \param [inout] nodeNodeMap - nodes to merge +// \param [in] avoidMakingHoles - if true and and the element becomes invalid +// after merging (but not degenerated), removes nodes causing +// the invalidity from \a nodeNodeMap. +// \return bool - true if the element should be removed +//======================================================================= + +bool SMESH_MeshEditor::applyMerge( const SMDS_MeshElement* elem, + vector< ElemFeatures >& newElemDefs, + TNodeNodeMap& nodeNodeMap, + const bool avoidMakingHoles ) +{ + bool toRemove = false; // to remove elem + int nbResElems = 1; // nb new elements + + newElemDefs.resize(nbResElems); + newElemDefs[0].Init( elem ); + newElemDefs[0].myNodes.clear(); + + set nodeSet; + vector< const SMDS_MeshNode*> curNodes; + vector< const SMDS_MeshNode*> & uniqueNodes = newElemDefs[0].myNodes; + vector iRepl; - bool isOk = true; - int nbUniqueNodes = nodeSet.size(); - if ( nbNodes != nbUniqueNodes ) // some nodes stick + const int nbNodes = elem->NbNodes(); + SMDSAbs_EntityType entity = elem->GetEntityType(); + + curNodes.resize( nbNodes ); + uniqueNodes.resize( nbNodes ); + iRepl.resize( nbNodes ); + int iUnique = 0, iCur = 0, nbRepl = 0; + + // Get new seq of nodes + + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + while ( itN->more() ) + { + const SMDS_MeshNode* n = static_cast( itN->next() ); + + TNodeNodeMap::iterator nnIt = nodeNodeMap.find( n ); + if ( nnIt != nodeNodeMap.end() ) { + n = (*nnIt).second; + } + curNodes[ iCur ] = n; + bool isUnique = nodeSet.insert( n ).second; + if ( isUnique ) + uniqueNodes[ iUnique++ ] = n; + else + iRepl[ nbRepl++ ] = iCur; + iCur++; + } + + // Analyse element topology after replacement + + int nbUniqueNodes = nodeSet.size(); + if ( nbNodes != nbUniqueNodes ) // some nodes stick + { + toRemove = true; + nbResElems = 0; + + if ( elem->IsQuadratic() && newElemDefs[0].myType == SMDSAbs_Face && nbNodes > 6 ) { - if (elem->IsPoly()) // Polygons and Polyhedral volumes + // if corner nodes stick, remove medium nodes between them from uniqueNodes + int nbCorners = nbNodes / 2; + for ( int iCur = 0; iCur < nbCorners; ++iCur ) { - if (elem->GetType() == SMDSAbs_Face) // Polygon + int iPrev = ( iCur + 1 ) % nbCorners; + if ( curNodes[ iCur ] == curNodes[ iPrev ] ) // corners stick { - elemType.Init( elem ); - const bool isQuad = elemType.myIsQuad; - if ( isQuad ) - SMDS_MeshCell::applyInterlace // interlace medium and corner nodes - ( SMDS_MeshCell::interlacedSmdsOrder( SMDSEntity_Quad_Polygon, nbNodes ), curNodes ); - - // a polygon can divide into several elements - vector polygons_nodes; - vector quantities; - int nbNew = SimplifyFace( curNodes, polygons_nodes, quantities ); - if (nbNew > 0) + int iMedium = iCur + nbCorners; + vector< const SMDS_MeshNode* >::iterator i = + std::find( uniqueNodes.begin() + nbCorners - nbRepl, + uniqueNodes.end(), + curNodes[ iMedium ]); + if ( i != uniqueNodes.end() ) { - vector face_nodes; - int inode = 0; - for (int iface = 0; iface < nbNew; iface++) - { - int nbNewNodes = quantities[iface]; - face_nodes.assign( polygons_nodes.begin() + inode, - polygons_nodes.begin() + inode + nbNewNodes ); - inode += nbNewNodes; - if ( isQuad ) // check if a result elem is a valid quadratic polygon - { - bool isValid = ( nbNewNodes % 2 == 0 ); - for ( int i = 0; i < nbNewNodes && isValid; ++i ) - isValid = ( elem->IsMediumNode( face_nodes[i]) == bool( i % 2 )); - elemType.SetQuad( isValid ); - if ( isValid ) // put medium nodes after corners - SMDS_MeshCell::applyInterlaceRev - ( SMDS_MeshCell::interlacedSmdsOrder( SMDSEntity_Quad_Polygon, - nbNewNodes ), face_nodes ); - } - elemType.SetPoly(( nbNewNodes / ( elemType.myIsQuad + 1 ) > 4 )); - - SMDS_MeshElement* newElem = AddElement( face_nodes, elemType ); - if ( aShapeId ) - aMesh->SetMeshElementOnShape(newElem, aShapeId); - } + --nbUniqueNodes; + for ( ; i+1 != uniqueNodes.end(); ++i ) + *i = *(i+1); } - rmElemIds.push_back(elem->GetID()); + } + } + } - } // Polygon + switch ( entity ) + { + case SMDSEntity_Polygon: + case SMDSEntity_Quad_Polygon: // Polygon + { + ElemFeatures* elemType = & newElemDefs[0]; + const bool isQuad = elemType->myIsQuad; + if ( isQuad ) + SMDS_MeshCell::applyInterlace // interlace medium and corner nodes + ( SMDS_MeshCell::interlacedSmdsOrder( SMDSEntity_Quad_Polygon, nbNodes ), curNodes ); - else if (elem->GetType() == SMDSAbs_Volume) // Polyhedral volume + // a polygon can divide into several elements + vector polygons_nodes; + vector quantities; + nbResElems = SimplifyFace( curNodes, polygons_nodes, quantities ); + newElemDefs.resize( nbResElems ); + for ( int inode = 0, iface = 0; iface < nbResElems; iface++ ) + { + ElemFeatures* elemType = & newElemDefs[iface]; + if ( iface ) elemType->Init( elem ); + + vector& face_nodes = elemType->myNodes; + int nbNewNodes = quantities[iface]; + face_nodes.assign( polygons_nodes.begin() + inode, + polygons_nodes.begin() + inode + nbNewNodes ); + inode += nbNewNodes; + if ( isQuad ) // check if a result elem is a valid quadratic polygon { - 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) - { - int nbFaces = aPolyedre->NbFaces(); - - vector poly_nodes; - vector quantities; - - for (int iface = 1; iface <= nbFaces; iface++) { - int nbFaceNodes = aPolyedre->NbFaceNodes(iface); - vector faceNodes (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 - faceNode = (*nnIt).second; - } - faceNodes[inode - 1] = faceNode; - } + bool isValid = ( nbNewNodes % 2 == 0 ); + for ( int i = 0; i < nbNewNodes && isValid; ++i ) + isValid = ( elem->IsMediumNode( face_nodes[i]) == bool( i % 2 )); + elemType->SetQuad( isValid ); + if ( isValid ) // put medium nodes after corners + SMDS_MeshCell::applyInterlaceRev + ( SMDS_MeshCell::interlacedSmdsOrder( SMDSEntity_Quad_Polygon, + nbNewNodes ), face_nodes ); + } + elemType->SetPoly(( nbNewNodes / ( elemType->myIsQuad + 1 ) > 4 )); + } + nbUniqueNodes = newElemDefs[0].myNodes.size(); + break; + } // Polygon - SimplifyFace(faceNodes, poly_nodes, quantities); - } + case SMDSEntity_Polyhedra: // Polyhedral volume + { + if ( nbUniqueNodes >= 4 ) + { + // each face has to be analyzed in order to check volume validity + if ( const SMDS_VtkVolume* aPolyedre = dynamic_cast( elem )) + { + int nbFaces = aPolyedre->NbFaces(); - if (quantities.size() > 3) { - // to be done: remove coincident faces - } + vector& poly_nodes = newElemDefs[0].myNodes; + vector & quantities = newElemDefs[0].myPolyhedQuantities; + vector faceNodes; + poly_nodes.clear(); + quantities.clear(); - if (quantities.size() > 3) - { - const SMDS_MeshElement* newElem = - aMesh->AddPolyhedralVolume(poly_nodes, quantities); - myLastCreatedElems.Append(newElem); - if ( aShapeId && newElem ) - aMesh->SetMeshElementOnShape( newElem, aShapeId ); - rmElemIds.push_back(elem->GetID()); - } - } - else { - rmElemIds.push_back(elem->GetID()); + for (int iface = 1; iface <= nbFaces; iface++) + { + int nbFaceNodes = aPolyedre->NbFaceNodes(iface); + 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 + faceNode = (*nnIt).second; + faceNodes[inode - 1] = faceNode; } + SimplifyFace(faceNodes, poly_nodes, quantities); } - } - else { - } - continue; - } // poly element - - // 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 - 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); - } - break; - case 6: ///////////////////////////////////// PENTAHEDRON - 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 ]; - } - else if (nbRepl == 3 && - iRepl[ 0 ] < 3 && iRepl[ 1 ] < 3 && iRepl[ 2 ] < 3 ) { - // all bottom nodes stick: set a top before - uniqueNodes[ 3 ] = uniqueNodes [ 0 ]; - uniqueNodes[ 0 ] = curNodes [ 3 ]; - uniqueNodes[ 1 ] = curNodes [ 4 ]; - uniqueNodes[ 2 ] = curNodes [ 5 ]; - } - 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 - 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; + if ( quantities.size() > 3 ) + { + // TODO: remove coincident faces + nbResElems = 1; + nbUniqueNodes = newElemDefs[0].myNodes.size(); } - 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; + } + } + break; + + // Regular elements + // TODO not all the possible cases are solved. Find something more generic? + case SMDSEntity_Edge: //////// EDGE + case SMDSEntity_Triangle: //// TRIANGLE + case SMDSEntity_Quad_Triangle: + case SMDSEntity_Tetra: + case SMDSEntity_Quad_Tetra: // TETRAHEDRON + { + break; + } + case SMDSEntity_Quad_Edge: + { + break; + } + case SMDSEntity_Quadrangle: //////////////////////////////////// QUADRANGLE + { + if ( nbUniqueNodes < 3 ) + toRemove = true; + else if ( nbRepl == 1 && curNodes[ iRepl[0]] == curNodes[( iRepl[0]+2 )%4 ]) + toRemove = true; // opposite nodes stick + else + toRemove = false; + break; + } + case SMDSEntity_Quad_Quadrangle: // Quadratic QUADRANGLE + { + // 1 5 2 + // +---+---+ + // | | + // 4+ +6 + // | | + // +---+---+ + // 0 7 3 + if ( nbUniqueNodes == 6 && + iRepl[0] < 4 && + ( nbRepl == 1 || iRepl[1] >= 4 )) + { + toRemove = false; + } + 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] ))) + { + toRemove = false; + } + break; + } + case SMDSEntity_Penta: ///////////////////////////////////// PENTAHEDRON + { + if ( nbUniqueNodes == 4 ) { + // ---------------------------------> tetrahedron + if ( curNodes[3] == curNodes[4] && + curNodes[3] == curNodes[5] ) { + // top nodes stick + toRemove = false; + } + else if ( curNodes[0] == curNodes[1] && + curNodes[0] == curNodes[2] ) { + // bottom nodes stick: set a top before + uniqueNodes[ 3 ] = uniqueNodes [ 0 ]; + uniqueNodes[ 0 ] = curNodes [ 5 ]; + uniqueNodes[ 1 ] = curNodes [ 4 ]; + uniqueNodes[ 2 ] = curNodes [ 3 ]; + toRemove = false; + } + else if (( curNodes[0] == curNodes[3] ) + + ( curNodes[1] == curNodes[4] ) + + ( curNodes[2] == curNodes[5] ) == 2 ) { + // a lateral face turns into a line + toRemove = false; + } + } + else if ( nbUniqueNodes == 5 ) { + // 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 ]; + toRemove = false; + } + 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 ]; + toRemove = false; + } + 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 ]; + toRemove = false; + } + } + break; + } + case SMDSEntity_Hexa: + { + //////////////////////////////////// HEXAHEDRON + SMDS_VolumeTool hexa (elem); + hexa.SetExternalNormal(); + if ( nbUniqueNodes == 4 && nbRepl == 4 ) { + //////////////////////// 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( 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; + if ( nbStick == 1 ) { + // ... and the opposite one - into a triangle. + // set a top node + uniqueNodes.push_back( curNodes[ pickInd ]); + toRemove = false; } + break; } - if(nbRepl==4) { - MESSAGE("nbRepl=4: " << iRepl[0] << " " << iRepl[1] << " " << iRepl[2] << " " << iRepl[3]); - } - if(nbRepl==5) { - MESSAGE("nbRepl=5: " << iRepl[0] << " " << iRepl[1] << " " << iRepl[2] << " " << iRepl[3] << " " << iRepl[4]); - } - break; } - //////////////////////////////////// HEXAHEDRON - isOk = false; - SMDS_VolumeTool hexa (elem); - hexa.SetExternalNormal(); - if ( nbUniqueNodes == 4 && nbRepl == 4 ) { - //////////////////////// HEX ---> 1 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 iOppFace = hexa.GetOppFaceIndex( iFace ); - ind = hexa.GetFaceNodesIndices( iOppFace ); - int nbStick = 0; - for ( iCur = 0; iCur < 4 && nbStick < 2; iCur++ ) { - if ( curNodes[ind[ iCur ]] == curNodes[ind[ iCur + 1 ]] ) - nbStick++; - } - if ( nbStick == 1 ) { - // ... and the opposite one - into a triangle. - // set a top node - ind = hexa.GetFaceNodesIndices( iFace ); - uniqueNodes[ 3 ] = curNodes[ind[ 0 ]]; - isOk = true; + } + else if ( nbUniqueNodes == 6 && nbRepl == 2 ) { + //////////////////////// HEX ---> prism + int nbTria = 0, iTria[3]; + const int *ind; // indices of face nodes + // look for triangular faces + for ( int iFace = 0; iFace < 6 && nbTria < 3; iFace++ ) { + ind = hexa.GetFaceNodesIndices( iFace ); + TIDSortedNodeSet faceNodes; + for ( iCur = 0; iCur < 4; iCur++ ) + faceNodes.insert( curNodes[ind[iCur]] ); + if ( faceNodes.size() == 3 ) + iTria[ nbTria++ ] = iFace; + } + // check if triangles are opposite + if ( nbTria == 2 && iTria[0] == hexa.GetOppFaceIndex( iTria[1] )) + { + // set nodes of the bottom triangle + ind = hexa.GetFaceNodesIndices( iTria[ 0 ]); + vector indB; + for ( iCur = 0; iCur < 4; iCur++ ) + if ( ind[iCur] != iRepl[0] && ind[iCur] != iRepl[1]) + indB.push_back( ind[iCur] ); + if ( !hexa.IsForward() ) + std::swap( indB[0], indB[2] ); + for ( iCur = 0; iCur < 3; iCur++ ) + uniqueNodes[ iCur ] = curNodes[indB[iCur]]; + // set nodes of the top triangle + const int *indT = hexa.GetFaceNodesIndices( iTria[ 1 ]); + for ( iCur = 0; iCur < 3; ++iCur ) + for ( int j = 0; j < 4; ++j ) + if ( hexa.IsLinked( indB[ iCur ], indT[ j ] )) + { + uniqueNodes[ iCur + 3 ] = curNodes[ indT[ j ]]; + break; } - break; - } - } - } - else if ( nbUniqueNodes == 6 && nbRepl == 2 ) { - //////////////////////// HEX ---> 1 prism - int nbTria = 0, iTria[3]; - const int *ind; // indices of face nodes - // look for triangular faces - for ( int iFace = 0; iFace < 6 && nbTria < 3; iFace++ ) { - ind = hexa.GetFaceNodesIndices( iFace ); - TIDSortedNodeSet faceNodes; - for ( iCur = 0; iCur < 4; iCur++ ) - faceNodes.insert( curNodes[ind[iCur]] ); - if ( faceNodes.size() == 3 ) - iTria[ nbTria++ ] = iFace; - } - // 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; - for ( iCur = 0; iCur < 4; iCur++ ) - if ( ind[iCur] != iRepl[0] && ind[iCur] != iRepl[1]) - indB.push_back( ind[iCur] ); - if ( !hexa.IsForward() ) - std::swap( indB[0], indB[2] ); - for ( iCur = 0; iCur < 3; iCur++ ) - uniqueNodes[ iCur ] = curNodes[indB[iCur]]; - // set nodes of the top triangle - const int *indT = hexa.GetFaceNodesIndices( iTria[ 1 ]); - for ( iCur = 0; iCur < 3; ++iCur ) - for ( int j = 0; j < 4; ++j ) - if ( hexa.IsLinked( indB[ iCur ], indT[ j ] )) - { - uniqueNodes[ iCur + 3 ] = curNodes[ indT[ j ]]; - break; - } - } + toRemove = false; break; } - else if (nbUniqueNodes == 5 && nbRepl == 4 ) { - //////////////////// HEXAHEDRON ---> 2 tetrahedrons - 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 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++ ) { - if ( curNodes[ind[ iCur ]] == curNodes[ind[ iCur + 1 ]] ) - nbStick++; - else if ( iUnique >= 0 ) - uniqueNodes[ iUnique-- ] = curNodes[ind[ iCur ]]; - } - if ( nbStick == 0 ) { - // ... 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 ); - isOk = true; - } - break; + } + 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 ]] && + curNodes[ind[ 0 ]] == curNodes[ind[ 2 ]] && + curNodes[ind[ 0 ]] == curNodes[ind[ 3 ]] ) { + // one face turns into a point ... + int iOppFace = hexa.GetOppFaceIndex( iFace ); + ind = hexa.GetFaceNodesIndices( iOppFace ); + uniqueNodes.clear(); + for ( iCur = 0; iCur < 4; iCur++ ) { + if ( curNodes[ind[ iCur ]] == curNodes[ind[ iCur + 1 ]] ) + break; + else + uniqueNodes.push_back( curNodes[ind[ iCur ]]); } + if ( uniqueNodes.size() == 4 ) { + // ... and the opposite one is a quadrangle + // set a top node + const int* indTop = hexa.GetFaceNodesIndices( iFace ); + uniqueNodes.push_back( curNodes[indTop[ 0 ]]); + toRemove = false; + } + 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++ ) { - const int *ind = hexa.GetFaceNodesIndices( iFace ); // indices of face nodes - 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); - } - // 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 ( toRemove && nbUniqueNodes > 4 ) { + ////////////////// HEXAHEDRON ---> polyhedron + hexa.SetExternalNormal(); + vector& poly_nodes = newElemDefs[0].myNodes; + vector & quantities = newElemDefs[0].myPolyhedQuantities; + poly_nodes.reserve( 6 * 4 ); poly_nodes.clear(); + quantities.reserve( 6 ); quantities.clear(); + 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 } - 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; - } - } + nodeSet.clear(); + for ( iCur = 0; iCur < 4; iCur++ ) + { + if ( nodeSet.insert( curNodes[ind[ iCur ]] ).second ) + poly_nodes.push_back( curNodes[ind[ iCur ]]); } - } // if ( nbUniqueNodes == 6 && nbRepl == 4 ) - else + if ( nodeSet.size() < 3 ) + poly_nodes.resize( poly_nodes.size() - nodeSet.size() ); + else + quantities.push_back( nodeSet.size() ); + } + if ( quantities.size() >= 4 ) { - MESSAGE("MergeNodes() removes hexahedron "<< elem); + nbResElems = 1; + nbUniqueNodes = poly_nodes.size(); + newElemDefs[0].SetPoly(true); } - break; - } // HEXAHEDRON + } + break; + } // case HEXAHEDRON - default: - isOk = false; - } // switch ( nbNodes ) + default: + toRemove = true; - } // if ( nbNodes != nbUniqueNodes ) // some nodes stick + } // switch ( entity ) - if ( isOk ) // the non-poly elem remains valid after sticking nodes + if ( toRemove && nbResElems == 0 && avoidMakingHoles ) { - if ( nbNodes != nbUniqueNodes || - !aMesh->ChangeElementNodes( elem, & curNodes[0], nbNodes )) - { - elemType.Init( elem ).SetID( elem->GetID() ); - - SMESHDS_SubMesh * sm = aShapeId > 0 ? aMesh->MeshElements(aShapeId) : 0; - aMesh->RemoveFreeElement(elem, sm, /*fromGroups=*/false); - - uniqueNodes.resize(nbUniqueNodes); - SMDS_MeshElement* newElem = this->AddElement( uniqueNodes, elemType ); - if ( sm && newElem ) - sm->AddElement( newElem ); - if ( elem != newElem ) - ReplaceElemInGroups( elem, newElem, aMesh ); - } - } - else { - // Remove invalid regular element or invalid polygon - rmElemIds.push_back( elem->GetID() ); + // erase from nodeNodeMap nodes whose merge spoils elem + vector< const SMDS_MeshNode* > noMergeNodes; + SMESH_MeshAlgos::DeMerge( elem, curNodes, noMergeNodes ); + for ( size_t i = 0; i < noMergeNodes.size(); ++i ) + nodeNodeMap.erase( noMergeNodes[i] ); } + + } // if ( nbNodes != nbUniqueNodes ) // some nodes stick - } // loop on elements + uniqueNodes.resize( nbUniqueNodes ); - // Remove bad elements, then equal nodes (order important) + if ( !toRemove && nbResElems == 0 ) + nbResElems = 1; - Remove( rmElemIds, false ); - Remove( rmNodeIds, true ); + newElemDefs.resize( nbResElems ); - return; + return !toRemove; } @@ -8262,7 +8287,6 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode, myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - MESSAGE("::SewFreeBorder()"); Sew_Error aResult = SEW_OK; // ==================================== @@ -8307,7 +8331,7 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode, // ------------------------------------------------------------------------- // 1. Since sewing may break if there are volumes to split on the side 2, - // we wont move nodes but just compute new coordinates for them + // we won't move nodes but just compute new coordinates for them typedef map TNodeXYZMap; TNodeXYZMap nBordXYZ; list< const SMDS_MeshNode* >& bordNodes = nSide[ 0 ]; @@ -8370,7 +8394,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(); @@ -8395,7 +8419,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]; @@ -8471,7 +8495,7 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode, } // loop on inverse elements of prevSideNode if ( !sideNode ) { - MESSAGE(" Cant find path by links of the Side 2 "); + MESSAGE(" Can't find path by links of the Side 2 "); return SEW_BAD_SIDE_NODES; } sideNodes.push_back( sideNode ); @@ -8943,7 +8967,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; @@ -9269,7 +9293,7 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, // remove a linear element GetMeshDS()->RemoveFreeElement(elem, theSm, /*fromGroups=*/false); - // remove central nodes of biquadratic elements (biquad->quad convertion) + // remove central nodes of biquadratic elements (biquad->quad conversion) if ( hasCentralNodes ) for ( size_t i = nbNodes * 2; i < nodes.size(); ++i ) if ( nodes[i]->NbInverseElements() == 0 ) @@ -9899,7 +9923,6 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet& theSide1, myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - MESSAGE ("::::SewSideElements()"); if ( theSide1.size() != theSide2.size() ) return SEW_DIFF_NB_OF_ELEMENTS; @@ -9918,7 +9941,7 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet& theSide1, // face does not exist SMESHDS_Mesh* aMesh = GetMeshDS(); - // TODO algoritm not OK with vtkUnstructuredGrid: 2 meshes can't share nodes + // TODO algorithm not OK with vtkUnstructuredGrid: 2 meshes can't share nodes //SMDS_Mesh aTmpFacesMesh; // try to use the same mesh TIDSortedElemSet faceSet1, faceSet2; set volSet1, volSet2; @@ -10578,7 +10601,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() ) @@ -10680,7 +10703,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; @@ -10745,7 +10767,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(); @@ -10819,10 +10840,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; @@ -10922,15 +10942,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(); @@ -10942,7 +10960,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; @@ -10952,7 +10969,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; @@ -10974,10 +10990,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) @@ -11003,7 +11017,6 @@ bool SMESH_MeshEditor::AffectedElemGroupsInRegion( const TIDSortedElemSet& theEl } if (onside) { - MESSAGE(" --- edge onside inserted") theAffectedElems.insert(anEdge); } } @@ -11025,24 +11038,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() ? @@ -11128,10 +11137,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); @@ -11166,9 +11171,9 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectormyMesh->GetMeshDS(); meshDS->BuildDownWardConnectivity(true); @@ -11191,7 +11196,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector emptySet; emptyMap.clear(); - MESSAGE(".. Number of domains :"< > mutipleNodes; // nodes multi domains with domain order std::map > mutipleNodesToFace; // nodes multi domains with domain order to transform in Face (junction between 3 or more 2D domains) - MESSAGE(".. Duplication of the nodes"); + //MESSAGE(".. Duplication of the nodes"); for (int idomain = idom0; idomain < nbDomains; idomain++) { itface = faceDomains.begin(); @@ -11403,7 +11408,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector > nodeQuadDomains; std::map mapOfJunctionGroups; - MESSAGE(".. Creation of elements: simple junction"); + //MESSAGE(".. Creation of elements: simple junction"); if (createJointElems) { int idg; @@ -11585,7 +11590,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector >::const_iterator itnod = nodeDomains.begin(); @@ -11741,7 +11746,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorCleanDownWardConnectivity(); // Mesh has been modified, downward connectivity is no more usable, free memory - grid->BuildLinks(); + grid->DeleteLinks(); CHRONOSTOP(50); counters::stats(); @@ -11760,9 +11765,9 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector& theElems) { - MESSAGE("-------------------------------------------------"); - MESSAGE("SMESH_MeshEditor::CreateFlatElementsOnFacesGroups"); - MESSAGE("-------------------------------------------------"); + // MESSAGE("-------------------------------------------------"); + // MESSAGE("SMESH_MeshEditor::CreateFlatElementsOnFacesGroups"); + // MESSAGE("-------------------------------------------------"); SMESHDS_Mesh *meshDS = this->myMesh->GetMeshDS(); @@ -11924,9 +11929,9 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, std::vector& nodesCoords, std::vector >& listOfListOfNodes) { - MESSAGE("--------------------------------"); - MESSAGE("SMESH_MeshEditor::CreateHoleSkin"); - MESSAGE("--------------------------------"); + // MESSAGE("--------------------------------"); + // MESSAGE("SMESH_MeshEditor::CreateHoleSkin"); + // MESSAGE("--------------------------------"); // --- zone of volumes to remove is given : // 1 either by a geom shape (one or more vertices) and a radius, @@ -12028,7 +12033,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, if (isNodeGroup) // --- a group of nodes is provided : find all the volumes using one or more of this nodes { - MESSAGE("group of nodes provided"); + //MESSAGE("group of nodes provided"); SMDS_ElemIteratorPtr elemIt = groupDS->GetElements(); while ( elemIt->more() ) { @@ -12050,7 +12055,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, } else if (isNodeCoords) { - MESSAGE("list of nodes coordinates provided"); + //MESSAGE("list of nodes coordinates provided"); size_t i = 0; int k = 0; while ( i < nodesCoords.size()-2 ) @@ -12060,13 +12065,13 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, 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()); + //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"); + //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); @@ -12078,20 +12083,17 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, 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()); + //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); + //MESSAGE("startNode->nodeId " << nodeId); double radius2 = radius*radius; - MESSAGE("radius2 " << radius2); + //MESSAGE("radius2 " << radius2); // --- volumes on start node @@ -12120,7 +12122,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, { std::set::iterator it = setOfVolToCheck.begin(); int vtkId = *it; - MESSAGE("volume to check, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); + //MESSAGE("volume to check, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); bool volInside = false; vtkIdType npts = 0; vtkIdType* pts = 0; @@ -12131,7 +12133,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, if (mapOfNodeDistance2.count(pts[i])) { distance2 = mapOfNodeDistance2[pts[i]]; - MESSAGE("point " << pts[i] << " distance2 " << distance2); + //MESSAGE("point " << pts[i] << " distance2 " << distance2); } else { @@ -12149,7 +12151,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, } } mapOfNodeDistance2[pts[i]] = distance2; - MESSAGE(" point " << pts[i] << " distance2 " << distance2 << " coords " << coords[0] << " " << coords[1] << " " << coords[2]); + //MESSAGE(" point " << pts[i] << " distance2 " << distance2 << " coords " << coords[0] << " " << coords[1] << " " << coords[2]); } if (distance2 < radius2) { @@ -12161,7 +12163,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, if (volInside) { setOfInsideVol.insert(vtkId); - MESSAGE(" volume inside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); + //MESSAGE(" volume inside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); int neighborsVtkIds[NBMAXNEIGHBORS]; int downIds[NBMAXNEIGHBORS]; unsigned char downTypes[NBMAXNEIGHBORS]; @@ -12173,7 +12175,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, else { setOfOutsideVol.insert(vtkId); - MESSAGE(" volume outside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); + //MESSAGE(" volume outside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); } setOfVolToCheck.erase(vtkId); } @@ -12186,7 +12188,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, std::set setOfVolToReCheck; while (addedInside) { - MESSAGE(" --------------------------- re check"); + //MESSAGE(" --------------------------- re check"); addedInside = false; std::set::iterator itv = setOfInsideVol.begin(); for (; itv != setOfInsideVol.end(); ++itv) @@ -12208,7 +12210,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, int vtkId = *it; if (grid->GetCellType(vtkId) == VTK_HEXAHEDRON) { - MESSAGE("volume to recheck, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); + //MESSAGE("volume to recheck, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); int countInside = 0; int neighborsVtkIds[NBMAXNEIGHBORS]; int downIds[NBMAXNEIGHBORS]; @@ -12217,10 +12219,10 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, for (int n = 0; n < nbNeighbors; n++) if (setOfInsideVol.count(neighborsVtkIds[n])) countInside++; - MESSAGE("countInside " << countInside); + //MESSAGE("countInside " << countInside); if (countInside > 1) { - MESSAGE(" volume inside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); + //MESSAGE(" volume inside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId)); setOfInsideVol.insert(vtkId); sgrp->Add(meshDS->fromVtkToSmds(vtkId)); addedInside = true; @@ -12317,7 +12319,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, for (; itShape != shapeIdToVtkIdSet.end(); ++itShape) { int shapeId = itShape->first; - MESSAGE(" --- Shape ID --- "<< shapeId); + //MESSAGE(" --- Shape ID --- "<< shapeId); shapeIdToEdges[shapeId] = emptyEdges; std::vector nodesEdges; @@ -12326,7 +12328,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, for (; its != itShape->second.end(); ++its) { int vtkId = *its; - MESSAGE(" " << vtkId); + //MESSAGE(" " << vtkId); int neighborsVtkIds[NBMAXNEIGHBORS]; int downIds[NBMAXNEIGHBORS]; unsigned char downTypes[NBMAXNEIGHBORS]; @@ -12347,7 +12349,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, 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); + //MESSAGE(" --- nodes " << vtkNodeId[0]+1 << " " << vtkNodeId[nbNodes-1]+1); } } } @@ -12357,9 +12359,9 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, order.clear(); if (nodesEdges.size() > 0) { - order.push_back(nodesEdges[0]); MESSAGE(" --- back " << order.back()+1); // SMDS id = VTK id + 1; + 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); + order.push_back(nodesEdges[1]); //MESSAGE(" --- back " << order.back()+1); nodesEdges[1] = -1; // do not reuse this edge bool found = true; while (found) @@ -12378,7 +12380,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, found = false; else { - order.push_back(nodesEdges[i-1]); MESSAGE(" --- back " << order.back()+1); + order.push_back(nodesEdges[i-1]); //MESSAGE(" --- back " << order.back()+1); nodesEdges[i-1] = -1; } else // even ==> use the next one @@ -12386,7 +12388,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, found = false; else { - order.push_back(nodesEdges[i+1]); MESSAGE(" --- back " << order.back()+1); + order.push_back(nodesEdges[i+1]); //MESSAGE(" --- back " << order.back()+1); nodesEdges[i+1] = -1; } } @@ -12408,7 +12410,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, found = false; else { - order.push_front(nodesEdges[i-1]); MESSAGE(" --- front " << order.front()+1); + order.push_front(nodesEdges[i-1]); //MESSAGE(" --- front " << order.front()+1); nodesEdges[i-1] = -1; } else // even ==> use the next one @@ -12416,7 +12418,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, found = false; else { - order.push_front(nodesEdges[i+1]); MESSAGE(" --- front " << order.front()+1); + order.push_front(nodesEdges[i+1]); //MESSAGE(" --- front " << order.front()+1); nodesEdges[i+1] = -1; } } @@ -12429,7 +12431,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius, for (; itl != order.end(); itl++) { nodes.push_back((*itl) + 1); // SMDS id = VTK id + 1; - MESSAGE(" ordered node " << nodes[nodes.size()-1]); + //MESSAGE(" ordered node " << nodes[nodes.size()-1]); } listOfListOfNodes.push_back(nodes); }