Salome HOME
+ const SMESHDS_SubMesh * GetSubMeshDS() const;
[modules/smesh.git] / src / Controls / SMESH_Controls.cxx
index 74f6a9563b5f95bb6eaddb895d54c6ce73e9c1cf..66601f3dfd478a4841ff615dab6905aadd3d2b16 100644 (file)
 
 #include "SMESH_ControlsDef.hxx"
 
-#include <set>
-#include <limits>
+#include "SMDS_BallElement.hxx"
+#include "SMDS_Iterator.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_QuadraticEdge.hxx"
+#include "SMDS_QuadraticFaceOfNodes.hxx"
+#include "SMDS_VolumeTool.hxx"
+#include "SMESHDS_GroupBase.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESH_OctreeNode.hxx"
 
 #include <BRepAdaptor_Surface.hxx>
 #include <BRepClass_FaceClassifier.hxx>
 #include <BRep_Tool.hxx>
-
-#include <TopAbs.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Shape.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopoDS_Iterator.hxx>
-
 #include <Geom_CylindricalSurface.hxx>
 #include <Geom_Plane.hxx>
 #include <Geom_Surface.hxx>
-
 #include <Precision.hxx>
 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
 #include <TColStd_MapOfInteger.hxx>
 #include <TColStd_SequenceOfAsciiString.hxx>
 #include <TColgp_Array1OfXYZ.hxx>
-
+#include <TopAbs.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Vertex.hxx>
 #include <gp_Ax3.hxx>
 #include <gp_Cylinder.hxx>
 #include <gp_Dir.hxx>
 #include <gp_Vec.hxx>
 #include <gp_XYZ.hxx>
 
-#include "SMDS_Mesh.hxx"
-#include "SMDS_Iterator.hxx"
-#include "SMDS_MeshElement.hxx"
-#include "SMDS_MeshNode.hxx"
-#include "SMDS_VolumeTool.hxx"
-#include "SMDS_QuadraticFaceOfNodes.hxx"
-#include "SMDS_QuadraticEdge.hxx"
-
-#include "SMESHDS_Mesh.hxx"
-#include "SMESHDS_GroupBase.hxx"
+#include <vtkMeshQuality.h>
 
-#include "SMESH_OctreeNode.hxx"
+#include <set>
+#include <limits>
 
-#include <vtkMeshQuality.h>
 
 /*
                             AUXILIARY METHODS
@@ -715,6 +711,26 @@ SMDSAbs_ElementType MinimumAngle::GetType() const
   Class       : AspectRatio
   Description : Functor for calculating aspect ratio
 */
