mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-01 04:10:33 +05:00
21948: EDF SMESH : Memory is not freed when deleting a mesh
Optimize ElementsOnShape for large meshes
This commit is contained in:
parent
11e1059f3e
commit
3304d08571
@ -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()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user