mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-12-28 18:30:35 +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()),
|
||||
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()
|
||||
{}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user