Salome HOME
Fix for PAL7758(Incorrect work of "Lying on Geom" filter for faces).
[modules/smesh.git] / src / SMESH_I / SMESH_Filter_i.cxx
index 05205350042ef21ba124e8ca65a5ad0c3af6d653..95893bc0eb2a956816822096a72b1408e83cdf5c 100644 (file)
@@ -91,7 +91,7 @@ static bool IsContains( SMESHDS_Mesh*           theMeshDS,
                         TopAbs_ShapeEnum        theAvoidShapeEnum = TopAbs_SHAPE )
 {
   TopExp_Explorer anExp( theShape,theFindShapeEnum,theAvoidShapeEnum );
-
+  
   while( anExp.More() )
   {
     const TopoDS_Shape& aShape = anExp.Current();
@@ -171,6 +171,131 @@ SMESHDS_Mesh* Controls::BelongToGeom::GetMeshDS()
   return myMeshDS;
 }
 
+/*
+  Class       : LyingOnGeom
+  Description : Predicate for verifying whether entiy lying or partially lying on
+                specified geometrical support
+*/
+
+Controls::LyingOnGeom::LyingOnGeom()
+: myMeshDS(NULL),
+  myType(SMDSAbs_All)
+{}
+
+void Controls::LyingOnGeom::SetMesh( SMDS_Mesh* theMesh )
+{
+ myMeshDS = dynamic_cast<SMESHDS_Mesh*>(theMesh);
+}
+
+void Controls::LyingOnGeom::SetGeom( const TopoDS_Shape& theShape )
+{
+  myShape = theShape;
+}
+
+bool Controls::LyingOnGeom::IsSatisfy( long theId )
+{
+  if ( myMeshDS == 0 || myShape.IsNull() )
+    return false;
+
+  if( myType == SMDSAbs_Node )
+  {
+    if( const SMDS_MeshNode* aNode = myMeshDS->FindNode( theId ) )
+    {
+      const SMDS_PositionPtr& aPosition = aNode->GetPosition();
+      SMDS_TypeOfPosition aTypeOfPosition = aPosition->GetTypeOfPosition();
+      switch( aTypeOfPosition )
+      {
+      case SMDS_TOP_VERTEX : return IsContains( myMeshDS,myShape,aNode,TopAbs_VERTEX );
+      case SMDS_TOP_EDGE   : return IsContains( myMeshDS,myShape,aNode,TopAbs_EDGE );
+      case SMDS_TOP_FACE   : return IsContains( myMeshDS,myShape,aNode,TopAbs_FACE );
+      case SMDS_TOP_3DSPACE: return IsContains( myMeshDS,myShape,aNode,TopAbs_SHELL );
+      }
+    }
+  }
+  else
+  {
+    if( const SMDS_MeshElement* anElem = myMeshDS->FindElement( theId ) )
+    {
+      if( myType == SMDSAbs_All )
+      {
+        return Contains( myMeshDS,myShape,anElem,TopAbs_EDGE ) ||
+               Contains( myMeshDS,myShape,anElem,TopAbs_FACE ) ||
+               Contains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
+               Contains( myMeshDS,myShape,anElem,TopAbs_SOLID );
+      }
+      else if( myType == anElem->GetType() )
+      {
+        switch( myType )
+        {
+        case SMDSAbs_Edge  : return Contains( myMeshDS,myShape,anElem,TopAbs_EDGE );
+        case SMDSAbs_Face  : return Contains( myMeshDS,myShape,anElem,TopAbs_FACE );
+        case SMDSAbs_Volume: return Contains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
+                                    Contains( myMeshDS,myShape,anElem,TopAbs_SOLID );
+        }
+      }
+    }
+  }
+    
+  return false;
+}
+
+void Controls::LyingOnGeom::SetType( SMDSAbs_ElementType theType )
+{
+  myType = theType;
+}
+
+SMDSAbs_ElementType Controls::LyingOnGeom::GetType() const
+{
+  return myType;
+}
+
+TopoDS_Shape Controls::LyingOnGeom::GetShape()
+{
+  return myShape;
+}
+
+SMESHDS_Mesh* Controls::LyingOnGeom::GetMeshDS()
+{
+  return myMeshDS;
+}
+
+bool Controls::LyingOnGeom::Contains( SMESHDS_Mesh*           theMeshDS,
+                                     const TopoDS_Shape&     theShape,
+                                     const SMDS_MeshElement* theElem,
+                                     TopAbs_ShapeEnum        theFindShapeEnum,
+                                     TopAbs_ShapeEnum        theAvoidShapeEnum )
+{
+  if (IsContains(theMeshDS, theShape, theElem, theFindShapeEnum, theAvoidShapeEnum))
+    return true;
+  
+  TopTools_IndexedMapOfShape aSubShapes;
+  TopExp::MapShapes( theShape, aSubShapes );
+  
+  for (int i = 1; i <= aSubShapes.Extent(); i++)
+    {
+      const TopoDS_Shape& aShape = aSubShapes.FindKey(i);
+      
+      if( SMESHDS_SubMesh* aSubMesh = theMeshDS->MeshElements( aShape ) ){
+       if( aSubMesh->Contains( theElem ) )
+         return true;
+       
+       SMDS_NodeIteratorPtr aNodeIt = aSubMesh->GetNodes();
+       while ( aNodeIt->more() )
+         {
+           const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(aNodeIt->next());
+           SMDS_ElemIteratorPtr anElemIt = aNode->GetInverseElementIterator();
+           while ( anElemIt->more() )
+             {
+               const SMDS_MeshElement* anElement = static_cast<const SMDS_MeshElement*>(anElemIt->next());
+               if (anElement == theElem)
+                 return true;
+             }
+         }
+      }
+    }
+  return false;
+}
+
 
 /*
                             AUXILIARY METHODS
@@ -334,6 +459,22 @@ FunctorType AspectRatio_i::GetFunctorType()
 }
 
 
+/*
+  Class       : AspectRatio3D
+  Description : Functor for calculating aspect ratio 3D
+*/
+AspectRatio3D_i::AspectRatio3D_i()
+{
+  myNumericalFunctorPtr.reset( new Controls::AspectRatio3D() );
+  myFunctorPtr = myNumericalFunctorPtr;
+}
+
+FunctorType AspectRatio3D_i::GetFunctorType()
+{
+  return SMESH::FT_AspectRatio3D;
+}
+
+
 /*
   Class       : Warping_i
   Description : Functor for calculating warping
@@ -411,6 +552,47 @@ FunctorType Length_i::GetFunctorType()
   return SMESH::FT_Length;
 }
 
+/*
+  Class       : Length2D_i
+  Description : Functor for calculating length of edge
+*/
+Length2D_i::Length2D_i()
+{
+  myNumericalFunctorPtr.reset( new Controls::Length2D() );
+  myFunctorPtr = myNumericalFunctorPtr;
+}
+
+FunctorType Length2D_i::GetFunctorType()
+{
+  return SMESH::FT_Length2D;
+}
+
+SMESH::Length2D::Values* Length2D_i::GetValues()
+{
+  INFOS("Length2D_i::GetValues");
+  SMESH::Controls::Length2D::TValues aValues;
+  myLength2DPtr->GetValues( aValues );
+  
+  long i = 0, iEnd = aValues.size();
+
+  SMESH::Length2D::Values_var aResult = new SMESH::Length2D::Values(iEnd);
+
+  SMESH::Controls::Length2D::TValues::const_iterator anIter;
+  for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ )
+  {
+    const SMESH::Controls::Length2D::Value&  aVal = *anIter;
+    SMESH::Length2D::Value &aValue = aResult[ i ];
+    
+    aValue.myLength = aVal.myLength;
+    aValue.myPnt1 = aVal.myPntId[ 0 ];
+    aValue.myPnt2 = aVal.myPntId[ 1 ];
+   
+  }
+
+  INFOS("Length2D_i::GetValuess~");
+  return aResult._retn();
+}
+
 /*
   Class       : MultiConnection_i
   Description : Functor for calculating number of faces conneted to the edge
@@ -426,6 +608,46 @@ FunctorType MultiConnection_i::GetFunctorType()
   return SMESH::FT_MultiConnection;
 }
 
+/*
+  Class       : MultiConnection2D_i
+  Description : Functor for calculating number of faces conneted to the edge
+*/
+MultiConnection2D_i::MultiConnection2D_i()
+{
+  myNumericalFunctorPtr.reset( new Controls::MultiConnection2D() );
+  myFunctorPtr = myNumericalFunctorPtr;
+}
+
+FunctorType MultiConnection2D_i::GetFunctorType()
+{
+  return SMESH::FT_MultiConnection2D;
+}
+
+SMESH::MultiConnection2D::Values* MultiConnection2D_i::GetValues()
+{
+  INFOS("MultiConnection2D_i::GetValues");
+  SMESH::Controls::MultiConnection2D::MValues aValues;
+  myMulticonnection2DPtr->GetValues( aValues );
+  
+  long i = 0, iEnd = aValues.size();
+
+  SMESH::MultiConnection2D::Values_var aResult = new SMESH::MultiConnection2D::Values(iEnd);
+
+  SMESH::Controls::MultiConnection2D::MValues::const_iterator anIter;
+  for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ )
+  {
+    const SMESH::Controls::MultiConnection2D::Value&  aVal = (*anIter).first;
+    SMESH::MultiConnection2D::Value &aValue = aResult[ i ];
+    
+    aValue.myPnt1 = aVal.myPntId[ 0 ];
+    aValue.myPnt2 = aVal.myPntId[ 1 ];
+    aValue.myNbConnects = (*anIter).second;
+   
+  }
+
+  INFOS("Multiconnection2D_i::GetValuess~");
+  return aResult._retn();
+}
 
 /*
                             PREDICATES
@@ -599,7 +821,57 @@ FunctorType BelongToCylinder_i::GetFunctorType()
   return FT_BelongToCylinder;
 }
 
+/*
+  Class       : LyingOnGeom_i
+  Description : Predicate for selection on geometrical support
+*/
+LyingOnGeom_i::LyingOnGeom_i()
+{
+  myLyingOnGeomPtr.reset( new Controls::LyingOnGeom() );
+  myFunctorPtr = myPredicatePtr = myLyingOnGeomPtr;
+  myShapeName = 0;
+}
 
