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=e4f2bda0016f622017fc722f46e86d4370c17b7b;hb=442fd64c19a6e27a339ca36264c15ec91732cf32;hpb=65c1beab50fcec33a4e988c10b3fedb081543164 diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index e4f2bda00..1f343b1c4 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -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() ); } } } @@ -1160,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. */ @@ -2124,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 ) @@ -2390,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 @@ -2516,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; @@ -3986,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 ); } @@ -4049,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 ); @@ -4334,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, @@ -4560,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; @@ -5468,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 ) @@ -5482,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 )) { @@ -5550,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(); + } } //======================================================================= @@ -5625,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; } @@ -5799,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 ); } @@ -5820,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) + @@ -5992,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; @@ -6037,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 @@ -6080,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); } @@ -6219,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(); @@ -6277,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; @@ -6336,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 @@ -6372,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) @@ -6433,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, @@ -6450,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; @@ -6643,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 ); @@ -6683,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 ); } } @@ -7159,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 { @@ -7246,16 +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) { 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 @@ -7269,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(); @@ -7287,469 +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 ); - SMDSAbs_EntityType entity = elem->GetEntityType(); + 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 dependency - 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 ); - bool isOk = true; - int nbUniqueNodes = nodeSet.size(); - if ( nbNodes != nbUniqueNodes ) // some nodes stick + 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; + + 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.SetID(-1)); - 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 - { - 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(); + // 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 poly_nodes; - vector quantities; - vector faceNodes; + 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 + { + 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 - 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); - } + 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 ) { - // TODO: 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 ( entity ) { - case SMDSEntity_Edge: //////// EDGE - case SMDSEntity_Triangle: //// TRIANGLE - case SMDSEntity_Quad_Triangle: - case SMDSEntity_Tetra: - case SMDSEntity_Quad_Tetra: // TETRAHEDRON - { - isOk = false; - break; + if ( quantities.size() > 3 ) + { + // TODO: remove coincident faces + nbResElems = 1; + nbUniqueNodes = newElemDefs[0].myNodes.size(); + } + } } - case SMDSEntity_Quad_Edge: + } + 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 )) { - isOk = false; // to linear EDGE ??????? - break; + toRemove = false; } - case SMDSEntity_Quadrangle: //////////////////////////////////// QUADRANGLE + 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] ))) { - if ( nbUniqueNodes < 3 ) - isOk = false; - else if ( nbRepl == 1 && curNodes[ iRepl[0]] == curNodes[( iRepl[0]+2 )%4 ]) - isOk = false; // opposite nodes stick - break; + toRemove = false; } - 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] ))) + 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] ) { - 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] ))) + 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] ) { - isOk = true; - } - break; - } - case SMDSEntity_Penta: ///////////////////////////////////// PENTAHEDRON - { - isOk = false; - if ( nbUniqueNodes == 4 ) { - // ---------------------------------> tetrahedron - if ( curNodes[3] == curNodes[4] && - curNodes[3] == curNodes[5] ) { - // top nodes stick - isOk = true; - } - 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 ]; - isOk = true; - } - 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 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 ]; - isOk = true; - } - 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 ( 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; - } + 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 - isOk = false; - 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 ( nbStick == 1 ) { - // ... and the opposite one - into a triangle. - // set a top node - uniqueNodes.push_back( curNodes[ pickInd ]); - isOk = true; - } - break; + 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 ( nbStick == 1 ) { + // ... and the opposite one - into a triangle. + // set a top node + uniqueNodes.push_back( curNodes[ pickInd ]); + toRemove = false; } - } - } - 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; - } - 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 ]]); - 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; + toRemove = false; + 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; } } + } - 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++ ) + 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]] ) { - 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++ ) - { - if ( nodeSet.insert( curNodes[ind[ iCur ]] ).second ) - poly_nodes.push_back( curNodes[ind[ iCur ]]); - } - if ( nodeSet.size() < 3 ) - poly_nodes.resize( poly_nodes.size() - nodeSet.size() ); - else - quantities.push_back( nodeSet.size() ); + quantities.clear(); + break; // opposite nodes stick } - if ( quantities.size() >= 4 ) + nodeSet.clear(); + for ( iCur = 0; iCur < 4; iCur++ ) { - 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 ( nodeSet.insert( curNodes[ind[ iCur ]] ).second ) + poly_nodes.push_back( curNodes[ind[ iCur ]]); } + if ( nodeSet.size() < 3 ) + poly_nodes.resize( poly_nodes.size() - nodeSet.size() ); + else + quantities.push_back( nodeSet.size() ); } - break; - } // case HEXAHEDRON + if ( quantities.size() >= 4 ) + { + nbResElems = 1; + nbUniqueNodes = poly_nodes.size(); + newElemDefs[0].SetPoly(true); + } + } + break; + } // case HEXAHEDRON - default: - isOk = false; - } // switch ( nbNodes ) + default: + toRemove = true; - } // if ( nbNodes != nbUniqueNodes ) // some nodes stick + } // switch ( entity ) - if ( isOk ) // a 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; } @@ -8140,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 ]; @@ -8304,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 ); @@ -9102,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 ) @@ -9750,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; @@ -10751,8 +10942,7 @@ 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)) @@ -10848,8 +11038,7 @@ 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 ) { SMDS_MeshElement* anElem = (SMDS_MeshElement*)*elemItr; if (!anElem) @@ -10982,9 +11171,9 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectormyMesh->GetMeshDS(); meshDS->BuildDownWardConnectivity(true); @@ -11007,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(); @@ -11219,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; @@ -11401,7 +11590,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector >::const_iterator itnod = nodeDomains.begin(); @@ -11557,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(); @@ -11576,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(); @@ -11740,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, @@ -11844,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() ) { @@ -11866,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 ) @@ -11876,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); @@ -11894,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 @@ -11936,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; @@ -11947,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 { @@ -11965,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) { @@ -11977,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]; @@ -11989,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); } @@ -12002,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) @@ -12024,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]; @@ -12033,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; @@ -12133,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; @@ -12142,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]; @@ -12163,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); } } } @@ -12173,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) @@ -12194,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 @@ -12202,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; } } @@ -12224,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 @@ -12232,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; } } @@ -12245,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); }