From e65e4d9a038de28ef8bd0f0ba832d5818674b1b5 Mon Sep 17 00:00:00 2001 From: eap Date: Thu, 26 Jan 2012 15:56:22 +0000 Subject: [PATCH] 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 --- src/Controls/SMESH_Controls.cxx | 119 +++++++++++++++-------------- src/Controls/SMESH_ControlsDef.hxx | 40 ++++++---- 2 files changed, 90 insertions(+), 69 deletions(-) diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx index 5bdcc486f..e65db837f 100644 --- a/src/Controls/SMESH_Controls.cxx +++ b/src/Controls/SMESH_Controls.cxx @@ -2025,10 +2025,11 @@ bool BareBorderFace::IsSatisfy(long theElementId ) } if ( !isShared ) { - myLinkNodes.resize( 2 + face->IsQuadratic()); + const int iQuad = face->IsQuadratic(); + myLinkNodes.resize( 2 + iQuad); myLinkNodes[0] = n1; myLinkNodes[1] = n2; - if ( face->IsQuadratic() ) + if ( iQuad ) myLinkNodes[2] = face->GetNode( i+nbN ); ok = !myMesh->FindElement( myLinkNodes, SMDSAbs_Edge, /*noMedium=*/false); } @@ -2111,28 +2112,28 @@ SMDSAbs_ElementType CoincidentNodes::GetType() const return SMDSAbs_Node; } -void CoincidentNodes::SetMesh( const SMDS_Mesh* theMesh, TIDSortedNodeSet* nodesToCheck ) +void CoincidentNodes::SetMesh( const SMDS_Mesh* theMesh ) { - TIDSortedNodeSet allNodes; - if ( !nodesToCheck ) + myMeshModifTracer.SetMesh( theMesh ); + if ( myMeshModifTracer.IsMeshModified() ) { - nodesToCheck = &allNodes; + TIDSortedNodeSet nodesToCheck; SMDS_NodeIteratorPtr nIt = theMesh->nodesIterator(/*idInceasingOrder=*/true); while ( nIt->more() ) - allNodes.insert( allNodes.end(), nIt->next() ); - } + nodesToCheck.insert( nodesToCheck.end(), nIt->next() ); - list< list< const SMDS_MeshNode*> > nodeGroups; - SMESH_OctreeNode::FindCoincidentNodes ( *nodesToCheck, &nodeGroups, myToler ); + list< list< const SMDS_MeshNode*> > nodeGroups; + SMESH_OctreeNode::FindCoincidentNodes ( nodesToCheck, &nodeGroups, myToler ); - myCoincidentIDs.Clear(); - list< list< const SMDS_MeshNode*> >::iterator groupIt = nodeGroups.begin(); - for ( ; groupIt != nodeGroups.end(); ++groupIt ) - { - list< const SMDS_MeshNode*>& coincNodes = *groupIt; - list< const SMDS_MeshNode*>::iterator n = coincNodes.begin(); - for ( ; n != coincNodes.end(); ++n ) - myCoincidentIDs.Add( (*n)->GetID() ); + myCoincidentIDs.Clear(); + list< list< const SMDS_MeshNode*> >::iterator groupIt = nodeGroups.begin(); + for ( ; groupIt != nodeGroups.end(); ++groupIt ) + { + list< const SMDS_MeshNode*>& coincNodes = *groupIt; + list< const SMDS_MeshNode*>::iterator n = coincNodes.begin(); + for ( ; n != coincNodes.end(); ++n ) + myCoincidentIDs.Add( (*n)->GetID() ); + } } } @@ -2145,37 +2146,15 @@ void CoincidentNodes::SetMesh( const SMDS_Mesh* theMesh, TIDSortedNodeSet* node CoincidentElements::CoincidentElements() { myMesh = 0; - myElemsToCheck = 0; } -void CoincidentElements::SetMesh( const SMDS_Mesh* theMesh, TIDSortedElemSet* elemsToCheck ) +void CoincidentElements::SetMesh( const SMDS_Mesh* 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 ) { - if ( !myCoincidentIDs.IsEmpty() ) - return myCoincidentIDs.Contains( theElementId ); - if ( !myMesh ) return false; if ( const SMDS_MeshElement* e = myMesh->FindElement( theElementId )) @@ -2187,7 +2166,6 @@ bool CoincidentElements::IsSatisfy( long theElementId ) { const SMDS_MeshElement* e2 = invIt->next(); if ( e2 == e || e2->NbNodes() != (int)elemNodes.size() ) continue; - if ( myElemsToCheck && !myElemsToCheck->count( e2 )) continue; bool sameNodes = true; for ( size_t i = 0; i < elemNodes.size() && sameNodes; ++i ) @@ -2688,26 +2666,29 @@ SMDSAbs_GeometryType ElemGeomType::GetGeomType() const //================================================================================ 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 - if ( !myMesh || !myFaceID || !myToler ) - return false; + myCoplanarIDs.clear(); - 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 ) - return false; + return; bool normOK; gp_Vec myNorm = getNormale( static_cast(face), &normOK ); if (!normOK) - return false; + return; const double radianTol = myToler * M_PI / 180.; typedef SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > TFaceIt; @@ -2736,6 +2717,9 @@ bool CoplanarFaces::IsSatisfy( long theElementId ) faceQueue.pop_front(); } } +} +bool CoplanarFaces::IsSatisfy( long theElementId ) +{ return myCoplanarIDs.count( theElementId ); } @@ -3713,7 +3697,7 @@ bool ElementsOnSurface::isOnSurface( const SMDS_MeshNode* theNode ) */ ElementsOnShape::ElementsOnShape() - : myMesh(0), + : //myMesh(0), myType(SMDSAbs_All), myToler(Precision::Confusion()), myAllNodesFlag(false) @@ -3727,10 +3711,9 @@ ElementsOnShape::~ElementsOnShape() void ElementsOnShape::SetMesh (const SMDS_Mesh* theMesh) { - if (myMesh != theMesh) { - myMesh = theMesh; + myMeshModifTracer.SetMesh( theMesh ); + if ( myMeshModifTracer.IsMeshModified()) SetShape(myShape, myType); - } } bool ElementsOnShape::IsSatisfy (long theElementId) @@ -3771,7 +3754,9 @@ void ElementsOnShape::SetShape (const TopoDS_Shape& theShape, myShape = theShape; myIds.Clear(); - if (myMesh == 0) return; + const SMDS_Mesh* myMesh = myMeshModifTracer.GetMesh(); + + if ( !myMesh ) return; switch (myType) { @@ -3800,7 +3785,7 @@ void ElementsOnShape::SetShape (const TopoDS_Shape& theShape, void ElementsOnShape::addShape (const TopoDS_Shape& theShape) { - if (theShape.IsNull() || myMesh == 0) + if (theShape.IsNull() || myMeshModifTracer.GetMesh() == 0) return; if (!myShapesMap.Add(theShape)) return; @@ -3861,6 +3846,7 @@ void ElementsOnShape::addShape (const TopoDS_Shape& theShape) void ElementsOnShape::process() { + const SMDS_Mesh* myMesh = myMeshModifTracer.GetMesh(); if (myShape.IsNull() || myMesh == 0) return; @@ -4019,3 +4005,24 @@ TSequenceOfXYZ::size_type TSequenceOfXYZ::size() const { 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; +} diff --git a/src/Controls/SMESH_ControlsDef.hxx b/src/Controls/SMESH_ControlsDef.hxx index ac07599ed..80d573d04 100644 --- a/src/Controls/SMESH_ControlsDef.hxx +++ b/src/Controls/SMESH_ControlsDef.hxx @@ -96,6 +96,21 @@ namespace SMESH{ std::vector 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 Description : Root of all Functors returning numeric value @@ -326,16 +341,19 @@ namespace SMESH{ class SMESHCONTROLS_EXPORT CoincidentNodes: public Predicate { public: CoincidentNodes(); - void SetTolerance (const double theToler) { myToler = theToler; } - void SetMesh( const SMDS_Mesh* theMesh, TIDSortedNodeSet* nodesToCheck ); - virtual void SetMesh( const SMDS_Mesh* theMesh ) { SetMesh( theMesh, 0 ); } + virtual void SetMesh( const SMDS_Mesh* theMesh ); virtual bool IsSatisfy( long theElementId ); virtual SMDSAbs_ElementType GetType() const; + void SetTolerance (const double theToler) { myToler = theToler; } + double GetTolerance () const { return myToler; } + private: - TColStd_MapOfInteger myCoincidentIDs; double myToler; + TColStd_MapOfInteger myCoincidentIDs; + TMeshModifTracer myMeshModifTracer; }; + typedef boost::shared_ptr CoincidentNodesPtr; /* Class : CoincidentElements @@ -345,14 +363,11 @@ namespace SMESH{ class SMESHCONTROLS_EXPORT CoincidentElements: public Predicate { public: CoincidentElements(); - void SetMesh( const SMDS_Mesh* theMesh, TIDSortedElemSet* elemsToCheck ); - virtual void SetMesh( const SMDS_Mesh* theMesh ) { SetMesh( theMesh, 0 ); } + virtual void SetMesh( const SMDS_Mesh* theMesh ); virtual bool IsSatisfy( long theElementId ); private: - const SMDS_Mesh* myMesh; - TIDSortedElemSet* myElemsToCheck; - TColStd_MapOfInteger myCoincidentIDs; + const SMDS_Mesh* myMesh; }; class SMESHCONTROLS_EXPORT CoincidentElements1D: public CoincidentElements { public: @@ -456,7 +471,6 @@ namespace SMESH{ virtual bool IsSatisfy( long theElementId ); protected: const SMDS_Mesh* myMesh; - std::vector< const SMDS_MeshNode* > myLinkNodes; }; typedef boost::shared_ptr OverConstrainedFacePtr; @@ -796,7 +810,7 @@ namespace SMESH{ void process (const SMDS_MeshElement* theElem); private: - const SMDS_Mesh* myMesh; + TMeshModifTracer myMeshModifTracer; TColStd_MapOfInteger myIds; SMDSAbs_ElementType myType; TopoDS_Shape myShape; @@ -904,13 +918,13 @@ namespace SMESH{ long GetFace() const { return myFaceID; } void SetTolerance (const double theToler) { myToler = theToler; } double GetTolerance () const { return myToler; } - virtual void SetMesh( const SMDS_Mesh* theMesh ) { myMesh = theMesh; } virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Face; } + virtual void SetMesh( const SMDS_Mesh* theMesh ); virtual bool IsSatisfy( long theElementId ); private: - const SMDS_Mesh* myMesh; + TMeshModifTracer myMeshModifTracer; long myFaceID; double myToler; std::set< long > myCoplanarIDs;