#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"
#include <TopTools_ListOfShape.hxx>
#include <TopTools_SequenceOfShape.hxx>
#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Solid.hxx>
#include <gp.hxx>
{
}
+//================================================================================
+/*!
+ * \brief Return mesh DS
+ */
+//================================================================================
+
+SMESHDS_Mesh * SMESH_MeshEditor::GetMeshDS()
+{
+ return myMesh->GetMeshDS();
+}
+
+
//================================================================================
/*!
* \brief Clears myLastCreatedNodes and myLastCreatedElems
//================================================================================
/*!
- * \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
{
{
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() );
}
}
}
* \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.
*/
}
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
// 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;
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 );
}
{
// 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 );
}
}
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,
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;
//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<double>& theScales,
+ const gp_XYZ* theBasePoint,
+ const int theFlags,
+ const double theTolerance):
myDir( theStep ),
+ myBaseP( Precision::Infinite(), 0, 0 ),
myFlags( theFlags ),
myTolerance( theTolerance ),
myElemsToUse( NULL )
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<double>::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 ))
{
//=======================================================================
//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();
+ }
}
//=======================================================================
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<double>::iterator ScaleIt;
+ ScaleIt scales[] = { myScales.begin(), myMediumScales.begin() };
+
+ size_t iSc = 0, nbScales = myScales.size() + myMediumScales.size();
+
+ gp_XYZ center = myBaseP;
+ std::list<const SMDS_MeshNode*>::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;
}
const int theFlags,
const double theTolerance)
{
- ExtrusParam aParams( theStep, theNbSteps, theFlags, theTolerance );
+ ExtrusParam aParams( theStep, theNbSteps, std::list<double>(), 0, theFlags, theTolerance );
return ExtrusionSweep( theElems, aParams, newElemsMap );
}
// 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) +
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;
}
list<SMESH_MeshEditor_PathPoint> 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
return EXTR_BAD_PATH_SHAPE;
}
- return MakeExtrElements(theElements, fullList, theHasAngles, theAngles, theLinearVariation,
+ return makeExtrElements(theElements, fullList, theHasAngles, theAngles, theLinearVariation,
theHasRefPoint, theRefPoint, theMakeGroups);
}
TopoDS_Edge e = BRepBuilderAPI_MakeEdge( p1, p2 );
list<SMESH_MeshEditor_PathPoint> 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();
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;
}
list<SMESH_MeshEditor_PathPoint> 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
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<double>& aPrms,
+SMESH_MeshEditor::makeEdgePathPoints(std::list<double>& aPrms,
const TopoDS_Edge& aTrackEdge,
bool FirstIsStart,
list<SMESH_MeshEditor_PathPoint>& LPP)
//=======================================================================
-//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<SMESH_MeshEditor_PathPoint>& fullList,
const bool theHasAngles,
list<double>& theAngles,
// Angles
if( theHasAngles && !theAngles.empty() && theLinearVariation )
- LinearAngleVariation(aNbTP-1, theAngles);
+ linearAngleVariation(aNbTP-1, theAngles);
// fill vector of path points with angles
vector<SMESH_MeshEditor_PathPoint> aPPs;
//=======================================================================
-//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<double>& Angles)
{
int nbAngles = Angles.size();
- if( nbSteps > nbAngles ) {
+ if( nbSteps > nbAngles && nbAngles > 0 )
+ {
vector<double> theAngles(nbAngles);
- list<double>::iterator it = Angles.begin();
- int i = -1;
- for(; it!=Angles.end(); it++) {
- i++;
- theAngles[i] = (*it);
- }
+ theAngles.assign( Angles.begin(), Angles.end() );
+
list<double> 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 );
res.push_back(angle);
angPrev = angCur;
}
- Angles.clear();
- it = res.begin();
- for(; it!=res.end(); it++)
- Angles.push_back( *it );
+ Angles.swap( res );
}
}
}
else
while ( nIt->more() )
- theNodes.insert( theNodes.end(),nIt->next() );
+ theNodes.insert( theNodes.end(), nIt->next() );
}
else if ( theSeparateCornersAndMedium ) // separate corners from medium nodes
{
// 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<const SMDS_MeshElement*> elems; // all elements with changed nodes
list< int > rmElemIds, rmNodeIds;
+ vector< ElemFeatures > newElemDefs;
// Fill nodeNodeMap and elems
{
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();
}
}
}
- // Change element nodes or remove an element
- set<const SMDS_MeshNode*> nodeSet;
- vector< const SMDS_MeshNode*> curNodes, uniqueNodes;
- vector<int> 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<const SMDS_MeshElement*> pbElems;
+ set<const SMDS_MeshElement*>::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<const SMDS_MeshNode*>( 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<const SMDS_MeshElement*>::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<const SMDS_MeshNode*>( itN->next() );
-
- TNodeNodeMap::iterator nnIt = nodeNodeMap.find( n );
- if ( nnIt != nodeNodeMap.end() ) { // n sticks
- n = (*nnIt).second;
- { ////////// BUG 0020185: begin
- bool stopRecur = false;
- set<const SMDS_MeshNode*> 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<const SMDS_MeshNode*> nodeSet;
+ vector< const SMDS_MeshNode*> curNodes;
+ vector< const SMDS_MeshNode*> & uniqueNodes = newElemDefs[0].myNodes;
+ vector<int> 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<const SMDS_MeshNode*>( 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<const SMDS_MeshNode *> polygons_nodes;
- vector<int> 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<const SMDS_MeshNode *> 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<const SMDS_VtkVolume*>( elem );
- if ( aPolyedre )
- {
- int nbFaces = aPolyedre->NbFaces();
+ // a polygon can divide into several elements
+ vector<const SMDS_MeshNode *> polygons_nodes;
+ vector<int> 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<const SMDS_MeshNode *> poly_nodes;
- vector<int> quantities;
- vector<const SMDS_MeshNode *> faceNodes;
+ vector<const SMDS_MeshNode *>& 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<const SMDS_VtkVolume*>( elem ))
+ {
+ int nbFaces = aPolyedre->NbFaces();
- if ( quantities.size() > 3 ) {
- // TODO: remove coincident faces
- }
+ vector<const SMDS_MeshNode *>& poly_nodes = newElemDefs[0].myNodes;
+ vector<int> & quantities = newElemDefs[0].myPolyhedQuantities;
+ vector<const SMDS_MeshNode *> 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<int> 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<int> 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<const SMDS_MeshNode *> poly_nodes; poly_nodes.reserve( 6 * 4 );
- vector<int> quantities; quantities.reserve( 6 );
- for ( int iFace = 0; iFace < 6; iFace++ )
+ if ( toRemove && nbUniqueNodes > 4 ) {
+ ////////////////// HEXAHEDRON ---> polyhedron
+ hexa.SetExternalNormal();
+ vector<const SMDS_MeshNode *>& poly_nodes = newElemDefs[0].myNodes;
+ vector<int> & 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;
}
// -------------------------------------------------------------------------
// 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<const SMDS_MeshNode*, gp_XYZ> TNodeXYZMap;
TNodeXYZMap nBordXYZ;
list< const SMDS_MeshNode* >& bordNodes = nSide[ 0 ];
} // 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 );
// 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 )
// 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<const SMDS_MeshElement*> volSet1, volSet2;
bool createJointElems,
bool onAllBoundaries)
{
- MESSAGE("----------------------------------------------");
- MESSAGE("SMESH_MeshEditor::doubleNodesOnGroupBoundaries");
- MESSAGE("----------------------------------------------");
+ // MESSAGE("----------------------------------------------");
+ // MESSAGE("SMESH_MeshEditor::doubleNodesOnGroupBoundaries");
+ // MESSAGE("----------------------------------------------");
SMESHDS_Mesh *meshDS = this->myMesh->GetMeshDS();
meshDS->BuildDownWardConnectivity(true);
std::set<int> emptySet;
emptyMap.clear();
- MESSAGE(".. Number of domains :"<<theElems.size());
+ //MESSAGE(".. Number of domains :"<<theElems.size());
TIDSortedElemSet theRestDomElems;
const int iRestDom = -1;
// and corresponding volume of this domain, for each shared face.
// a volume has a face shared by 2 domains if it has a neighbor which is not in his domain.
- MESSAGE("... Neighbors of domain #" << idom);
+ //MESSAGE("... Neighbors of domain #" << idom);
const TIDSortedElemSet& domain = theElems[idom];
TIDSortedElemSet::const_iterator elemItr = domain.begin();
for (; elemItr != domain.end(); ++elemItr)
std::map<int, std::vector<int> > mutipleNodes; // nodes multi domains with domain order
std::map<int, std::vector<int> > 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();
}
}
- MESSAGE(".. Creation of elements");
+ //MESSAGE(".. Creation of elements");
for (int idomain = idom0; idomain < nbDomains; idomain++)
{
itface = faceDomains.begin();
std::map<int, std::map<long,int> > nodeQuadDomains;
std::map<std::string, SMESH_Group*> mapOfJunctionGroups;
- MESSAGE(".. Creation of elements: simple junction");
+ //MESSAGE(".. Creation of elements: simple junction");
if (createJointElems)
{
int idg;
// iterate on mutipleNodesToFace
// iterate on edgesMultiDomains
- MESSAGE(".. Creation of elements: multiple junction");
+ //MESSAGE(".. Creation of elements: multiple junction");
if (createJointElems)
{
// --- iterate on mutipleNodesToFace
faceOrEdgeDom.clear();
feDom.clear();
- MESSAGE(".. Modification of elements");
+ //MESSAGE(".. Modification of elements");
for (int idomain = idom0; idomain < nbDomains; idomain++)
{
std::map<int, std::map<int, int> >::const_iterator itnod = nodeDomains.begin();
}
meshDS->CleanDownWardConnectivity(); // Mesh has been modified, downward connectivity is no more usable, free memory
- grid->BuildLinks();
+ grid->DeleteLinks();
CHRONOSTOP(50);
counters::stats();
*/
bool SMESH_MeshEditor::CreateFlatElementsOnFacesGroups(const std::vector<TIDSortedElemSet>& theElems)
{
- MESSAGE("-------------------------------------------------");
- MESSAGE("SMESH_MeshEditor::CreateFlatElementsOnFacesGroups");
- MESSAGE("-------------------------------------------------");
+ // MESSAGE("-------------------------------------------------");
+ // MESSAGE("SMESH_MeshEditor::CreateFlatElementsOnFacesGroups");
+ // MESSAGE("-------------------------------------------------");
SMESHDS_Mesh *meshDS = this->myMesh->GetMeshDS();
std::vector<double>& nodesCoords,
std::vector<std::vector<int> >& 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,
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() )
{
}
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 )
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);
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
{
std::set<int>::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;
if (mapOfNodeDistance2.count(pts[i]))
{
distance2 = mapOfNodeDistance2[pts[i]];
- MESSAGE("point " << pts[i] << " distance2 " << distance2);
+ //MESSAGE("point " << pts[i] << " distance2 " << distance2);
}
else
{
}
}
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)
{
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];
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);
}
std::set<int> setOfVolToReCheck;
while (addedInside)
{
- MESSAGE(" --------------------------- re check");
+ //MESSAGE(" --------------------------- re check");
addedInside = false;
std::set<int>::iterator itv = setOfInsideVol.begin();
for (; itv != setOfInsideVol.end(); ++itv)
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];
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;
for (; itShape != shapeIdToVtkIdSet.end(); ++itShape)
{
int shapeId = itShape->first;
- MESSAGE(" --- Shape ID --- "<< shapeId);
+ //MESSAGE(" --- Shape ID --- "<< shapeId);
shapeIdToEdges[shapeId] = emptyEdges;
std::vector<int> nodesEdges;
for (; its != itShape->second.end(); ++its)
{
int vtkId = *its;
- MESSAGE(" " << vtkId);
+ //MESSAGE(" " << vtkId);
int neighborsVtkIds[NBMAXNEIGHBORS];
int downIds[NBMAXNEIGHBORS];
unsigned char downTypes[NBMAXNEIGHBORS];
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);
}
}
}
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)
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
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;
}
}
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
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;
}
}
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);
}