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()), myToler(Precision::Confusion()),
myAllNodesFlag(false) myAllNodesFlag(false)
{ {
myCurShapeType = TopAbs_SHAPE;
} }
ElementsOnShape::~ElementsOnShape() ElementsOnShape::~ElementsOnShape()
{ {
} clearClassifiers();
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);
} }
SMDSAbs_ElementType ElementsOnShape::GetType() const SMDSAbs_ElementType ElementsOnShape::GetType() const
@ -3710,10 +3698,12 @@ double ElementsOnShape::GetTolerance() const
void ElementsOnShape::SetAllNodes (bool theAllNodes) void ElementsOnShape::SetAllNodes (bool theAllNodes)
{ {
if (myAllNodesFlag != theAllNodes) {
myAllNodesFlag = theAllNodes; myAllNodesFlag = theAllNodes;
SetShape(myShape, myType); }
}
void ElementsOnShape::SetMesh (const SMDS_Mesh* theMesh)
{
myMesh = theMesh;
} }
void ElementsOnShape::SetShape (const TopoDS_Shape& theShape, void ElementsOnShape::SetShape (const TopoDS_Shape& theShape,
@ -3721,96 +3711,44 @@ void ElementsOnShape::SetShape (const TopoDS_Shape& theShape,
{ {
myType = theType; myType = theType;
myShape = theShape; myShape = theShape;
myIds.Clear(); if ( myShape.IsNull() ) return;
const SMDS_Mesh* myMesh = myMeshModifTracer.GetMesh(); 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() );
}
if ( !myMesh ) return; clearClassifiers();
myClassifiers.resize( shapesMap.Extent() );
myIds.ReSize( myMeshModifTracer.GetMesh()->GetMeshInfo().NbElements( myType )); for ( int i = 0; i < shapesMap.Extent(); ++i )
myClassifiers[ i ] = new TClassifier( shapesMap( i+1 ), myToler );
myShapesMap.Clear();
addShape(myShape);
} }
void ElementsOnShape::addShape (const TopoDS_Shape& theShape) void ElementsOnShape::clearClassifiers()
{ {
if (theShape.IsNull() || myMeshModifTracer.GetMesh() == 0) for ( size_t i = 0; i < myClassifiers.size(); ++i )
return; delete myClassifiers[ i ];
myClassifiers.clear();
if (!myShapesMap.Add(theShape)) return;
myCurShapeType = theShape.ShapeType();
switch (myCurShapeType)
{
case TopAbs_COMPOUND:
case TopAbs_COMPSOLID:
case TopAbs_SHELL:
case TopAbs_WIRE:
{
TopoDS_Iterator anIt (theShape, Standard_True, Standard_True);
for (; anIt.More(); anIt.Next()) addShape(anIt.Value());
}
break;
case TopAbs_SOLID:
{
myCurSC.Load(theShape);
process();
}
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();
}
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();
}
break;
case TopAbs_VERTEX:
{
TopoDS_Vertex aV = TopoDS::Vertex(theShape);
myCurPnt = BRep_Tool::Pnt(aV);
process();
}
break;
default:
break;
}
} }
void ElementsOnShape::process() bool ElementsOnShape::IsSatisfy (long elemId)
{ {
const SMDS_Mesh* myMesh = myMeshModifTracer.GetMesh(); const SMDS_MeshElement* elem =
if (myShape.IsNull() || myMesh == 0) ( myType == SMDSAbs_Node ? myMesh->FindNode( elemId ) : myMesh->FindElement( elemId ));
return; if ( !elem || myClassifiers.empty() )
return false;
SMDS_ElemIteratorPtr anIter = myMesh->elementsIterator(myType); for ( size_t i = 0; i < myClassifiers.size(); ++i )
while (anIter->more()) {
process(anIter->next()); SMDS_ElemIteratorPtr aNodeItr = elem->nodesIterator();
}
void ElementsOnShape::process (const SMDS_MeshElement* theElemPtr)
{
if (myShape.IsNull())
return;
SMDS_ElemIteratorPtr aNodeItr = theElemPtr->nodesIterator();
bool isSatisfy = myAllNodesFlag; bool isSatisfy = myAllNodesFlag;
gp_XYZ centerXYZ (0, 0, 0); gp_XYZ centerXYZ (0, 0, 0);
@ -3819,60 +3757,102 @@ void ElementsOnShape::process (const SMDS_MeshElement* theElemPtr)
{ {
SMESH_TNodeXYZ aPnt ( aNodeItr->next() ); SMESH_TNodeXYZ aPnt ( aNodeItr->next() );
centerXYZ += aPnt; centerXYZ += aPnt;
isSatisfy = ! myClassifiers[i]->IsOut( 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;
}
}
} }
if (isSatisfy && myCurShapeType == TopAbs_SOLID) { // Check the center point for volumes MantisBug 0020168 // Check the center point for volumes MantisBug 0020168
centerXYZ /= theElemPtr->NbNodes(); if (isSatisfy && myClassifiers[i]->ShapeType() == TopAbs_SOLID)
gp_Pnt aCenterPnt (centerXYZ); {
myCurSC.Perform(aCenterPnt, myToler); centerXYZ /= elem->NbNodes();
if ( !(myCurSC.State() == TopAbs_IN || myCurSC.State() == TopAbs_ON)) isSatisfy = ! myClassifiers[i]->IsOut( centerXYZ );
isSatisfy = false; }
if ( isSatisfy )
return true;
} }
if (isSatisfy) return false;
myIds.Add(theElemPtr->GetID());
} }
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: {
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: {
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:{
myVertexXYZ = BRep_Tool::Pnt( TopoDS::Vertex( theShape ) );
myIsOutFun = & ElementsOnShape::TClassifier::isOutOfVertex;
break;
}
default:
throw SALOME_Exception("Programmer error in usage of ElementsOnShape::TClassifier");
}
}
bool ElementsOnShape::TClassifier::isOutOfSolid (const gp_Pnt& p)
{
mySolidClfr.Perform( p, myTol );
return ( mySolidClfr.State() != TopAbs_IN && mySolidClfr.State() != TopAbs_ON );
}
bool ElementsOnShape::TClassifier::isOutOfFace (const gp_Pnt& p)
{
myProjFace.Perform( p );
if ( myProjFace.IsDone() && myProjFace.LowerDistance() <= myTol );
{
// 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;
}
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() TSequenceOfXYZ::TSequenceOfXYZ()
{} {}

View File

@ -820,25 +820,36 @@ namespace SMESH{
const SMDSAbs_ElementType theType); const SMDSAbs_ElementType theType);
private: private:
void addShape (const TopoDS_Shape& theShape);
void process();
void process (const SMDS_MeshElement* theElem);
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: private:
TMeshModifTracer myMeshModifTracer; bool isOutOfSolid (const gp_Pnt& p);
TColStd_MapOfInteger myIds; 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; SMDSAbs_ElementType myType;
TopoDS_Shape myShape; TopoDS_Shape myShape;
double myToler; double myToler;
bool myAllNodesFlag; 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; typedef boost::shared_ptr<ElementsOnShape> ElementsOnShapePtr;