+double AspectRatio::GetValue( long theId )
+{
+  double aVal = 0;
+  myCurrElement = myMesh->FindElement( theId );
+  if ( myCurrElement && myCurrElement->GetVtkType() == VTK_QUAD )
+  {
+    // issue 21723
+    vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myCurrElement->getMeshId()]->getGrid();
+    if ( vtkCell* avtkCell = grid->GetCell( myCurrElement->getVtkId() ))
+      aVal = Round( vtkMeshQuality::QuadAspectRatio( avtkCell ));
+  }
+  else
+  {
+    TSequenceOfXYZ P;
+    if ( GetPoints( myCurrElement, P ))
+      aVal = Round( GetValue( P ));
+  }
+  return aVal;
+}
+
 double AspectRatio::GetValue( const TSequenceOfXYZ& P )
 {
   // According to "Mesh quality control" by Nadir Bouhamau referring to
@@ -1946,6 +1962,34 @@ void MultiConnection2D::GetValues(MValues& theValues){
 
 }
 
+/*
+  Class       : BallDiameter
+  Description : Functor returning diameter of a ball element
+*/
+double BallDiameter::GetValue( long theId )
+{
+  double diameter = 0;
+
+  if ( const SMDS_BallElement* ball =
+       dynamic_cast<const SMDS_BallElement*>( myMesh->FindElement( theId )))
+  {
+    diameter = ball->GetDiameter();
+  }
+  return diameter;
+}
+
+double BallDiameter::GetBadRate( double Value, int /*nbNodes*/ ) const
+{
+  // meaningless as it is not a quality control functor
+  return Value;
+}
+
+SMDSAbs_ElementType BallDiameter::GetType() const
+{
+  return SMDSAbs_Ball;
+}
+
+
 /*
                             PREDICATES
 */
@@ -2693,30 +2737,37 @@ void CoplanarFaces::SetMesh( const SMDS_Mesh* theMesh )
       return;
 
     const double radianTol = myToler * M_PI / 180.;
-    typedef SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > TFaceIt;
-    std::set<const SMDS_MeshElement*> checkedFaces, checkedNodes;
-    std::list<const SMDS_MeshElement*> faceQueue( 1, face );
+    std::set< SMESH_TLink > checkedLinks;
+
+    std::list< pair< const SMDS_MeshElement*, gp_Vec > > faceQueue;
+    faceQueue.push_back( make_pair( face, myNorm ));
     while ( !faceQueue.empty() )
     {
-      face = faceQueue.front();
-      if ( checkedFaces.insert( face ).second )
+      face   = faceQueue.front().first;
+      myNorm = faceQueue.front().second;
+      faceQueue.pop_front();
+
+      for ( int i = 0, nbN = face->NbCornerNodes(); i < nbN; ++i )
       {
-        gp_Vec norm = getNormale( static_cast<const SMDS_MeshFace*>(face), &normOK );
-        if (!normOK || myNorm.Angle( norm ) <= radianTol)
+        const SMDS_MeshNode*  n1 = face->GetNode( i );
+        const SMDS_MeshNode*  n2 = face->GetNode(( i+1 )%nbN);
+        if ( !checkedLinks.insert( SMESH_TLink( n1, n2 )).second )
+          continue;
+        SMDS_ElemIteratorPtr fIt = n1->GetInverseElementIterator(SMDSAbs_Face);
+        while ( fIt->more() )
         {
-          myCoplanarIDs.insert( face->GetID() );
-          std::set<const SMDS_MeshElement*> neighborFaces;
-          for ( int i = 0; i < face->NbCornerNodes(); ++i )
+          const SMDS_MeshElement* f = fIt->next();
+          if ( f->GetNodeIndex( n2 ) > -1 )
           {
-            const SMDS_MeshNode* n = face->GetNode( i );
-            if ( checkedNodes.insert( n ).second )
-              neighborFaces.insert( TFaceIt( n->GetInverseElementIterator(SMDSAbs_Face)),
-                                    TFaceIt());
+            gp_Vec norm = getNormale( static_cast<const SMDS_MeshFace*>(f), &normOK );
+            if (!normOK || myNorm.Angle( norm ) <= radianTol)
+            {
+              myCoplanarIDs.insert( f->GetID() );
+              faceQueue.push_back( make_pair( f, norm ));
+            }
           }
-          faceQueue.insert( faceQueue.end(), neighborFaces.begin(), neighborFaces.end() );
         }
       }
-      faceQueue.pop_front();
     }
   }
 }
