21948: EDF SMESH : Memory is not freed when deleting a mesh

Optimize ElementsOnShape for large meshes
This commit is contained in:
eap 2012-12-14 13:36:23 +00:00
parent 11e1059f3e
commit 3304d08571
2 changed files with 150 additions and 159 deletions

View File

@ -3671,23 +3671,11 @@ ElementsOnShape::ElementsOnShape()
myToler(Precision::Confusion()),
myAllNodesFlag(false)
{
myCurShapeType = TopAbs_SHAPE;
}
ElementsOnShape::~ElementsOnShape()
{
}
void ElementsOnShape::SetMesh (const SMDS_Mesh* theMesh)
{
myMeshModifTracer.SetMesh( theMesh );
if ( myMeshModifTracer.IsMeshModified())
SetShape(myShape, myType);
}
bool ElementsOnShape::IsSatisfy (long theElementId)
{
return myIds.Contains(theElementId);
clearClassifiers();
}
SMDSAbs_ElementType ElementsOnShape::GetType() const
@ -3710,169 +3698,161 @@ double ElementsOnShape::GetTolerance() const
void ElementsOnShape::SetAllNodes (bool theAllNodes)
{
if (myAllNodesFlag != theAllNodes) {
myAllNodesFlag = theAllNodes;
SetShape(myShape, myType);
}
myAllNodesFlag = theAllNodes;
}
void ElementsOnShape::SetMesh (const SMDS_Mesh* theMesh)
{
myMesh = theMesh;
}
void ElementsOnShape::SetShape (const TopoDS_Shape& theShape,
const SMDSAbs_ElementType theType)
{
myType = theType;
myType = theType;
myShape = theShape;
myIds.Clear();
const SMDS_Mesh* myMesh = myMeshModifTracer.GetMesh();
if ( myShape.IsNull() ) return;
if ( !myMesh ) return;
TopTools_IndexedMapOfShape shapesMap;
TopAbs_ShapeEnum shapeTypes[4] = { TopAbs_SOLID, TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX };
TopExp_Explorer sub;
for ( int i = 0; i < 4; ++i )
{
if ( shapesMap.IsEmpty() )
for ( sub.Init( myShape, shapeTypes[i] ); sub.More(); sub.Next() )
shapesMap.Add( sub.Current() );
if ( i > 0 )
for ( sub.Init( myShape, shapeTypes[i], shapeTypes[i-1] ); sub.More(); sub.Next() )
shapesMap.Add( sub.Current() );
}
myIds.ReSize( myMeshModifTracer.GetMesh()->GetMeshInfo().NbElements( myType ));
myShapesMap.Clear();
addShape(myShape);
clearClassifiers();
myClassifiers.resize( shapesMap.Extent() );
for ( int i = 0; i < shapesMap.Extent(); ++i )
myClassifiers[ i ] = new TClassifier( shapesMap( i+1 ), myToler );
}
void ElementsOnShape::addShape (const TopoDS_Shape& theShape)
void ElementsOnShape::clearClassifiers()
{
if (theShape.IsNull() || myMeshModifTracer.GetMesh() == 0)
return;
for ( size_t i = 0; i < myClassifiers.size(); ++i )
delete myClassifiers[ i ];
myClassifiers.clear();
}
if (!myShapesMap.Add(theShape)) return;
bool ElementsOnShape::IsSatisfy (long elemId)
{
const SMDS_MeshElement* elem =
( myType == SMDSAbs_Node ? myMesh->FindNode( elemId ) : myMesh->FindElement( elemId ));
if ( !elem || myClassifiers.empty() )
return false;
myCurShapeType = theShape.ShapeType();
switch (myCurShapeType)
for ( size_t i = 0; i < myClassifiers.size(); ++i )
{
case TopAbs_COMPOUND:
case TopAbs_COMPSOLID:
case TopAbs_SHELL:
case TopAbs_WIRE:
SMDS_ElemIteratorPtr aNodeItr = elem->nodesIterator();
bool isSatisfy = myAllNodesFlag;
gp_XYZ centerXYZ (0, 0, 0);
while (aNodeItr->more() && (isSatisfy == myAllNodesFlag))
{
TopoDS_Iterator anIt (theShape, Standard_True, Standard_True);
for (; anIt.More(); anIt.Next()) addShape(anIt.Value());
SMESH_TNodeXYZ aPnt ( aNodeItr->next() );
centerXYZ += aPnt;
isSatisfy = ! myClassifiers[i]->IsOut( aPnt );
}
break;
case TopAbs_SOLID:
// Check the center point for volumes MantisBug 0020168
if (isSatisfy && myClassifiers[i]->ShapeType() == TopAbs_SOLID)
{
myCurSC.Load(theShape);
process();
centerXYZ /= elem->NbNodes();
isSatisfy = ! myClassifiers[i]->IsOut( centerXYZ );
}
if ( isSatisfy )
return true;
}
return false;
}
TopAbs_ShapeEnum ElementsOnShape::TClassifier::ShapeType() const
{
return myShape.ShapeType();
}
bool ElementsOnShape::TClassifier::IsOut(const gp_Pnt& p)
{
return (this->*myIsOutFun)( p );
}
void ElementsOnShape::TClassifier::Init (const TopoDS_Shape& theShape, double theTol)
{
myShape = theShape;
myTol = theTol;
switch ( myShape.ShapeType() )
{
case TopAbs_SOLID: {
mySolidClfr.Load(theShape);
myIsOutFun = & ElementsOnShape::TClassifier::isOutOfSolid;
break;
case TopAbs_FACE:
{
TopoDS_Face aFace = TopoDS::Face(theShape);
BRepAdaptor_Surface SA (aFace, true);
Standard_Real
u1 = SA.FirstUParameter(),
u2 = SA.LastUParameter(),
v1 = SA.FirstVParameter(),
v2 = SA.LastVParameter();
Handle(Geom_Surface) surf = BRep_Tool::Surface(aFace);
myCurProjFace.Init(surf, u1,u2, v1,v2);
myCurFace = aFace;
process();
}
}
case TopAbs_FACE: {
Standard_Real u1,u2,v1,v2;
Handle(Geom_Surface) surf = BRep_Tool::Surface( TopoDS::Face( theShape ));
surf->Bounds( u1,u2,v1,v2 );
myProjFace.Init(surf, u1,u2, v1,v2, myTol );
myIsOutFun = & ElementsOnShape::TClassifier::isOutOfFace;
break;
case TopAbs_EDGE:
{
TopoDS_Edge anEdge = TopoDS::Edge(theShape);
Standard_Real u1, u2;
Handle(Geom_Curve) curve = BRep_Tool::Curve(anEdge, u1, u2);
myCurProjEdge.Init(curve, u1, u2);
process();
}
}
case TopAbs_EDGE: {
Standard_Real u1, u2;
Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge(theShape), u1, u2);
myProjEdge.Init(curve, u1, u2);
myIsOutFun = & ElementsOnShape::TClassifier::isOutOfEdge;
break;
case TopAbs_VERTEX:
{
TopoDS_Vertex aV = TopoDS::Vertex(theShape);
myCurPnt = BRep_Tool::Pnt(aV);
process();
}
}
case TopAbs_VERTEX:{
myVertexXYZ = BRep_Tool::Pnt( TopoDS::Vertex( theShape ) );
myIsOutFun = & ElementsOnShape::TClassifier::isOutOfVertex;
break;
}
default:
break;
throw SALOME_Exception("Programmer error in usage of ElementsOnShape::TClassifier");
}
}
void ElementsOnShape::process()
bool ElementsOnShape::TClassifier::isOutOfSolid (const gp_Pnt& p)
{
const SMDS_Mesh* myMesh = myMeshModifTracer.GetMesh();
if (myShape.IsNull() || myMesh == 0)
return;
SMDS_ElemIteratorPtr anIter = myMesh->elementsIterator(myType);
while (anIter->more())
process(anIter->next());
mySolidClfr.Perform( p, myTol );
return ( mySolidClfr.State() != TopAbs_IN && mySolidClfr.State() != TopAbs_ON );
}
void ElementsOnShape::process (const SMDS_MeshElement* theElemPtr)
bool ElementsOnShape::TClassifier::isOutOfFace (const gp_Pnt& p)
{
if (myShape.IsNull())
return;
SMDS_ElemIteratorPtr aNodeItr = theElemPtr->nodesIterator();
bool isSatisfy = myAllNodesFlag;
gp_XYZ centerXYZ (0, 0, 0);
while (aNodeItr->more() && (isSatisfy == myAllNodesFlag))
myProjFace.Perform( p );
if ( myProjFace.IsDone() && myProjFace.LowerDistance() <= myTol );
{
SMESH_TNodeXYZ aPnt ( aNodeItr->next() );
centerXYZ += aPnt;
switch (myCurShapeType)
{
case TopAbs_SOLID:
{
myCurSC.Perform(aPnt, myToler);
isSatisfy = (myCurSC.State() == TopAbs_IN || myCurSC.State() == TopAbs_ON);
}
break;
case TopAbs_FACE:
{
myCurProjFace.Perform(aPnt);
isSatisfy = (myCurProjFace.IsDone() && myCurProjFace.LowerDistance() <= myToler);
if (isSatisfy)
{
// check relatively the face
Quantity_Parameter u, v;
myCurProjFace.LowerDistanceParameters(u, v);
gp_Pnt2d aProjPnt (u, v);
BRepClass_FaceClassifier aClsf (myCurFace, aProjPnt, myToler);
isSatisfy = (aClsf.State() == TopAbs_IN || aClsf.State() == TopAbs_ON);
}
}
break;
case TopAbs_EDGE:
{
myCurProjEdge.Perform(aPnt);
isSatisfy = (myCurProjEdge.NbPoints() > 0 && myCurProjEdge.LowerDistance() <= myToler);
}
break;
case TopAbs_VERTEX:
{
isSatisfy = (myCurPnt.Distance(aPnt) <= myToler);
}
break;
default:
{
isSatisfy = false;
}
}
// check relatively to the face
Quantity_Parameter u, v;
myProjFace.LowerDistanceParameters(u, v);
gp_Pnt2d aProjPnt (u, v);
BRepClass_FaceClassifier aClsf ( TopoDS::Face( myShape ), aProjPnt, myTol );
if ( aClsf.State() == TopAbs_IN || aClsf.State() == TopAbs_ON )
return false;
}
if (isSatisfy && myCurShapeType == TopAbs_SOLID) { // Check the center point for volumes MantisBug 0020168
centerXYZ /= theElemPtr->NbNodes();
gp_Pnt aCenterPnt (centerXYZ);
myCurSC.Perform(aCenterPnt, myToler);
if ( !(myCurSC.State() == TopAbs_IN || myCurSC.State() == TopAbs_ON))
isSatisfy = false;
}
if (isSatisfy)
myIds.Add(theElemPtr->GetID());
return true;
}
bool ElementsOnShape::TClassifier::isOutOfEdge (const gp_Pnt& p)
{
myProjEdge.Perform( p );
return ! ( myProjEdge.NbPoints() > 0 && myProjEdge.LowerDistance() <= myTol );
}
bool ElementsOnShape::TClassifier::isOutOfVertex(const gp_Pnt& p)
{
return ( myVertexXYZ.Distance( p ) > myTol );
}
TSequenceOfXYZ::TSequenceOfXYZ()
{}

