0021338: EDF 1926 SMESH: New controls and filters

+    /*!
+     * \brief Class used to detect mesh modification: IsMeshModified() returns
+     * true if a mesh has changed since last calling IsMeshModified()
+     */
+    class SMESHCONTROLS_EXPORT TMeshModifTracer
This commit is contained in:
eap 2012-01-26 15:56:22 +00:00
parent 2d179048e3
commit e65e4d9a03
2 changed files with 90 additions and 69 deletions

View File

@ -2025,10 +2025,11 @@ bool BareBorderFace::IsSatisfy(long theElementId )
} }
if ( !isShared ) if ( !isShared )
{ {
myLinkNodes.resize( 2 + face->IsQuadratic()); const int iQuad = face->IsQuadratic();
myLinkNodes.resize( 2 + iQuad);
myLinkNodes[0] = n1; myLinkNodes[0] = n1;
myLinkNodes[1] = n2; myLinkNodes[1] = n2;
if ( face->IsQuadratic() ) if ( iQuad )
myLinkNodes[2] = face->GetNode( i+nbN ); myLinkNodes[2] = face->GetNode( i+nbN );
ok = !myMesh->FindElement( myLinkNodes, SMDSAbs_Edge, /*noMedium=*/false); ok = !myMesh->FindElement( myLinkNodes, SMDSAbs_Edge, /*noMedium=*/false);
} }
@ -2111,28 +2112,28 @@ SMDSAbs_ElementType CoincidentNodes::GetType() const
return SMDSAbs_Node; return SMDSAbs_Node;
} }
void CoincidentNodes::SetMesh( const SMDS_Mesh* theMesh, TIDSortedNodeSet* nodesToCheck ) void CoincidentNodes::SetMesh( const SMDS_Mesh* theMesh )
{ {
TIDSortedNodeSet allNodes; myMeshModifTracer.SetMesh( theMesh );
if ( !nodesToCheck ) if ( myMeshModifTracer.IsMeshModified() )
{ {
nodesToCheck = &allNodes; TIDSortedNodeSet nodesToCheck;
SMDS_NodeIteratorPtr nIt = theMesh->nodesIterator(/*idInceasingOrder=*/true); SMDS_NodeIteratorPtr nIt = theMesh->nodesIterator(/*idInceasingOrder=*/true);
while ( nIt->more() ) while ( nIt->more() )
allNodes.insert( allNodes.end(), nIt->next() ); nodesToCheck.insert( nodesToCheck.end(), nIt->next() );
}
list< list< const SMDS_MeshNode*> > nodeGroups; list< list< const SMDS_MeshNode*> > nodeGroups;
SMESH_OctreeNode::FindCoincidentNodes ( *nodesToCheck, &nodeGroups, myToler ); SMESH_OctreeNode::FindCoincidentNodes ( nodesToCheck, &nodeGroups, myToler );
myCoincidentIDs.Clear(); myCoincidentIDs.Clear();
list< list< const SMDS_MeshNode*> >::iterator groupIt = nodeGroups.begin(); list< list< const SMDS_MeshNode*> >::iterator groupIt = nodeGroups.begin();
for ( ; groupIt != nodeGroups.end(); ++groupIt ) for ( ; groupIt != nodeGroups.end(); ++groupIt )
{ {
list< const SMDS_MeshNode*>& coincNodes = *groupIt; list< const SMDS_MeshNode*>& coincNodes = *groupIt;
list< const SMDS_MeshNode*>::iterator n = coincNodes.begin(); list< const SMDS_MeshNode*>::iterator n = coincNodes.begin();
for ( ; n != coincNodes.end(); ++n ) for ( ; n != coincNodes.end(); ++n )
myCoincidentIDs.Add( (*n)->GetID() ); myCoincidentIDs.Add( (*n)->GetID() );
}
} }
} }
@ -2145,37 +2146,15 @@ void CoincidentNodes::SetMesh( const SMDS_Mesh* theMesh, TIDSortedNodeSet* node
CoincidentElements::CoincidentElements() CoincidentElements::CoincidentElements()
{ {
myMesh = 0; myMesh = 0;
myElemsToCheck = 0;
} }
void CoincidentElements::SetMesh( const SMDS_Mesh* theMesh, TIDSortedElemSet* elemsToCheck ) void CoincidentElements::SetMesh( const SMDS_Mesh* theMesh )
{ {
myMesh = theMesh; myMesh = theMesh;
myCoincidentIDs.Clear();
myElemsToCheck = elemsToCheck;
if ( myElemsToCheck )
{
TColStd_MapOfInteger coincidentIDs;
TIDSortedElemSet::iterator elem = myElemsToCheck->begin();
for ( ; elem != myElemsToCheck->end(); ++elem )
if ( IsSatisfy( (*elem)->GetID() ))
coincidentIDs.Add( (*elem)->GetID() );
myCoincidentIDs = coincidentIDs;
if ( myCoincidentIDs.IsEmpty() )
myCoincidentIDs.Add( -1 ); // mark that analysis is already performed
myElemsToCheck = 0; // not needed anymore
}
} }
bool CoincidentElements::IsSatisfy( long theElementId ) bool CoincidentElements::IsSatisfy( long theElementId )
{ {
if ( !myCoincidentIDs.IsEmpty() )
return myCoincidentIDs.Contains( theElementId );
if ( !myMesh ) return false; if ( !myMesh ) return false;
if ( const SMDS_MeshElement* e = myMesh->FindElement( theElementId )) if ( const SMDS_MeshElement* e = myMesh->FindElement( theElementId ))
@ -2187,7 +2166,6 @@ bool CoincidentElements::IsSatisfy( long theElementId )
{ {
const SMDS_MeshElement* e2 = invIt->next(); const SMDS_MeshElement* e2 = invIt->next();
if ( e2 == e || e2->NbNodes() != (int)elemNodes.size() ) continue; if ( e2 == e || e2->NbNodes() != (int)elemNodes.size() ) continue;
if ( myElemsToCheck && !myElemsToCheck->count( e2 )) continue;
bool sameNodes = true; bool sameNodes = true;
for ( size_t i = 0; i < elemNodes.size() && sameNodes; ++i ) for ( size_t i = 0; i < elemNodes.size() && sameNodes; ++i )
@ -2688,26 +2666,29 @@ SMDSAbs_GeometryType ElemGeomType::GetGeomType() const
//================================================================================ //================================================================================
CoplanarFaces::CoplanarFaces() CoplanarFaces::CoplanarFaces()
: myMesh(0), myFaceID(0), myToler(0) : myFaceID(0), myToler(0)
{ {
} }
bool CoplanarFaces::IsSatisfy( long theElementId ) void CoplanarFaces::SetMesh( const SMDS_Mesh* theMesh )
{ {
if ( myCoplanarIDs.empty() ) myMeshModifTracer.SetMesh( theMesh );
if ( myMeshModifTracer.IsMeshModified() )
{ {
// Build a set of coplanar face ids // Build a set of coplanar face ids
if ( !myMesh || !myFaceID || !myToler ) myCoplanarIDs.clear();
return false;
const SMDS_MeshElement* face = myMesh->FindElement( myFaceID ); if ( !myMeshModifTracer.GetMesh() || !myFaceID || !myToler )
return;
const SMDS_MeshElement* face = myMeshModifTracer.GetMesh()->FindElement( myFaceID );
if ( !face || face->GetType() != SMDSAbs_Face ) if ( !face || face->GetType() != SMDSAbs_Face )
return false; return;
bool normOK; bool normOK;
gp_Vec myNorm = getNormale( static_cast<const SMDS_MeshFace*>(face), &normOK ); gp_Vec myNorm = getNormale( static_cast<const SMDS_MeshFace*>(face), &normOK );
if (!normOK) if (!normOK)
return false; return;
const double radianTol = myToler * M_PI / 180.; const double radianTol = myToler * M_PI / 180.;
typedef SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > TFaceIt; typedef SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > TFaceIt;
@ -2736,6 +2717,9 @@ bool CoplanarFaces::IsSatisfy( long theElementId )
faceQueue.pop_front(); faceQueue.pop_front();
} }
} }
}
bool CoplanarFaces::IsSatisfy( long theElementId )
{
return myCoplanarIDs.count( theElementId ); return myCoplanarIDs.count( theElementId );
} }
@ -3713,7 +3697,7 @@ bool ElementsOnSurface::isOnSurface( const SMDS_MeshNode* theNode )
*/ */
ElementsOnShape::ElementsOnShape() ElementsOnShape::ElementsOnShape()
: myMesh(0), : //myMesh(0),
myType(SMDSAbs_All), myType(SMDSAbs_All),
myToler(Precision::Confusion()), myToler(Precision::Confusion()),
myAllNodesFlag(false) myAllNodesFlag(false)
@ -3727,10 +3711,9 @@ ElementsOnShape::~ElementsOnShape()
void ElementsOnShape::SetMesh (const SMDS_Mesh* theMesh) void ElementsOnShape::SetMesh (const SMDS_Mesh* theMesh)
{ {
if (myMesh != theMesh) { myMeshModifTracer.SetMesh( theMesh );
myMesh = theMesh; if ( myMeshModifTracer.IsMeshModified())
SetShape(myShape, myType); SetShape(myShape, myType);
}
} }
bool ElementsOnShape::IsSatisfy (long theElementId) bool ElementsOnShape::IsSatisfy (long theElementId)
@ -3771,7 +3754,9 @@ void ElementsOnShape::SetShape (const TopoDS_Shape& theShape,
myShape = theShape; myShape = theShape;
myIds.Clear(); myIds.Clear();
if (myMesh == 0) return; const SMDS_Mesh* myMesh = myMeshModifTracer.GetMesh();
if ( !myMesh ) return;
switch (myType) switch (myType)
{ {
@ -3800,7 +3785,7 @@ void ElementsOnShape::SetShape (const TopoDS_Shape& theShape,
void ElementsOnShape::addShape (const TopoDS_Shape& theShape) void ElementsOnShape::addShape (const TopoDS_Shape& theShape)
{ {
if (theShape.IsNull() || myMesh == 0) if (theShape.IsNull() || myMeshModifTracer.GetMesh() == 0)
return; return;
if (!myShapesMap.Add(theShape)) return; if (!myShapesMap.Add(theShape)) return;
@ -3861,6 +3846,7 @@ void ElementsOnShape::addShape (const TopoDS_Shape& theShape)
void ElementsOnShape::process() void ElementsOnShape::process()
{ {
const SMDS_Mesh* myMesh = myMeshModifTracer.GetMesh();
if (myShape.IsNull() || myMesh == 0) if (myShape.IsNull() || myMesh == 0)
return; return;
@ -4019,3 +4005,24 @@ TSequenceOfXYZ::size_type TSequenceOfXYZ::size() const
{ {
return myArray.size(); return myArray.size();
} }
TMeshModifTracer::TMeshModifTracer():
myMeshModifTime(0), myMesh(0)
{
}
void TMeshModifTracer::SetMesh( const SMDS_Mesh* theMesh )
{
if ( theMesh != myMesh )
myMeshModifTime = 0;
myMesh = theMesh;
}
bool TMeshModifTracer::IsMeshModified()
{
bool modified = false;
if ( myMesh )
{
modified = ( myMeshModifTime != myMesh->GetMTime() );
myMeshModifTime = myMesh->GetMTime();
}
return modified;
}

View File

@ -96,6 +96,21 @@ namespace SMESH{
std::vector<gp_XYZ> myArray; std::vector<gp_XYZ> myArray;
}; };
/*!
* \brief Class used to detect mesh modification: IsMeshModified() returns
* true if a mesh has changed since last calling IsMeshModified()
*/
class SMESHCONTROLS_EXPORT TMeshModifTracer
{
unsigned long myMeshModifTime;
const SMDS_Mesh* myMesh;
public:
TMeshModifTracer();
void SetMesh( const SMDS_Mesh* theMesh );
const SMDS_Mesh* GetMesh() const { return myMesh; }
bool IsMeshModified();
};
/* /*
Class : NumericalFunctor Class : NumericalFunctor
Description : Root of all Functors returning numeric value Description : Root of all Functors returning numeric value
@ -326,16 +341,19 @@ namespace SMESH{
class SMESHCONTROLS_EXPORT CoincidentNodes: public Predicate { class SMESHCONTROLS_EXPORT CoincidentNodes: public Predicate {
public: public:
CoincidentNodes(); CoincidentNodes();
void SetTolerance (const double theToler) { myToler = theToler; } virtual void SetMesh( const SMDS_Mesh* theMesh );
void SetMesh( const SMDS_Mesh* theMesh, TIDSortedNodeSet* nodesToCheck );
virtual void SetMesh( const SMDS_Mesh* theMesh ) { SetMesh( theMesh, 0 ); }
virtual bool IsSatisfy( long theElementId ); virtual bool IsSatisfy( long theElementId );
virtual SMDSAbs_ElementType GetType() const; virtual SMDSAbs_ElementType GetType() const;
void SetTolerance (const double theToler) { myToler = theToler; }
double GetTolerance () const { return myToler; }
private: private:
TColStd_MapOfInteger myCoincidentIDs;
double myToler; double myToler;
TColStd_MapOfInteger myCoincidentIDs;
TMeshModifTracer myMeshModifTracer;
}; };
typedef boost::shared_ptr<CoincidentNodes> CoincidentNodesPtr;
/* /*
Class : CoincidentElements Class : CoincidentElements
@ -345,14 +363,11 @@ namespace SMESH{
class SMESHCONTROLS_EXPORT CoincidentElements: public Predicate { class SMESHCONTROLS_EXPORT CoincidentElements: public Predicate {
public: public:
CoincidentElements(); CoincidentElements();
void SetMesh( const SMDS_Mesh* theMesh, TIDSortedElemSet* elemsToCheck ); virtual void SetMesh( const SMDS_Mesh* theMesh );
virtual void SetMesh( const SMDS_Mesh* theMesh ) { SetMesh( theMesh, 0 ); }
virtual bool IsSatisfy( long theElementId ); virtual bool IsSatisfy( long theElementId );
private: private:
const SMDS_Mesh* myMesh; const SMDS_Mesh* myMesh;
TIDSortedElemSet* myElemsToCheck;
TColStd_MapOfInteger myCoincidentIDs;
}; };
class SMESHCONTROLS_EXPORT CoincidentElements1D: public CoincidentElements { class SMESHCONTROLS_EXPORT CoincidentElements1D: public CoincidentElements {
public: public:
@ -456,7 +471,6 @@ namespace SMESH{
virtual bool IsSatisfy( long theElementId ); virtual bool IsSatisfy( long theElementId );
protected: protected:
const SMDS_Mesh* myMesh; const SMDS_Mesh* myMesh;
std::vector< const SMDS_MeshNode* > myLinkNodes;
}; };
typedef boost::shared_ptr<OverConstrainedFace> OverConstrainedFacePtr; typedef boost::shared_ptr<OverConstrainedFace> OverConstrainedFacePtr;
@ -796,7 +810,7 @@ namespace SMESH{
void process (const SMDS_MeshElement* theElem); void process (const SMDS_MeshElement* theElem);
private: private:
const SMDS_Mesh* myMesh; TMeshModifTracer myMeshModifTracer;
TColStd_MapOfInteger myIds; TColStd_MapOfInteger myIds;
SMDSAbs_ElementType myType; SMDSAbs_ElementType myType;
TopoDS_Shape myShape; TopoDS_Shape myShape;
@ -904,13 +918,13 @@ namespace SMESH{
long GetFace() const { return myFaceID; } long GetFace() const { return myFaceID; }
void SetTolerance (const double theToler) { myToler = theToler; } void SetTolerance (const double theToler) { myToler = theToler; }
double GetTolerance () const { return myToler; } double GetTolerance () const { return myToler; }
virtual void SetMesh( const SMDS_Mesh* theMesh ) { myMesh = theMesh; }
virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Face; } virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Face; }
virtual void SetMesh( const SMDS_Mesh* theMesh );
virtual bool IsSatisfy( long theElementId ); virtual bool IsSatisfy( long theElementId );
private: private:
const SMDS_Mesh* myMesh; TMeshModifTracer myMeshModifTracer;
long myFaceID; long myFaceID;
double myToler; double myToler;
std::set< long > myCoplanarIDs; std::set< long > myCoplanarIDs;