Salome HOME
0021338: EDF 1926 SMESH: New controls and filters
authoreap <eap@opencascade.com>
Thu, 26 Jan 2012 15:56:22 +0000 (15:56 +0000)
committereap <eap@opencascade.com>
Thu, 26 Jan 2012 15:56:22 +0000 (15:56 +0000)
+    /*!
+     * \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
src/Controls/SMESH_ControlsDef.hxx

index 5bdcc486f6d10993da632b6b60e16c92bcd106e6..e65db837fb57b6999917e277799c5b077f829369 100644 (file)
@@ -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();
+
+    if ( !myMeshModifTracer.GetMesh() || !myFaceID || !myToler )
+      return;
 
-    const SMDS_MeshElement* face = myMesh->FindElement( myFaceID );
+    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<const SMDS_MeshFace*>(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;
+}
index ac07599edfada8074e84cde0807072786a22edae..80d573d04b59f10d0daa671884806da6fef09440 100644 (file)
@@ -96,6 +96,21 @@ namespace SMESH{
       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
       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<CoincidentNodes> 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<OverConstrainedFace> 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;