+LyingOnGeom_i::~LyingOnGeom_i()
+{
+  delete myShapeName;
+}
+
+void LyingOnGeom_i::SetGeom( GEOM::GEOM_Object_ptr theGeom )
+{
+  if ( theGeom->_is_nil() )
+    return;
+  SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
+  GEOM::GEOM_Gen_var aGEOMGen = SMESH_Gen_i::GetGeomEngine();
+  TopoDS_Shape aLocShape = aSMESHGen->GetShapeReader()->GetShape( aGEOMGen, theGeom );
+  myLyingOnGeomPtr->SetGeom( aLocShape );
+}
+
+void LyingOnGeom_i::SetGeom( const TopoDS_Shape& theShape )
+{
+  myLyingOnGeomPtr->SetGeom( theShape );
+}
+
+void LyingOnGeom_i::SetElementType(ElementType theType){
+  myLyingOnGeomPtr->SetType(SMDSAbs_ElementType(theType));
+}
+
+FunctorType LyingOnGeom_i::GetFunctorType()
+{
+  return SMESH::FT_LyingOnGeom;
+}
+
+void LyingOnGeom_i::SetShapeName( const char* theName )
+{
+  delete myShapeName;
+  myShapeName = strdup( theName );
+  myLyingOnGeomPtr->SetGeom( getShapeByName( myShapeName ) );
+}
+
+char* LyingOnGeom_i::GetShapeName()
+{
+  return CORBA::string_dup( myShapeName );
+}
 
 /*
   Class       : FreeBorders_i
@@ -974,6 +1246,14 @@ AspectRatio_ptr FilterManager_i::CreateAspectRatio()
 }
 
 
+AspectRatio3D_ptr FilterManager_i::CreateAspectRatio3D()
+{
+  SMESH::AspectRatio3D_i* aServant = new SMESH::AspectRatio3D_i();
+  SMESH::AspectRatio3D_var anObj = aServant->_this();
+  return anObj._retn();
+}
+
+
 Warping_ptr FilterManager_i::CreateWarping()
 {
   SMESH::Warping_i* aServant = new SMESH::Warping_i();
@@ -1013,6 +1293,12 @@ Length_ptr FilterManager_i::CreateLength()
   return anObj._retn();
 }
 
+Length2D_ptr FilterManager_i::CreateLength2D()
+{
+  SMESH::Length2D_i* aServant = new SMESH::Length2D_i();
+  SMESH::Length2D_var anObj = aServant->_this();
+  return anObj._retn();
+}
 
 MultiConnection_ptr FilterManager_i::CreateMultiConnection()
 {
@@ -1021,6 +1307,12 @@ MultiConnection_ptr FilterManager_i::CreateMultiConnection()
   return anObj._retn();
 }
 
+MultiConnection2D_ptr FilterManager_i::CreateMultiConnection2D()
+{
+  SMESH::MultiConnection2D_i* aServant = new SMESH::MultiConnection2D_i();
+  SMESH::MultiConnection2D_var anObj = aServant->_this();
+  return anObj._retn();
+}
 
 BelongToGeom_ptr FilterManager_i::CreateBelongToGeom()
 {
@@ -1043,6 +1335,13 @@ BelongToCylinder_ptr FilterManager_i::CreateBelongToCylinder()
   return anObj._retn();
 }
 
+LyingOnGeom_ptr FilterManager_i::CreateLyingOnGeom()
+{
+  SMESH::LyingOnGeom_i* aServant = new SMESH::LyingOnGeom_i();
+  SMESH::LyingOnGeom_var anObj = aServant->_this();
+  return anObj._retn();
+}
+
 FreeBorders_ptr FilterManager_i::CreateFreeBorders()
 {
   SMESH::FreeBorders_i* aServant = new SMESH::FreeBorders_i();
@@ -1283,6 +1582,21 @@ static inline bool getCriteria( Predicate_i*                thePred,
       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
       theCriteria[ i ].Tolerance     = aPred->GetTolerance();
 
+      return true;
+    }
+   case FT_LyingOnGeom:
+    {
+      LyingOnGeom_i* aPred = dynamic_cast<LyingOnGeom_i*>( thePred );
+
+      CORBA::ULong i = theCriteria->length();
+      theCriteria->length( i + 1 );
+
+      theCriteria[ i ] = createCriterion();
+
+      theCriteria[ i ].Type          = FT_LyingOnGeom;
+      theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
+      theCriteria[ i ].TypeOfElement = aPred->GetElementType();
+
       return true;
     }
   case FT_RangeOfIds:
@@ -1399,12 +1713,21 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
       case SMESH::FT_MultiConnection:
         aFunctor = aFilterMgr->CreateMultiConnection();
         break;
+      case SMESH::FT_MultiConnection2D:
+       aFunctor = aFilterMgr->CreateMultiConnection2D();
+       break;
       case SMESH::FT_Length:
         aFunctor = aFilterMgr->CreateLength();
         break;
+      case SMESH::FT_Length2D:
+        aFunctor = aFilterMgr->CreateLength2D();
+        break;
       case SMESH::FT_AspectRatio:
         aFunctor = aFilterMgr->CreateAspectRatio();
         break;
+      case SMESH::FT_AspectRatio3D:
+        aFunctor = aFilterMgr->CreateAspectRatio3D();
+        break;
       case SMESH::FT_Warping:
         aFunctor = aFilterMgr->CreateWarping();
         break;
@@ -1450,6 +1773,14 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
           aPredicate = tmpPred;
         }
         break;
+      case SMESH::FT_LyingOnGeom:
+        {
+          SMESH::LyingOnGeom_ptr tmpPred = aFilterMgr->CreateLyingOnGeom();
+          tmpPred->SetElementType( aTypeOfElem );
+          tmpPred->SetShapeName( aThresholdStr );
+          aPredicate = tmpPred;
+        }
+        break; 
       case SMESH::FT_RangeOfIds:
         {
           SMESH::RangeOfIds_ptr tmpPred = aFilterMgr->CreateRangeOfIds();
@@ -1660,11 +1991,14 @@ static inline LDOMString toString( const long theType )
     case FT_BelongToGeom    : return "Belong to Geom";
     case FT_BelongToPlane   : return "Belong to Plane";
     case FT_BelongToCylinder: return "Belong to Cylinder";
+    case FT_LyingOnGeom     : return "Lying on Geom";
     case FT_RangeOfIds      : return "Range of IDs";
     case FT_FreeBorders     : return "Free borders";
     case FT_FreeEdges       : return "Free edges";
     case FT_MultiConnection : return "Borders at multi-connections";
+    case FT_MultiConnection2D: return "Borders at multi-connections 2D";
     case FT_Length          : return "Length";
+    case FT_Length2D        : return "Length2D";
     case FT_LessThan        : return "Less than";
     case FT_MoreThan        : return "More than";
     case FT_EqualTo         : return "Equal to";
@@ -1691,10 +2025,13 @@ static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr )
   else if ( theStr.equals( "Belong to Geom"               ) ) return FT_BelongToGeom;
   else if ( theStr.equals( "Belong to Plane"              ) ) return FT_BelongToPlane;
   else if ( theStr.equals( "Belong to Cylinder"           ) ) return FT_BelongToCylinder;
+  else if ( theStr.equals( "Lying on Geom"                ) ) return FT_LyingOnGeom;
   else if ( theStr.equals( "Free borders"                 ) ) return FT_FreeBorders;
   else if ( theStr.equals( "Free edges"                   ) ) return FT_FreeEdges;
   else if ( theStr.equals( "Borders at multi-connections" ) ) return FT_MultiConnection;
+  //  else if ( theStr.equals( "Borders at multi-connections 2D" ) ) return FT_MultiConnection2D;
   else if ( theStr.equals( "Length"                       ) ) return FT_Length;
+  //  else if ( theStr.equals( "Length2D"                     ) ) return FT_Length2D;
   else if ( theStr.equals( "Range of IDs"                 ) ) return FT_RangeOfIds;
   else if ( theStr.equals( "Less than"                    ) ) return FT_LessThan;
   else if ( theStr.equals( "More than"                    ) ) return FT_MoreThan;
@@ -2204,23 +2541,3 @@ string_array* FilterLibrary_i::GetAllNames()
 
   return aResArray._retn();
 }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-