// SMESH SMESH : idl implementation based on 'SMESH' unit's classes
//
// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
//
//
//
#include <Extrema_POnSurf.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <ElCLib.hxx>
+#include <TColStd_ListOfInteger.hxx>
#include <map>
//=======================================================================
//function : SMESH_MeshEditor
-//purpose :
+//purpose :
//=======================================================================
SMESH_MeshEditor::SMESH_MeshEditor( SMESH_Mesh* theMesh ):
SMESHDS_Mesh* aMesh = GetMeshDS();
set< SMESH_subMesh *> smmap;
-
+
list<int>::const_iterator it = theIDs.begin();
for ( ; it != theIDs.end(); it++ )
{
if (!F2) return false;
// 1 +--+ A theTria1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A
- // | /| theTria2: ( B A 2 ) B->1 ( 1 A 2 ) |\ |
- // |/ | | \|
+ // | /| theTria2: ( B A 2 ) B->1 ( 1 A 2 ) |\ |
+ // |/ | | \|
// B +--+ 2 B +--+ 2
// put nodes in array and find out indices of the same ones
if (!F2) return false;
// 1 +--+ A tr1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A
- // | /| tr2: ( B A 2 ) B->1 ( 1 A 2 ) |\ |
- // |/ | | \|
+ // | /| tr2: ( B A 2 ) B->1 ( 1 A 2 ) |\ |
+ // |/ | | \|
// B +--+ 2 B +--+ 2
// put nodes in array
//MESSAGE( tr1 << tr2 );
return true;
-
+
}
//=======================================================================
return false;
switch ( theElem->GetType() ) {
-
+
case SMDSAbs_Edge:
case SMDSAbs_Face:
{
//=======================================================================
//function : getBadRate
-//purpose :
+//purpose :
//=======================================================================
static double getBadRate (const SMDS_MeshElement* theElem,
if ( !theElem || !theCrit->GetPoints( theElem, P ))
return 1e100;
return theCrit->GetBadRate( theCrit->GetValue( P ), theElem->NbNodes() );
+ //return theCrit->GetBadRate( theCrit->GetValue( theElem->GetID() ), theElem->NbNodes() );
}
-
+
//=======================================================================
//function : QuadToTri
//purpose : Cut quadrangles into triangles.
SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] );
SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] );
aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit );
-
+
SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] );
SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] );
aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit );
int aShapeId = FindShape( elem );
//MESSAGE( "aBadRate1 = " << aBadRate1 << "; aBadRate2 = " << aBadRate2
// << " ShapeID = " << aShapeId << endl << elem );
-
+
if ( aBadRate1 <= aBadRate2 ) {
// tr1 + tr2 is better
aMesh->ChangeElementNodes( elem, aNodes, 3 );
return true;
}
+//=======================================================================
+//function : BestSplit
+//purpose : Find better diagonal for cutting.
+//=======================================================================
+int SMESH_MeshEditor::BestSplit (const SMDS_MeshElement* theQuad,
+ SMESH::Controls::NumericalFunctorPtr theCrit)
+{
+ if (!theCrit.get())
+ return -1;
+
+ if (!theQuad || theQuad->GetType() != SMDSAbs_Face || theQuad->NbNodes() != 4)
+ return -1;
+
+ // retrieve element nodes
+ const SMDS_MeshNode* aNodes [4];
+ SMDS_ElemIteratorPtr itN = theQuad->nodesIterator();
+ int i = 0;
+ while (itN->more())
+ aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+
+ // compare two sets of possible triangles
+ double aBadRate1, aBadRate2; // to what extent a set is bad
+ SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] );
+ SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] );
+ aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit );
+
+ SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] );
+ SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] );
+ aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit );
+
+ if (aBadRate1 <= aBadRate2) // tr1 + tr2 is better
+ return 1; // diagonal 1-3
+
+ return 2; // diagonal 2-4
+}
+
//=======================================================================
//function : AddToSameGroups
//purpose : add elemToAdd to the groups the elemInGroups belongs to
//=======================================================================
//function : getAngle
-//purpose :
+//purpose :
//=======================================================================
double getAngle(const SMDS_MeshElement * tr1,
gp_Vec N2 = gp_Vec( P2(2) - P2(1) ) ^ gp_Vec( P2(3) - P2(1) );
if ( N2.SquareMagnitude() <= gp::Resolution() )
return angle;
-
+
// find the first diagonal node n1 in the triangles:
// take in account a diagonal link orientation
const SMDS_MeshElement *nFirst[2], *tr[] = { tr1, tr2 };
itLE = mapLi_listEl.find( linkID );
if ( itLE != mapLi_listEl.end() )
{
- if ((*itLE).second.size() > 1 ) // consider only 2 elems adjacent by a link
+ if ((*itLE).second.size() > 1 ) // consider only 2 elems adjacent by a link
continue;
const SMDS_MeshElement* elem2 = (*itLE).second.front();
// if ( FindShape( elem ) != FindShape( elem2 ))
}
// Algo: fuse triangles into quadrangles
-
+
while ( ! mapEl_setLi.empty() )
{
// Look for the start element:
} // if ( startElem )
} // while ( startElem || !startLinks.empty() )
} // while ( ! mapEl_setLi.empty() )
-
+
return true;
}
}
DUMPSO( "========================================");
-
+
set<int> faceNodes; // ids of bottom face nodes, to be found
set<int> checkedId1; // ids of tried 2-nd nodes
Standard_Real leastDist = DBL_MAX; // dist of the 4-th node from 123 plane
checkedId1.insert ( id1 );
break;
}
-
+
// Find the 3-d node so that 1-2-3 triangle to be on a hexa face,
// ie that all but meybe one (id3 which is on the same face) nodes
// lay on the same side from the triangle plane.
}
}
-
+
// Set nodes of the found bottom face in good order
DUMPSO( " Found bottom face: ");
i = SortQuadNodes( theMesh, idNodes );
Standard_Real upDirSize = upDir.Magnitude();
if ( upDirSize <= gp::Resolution() ) return false;
upDir / upDirSize;
-
+
// Assure that the bottom face normal points up
gp_Vec Nb = gp_Vec (P[0], P[1]).Crossed( gp_Vec (P[0], P[2]) );
Nb += gp_Vec (P[0], P[2]).Crossed( gp_Vec (P[0], P[3]) );
SMESH::Controls::AspectRatio aQualityFunc;
SMESHDS_Mesh* aMesh = GetMeshDS();
-
+
if ( theElems.empty() ) {
// add all faces to theElems
SMDS_FaceIteratorPtr fIt = aMesh->facesIterator();
const SMDS_PositionPtr& pos = node->GetPosition();
posType = pos.get() ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE;
if (posType != SMDS_TOP_EDGE &&
- posType != SMDS_TOP_VERTEX &&
+ posType != SMDS_TOP_VERTEX &&
theFixedNodes.find( node ) == theFixedNodes.end())
{
// check if all faces around the node are on faceSubMesh
}
}
}
- } // loop on nodes on seam
+ } // loop on nodes on seam
} // loop on edge of a face
} // if ( !face.IsNull() )
// Make a ceiling for each element ie an equal element of last new nodes.
// Find free links of faces - make edges and sweep them into faces.
-
+
TElemOfElemListMap::iterator itElem = newElemsMap.begin();
TElemOfVecOfNnlmiMap::iterator itElemNodes = elemNewNodesMap.begin();
for ( ; itElem != newElemsMap.end(); itElem++, itElemNodes++ )
} // sweep free links into faces
// make a ceiling face with a normal external to a volume
-
+
SMDS_VolumeTool lastVol( itElem->second.back() );
int iF = lastVol.GetFaceIndex( aFaceLastNodes );
if ( iF >= 0 )
//=======================================================================
//function : RotationSweep
-//purpose :
+//purpose :
//=======================================================================
void SMESH_MeshEditor::RotationSweep(set<const SMDS_MeshElement*> & theElems,
makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems );
}
+
+
//=======================================================================
-//function : ExtrusionSweep
+//function : CreateNode
//purpose :
//=======================================================================
+const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x,
+ const double y,
+ const double z,
+ const double tolnode)
+{
+ gp_Pnt P1(x,y,z);
+ SMESHDS_Mesh * aMesh = myMesh->GetMeshDS();
+ // try to search in sequence of existing nodes
+ SMDS_NodeIteratorPtr itn = aMesh->nodesIterator();
+ while(itn->more()) {
+ const SMDS_MeshNode* aN = static_cast<const SMDS_MeshNode*> (itn->next());
+ gp_Pnt P2(aN->X(),aN->Y(),aN->Z());
+ if(P1.Distance(P2)<tolnode)
+ return aN;
+ }
+ // create new node and return it
+ const SMDS_MeshNode* NewNode = aMesh->AddNode(x,y,z);
+ return NewNode;
+}
+
+
+//=======================================================================
+//function : ExtrusionSweep
+//purpose :
+//=======================================================================
-void SMESH_MeshEditor::ExtrusionSweep(set<const SMDS_MeshElement*> & theElems,
- const gp_Vec& theStep,
- const int theNbSteps)
+void SMESH_MeshEditor::ExtrusionSweep
+ (set<const SMDS_MeshElement*> & theElems,
+ const gp_Vec& theStep,
+ const int theNbSteps,
+ TElemOfElemListMap& newElemsMap,
+ const int theFlags,
+ const double theTolerance)
{
gp_Trsf aTrsf;
aTrsf.SetTranslation( theStep );
TNodeOfNodeListMap mapNewNodes;
TElemOfVecOfNnlmiMap mapElemNewNodes;
- TElemOfElemListMap newElemsMap;
+ //TElemOfElemListMap newElemsMap;
// loop on theElems
set< const SMDS_MeshElement* >::iterator itElem;
double coord[] = { node->X(), node->Y(), node->Z() };
for ( int i = 0; i < theNbSteps; i++ ) {
aTrsf.Transforms( coord[0], coord[1], coord[2] );
- const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
- listNewNodes.push_back( newNode );
+ if( theFlags & EXTRUSION_FLAG_SEW ) {
+ const SMDS_MeshNode * newNode = CreateNode(coord[0], coord[1],
+ coord[2], theTolerance);
+ listNewNodes.push_back( newNode );
+ }
+ else {
+ const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+ listNewNodes.push_back( newNode );
+ }
}
}
newNodesItVec.push_back( nIt );
// make new elements
sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem] );
}
- makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems );
+ if( theFlags & EXTRUSION_FLAG_BOUNDARY ) {
+ makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems );
+ }
}
//=======================================================================
//class : SMESH_MeshEditor_PathPoint
-//purpose : auxiliary class
+//purpose : auxiliary class
//=======================================================================
class SMESH_MeshEditor_PathPoint {
public:
//=======================================================================
//function : ExtrusionAlongTrack
-//purpose :
+//purpose :
//=======================================================================
-SMESH_MeshEditor::Extrusion_Error
+SMESH_MeshEditor::Extrusion_Error
SMESH_MeshEditor::ExtrusionAlongTrack (std::set<const SMDS_MeshElement*> & theElements,
SMESH_subMesh* theTrack,
const SMDS_MeshNode* theN1,
aItN = theTrack->GetFather()->GetSubMesh( aV2 )->GetSubMeshDS()->GetNodes();
const SMDS_MeshNode* aN2 = aItN->next();
- // starting node must be aN1 or aN2
+ // starting node must be aN1 or aN2
if ( !( aN1 == theN1 || aN2 == theN1 ) )
return EXTR_BAD_STARTING_NODE;
for ( j=0; j < aNbTP; ++j ) {
aAngles[j] = 0.;
}
-
+
if ( theHasAngles ) {
aItD = theAngles.begin();
for ( j=1; (aItD != theAngles.end()) && (j<aNbTP); ++aItD, ++j ) {
}
}
- // 2. Collect parameters on the track edge
+ // 2. Collect parameters on the track edge
aPrms.push_back( aT1 );
aPrms.push_back( aT2 );
while ( itN->more() ) {
// check if a node has been already processed
- const SMDS_MeshNode* node =
+ const SMDS_MeshNode* node =
static_cast<const SMDS_MeshNode*>( itN->next() );
TNodeOfNodeListMap::iterator nIt = mapNewNodes.find( node );
if ( nIt == mapNewNodes.end() ) {
nIt = mapNewNodes.insert( make_pair( node, list<const SMDS_MeshNode*>() )).first;
list<const SMDS_MeshNode*>& listNewNodes = nIt->second;
-
+
// make new nodes
aX = node->X(); aY = node->Y(); aZ = node->Z();
-
+
Standard_Real aAngle1x, aAngleT1T0, aTolAng;
gp_Pnt aP0x, aP1x, aPN0, aPN1, aV0x, aV1x;
gp_Ax1 anAx1, anAxT1T0;
aP1x = aPP1.Pnt();
aDT1x = aPP1.Tangent();
aAngle1x = aPP1.Angle();
-
- gp_Trsf aTrsf, aTrsfRot, aTrsfRotT1T0;
+
+ gp_Trsf aTrsf, aTrsfRot, aTrsfRotT1T0;
// Translation
gp_Vec aV01x( aP0x, aP1x );
aTrsf.SetTranslation( aV01x );
-
+
// traslated point
aV1x = aV0x.Transformed( aTrsf );
aPN1 = aPN0.Transformed( aTrsf );
-
+
// rotation 1 [ T1,T0 ]
aAngleT1T0=-aDT1x.Angle( aDT0x );
if (fabs(aAngleT1T0) > aTolAng) {
anAxT1T0.SetLocation( aV1x );
anAxT1T0.SetDirection( aDT1T0 );
aTrsfRotT1T0.SetRotation( anAxT1T0, aAngleT1T0 );
-
+
aPN1 = aPN1.Transformed( aTrsfRotT1T0 );
}
anAx1.SetLocation( aV1x );
anAx1.SetDirection( aDT1x );
aTrsfRot.SetRotation( anAx1, aAngle1x );
-
+
aPN1 = aPN1.Transformed( aTrsfRot );
}
aZ = aPN1.Z();
const SMDS_MeshNode* newNode = aMesh->AddNode( aX, aY, aZ );
listNewNodes.push_back( newNode );
-
+
aPN0 = aPN1;
aP0x = aP1x;
aV0x = aV1x;
// make new elements
sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem] );
}
-
+
makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElements );
return EXTR_OK;
//=======================================================================
//function : Transform
-//purpose :
+//purpose :
//=======================================================================
void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
const SMDS_MeshNode* node =
static_cast<const SMDS_MeshNode*>( itN->next() );
if (nodeMap.find( node ) != nodeMap.end() )
- continue;
+ continue;
double coord[3];
coord[0] = node->X();
theElems.insert( *invElemIt );
}
- // replicate or reverse elements
+ // replicate or reverse elements
enum {
REV_TETRA = 0, // = nbNodes - 4
FORWARD = 5
};
int index[][8] = {
- { 2, 1, 0, 3, 4, 0, 0, 0 }, // REV_TETRA
+ { 2, 1, 0, 3, 4, 0, 0, 0 }, // REV_TETRA
{ 2, 1, 0, 3, 4, 0, 0, 0 }, // REV_PYRAMID
- { 2, 1, 0, 5, 4, 3, 0, 0 }, // REV_PENTA
- { 2, 1, 0, 3, 0, 0, 0, 0 }, // REV_FACE
- { 2, 1, 0, 3, 6, 5, 4, 7 }, // REV_HEXA
- { 0, 1, 2, 3, 4, 5, 6, 7 } // FORWARD
+ { 2, 1, 0, 5, 4, 3, 0, 0 }, // REV_PENTA
+ { 2, 1, 0, 3, 0, 0, 0, 0 }, // REV_FACE
+ { 2, 1, 0, 3, 6, 5, 4, 7 }, // REV_HEXA
+ { 0, 1, 2, 3, 4, 5, 6, 7 } // FORWARD
};
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
if ( iNode != nbNodes )
continue; // not all nodes transformed
- if ( theCopy )
+ if ( theCopy )
{
// add a new element
switch ( elemType ) {
else
{
nodes.insert( nodes.end(), theNodes.begin(), theNodes.end() );
- }
+ }
list<const SMDS_MeshNode*>::iterator it2, it1 = nodes.begin();
for ( ; it1 != nodes.end(); it1++ )
//=======================================================================
//function : SimplifyFace
-//purpose :
+//purpose :
//=======================================================================
int SMESH_MeshEditor::SimplifyFace (const vector<const SMDS_MeshNode *> faceNodes,
vector<const SMDS_MeshNode *>& poly_nodes,
elems.insert( invElemIt->next() );
}
}
- // Change element nodes or remove an element
+ // Change element nodes or remove an element
set<const SMDS_MeshElement*>::iterator eIt = elems.begin();
for ( ; eIt != elems.end(); eIt++ )
if ( nbRepl == 2 && iRepl[ 1 ] - iRepl [ 0 ] == 3 ) {
// a bottom node sticks with a linked top one
// 1.
- SMDS_MeshElement* newElem =
+ SMDS_MeshElement* newElem =
aMesh->AddVolume(curNodes[ 3 ],
curNodes[ 4 ],
curNodes[ 5 ],
uniqueNodes[ 3 ] = curNodes[indTop[ 0 ]];
nbUniqueNodes = 4;
// tetrahedron 2
- SMDS_MeshElement* newElem =
+ SMDS_MeshElement* newElem =
aMesh->AddVolume(curNodes[ind[ 0 ]],
curNodes[ind[ 3 ]],
curNodes[ind[ 2 ]],
} // switch ( nbNodes )
} // if ( nbNodes != nbUniqueNodes ) // some nodes stick
-
+
if ( isOk ) {
if (elem->IsPoly() && elem->GetType() == SMDSAbs_Volume) {
// Change nodes of polyedre
//=======================================================================
//function : findAdjacentFace
-//purpose :
+//purpose :
//=======================================================================
static const SMDS_MeshElement* findAdjacentFace(const SMDS_MeshNode* n1,
avoidSet.insert ( elem );
return SMESH_MeshEditor::FindFaceInSet( n1, n2, elemSet, avoidSet );
}
-
+
//=======================================================================
//function : findFreeBorder
-//purpose :
+//purpose :
//=======================================================================
#define ControlFreeBorder SMESH::Controls::FreeEdges::IsFreeEdge
//=======================================================================
//function : SewFreeBorder
-//purpose :
+//purpose :
//=======================================================================
SMESH_MeshEditor::Sew_Error
aResult = SEW_BORDER1_NOT_FOUND;
}
if (theSideIsFreeBorder)
- {
+ {
// Free border 2
// --------------
if (!findFreeBorder(theSideFirstNode, theSideSecondNode, theSideThirdNode,
toBordSys.SetTransformation( toBordAx );
fromSide2Sys.SetTransformation( fromSideAx, toGlobalAx );
fromSide2Sys.SetScaleFactor( Zs.Magnitude() / Zb.Magnitude() );
-
+
// move
for ( nBordIt = bordNodes.begin(); nBordIt != bordNodes.end(); nBordIt++ ) {
const SMDS_MeshNode* n = *nBordIt;
nIt[0]++, nIt[1]++ )
{
nodeGroupsToMerge.push_back( list<const SMDS_MeshNode*>() );
- nodeGroupsToMerge.back().push_back( *nIt[1] ); // to keep
+ nodeGroupsToMerge.back().push_back( *nIt[1] ); // to keep
nodeGroupsToMerge.back().push_back( *nIt[0] ); // tp remove
}
}
double minParam = Min( param[ 0 ][ i[0] ], param[ 1 ][ i[1] ]);
double maxParam = Max( param[ 0 ][ i[0] ], param[ 1 ][ i[1] ]);
double minSegLen = Min( nextParam - minParam, maxParam - prevParam );
-
+
// choose to insert or to merge nodes
double du = param[ 1 ][ i[1] ] - param[ 0 ][ i[0] ];
if ( Abs( du ) <= minSegLen * 0.2 ) {
iNode = i3;
i3 = i4;
i4 = iNode;
- }
+ }
if (toCreatePoly || theFace->IsPoly()) {
// create new elements
SMESHDS_Mesh *aMesh = GetMeshDS();
int aShapeId = FindShape( theFace );
-
+
i1 = 0; i2 = 1;
for ( iSplit = 0; iSplit < nbSplits - 1; iSplit++ ) {
SMDS_MeshElement* newElem = 0;
//=======================================================================
//function : UpdateVolumes
-//purpose :
+//purpose :
//=======================================================================
void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode* theBetweenNode1,
const SMDS_MeshNode* theBetweenNode2,
//=======================================================================
//function : SewSideElements
-//purpose :
+//purpose :
//=======================================================================
SMESH_MeshEditor::Sew_Error
if ( !volSet->empty() )
{
//int nodeSetSize = nodeSet->size();
-
+
// loop on given volumes
for ( vIt = volSet->begin(); vIt != volSet->end(); vIt++ ) {
SMDS_VolumeTool vol (*vIt);
maxNbNodes = nbSharedNodes;
fIt++;
}
- else
+ else
freeFaceList.erase( fIt++ ); // here fIt++ occures before erase
}
if ( freeFaceList.size() > 1 )