View File

@ -820,25 +820,36 @@ namespace SMESH{
const SMDSAbs_ElementType theType);
private:
void addShape (const TopoDS_Shape& theShape);
void process();
void process (const SMDS_MeshElement* theElem);
private:
TMeshModifTracer myMeshModifTracer;
TColStd_MapOfInteger myIds;
SMDSAbs_ElementType myType;
TopoDS_Shape myShape;
double myToler;
bool myAllNodesFlag;
struct TClassifier
{
TClassifier(const TopoDS_Shape& s, double tol) { Init(s,tol); }
void Init(const TopoDS_Shape& s, double tol);
bool IsOut(const gp_Pnt& p);
TopAbs_ShapeEnum ShapeType() const;
private:
bool isOutOfSolid (const gp_Pnt& p);
bool isOutOfFace (const gp_Pnt& p);
bool isOutOfEdge (const gp_Pnt& p);
bool isOutOfVertex(const gp_Pnt& p);
bool (TClassifier::* myIsOutFun)(const gp_Pnt& p);
BRepClass3d_SolidClassifier mySolidClfr;
GeomAPI_ProjectPointOnSurf myProjFace;
GeomAPI_ProjectPointOnCurve myProjEdge;
gp_Pnt myVertexXYZ;
TopoDS_Shape myShape;
double myTol;
};
void clearClassifiers();
std::vector< TClassifier* > myClassifiers;
const SMDS_Mesh* myMesh;
SMDSAbs_ElementType myType;
TopoDS_Shape myShape;
double myToler;
bool myAllNodesFlag;
TopTools_MapOfShape myShapesMap;
TopAbs_ShapeEnum myCurShapeType; // type of current sub-shape
BRepClass3d_SolidClassifier myCurSC; // current SOLID
GeomAPI_ProjectPointOnSurf myCurProjFace; // current FACE
TopoDS_Face myCurFace; // current FACE
GeomAPI_ProjectPointOnCurve myCurProjEdge; // current EDGE
gp_Pnt myCurPnt; // current VERTEX
};
typedef boost::shared_ptr<ElementsOnShape> ElementsOnShapePtr;