@@ -2726,7 +2777,7 @@ bool CoplanarFaces::IsSatisfy( long theElementId )
 }
 
 /*
 *Class       : RangeOfIds
+ *Class       : RangeOfIds
   *Description : Predicate for Range of Ids.
   *              Range may be specified with two ways.
   *              1. Using AddToRange method
@@ -3136,26 +3187,9 @@ void Filter::SetPredicate( PredicatePtr thePredicate )
   myPredicate = thePredicate;
 }
 
-template<class TElement, class TIterator, class TPredicate>
-inline void FillSequence(const TIterator& theIterator,
-                         TPredicate& thePredicate,
-                         Filter::TIdSequence& theSequence)
-{
-  if ( theIterator ) {
-    while( theIterator->more() ) {
-      TElement anElem = theIterator->next();
-      long anId = anElem->GetID();
-      if ( thePredicate->IsSatisfy( anId ) )
-        theSequence.push_back( anId );
-    }
-  }
-}
-
-void
-Filter::
-GetElementsId( const SMDS_Mesh* theMesh,
-               PredicatePtr thePredicate,
-               TIdSequence& theSequence )
+void Filter::GetElementsId( const SMDS_Mesh* theMesh,
+                            PredicatePtr     thePredicate,
+                            TIdSequence&     theSequence )
 {
   theSequence.clear();
 
@@ -3164,31 +3198,19 @@ GetElementsId( const SMDS_Mesh* theMesh,
 
   thePredicate->SetMesh( theMesh );
 
-  SMDSAbs_ElementType aType = thePredicate->GetType();
-  switch(aType){
-  case SMDSAbs_Node:
-    FillSequence<const SMDS_MeshNode*>(theMesh->nodesIterator(),thePredicate,theSequence);
-    break;
-  case SMDSAbs_Edge:
-    FillSequence<const SMDS_MeshElement*>(theMesh->edgesIterator(),thePredicate,theSequence);
-    break;
-  case SMDSAbs_Face:
-    FillSequence<const SMDS_MeshElement*>(theMesh->facesIterator(),thePredicate,theSequence);
-    break;
-  case SMDSAbs_Volume:
-    FillSequence<const SMDS_MeshElement*>(theMesh->volumesIterator(),thePredicate,theSequence);
-    break;
-  case SMDSAbs_All:
-    FillSequence<const SMDS_MeshElement*>(theMesh->edgesIterator(),thePredicate,theSequence);
-    FillSequence<const SMDS_MeshElement*>(theMesh->facesIterator(),thePredicate,theSequence);
-    FillSequence<const SMDS_MeshElement*>(theMesh->volumesIterator(),thePredicate,theSequence);
-    break;
+  SMDS_ElemIteratorPtr elemIt = theMesh->elementsIterator( thePredicate->GetType() );
+  if ( elemIt ) {
+    while ( elemIt->more() ) {
+      const SMDS_MeshElement* anElem = elemIt->next();
+      long anId = anElem->GetID();
+      if ( thePredicate->IsSatisfy( anId ) )
+        theSequence.push_back( anId );
+    }
   }
 }
 
-void
-Filter::GetElementsId( const SMDS_Mesh* theMesh,
-                       Filter::TIdSequence& theSequence )
+void Filter::GetElementsId( const SMDS_Mesh*     theMesh,
+                            Filter::TIdSequence& theSequence )
 {
   GetElementsId(theMesh,myPredicate,theSequence);
 }
@@ -3852,36 +3874,9 @@ void ElementsOnShape::process()
   if (myShape.IsNull() || myMesh == 0)
     return;
 
-  if (myType == SMDSAbs_Node)
-  {
-    SMDS_NodeIteratorPtr anIter = myMesh->nodesIterator();
-    while (anIter->more())
-      process(anIter->next());
-  }
-  else
-  {
-    if (myType == SMDSAbs_Edge || myType == SMDSAbs_All)
-    {
-      SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
-      while (anIter->more())
-        process(anIter->next());
-    }
-
-    if (myType == SMDSAbs_Face || myType == SMDSAbs_All)
-    {
-      SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
-      while (anIter->more()) {
-        process(anIter->next());
-      }
-    }
-
-    if (myType == SMDSAbs_Volume || myType == SMDSAbs_All)
-    {
-      SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
-      while (anIter->more())
-        process(anIter->next());
-    }
-  }
+  SMDS_ElemIteratorPtr anIter = myMesh->elementsIterator(myType);
+  while (anIter->more())
+    process(anIter->next());
 }
 
 void ElementsOnShape::process (const SMDS_MeshElement* theElemPtr)
@@ -3896,9 +3891,8 @@ void ElementsOnShape::process (const SMDS_MeshElement* theElemPtr)
 
   while (aNodeItr->more() && (isSatisfy == myAllNodesFlag))
   {
-    SMDS_MeshNode* aNode = (SMDS_MeshNode*)aNodeItr->next();
-    gp_Pnt aPnt (aNode->X(), aNode->Y(), aNode->Z());
-    centerXYZ += aPnt.XYZ();
+    SMESH_TNodeXYZ aPnt ( aNodeItr->next() );
+    centerXYZ += aPnt;
 
     switch (myCurShapeType)
     {
@@ -3931,7 +3925,7 @@ void ElementsOnShape::process (const SMDS_MeshElement* theElemPtr)
       break;
     case TopAbs_VERTEX:
       {
-        isSatisfy = (aPnt.Distance(myCurPnt) <= myToler);
+        isSatisfy = (myCurPnt.Distance(aPnt) <= myToler);
       }
       break;
     default: