X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH_I%2FSMESH_Filter_i.cxx;h=6916ea344e7db7d910cf9dbea35bc74cb58e9a10;hp=724d602dd7cfc3b2864f22f8012b8bf4369f1ecc;hb=bd8f1aee7c78f7d2eb82bd4fec5e08c9e3d280ce;hpb=c3bf92bd87b770fd81631a3853f7f5bb1ac6a4e8 diff --git a/src/SMESH_I/SMESH_Filter_i.cxx b/src/SMESH_I/SMESH_Filter_i.cxx index 724d602dd..6916ea344 100644 --- a/src/SMESH_I/SMESH_Filter_i.cxx +++ b/src/SMESH_I/SMESH_Filter_i.cxx @@ -1,914 +1,4011 @@ -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_Filter_i.cxx // Author : Alexey Petrov, OCC // Module : SMESH - #include "SMESH_Filter_i.hxx" -#include "SMDS_Iterator.hxx" +#include "SMDS_ElemIterator.hxx" +#include "SMDS_Mesh.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" -#include "SMDSAbs_ElementType.hxx" -#include "SMESH_Gen_i.hxx" #include "SMESHDS_Mesh.hxx" - -#include -#include -#include +#include "SMESH_Gen_i.hxx" +#include "SMESH_PythonDump.hxx" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace SMESH; +using namespace SMESH::Controls; + + +namespace SMESH +{ + Predicate_i* + GetPredicate( Predicate_ptr thePredicate ) + { + return DownCast(thePredicate); + } +} + /* - AUXILIARY METHODS + Class : BelongToGeom + Description : Predicate for verifying whether entity belongs to + specified geometrical support */ -static inline double getAngle( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 ) +Controls::BelongToGeom::BelongToGeom() + : myMeshDS(NULL), + myType(SMDSAbs_All), + myIsSubshape(false), + myTolerance(Precision::Confusion()) +{} + +void Controls::BelongToGeom::SetMesh( const SMDS_Mesh* theMesh ) { - return gp_Vec( P1 - P2 ).Angle( gp_Vec( P3 - P2 ) ); + myMeshDS = dynamic_cast(theMesh); + init(); } -static inline double getArea( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 ) +void Controls::BelongToGeom::SetGeom( const TopoDS_Shape& theShape ) { - gp_Vec aVec1( P2 - P1 ); - gp_Vec aVec2( P3 - P1 ); - return ( aVec1 ^ aVec2 ).Magnitude() * 0.5; + myShape = theShape; + init(); } -static inline double getArea( const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3 ) +static bool IsSubShape (const TopTools_IndexedMapOfShape& theMap, + const TopoDS_Shape& theShape) { - return getArea( P1.XYZ(), P2.XYZ(), P3.XYZ() ); + if (theMap.Contains(theShape)) return true; + + if (theShape.ShapeType() == TopAbs_COMPOUND || + theShape.ShapeType() == TopAbs_COMPSOLID) + { + TopoDS_Iterator anIt (theShape, Standard_True, Standard_True); + for (; anIt.More(); anIt.Next()) + { + if (!IsSubShape(theMap, anIt.Value())) { + return false; + } + } + return true; + } + + return false; } -static inline double getDistance( const gp_XYZ& P1, const gp_XYZ& P2 ) +void Controls::BelongToGeom::init() { - double aDist = gp_Pnt( P1 ).Distance( gp_Pnt( P2 ) ); - return aDist; + if (!myMeshDS || myShape.IsNull()) return; + + // is sub-shape of main shape? + TopoDS_Shape aMainShape = myMeshDS->ShapeToMesh(); + if (aMainShape.IsNull()) { + myIsSubshape = false; + } + else { + TopTools_IndexedMapOfShape aMap; + TopExp::MapShapes(aMainShape, aMap); + myIsSubshape = IsSubShape(aMap, myShape); + } + + if (!myIsSubshape) + { + myElementsOnShapePtr.reset(new Controls::ElementsOnShape()); + myElementsOnShapePtr->SetTolerance(myTolerance); + myElementsOnShapePtr->SetAllNodes(true); // belong, while false means "lays on" + myElementsOnShapePtr->SetMesh(myMeshDS); + myElementsOnShapePtr->SetShape(myShape, myType); + } } -static int getNbMultiConnection( SMESHDS_Mesh* theMesh, const int theId ) +static bool IsContains( const SMESHDS_Mesh* theMeshDS, + const TopoDS_Shape& theShape, + const SMDS_MeshElement* theElem, + TopAbs_ShapeEnum theFindShapeEnum, + TopAbs_ShapeEnum theAvoidShapeEnum = TopAbs_SHAPE ) { - if ( theMesh == 0 ) - return 0; + TopExp_Explorer anExp( theShape,theFindShapeEnum,theAvoidShapeEnum ); + + while( anExp.More() ) + { + const TopoDS_Shape& aShape = anExp.Current(); + if( SMESHDS_SubMesh* aSubMesh = theMeshDS->MeshElements( aShape ) ){ + if( aSubMesh->Contains( theElem ) ) + return true; + } + anExp.Next(); + } + return false; +} - const SMDS_MeshElement* anEdge = theMesh->FindElement( theId ); - if ( anEdge == 0 || anEdge->GetType() != SMDSAbs_Edge || anEdge->NbNodes() != 2 ) - return 0; +bool Controls::BelongToGeom::IsSatisfy (long theId) +{ + if (myMeshDS == 0 || myShape.IsNull()) + return false; - TColStd_MapOfInteger aMap; + if (!myIsSubshape) + { + return myElementsOnShapePtr->IsSatisfy(theId); + } - int aResult = 0; - SMDS_ElemIteratorPtr anIter = anEdge->nodesIterator(); - if ( anIter != 0 ) + // Case of submesh + 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 { - while( anIter->more() ) + if( const SMDS_MeshElement* anElem = myMeshDS->FindElement( theId ) ) { - const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next(); - if ( aNode == 0 ) - return 0; - SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator(); - while( anElemIter->more() ) + if( myType == SMDSAbs_All ) + { + return IsContains( myMeshDS,myShape,anElem,TopAbs_EDGE ) || + IsContains( myMeshDS,myShape,anElem,TopAbs_FACE ) || + IsContains( myMeshDS,myShape,anElem,TopAbs_SHELL )|| + IsContains( myMeshDS,myShape,anElem,TopAbs_SOLID ); + } + else if( myType == anElem->GetType() ) { - const SMDS_MeshElement* anElem = anElemIter->next(); - if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge ) + switch( myType ) { - int anId = anElem->GetID(); - - if ( anIter->more() ) // i.e. first node - aMap.Add( anId ); - else if ( aMap.Contains( anId ) ) - aResult++; + case SMDSAbs_Edge : return IsContains( myMeshDS,myShape,anElem,TopAbs_EDGE ); + case SMDSAbs_Face : return IsContains( myMeshDS,myShape,anElem,TopAbs_FACE ); + case SMDSAbs_Volume: return IsContains( myMeshDS,myShape,anElem,TopAbs_SHELL )|| + IsContains( myMeshDS,myShape,anElem,TopAbs_SOLID ); } } -// delete anElemIter; } -// delete anIter; } - return aResult; + return false; } -using namespace std; -using namespace SMESH; +void Controls::BelongToGeom::SetType (SMDSAbs_ElementType theType) +{ + myType = theType; + init(); +} -/* - FUNCTORS -*/ +SMDSAbs_ElementType Controls::BelongToGeom::GetType() const +{ + return myType; +} -/* - Class : NumericalFunctor_i - Description : Base class for numerical functors -*/ +TopoDS_Shape Controls::BelongToGeom::GetShape() +{ + return myShape; +} -NumericalFunctor_i::NumericalFunctor_i() -: SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() ) +const SMESHDS_Mesh* Controls::BelongToGeom::GetMeshDS() const { - myMesh = 0; - SMESH_Gen_i::GetPOA()->activate_object( this ); + return myMeshDS; } -void NumericalFunctor_i::SetMesh( SMESH_Mesh_ptr theMesh ) +void Controls::BelongToGeom::SetTolerance (double theTolerance) { - SMESH_Mesh_i* anImplPtr = - dynamic_cast( SMESH_Gen_i::GetServant( theMesh ).in() ); - myMesh = anImplPtr ? anImplPtr->GetImpl().GetMeshDS() : 0; + myTolerance = theTolerance; + if (!myIsSubshape) + init(); } -bool NumericalFunctor_i::getPoints( const int theId, - TColgp_SequenceOfXYZ& theRes ) const +double Controls::BelongToGeom::GetTolerance() { - theRes.Clear(); + return myTolerance; +} - if ( myMesh == 0 ) - return false; +/* + Class : LyingOnGeom + Description : Predicate for verifying whether entiy lying or partially lying on + specified geometrical support +*/ - // Get nodes of the face - const SMDS_MeshElement* anElem = myMesh->FindElement( theId ); - if ( anElem == 0 || anElem->GetType() != GetType() ) - return false; +Controls::LyingOnGeom::LyingOnGeom() + : myMeshDS(NULL), + myType(SMDSAbs_All), + myIsSubshape(false), + myTolerance(Precision::Confusion()) +{} - int nbNodes = anElem->NbNodes(); +void Controls::LyingOnGeom::SetMesh( const SMDS_Mesh* theMesh ) +{ + myMeshDS = dynamic_cast(theMesh); + init(); +} - SMDS_ElemIteratorPtr anIter = anElem->nodesIterator(); - if ( anIter != 0 ) - { - while( anIter->more() ) - { - const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next(); - if ( aNode != 0 ) - theRes.Append( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) ); - } +void Controls::LyingOnGeom::SetGeom( const TopoDS_Shape& theShape ) +{ + myShape = theShape; + init(); +} -// delete anIter; +void Controls::LyingOnGeom::init() +{ + if (!myMeshDS || myShape.IsNull()) return; + + // is sub-shape of main shape? + TopoDS_Shape aMainShape = myMeshDS->ShapeToMesh(); + if (aMainShape.IsNull()) { + myIsSubshape = false; + } + else { + TopTools_IndexedMapOfShape aMap; + TopExp::MapShapes(aMainShape, aMap); + myIsSubshape = IsSubShape(aMap, myShape); } - return true; + if (!myIsSubshape) + { + myElementsOnShapePtr.reset(new Controls::ElementsOnShape()); + myElementsOnShapePtr->SetTolerance(myTolerance); + myElementsOnShapePtr->SetAllNodes(false); // lays on, while true means "belong" + myElementsOnShapePtr->SetMesh(myMeshDS); + myElementsOnShapePtr->SetShape(myShape, myType); + } } - -/* - Class : SMESH_MinimumAngleFunct - Description : Functor for calculation of minimum angle -*/ - -CORBA::Double MinimumAngle_i::GetValue( CORBA::Long theId ) +bool Controls::LyingOnGeom::IsSatisfy( long theId ) { - TColgp_SequenceOfXYZ P; - if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 ) - return 0; - - double aMin; + if ( myMeshDS == 0 || myShape.IsNull() ) + return false; - if ( P.Length() == 3 ) + if (!myIsSubshape) { - double A0 = getAngle( P( 3 ), P( 1 ), P( 2 ) ); - double A1 = getAngle( P( 1 ), P( 2 ), P( 3 ) ); - double A2 = getAngle( P( 2 ), P( 3 ), P( 1 ) ); + return myElementsOnShapePtr->IsSatisfy(theId); + } - aMin = Min( A0, Min( A1, A2 ) ); + // Case of submesh + 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 { - double A0 = getAngle( P( 4 ), P( 1 ), P( 2 ) ); - double A1 = getAngle( P( 1 ), P( 2 ), P( 3 ) ); - double A2 = getAngle( P( 2 ), P( 3 ), P( 4 ) ); - double A3 = getAngle( P( 3 ), P( 4 ), P( 1 ) ); - - aMin = Min( Min( A0, A1 ), Min( A2, A3 ) ); + 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 aMin * 180 / PI; + + return false; } -int MinimumAngle_i::GetType() const +void Controls::LyingOnGeom::SetType( SMDSAbs_ElementType theType ) { - return SMDSAbs_Face; + myType = theType; + init(); } -/* - Class : AspectRatio_i - Description : Functor for calculating aspect ratio -*/ +SMDSAbs_ElementType Controls::LyingOnGeom::GetType() const +{ + return myType; +} + +TopoDS_Shape Controls::LyingOnGeom::GetShape() +{ + return myShape; +} -CORBA::Double AspectRatio_i::GetValue( CORBA::Long theId ) +const SMESHDS_Mesh* Controls::LyingOnGeom::GetMeshDS() const { - TColgp_SequenceOfXYZ P; - if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 ) - return 0; + return myMeshDS; +} - int nbNodes = P.Length(); +void Controls::LyingOnGeom::SetTolerance (double theTolerance) +{ + myTolerance = theTolerance; + if (!myIsSubshape) + init(); +} - // Compute lengths of the sides +double Controls::LyingOnGeom::GetTolerance() +{ + return myTolerance; +} - double aLen[ nbNodes ]; - for ( int i = 0; i < nbNodes - 1; i++ ) - aLen[ i ] = getDistance( P( i + 1 ), P( i + 2 ) ); - aLen[ nbNodes - 1 ] = getDistance( P( 1 ), P( nbNodes ) ); +bool Controls::LyingOnGeom::Contains( const 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; - // Compute aspect ratio + TopTools_IndexedMapOfShape aSubShapes; + TopExp::MapShapes( theShape, aSubShapes ); - if ( nbNodes == 3 ) + for (int i = 1; i <= aSubShapes.Extent(); i++) { - double aMaxLen = Max( aLen[ 0 ], Max( aLen[ 1 ], aLen[ 2 ] ) ); - double anArea = getArea( P( 1 ), P( 2 ), P( 3 ) ); - static double aCoef = sqrt( 3. ) / 4; + const TopoDS_Shape& aShape = aSubShapes.FindKey(i); - return anArea != 0 ? aCoef * aMaxLen * aMaxLen / anArea : 0; - } - else - { - double aMaxLen = Max( Max( aLen[ 0 ], aLen[ 1 ] ), Max( aLen[ 2 ], aLen[ 3 ] ) ); - double aMinLen = Min( Min( aLen[ 0 ], aLen[ 1 ] ), Min( aLen[ 2 ], aLen[ 3 ] ) ); - - return aMinLen != 0 ? aMaxLen / aMinLen : 0; + 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(aNodeIt->next()); + SMDS_ElemIteratorPtr anElemIt = aNode->GetInverseElementIterator(); + while ( anElemIt->more() ) + { + const SMDS_MeshElement* anElement = static_cast(anElemIt->next()); + if (anElement == theElem) + return true; + } + } + } } + return false; } -int AspectRatio_i::GetType() const -{ - return SMDSAbs_Face; -} /* - Class : Warping_i - Description : Functor for calculating warping + AUXILIARY METHODS */ -CORBA::Double Warping_i::GetValue( CORBA::Long theId ) +inline +const SMDS_Mesh* +MeshPtr2SMDSMesh( SMESH_Mesh_ptr theMesh ) +{ + SMESH_Mesh_i* anImplPtr = DownCast(theMesh); + return anImplPtr ? anImplPtr->GetImpl().GetMeshDS() : 0; +} + +inline +SMESH::long_array* +toArray( const TColStd_ListOfInteger& aList ) { - TColgp_SequenceOfXYZ P; - if ( !getPoints( theId, P ) || P.Length() != 4 ) - return 0; + SMESH::long_array_var anArray = new SMESH::long_array; + anArray->length( aList.Extent() ); + TColStd_ListIteratorOfListOfInteger anIter( aList ); + int i = 0; + for( ; anIter.More(); anIter.Next() ) + anArray[ i++ ] = anIter.Value(); - gp_XYZ G = ( P( 1 ) + P( 2 ) + P( 3 ) + P( 4 ) ) / 4; + return anArray._retn(); +} - double A1 = ComputeA( P( 1 ), P( 2 ), P( 3 ), G ); - double A2 = ComputeA( P( 2 ), P( 3 ), P( 4 ), G ); - double A3 = ComputeA( P( 3 ), P( 4 ), P( 1 ), G ); - double A4 = ComputeA( P( 4 ), P( 1 ), P( 2 ), G ); +inline +SMESH::double_array* +toArray( const TColStd_ListOfReal& aList ) +{ + SMESH::double_array_var anArray = new SMESH::double_array; + anArray->length( aList.Extent() ); + TColStd_ListIteratorOfListOfReal anIter( aList ); + int i = 0; + for( ; anIter.More(); anIter.Next() ) + anArray[ i++ ] = anIter.Value(); - return Max( Max( A1, A2 ), Max( A3, A4 ) ); + return anArray._retn(); } -double Warping_i::ComputeA( const gp_XYZ& thePnt1, - const gp_XYZ& thePnt2, - const gp_XYZ& thePnt3, - const gp_XYZ& theG ) const +static SMESH::Filter::Criterion createCriterion() { - double aLen1 = gp_Pnt( thePnt1 ).Distance( gp_Pnt( thePnt2 ) ); - double aLen2 = gp_Pnt( thePnt2 ).Distance( gp_Pnt( thePnt3 ) ); - double L = Min( aLen1, aLen2 ) * 0.5; + SMESH::Filter::Criterion aCriterion; + + aCriterion.Type = FT_Undefined; + aCriterion.Compare = FT_Undefined; + aCriterion.Threshold = 0; + aCriterion.UnaryOp = FT_Undefined; + aCriterion.BinaryOp = FT_Undefined; + aCriterion.ThresholdStr = ""; + aCriterion.ThresholdID = ""; + aCriterion.Tolerance = Precision::Confusion(); + aCriterion.TypeOfElement = SMESH::ALL; + aCriterion.Precision = -1; - gp_XYZ GI = ( thePnt2 - thePnt1 ) / 2. - theG; - gp_XYZ GJ = ( thePnt3 - thePnt2 ) / 2. - theG; - gp_XYZ N = GI.Crossed( GJ ); - N.Normalize(); + return aCriterion; +} + +static TopoDS_Shape getShapeByName( const char* theName ) +{ + if ( theName != 0 ) + { + SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); + SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy(); + if ( !aStudy->_is_nil() ) + { + SALOMEDS::Study::ListOfSObject_var aList = aStudy->FindObjectByName( theName, "GEOM" ); + if ( aList->length() > 0 ) + { + CORBA::Object_var anObj = aList[ 0 ]->GetObject(); + GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow( anObj ); + TopoDS_Shape shape = aSMESHGen->GeomObjectToShape( aGeomObj ); + SALOME::UnRegister( aList ); // UnRegister() objects in aList + return shape; + } + } + } + return TopoDS_Shape(); +} - double H = gp_Vec( thePnt2 - theG ).Dot( gp_Vec( N ) ); - return asin( fabs( H / L ) ) * 180 / PI; +static TopoDS_Shape getShapeByID (const char* theID) +{ + if ( theID && strlen( theID ) > 0 ) { + SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); + SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy(); + if ( !aStudy->_is_nil() ) { + SALOMEDS::SObject_wrap aSObj = aStudy->FindObjectID(theID); + if ( !aSObj->_is_nil() ) { + CORBA::Object_var obj = aSObj->GetObject(); + GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(obj); + return aSMESHGen->GeomObjectToShape( aGeomObj ); + } + } + } + return TopoDS_Shape(); } -int Warping_i::GetType() const +static std::string getShapeNameByID (const char* theID) { - return SMDSAbs_Face; + if ( theID && strlen( theID ) > 0 ) { + SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); + SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy(); + if ( !aStudy->_is_nil() ) { + SALOMEDS::SObject_wrap aSObj = aStudy->FindObjectID(theID); + if ( !aSObj->_is_nil() ) { + CORBA::String_var name = aSObj->GetName(); + return name.in(); + } + } + } + return ""; } /* - Class : Taper_i - Description : Functor for calculating taper + FUNCTORS */ -CORBA::Double Taper_i::GetValue( CORBA::Long theId ) +/* + Class : Functor_i + Description : An abstact class for all functors +*/ +Functor_i::Functor_i(): + SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() ) { - TColgp_SequenceOfXYZ P; - if ( !getPoints( theId, P ) || P.Length() != 4 ) - return 0; - - // Compute taper - double J1 = getArea( P( 4 ), P( 1 ), P( 2 ) ) / 2; - double J2 = getArea( P( 3 ), P( 1 ), P( 2 ) ) / 2; - double J3 = getArea( P( 2 ), P( 3 ), P( 4 ) ) / 2; - double J4 = getArea( P( 3 ), P( 4 ), P( 1 ) ) / 2; - - double JA = 0.25 * ( J1 + J2 + J3 + J4 ); + //Base class Salome_GenericObject do it inmplicitly by overriding PortableServer::POA_ptr _default_POA() method + //PortableServer::ObjectId_var anObjectId = + // SMESH_Gen_i::GetPOA()->activate_object( this ); +} - double T1 = fabs( ( J1 - JA ) / JA ); - double T2 = fabs( ( J2 - JA ) / JA ); - double T3 = fabs( ( J3 - JA ) / JA ); - double T4 = fabs( ( J4 - JA ) / JA ); +Functor_i::~Functor_i() +{ + //TPythonDump()<SetMesh( MeshPtr2SMDSMesh( theMesh ) ); + TPythonDump()<GetType(); } + /* - Class : Skew_i - Description : Functor for calculating skew in degrees + Class : NumericalFunctor_i + Description : Base class for numerical functors */ - -static inline double skewAngle( const gp_XYZ& p1, const gp_XYZ& p2, const gp_XYZ& p3 ) +CORBA::Double NumericalFunctor_i::GetValue( CORBA::Long theId ) { - gp_XYZ p12 = ( p2 + p1 ) / 2; - gp_XYZ p23 = ( p3 + p2 ) / 2; - gp_XYZ p31 = ( p3 + p1 ) / 2; - - return gp_Vec( p31 - p2 ).Angle( p12 - p23 ); + return myNumericalFunctorPtr->GetValue( theId ); } -CORBA::Double Skew_i::GetValue( CORBA::Long theId ) +SMESH::Histogram* NumericalFunctor_i::GetHistogram(CORBA::Short nbIntervals, CORBA::Boolean isLogarithmic) { - TColgp_SequenceOfXYZ P; - if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 ) - return 0; + std::vector nbEvents; + std::vector funValues; + std::vector elements; + myNumericalFunctorPtr->GetHistogram(nbIntervals,nbEvents,funValues,elements,0,isLogarithmic); - // Compute skew - static double PI2 = PI / 2; - if ( P.Length() == 3 ) +#ifdef WIN32 + nbIntervals = CORBA::Short( min( nbEvents.size(), funValues.size() - 1)); +#else + nbIntervals = CORBA::Short( std::min( nbEvents.size(), funValues.size() - 1)); +#endif + SMESH::Histogram_var histogram = new SMESH::Histogram; + if ( nbIntervals > 0 ) { - double A0 = fabs( PI2 - skewAngle( P( 3 ), P( 1 ), P( 2 ) ) ); - double A1 = fabs( PI2 - skewAngle( P( 1 ), P( 2 ), P( 3 ) ) ); - double A2 = fabs( PI2 - skewAngle( P( 2 ), P( 3 ), P( 1 ) ) ); - - return Max( A0, Max( A1, A2 ) ) * 180 / PI; + histogram->length( nbIntervals ); + for ( int i = 0; i < nbIntervals; ++i ) + { + HistogramRectangle& rect = histogram[i]; + rect.nbEvents = nbEvents[i]; + rect.min = funValues[i]; + rect.max = funValues[i+1]; + } } - else - { - gp_XYZ p12 = ( P( 1 ) + P( 2 ) ) / 2; - gp_XYZ p23 = ( P( 2 ) + P( 3 ) ) / 2; - gp_XYZ p34 = ( P( 3 ) + P( 4 ) ) / 2; - gp_XYZ p41 = ( P( 4 ) + P( 1 ) ) / 2; - - double A = fabs( PI2 - gp_Vec( p34 - p12 ).Angle( p23 - p41 ) ); + return histogram._retn(); +} - return A * 180 / PI; - } +void NumericalFunctor_i::SetPrecision( CORBA::Long thePrecision ) +{ + myNumericalFunctorPtr->SetPrecision( thePrecision ); + TPythonDump()<GetPrecision(); } -int Skew_i::GetType() const +Controls::NumericalFunctorPtr NumericalFunctor_i::GetNumericalFunctor() { - return SMDSAbs_Face; + return myNumericalFunctorPtr; } + /* - Class : Area_i - Description : Functor for calculating area + Class : SMESH_MinimumAngle + Description : Functor for calculation of minimum angle */ - -CORBA::Double Area_i::GetValue( CORBA::Long theId ) +MinimumAngle_i::MinimumAngle_i() { - TColgp_SequenceOfXYZ P; - if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 ) - return 0; - - if ( P.Length() == 3 ) - return getArea( P( 1 ), P( 2 ), P( 3 ) ); - else - return getArea( P( 1 ), P( 2 ), P( 3 ) ) + getArea( P( 1 ), P( 3 ), P( 4 ) ); + myNumericalFunctorPtr.reset( new Controls::MinimumAngle() ); + myFunctorPtr = myNumericalFunctorPtr; } -int Area_i::GetType() const +FunctorType MinimumAngle_i::GetFunctorType() { - return SMDSAbs_Face; + return SMESH::FT_MinimumAngle; } + /* - Class : Length_i - Description : Functor for calculating length off edge + Class : AspectRatio + Description : Functor for calculating aspect ratio */ - -CORBA::Double Length_i::GetValue( CORBA::Long theId ) +AspectRatio_i::AspectRatio_i() { - TColgp_SequenceOfXYZ P; - return getPoints( theId, P ) && P.Length() == 2 ? getDistance( P( 1 ), P( 2 ) ) : 0; + myNumericalFunctorPtr.reset( new Controls::AspectRatio() ); + myFunctorPtr = myNumericalFunctorPtr; } -int Length_i::GetType() const +FunctorType AspectRatio_i::GetFunctorType() { - return SMDSAbs_Edge; + return SMESH::FT_AspectRatio; } + /* - Class : MultiConnection_i - Description : Functor for calculating number of faces conneted to the edge + Class : AspectRatio3D + Description : Functor for calculating aspect ratio 3D */ - -CORBA::Double MultiConnection_i::GetValue( CORBA::Long theId ) +AspectRatio3D_i::AspectRatio3D_i() { - return getNbMultiConnection( myMesh, theId ); + myNumericalFunctorPtr.reset( new Controls::AspectRatio3D() ); + myFunctorPtr = myNumericalFunctorPtr; } -int MultiConnection_i::GetType() const +FunctorType AspectRatio3D_i::GetFunctorType() { - return SMDSAbs_Edge; + return SMESH::FT_AspectRatio3D; } -/* - PREDICATES -*/ /* - Class : Predicate_i - Description : Base class for all predicates + Class : Warping_i + Description : Functor for calculating warping */ -Predicate_i::Predicate_i() -: SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() ) +Warping_i::Warping_i() +{ + myNumericalFunctorPtr.reset( new Controls::Warping() ); + myFunctorPtr = myNumericalFunctorPtr; +} + +FunctorType Warping_i::GetFunctorType() { - SMESH_Gen_i::GetPOA()->activate_object( this ); + return SMESH::FT_Warping; } /* - Class : FreeBorders_i - Description : Predicate for free borders + Class : Taper_i + Description : Functor for calculating taper */ - -FreeBorders_i::FreeBorders_i() +Taper_i::Taper_i() { - myMesh = 0; + myNumericalFunctorPtr.reset( new Controls::Taper() ); + myFunctorPtr = myNumericalFunctorPtr; } -void FreeBorders_i::SetMesh( SMESH_Mesh_ptr theMesh ) +FunctorType Taper_i::GetFunctorType() { - SMESH_Mesh_i* anImplPtr = - dynamic_cast( SMESH_Gen_i::GetServant( theMesh ).in() ); - myMesh = anImplPtr ? anImplPtr->GetImpl().GetMeshDS() : 0; + return SMESH::FT_Taper; } -CORBA::Boolean FreeBorders_i::IsSatisfy( CORBA::Long theId ) +/* + Class : Skew_i + Description : Functor for calculating skew in degrees +*/ +Skew_i::Skew_i() { - return getNbMultiConnection( myMesh, theId ) == 1; + myNumericalFunctorPtr.reset( new Controls::Skew() ); + myFunctorPtr = myNumericalFunctorPtr; } -int FreeBorders_i::GetType() const +FunctorType Skew_i::GetFunctorType() { - return SMDSAbs_Edge; + return SMESH::FT_Skew; } /* - Class : Comparator_i - Description : Base class for comparators + Class : Area_i + Description : Functor for calculating area */ - -Comparator_i::Comparator_i() +Area_i::Area_i() { - myMargin = 0; - myFunctor = 0; + myNumericalFunctorPtr.reset( new Controls::Area() ); + myFunctorPtr = myNumericalFunctorPtr; } -Comparator_i::~Comparator_i() +FunctorType Area_i::GetFunctorType() { - if ( myFunctor != 0 ) - myFunctor->Destroy(); + return SMESH::FT_Area; } -void Comparator_i::SetMesh( SMESH_Mesh_ptr theMesh ) +/* + Class : Volume3D_i + Description : Functor for calculating volume of 3D element +*/ +Volume3D_i::Volume3D_i() { - if ( myFunctor != 0 ) - myFunctor->SetMesh( theMesh ); + myNumericalFunctorPtr.reset( new Controls::Volume() ); + myFunctorPtr = myNumericalFunctorPtr; } -void Comparator_i::SetMargin( CORBA::Double theValue ) +FunctorType Volume3D_i::GetFunctorType() { - myMargin = theValue; + return SMESH::FT_Volume3D; } -void Comparator_i::SetNumFunctor( NumericalFunctor_ptr theFunct ) +/* + Class : MaxElementLength2D_i + Description : Functor for calculating maximum length of 2D element +*/ +MaxElementLength2D_i::MaxElementLength2D_i() { - if ( myFunctor != 0 ) - myFunctor->Destroy(); - - myFunctor = dynamic_cast( SMESH_Gen_i::GetServant( theFunct ).in() ); - - if ( myFunctor != 0 ) - myFunctor->Register(); + myNumericalFunctorPtr.reset( new Controls::MaxElementLength2D() ); + myFunctorPtr = myNumericalFunctorPtr; } -int Comparator_i::GetType() const +FunctorType MaxElementLength2D_i::GetFunctorType() { - return myFunctor != 0 ? myFunctor->GetType() : SMDSAbs_All; + return SMESH::FT_MaxElementLength2D; } /* - Class : LessThan_i - Description : Comparator "<" + Class : MaxElementLength3D_i + Description : Functor for calculating maximum length of 3D element */ - -CORBA::Boolean LessThan_i::IsSatisfy( CORBA::Long theId ) +MaxElementLength3D_i::MaxElementLength3D_i() { - return myFunctor != 0 && myFunctor->GetValue( theId ) < myMargin; + myNumericalFunctorPtr.reset( new Controls::MaxElementLength3D() ); + myFunctorPtr = myNumericalFunctorPtr; +} + +FunctorType MaxElementLength3D_i::GetFunctorType() +{ + return SMESH::FT_MaxElementLength3D; } /* - Class : MoreThan_i - Description : Comparator ">" + Class : Length_i + Description : Functor for calculating length off edge */ +Length_i::Length_i() +{ + myNumericalFunctorPtr.reset( new Controls::Length() ); + myFunctorPtr = myNumericalFunctorPtr; +} -CORBA::Boolean MoreThan_i::IsSatisfy( CORBA::Long theId ) +FunctorType Length_i::GetFunctorType() { - return myFunctor != 0 && myFunctor->GetValue( theId ) > myMargin; + return SMESH::FT_Length; } /* - Class : EqualTo_i - Description : Comparator "=" + Class : Length2D_i + Description : Functor for calculating length of edge */ -EqualTo_i::EqualTo_i() +Length2D_i::Length2D_i() { - myToler = Precision::Confusion(); + myNumericalFunctorPtr.reset( new Controls::Length2D() ); + myFunctorPtr = myNumericalFunctorPtr; } -CORBA::Boolean EqualTo_i::IsSatisfy( CORBA::Long theId ) +FunctorType Length2D_i::GetFunctorType() { - return myFunctor != 0 && fabs( myFunctor->GetValue( theId ) - myMargin ) < myToler; + return SMESH::FT_Length2D; } -void EqualTo_i::SetTolerance( CORBA::Double theToler ) +SMESH::Length2D::Values* Length2D_i::GetValues() { - myToler = theToler; -} + INFOS("Length2D_i::GetValues"); + SMESH::Controls::Length2D::TValues aValues; + (dynamic_cast(myFunctorPtr.get()))->GetValues( aValues ); + + long i = 0, iEnd = aValues.size(); + + SMESH::Length2D::Values_var aResult = new SMESH::Length2D::Values(iEnd); + aResult->length(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 : LogicalNOT_i - Description : Logical NOT predicate + Class : MultiConnection_i + Description : Functor for calculating number of faces conneted to the edge */ - -LogicalNOT_i::LogicalNOT_i() +MultiConnection_i::MultiConnection_i() { - myPredicate = 0; + myNumericalFunctorPtr.reset( new Controls::MultiConnection() ); + myFunctorPtr = myNumericalFunctorPtr; } -LogicalNOT_i::~LogicalNOT_i() +FunctorType MultiConnection_i::GetFunctorType() { - if ( myPredicate ) - myPredicate->Destroy(); + return SMESH::FT_MultiConnection; } -CORBA::Boolean LogicalNOT_i::IsSatisfy( CORBA::Long theId ) +/* + Class : BallDiameter_i + Description : Functor returning diameter of a ball element +*/ +BallDiameter_i::BallDiameter_i() { - return myPredicate !=0 && !myPredicate->IsSatisfy( theId ); + myNumericalFunctorPtr.reset( new Controls::BallDiameter() ); + myFunctorPtr = myNumericalFunctorPtr; } -void LogicalNOT_i::SetMesh( SMESH_Mesh_ptr theMesh ) +FunctorType BallDiameter_i::GetFunctorType() { - if ( myPredicate != 0 ) - myPredicate->SetMesh( theMesh ); + return SMESH::FT_BallDiameter; } -void LogicalNOT_i::SetPredicate( Predicate_ptr thePred ) +/* + Class : MultiConnection2D_i + Description : Functor for calculating number of faces conneted to the edge +*/ +MultiConnection2D_i::MultiConnection2D_i() { - if ( myPredicate != 0 ) - myPredicate->Destroy(); - - myPredicate = dynamic_cast( SMESH_Gen_i::GetServant( thePred ).in() ); - - if ( myPredicate != 0 ) - myPredicate->Register(); + myNumericalFunctorPtr.reset( new Controls::MultiConnection2D() ); + myFunctorPtr = myNumericalFunctorPtr; } -int LogicalNOT_i::GetType() const +FunctorType MultiConnection2D_i::GetFunctorType() { - return myPredicate != 0 ? myPredicate->GetType() : SMDSAbs_All; + return SMESH::FT_MultiConnection2D; } +SMESH::MultiConnection2D::Values* MultiConnection2D_i::GetValues() +{ + INFOS("MultiConnection2D_i::GetValues"); + SMESH::Controls::MultiConnection2D::MValues aValues; + (dynamic_cast(myFunctorPtr.get()))->GetValues( aValues ); + + long i = 0, iEnd = aValues.size(); + + SMESH::MultiConnection2D::Values_var aResult = new SMESH::MultiConnection2D::Values(iEnd); + aResult->length(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(); +} /* - Class : LogicalBinary_i - Description : Base class for binary logical predicate + PREDICATES */ -LogicalBinary_i::LogicalBinary_i() + +/* + Class : Predicate_i + Description : Base class for all predicates +*/ +CORBA::Boolean Predicate_i::IsSatisfy( CORBA::Long theId ) { - myPredicate1 = 0; - myPredicate2 = 0; + return myPredicatePtr->IsSatisfy( theId ); } -LogicalBinary_i::~LogicalBinary_i() -{ - if ( myPredicate1 != 0 ) - myPredicate1->Destroy(); - if ( myPredicate2 != 0 ) - myPredicate2->Destroy(); +Controls::PredicatePtr Predicate_i::GetPredicate() +{ + return myPredicatePtr; } -void LogicalBinary_i::SetMesh( SMESH_Mesh_ptr theMesh ) +/* + Class : BadOrientedVolume_i + Description : Verify whether a mesh volume is incorrectly oriented from + the point of view of MED convention +*/ +BadOrientedVolume_i::BadOrientedVolume_i() { - if ( myPredicate1 != 0 ) - myPredicate1->SetMesh( theMesh ); + Controls::PredicatePtr control( new Controls::BadOrientedVolume() ); + myFunctorPtr = myPredicatePtr = control; +}; - if ( myPredicate2 != 0 ) - myPredicate2->SetMesh( theMesh ); +FunctorType BadOrientedVolume_i::GetFunctorType() +{ + return SMESH::FT_BadOrientedVolume; } -void LogicalBinary_i::SetPredicate1( Predicate_ptr thePredicate ) +/* + Class : BareBorderVolume_i + Description : Verify whether a mesh volume has a free facet without a face on it +*/ +BareBorderVolume_i::BareBorderVolume_i() { - if ( myPredicate1 != 0 ) - myPredicate1->Destroy(); + Controls::PredicatePtr control( new Controls::BareBorderVolume() ); + myFunctorPtr = myPredicatePtr = control; +}; - myPredicate1 = dynamic_cast( SMESH_Gen_i::GetServant( thePredicate ).in() ); - - if ( myPredicate1 != 0 ) - myPredicate1->Register(); +FunctorType BareBorderVolume_i::GetFunctorType() +{ + return SMESH::FT_BareBorderVolume; } -void LogicalBinary_i::SetPredicate2( Predicate_ptr thePredicate ) +/* + Class : BareBorderFace_i + Description : Verify whether a mesh face has a free border without an edge on it +*/ +BareBorderFace_i::BareBorderFace_i() { - if ( myPredicate2 != 0 ) - myPredicate2->Destroy(); + Controls::PredicatePtr control( new Controls::BareBorderFace() ); + myFunctorPtr = myPredicatePtr = control; +}; - myPredicate2 = dynamic_cast( SMESH_Gen_i::GetServant( thePredicate ).in() ); - - if ( myPredicate2 != 0 ) - myPredicate2->Register(); +FunctorType BareBorderFace_i::GetFunctorType() +{ + return SMESH::FT_BareBorderFace; } -int LogicalBinary_i::GetType() const +/* + Class : OverConstrainedVolume_i + Description : Verify whether a mesh volume has only one facet shared with other volumes +*/ +OverConstrainedVolume_i::OverConstrainedVolume_i() { - if ( myPredicate1 == 0 || myPredicate2 == 0 ) - return SMDSAbs_All; - - int aType1 = myPredicate1->GetType(); - int aType2 = myPredicate2->GetType(); + Controls::PredicatePtr control( new Controls::OverConstrainedVolume() ); + myFunctorPtr = myPredicatePtr = control; +}; - return aType1 == aType2 ? aType1 : SMDSAbs_All; +FunctorType OverConstrainedVolume_i::GetFunctorType() +{ + return SMESH::FT_OverConstrainedVolume; } /* - Class : LogicalAND_i - Description : Logical AND + Class : OverConstrainedFace_i + Description : Verify whether a mesh face has only one border shared with other faces */ +OverConstrainedFace_i::OverConstrainedFace_i() +{ + Controls::PredicatePtr control( new Controls::OverConstrainedFace() ); + myFunctorPtr = myPredicatePtr = control; +}; -CORBA::Boolean LogicalAND_i::IsSatisfy( CORBA::Long theId ) +FunctorType OverConstrainedFace_i::GetFunctorType() { - return myPredicate1 != 0 && - myPredicate2 != 0 && - myPredicate1->IsSatisfy( theId ) && myPredicate2->IsSatisfy( theId );; + return SMESH::FT_OverConstrainedFace; } /* - Class : LogicalOR_i - Description : Logical OR + Class : BelongToGeom_i + Description : Predicate for selection on geometrical support */ +BelongToGeom_i::BelongToGeom_i() +{ + myBelongToGeomPtr.reset( new Controls::BelongToGeom() ); + myFunctorPtr = myPredicatePtr = myBelongToGeomPtr; + myShapeName = 0; + myShapeID = 0; +} -CORBA::Boolean LogicalOR_i::IsSatisfy( CORBA::Long theId ) +BelongToGeom_i::~BelongToGeom_i() { - return myPredicate1 != 0 && - myPredicate2 != 0 && - myPredicate1->IsSatisfy( theId ) || myPredicate2->IsSatisfy( theId ); + delete myShapeName; + delete myShapeID; } +void BelongToGeom_i::SetGeom( GEOM::GEOM_Object_ptr theGeom ) +{ + if ( theGeom->_is_nil() ) + return; + SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); + GEOM::GEOM_Gen_ptr aGEOMGen = SMESH_Gen_i::GetGeomEngine(); + TopoDS_Shape aLocShape = aSMESHGen->GetShapeReader()->GetShape( aGEOMGen, theGeom ); + myBelongToGeomPtr->SetGeom( aLocShape ); + TPythonDump()<SetGeom( theShape ); +} -Filter_i::Filter_i() +void BelongToGeom_i::SetElementType(ElementType theType){ + myBelongToGeomPtr->SetType(SMDSAbs_ElementType(theType)); + TPythonDump()<Destroy(); + delete myShapeName; + myShapeName = strdup( theName ); + myBelongToGeomPtr->SetGeom( getShapeByName( myShapeName ) ); + TPythonDump()<Destroy(); + delete myShapeName; + myShapeName = strdup( theName ); + delete myShapeID; + if ( theID ) + myShapeID = strdup( theID ); + else + myShapeID = 0; - myPredicate = dynamic_cast( SMESH_Gen_i::GetServant( thePredicate ).in() ); + if ( myShapeID && myShapeName == getShapeNameByID(myShapeID)) + myBelongToGeomPtr->SetGeom( getShapeByID(myShapeID) ); + else + myBelongToGeomPtr->SetGeom( getShapeByName( myShapeName ) ); +} - if ( myPredicate != 0 ) - myPredicate->Register(); +char* BelongToGeom_i::GetShapeName() +{ + return CORBA::string_dup( myShapeName ); } -void Filter_i::SetMesh( SMESH_Mesh_ptr theMesh ) +char* BelongToGeom_i::GetShapeID() { - if ( myPredicate != 0 ) - myPredicate->SetMesh( theMesh ); + return CORBA::string_dup( myShapeID ); +} + +void BelongToGeom_i::SetTolerance( CORBA::Double theToler ) +{ + myBelongToGeomPtr->SetTolerance( theToler ); + TPythonDump()<GetTolerance(); +} - SetMesh( theMesh ); +/* + Class : BelongToSurface_i + Description : Predicate for selection on geometrical support +*/ +BelongToSurface_i::BelongToSurface_i( const Handle(Standard_Type)& theSurfaceType ) +{ + myElementsOnSurfacePtr.reset( new Controls::ElementsOnSurface() ); + myFunctorPtr = myPredicatePtr = myElementsOnSurfacePtr; + myShapeName = 0; + myShapeID = 0; + mySurfaceType = theSurfaceType; +} - SMESH_Mesh_i* anImplPtr = - dynamic_cast( SMESH_Gen_i::GetServant( theMesh ).in() ); +BelongToSurface_i::~BelongToSurface_i() +{ + delete myShapeName; + delete myShapeID; +} - TColStd_ListOfInteger aList; +void BelongToSurface_i::SetSurface( GEOM::GEOM_Object_ptr theGeom, ElementType theType ) +{ + if ( theGeom->_is_nil() ) + return; + SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); + GEOM::GEOM_Gen_ptr aGEOMGen = SMESH_Gen_i::GetGeomEngine(); + TopoDS_Shape aLocShape = aSMESHGen->GetShapeReader()->GetShape( aGEOMGen, theGeom ); - if ( anImplPtr != 0 ) + if ( aLocShape.ShapeType() == TopAbs_FACE ) { - SMESHDS_Mesh* aMesh = anImplPtr->GetImpl().GetMeshDS(); - - if ( myPredicate != 0 ) + Handle(Geom_Surface) aSurf = BRep_Tool::Surface( TopoDS::Face( aLocShape ) ); + if ( !aSurf.IsNull() && aSurf->DynamicType() == mySurfaceType ) { - int aType = myPredicate->GetType(); - - if ( aType == SMDSAbs_Edge ) - { - SMDS_EdgeIteratorPtr anIter = aMesh->edgesIterator(); - if ( anIter != 0 ) - { - while( anIter->more() ) - { - const SMDS_MeshElement* anElem = anIter->next(); - if ( myPredicate->IsSatisfy( anElem->GetID() ) ) - aList.Append( anElem->GetID() ); - } - } -// delete anIter; - } - else if ( aType == SMDSAbs_Face ) - { - SMDS_FaceIteratorPtr anIter = aMesh->facesIterator(); - if ( anIter != 0 ) - { - while( anIter->more() ) - { - const SMDS_MeshElement* anElem = anIter->next(); - if ( myPredicate->IsSatisfy( anElem->GetID() ) ) - aList.Append( anElem->GetID() ); - } - } -// delete anIter; - } + myElementsOnSurfacePtr->SetSurface( aLocShape, (SMDSAbs_ElementType)theType ); + return; } } - - SMESH::long_array_var anArray = new SMESH::long_array; - - anArray->length( aList.Extent() ); - TColStd_ListIteratorOfListOfInteger anIter( aList ); - int i = 0; - for( ; anIter.More(); anIter.Next() ) - anArray[ i++ ] = anIter.Value(); - return anArray._retn(); + myElementsOnSurfacePtr->SetSurface( TopoDS_Shape(), (SMDSAbs_ElementType)theType ); } -/* - FILTER MANAGER -*/ +void BelongToSurface_i::SetShapeName( const char* theName, ElementType theType ) +{ + delete myShapeName; + myShapeName = strdup( theName ); + myElementsOnSurfacePtr->SetSurface( getShapeByName( myShapeName ), (SMDSAbs_ElementType)theType ); + TPythonDump()<activate_object( this ); + delete myShapeName; + myShapeName = strdup( theName ); + delete myShapeID; + if ( theID ) + myShapeID = strdup( theID ); + else + myShapeID = 0; + + if ( myShapeID && myShapeName == getShapeNameByID(myShapeID)) + myElementsOnSurfacePtr->SetSurface( getShapeByID(myShapeID), (SMDSAbs_ElementType)theType ); + else + myElementsOnSurfacePtr->SetSurface( getShapeByName( myShapeName ), (SMDSAbs_ElementType)theType ); } -MinimumAngle_ptr FilterManager_i::CreateMinimumAngle() +char* BelongToSurface_i::GetShapeName() { - SMESH::MinimumAngle_i* aServant = new SMESH::MinimumAngle_i(); - SMESH::MinimumAngle_var anObj = aServant->_this(); - return anObj._retn(); + return CORBA::string_dup( myShapeName ); } +char* BelongToSurface_i::GetShapeID() +{ + return CORBA::string_dup( myShapeID ); +} -AspectRatio_ptr FilterManager_i::CreateAspectRatio() +void BelongToSurface_i::SetTolerance( CORBA::Double theToler ) { - SMESH::AspectRatio_i* aServant = new SMESH::AspectRatio_i(); - SMESH::AspectRatio_var anObj = aServant->_this(); - return anObj._retn(); + myElementsOnSurfacePtr->SetTolerance( theToler ); + TPythonDump()<GetTolerance(); +} -Warping_ptr FilterManager_i::CreateWarping() +void BelongToSurface_i::SetUseBoundaries( CORBA::Boolean theUseBndRestrictions ) { - SMESH::Warping_i* aServant = new SMESH::Warping_i(); - SMESH::Warping_var anObj = aServant->_this(); - return anObj._retn(); + myElementsOnSurfacePtr->SetUseBoundaries( theUseBndRestrictions ); + TPythonDump()<GetUseBoundaries(); +} -Taper_ptr FilterManager_i::CreateTaper() + +/* + Class : BelongToPlane_i + Description : Verify whether mesh element lie in pointed Geom planar object +*/ + +BelongToPlane_i::BelongToPlane_i() +: BelongToSurface_i( STANDARD_TYPE( Geom_Plane ) ) { - SMESH::Taper_i* aServant = new SMESH::Taper_i(); - SMESH::Taper_var anObj = aServant->_this(); - return anObj._retn(); } +void BelongToPlane_i::SetPlane( GEOM::GEOM_Object_ptr theGeom, ElementType theType ) +{ + BelongToSurface_i::SetSurface( theGeom, theType ); + TPythonDump()<_this(); - return anObj._retn(); + return FT_BelongToPlane; } +/* + Class : BelongToCylinder_i + Description : Verify whether mesh element lie in pointed Geom planar object +*/ -Area_ptr FilterManager_i::CreateArea() +BelongToCylinder_i::BelongToCylinder_i() +: BelongToSurface_i( STANDARD_TYPE( Geom_CylindricalSurface ) ) { - SMESH::Area_i* aServant = new SMESH::Area_i(); - SMESH::Area_var anObj = aServant->_this(); - return anObj._retn(); } +void BelongToCylinder_i::SetCylinder( GEOM::GEOM_Object_ptr theGeom, ElementType theType ) +{ + BelongToSurface_i::SetSurface( theGeom, theType ); + TPythonDump()<_this(); - return anObj._retn(); + return FT_BelongToCylinder; } +/* + Class : BelongToGenSurface_i + Description : Verify whether mesh element lie in pointed Geom planar object +*/ -MultiConnection_ptr FilterManager_i::CreateMultiConnection() +BelongToGenSurface_i::BelongToGenSurface_i() +: BelongToSurface_i( STANDARD_TYPE( Geom_CylindricalSurface ) ) { - SMESH::MultiConnection_i* aServant = new SMESH::MultiConnection_i(); - SMESH::MultiConnection_var anObj = aServant->_this(); - return anObj._retn(); } +void BelongToGenSurface_i::SetSurface( GEOM::GEOM_Object_ptr theGeom, ElementType theType ) +{ + if ( theGeom->_is_nil() ) + return; + TopoDS_Shape aLocShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theGeom ); + if ( !aLocShape.IsNull() && aLocShape.ShapeType() != TopAbs_FACE ) + aLocShape.Nullify(); + + BelongToSurface_i::myElementsOnSurfacePtr->SetSurface( aLocShape, (SMDSAbs_ElementType)theType ); + TPythonDump()<_this(); - return anObj._retn(); + return FT_BelongToGenSurface; } -LessThan_ptr FilterManager_i::CreateLessThan() +/* + Class : LyingOnGeom_i + Description : Predicate for selection on geometrical support +*/ +LyingOnGeom_i::LyingOnGeom_i() { - SMESH::LessThan_i* aServant = new SMESH::LessThan_i(); - SMESH::LessThan_var anObj = aServant->_this(); - return anObj._retn(); + myLyingOnGeomPtr.reset( new Controls::LyingOnGeom() ); + myFunctorPtr = myPredicatePtr = myLyingOnGeomPtr; + myShapeName = 0; + myShapeID = 0; } +LyingOnGeom_i::~LyingOnGeom_i() +{ + delete myShapeName; + delete myShapeID; +} -MoreThan_ptr FilterManager_i::CreateMoreThan() +void LyingOnGeom_i::SetGeom( GEOM::GEOM_Object_ptr theGeom ) { - SMESH::MoreThan_i* aServant = new SMESH::MoreThan_i(); - SMESH::MoreThan_var anObj = aServant->_this(); - return anObj._retn(); + if ( theGeom->_is_nil() ) + return; + SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); + GEOM::GEOM_Gen_ptr aGEOMGen = SMESH_Gen_i::GetGeomEngine(); + TopoDS_Shape aLocShape = aSMESHGen->GetShapeReader()->GetShape( aGEOMGen, theGeom ); + myLyingOnGeomPtr->SetGeom( aLocShape ); + TPythonDump()<_this(); - return anObj._retn(); + myLyingOnGeomPtr->SetGeom( theShape ); } +void LyingOnGeom_i::SetElementType(ElementType theType){ + myLyingOnGeomPtr->SetType(SMDSAbs_ElementType(theType)); + TPythonDump()<_this(); - return anObj._retn(); + return SMESH::FT_LyingOnGeom; } +void LyingOnGeom_i::SetShapeName( const char* theName ) +{ + delete myShapeName; + myShapeName = strdup( theName ); + myLyingOnGeomPtr->SetGeom( getShapeByName( myShapeName ) ); + TPythonDump()<_this(); - return anObj._retn(); + delete myShapeName; + myShapeName = strdup( theName ); + delete myShapeID; + if ( theID ) + myShapeID = strdup( theID ); + else + myShapeID = 0; + + if ( myShapeID && myShapeName == getShapeNameByID(myShapeID)) + myLyingOnGeomPtr->SetGeom( getShapeByID(myShapeID) ); + else + myLyingOnGeomPtr->SetGeom( getShapeByName( myShapeName ) ); +} + +char* LyingOnGeom_i::GetShapeName() +{ + return CORBA::string_dup( myShapeName ); } +char* LyingOnGeom_i::GetShapeID() +{ + return CORBA::string_dup( myShapeID ); +} -LogicalOR_ptr FilterManager_i::CreateLogicalOR() +void LyingOnGeom_i::SetTolerance( CORBA::Double theToler ) { - SMESH::LogicalOR_i* aServant = new SMESH::LogicalOR_i(); - SMESH::LogicalOR_var anObj = aServant->_this(); - return anObj._retn(); + myLyingOnGeomPtr->SetTolerance( theToler ); + TPythonDump()<_this(); - return anObj._retn(); + return myLyingOnGeomPtr->GetTolerance(); +} + +/* + Class : FreeBorders_i + Description : Predicate for free borders +*/ +FreeBorders_i::FreeBorders_i() +{ + myPredicatePtr.reset(new Controls::FreeBorders()); + myFunctorPtr = myPredicatePtr; +} + +FunctorType FreeBorders_i::GetFunctorType() +{ + return SMESH::FT_FreeBorders; +} + +/* + Class : FreeEdges_i + Description : Predicate for free borders +*/ +FreeEdges_i::FreeEdges_i() +: myFreeEdgesPtr( new Controls::FreeEdges() ) +{ + myFunctorPtr = myPredicatePtr = myFreeEdgesPtr; +} + +SMESH::FreeEdges::Borders* FreeEdges_i::GetBorders() +{ + INFOS("FreeEdges_i::GetBorders"); + SMESH::Controls::FreeEdges::TBorders aBorders; + myFreeEdgesPtr->GetBoreders( aBorders ); + + long i = 0, iEnd = aBorders.size(); + + SMESH::FreeEdges::Borders_var aResult = new SMESH::FreeEdges::Borders; + aResult->length(iEnd); + + SMESH::Controls::FreeEdges::TBorders::const_iterator anIter; + for ( anIter = aBorders.begin() ; anIter != aBorders.end(); anIter++, i++ ) + { + const SMESH::Controls::FreeEdges::Border& aBord = *anIter; + SMESH::FreeEdges::Border &aBorder = aResult[ i ]; + + aBorder.myElemId = aBord.myElemId; + aBorder.myPnt1 = aBord.myPntId[ 0 ]; + aBorder.myPnt2 = aBord.myPntId[ 1 ]; + } + + INFOS("FreeEdges_i::GetBorders~"); + return aResult._retn(); +} + +FunctorType FreeEdges_i::GetFunctorType() +{ + return SMESH::FT_FreeEdges; +} + +/* + Class : FreeFaces_i + Description : Predicate for free faces +*/ +FreeFaces_i::FreeFaces_i() +{ + myPredicatePtr.reset(new Controls::FreeFaces()); + myFunctorPtr = myPredicatePtr; +} + +FunctorType FreeFaces_i::GetFunctorType() +{ + return SMESH::FT_FreeFaces; +} + +/* + Class : FreeNodes_i + Description : Predicate for free nodes +*/ +FreeNodes_i::FreeNodes_i() +{ + myPredicatePtr.reset(new Controls::FreeNodes()); + myFunctorPtr = myPredicatePtr; +} + +FunctorType FreeNodes_i::GetFunctorType() +{ + return SMESH::FT_FreeNodes; +} + +/* + Class : EqualNodes_i + Description : Predicate for Equal nodes +*/ +EqualNodes_i::EqualNodes_i() +{ + myCoincidentNodesPtr.reset(new Controls::CoincidentNodes()); + myFunctorPtr = myPredicatePtr = myCoincidentNodesPtr; +} + +FunctorType EqualNodes_i::GetFunctorType() +{ + return SMESH::FT_EqualNodes; +} + +void EqualNodes_i::SetTolerance( double tol ) +{ + myCoincidentNodesPtr->SetTolerance( tol ); +} + +double EqualNodes_i::GetTolerance() +{ + return myCoincidentNodesPtr->GetTolerance(); +} + +/* + Class : EqualEdges_i + Description : Predicate for Equal Edges +*/ +EqualEdges_i::EqualEdges_i() +{ + myPredicatePtr.reset(new Controls::CoincidentElements1D()); + myFunctorPtr = myPredicatePtr; +} + +FunctorType EqualEdges_i::GetFunctorType() +{ + return SMESH::FT_EqualEdges; +} + +/* + Class : EqualFaces_i + Description : Predicate for Equal Faces +*/ +EqualFaces_i::EqualFaces_i() +{ + myPredicatePtr.reset(new Controls::CoincidentElements2D()); + myFunctorPtr = myPredicatePtr; +} + +FunctorType EqualFaces_i::GetFunctorType() +{ + return SMESH::FT_EqualFaces; +} + +/* + Class : EqualVolumes_i + Description : Predicate for Equal Volumes +*/ +EqualVolumes_i::EqualVolumes_i() +{ + myPredicatePtr.reset(new Controls::CoincidentElements3D()); + myFunctorPtr = myPredicatePtr; +} + +FunctorType EqualVolumes_i::GetFunctorType() +{ + return SMESH::FT_EqualVolumes; +} + + +/* + Class : RangeOfIds_i + Description : Predicate for Range of Ids. + Range may be specified with two ways. + 1. Using AddToRange method + 2. With SetRangeStr method. Parameter of this method is a string + like as "1,2,3,50-60,63,67,70-" +*/ + +RangeOfIds_i::RangeOfIds_i() +{ + myRangeOfIdsPtr.reset( new Controls::RangeOfIds() ); + myFunctorPtr = myPredicatePtr = myRangeOfIdsPtr; +} + +void RangeOfIds_i::SetRange( const SMESH::long_array& theIds ) +{ + CORBA::Long iEnd = theIds.length(); + for ( CORBA::Long i = 0; i < iEnd; i++ ) + myRangeOfIdsPtr->AddToRange( theIds[ i ] ); + TPythonDump()<SetRangeStr( + TCollection_AsciiString( (Standard_CString)theRange ) ); +} + +char* RangeOfIds_i::GetRangeStr() +{ + TCollection_AsciiString aStr; + myRangeOfIdsPtr->GetRangeStr( aStr ); + return CORBA::string_dup( aStr.ToCString() ); +} + +void RangeOfIds_i::SetElementType( ElementType theType ) +{ + myRangeOfIdsPtr->SetType( SMDSAbs_ElementType( theType ) ); + TPythonDump()<SetType(SMDSAbs_ElementType(theType)); + TPythonDump()<SetColorStr( + TCollection_AsciiString( (Standard_CString)theColor ) ); + TPythonDump()<GetColorStr( aStr ); + return CORBA::string_dup( aStr.ToCString() ); +} + +void GroupColor_i::SetElementType(ElementType theType) +{ + myGroupColorPtr->SetType(SMDSAbs_ElementType(theType)); + TPythonDump()<SetType(SMDSAbs_ElementType(theType)); + TPythonDump()<SetGeomType(SMDSAbs_GeometryType(theType)); + TPythonDump()<GetGeomType(); +} + +FunctorType ElemGeomType_i::GetFunctorType() +{ + return SMESH::FT_ElemGeomType; +} + +/* + Class : ElemEntityType_i + Description : Predicate check is element has indicated entity type +*/ +ElemEntityType_i::ElemEntityType_i() +{ + myElemEntityTypePtr.reset(new Controls::ElemEntityType()); + myFunctorPtr = myPredicatePtr = myElemEntityTypePtr; +} + +void ElemEntityType_i::SetElementType(ElementType theType) +{ + myElemEntityTypePtr->SetType(SMDSAbs_ElementType(theType)); + TPythonDump()<SetElemEntityType(SMDSAbs_EntityType (theEntityType)); + TPythonDump()<GetElemEntityType(); +} + +FunctorType ElemEntityType_i::GetFunctorType() +{ + return SMESH::FT_EntityType; +} + +/* + Class : CoplanarFaces_i + Description : Returns true if a mesh face is a coplanar neighbour to a given one +*/ +CoplanarFaces_i::CoplanarFaces_i() +{ + myCoplanarFacesPtr.reset(new Controls::CoplanarFaces()); + myFunctorPtr = myPredicatePtr = myCoplanarFacesPtr; +} + +void CoplanarFaces_i::SetFace ( CORBA::Long theFaceID ) +{ + myCoplanarFacesPtr->SetFace(theFaceID); + TPythonDump()<SetTolerance(theToler); + TPythonDump()<GetFace(); +} + +char* CoplanarFaces_i::GetFaceAsString () const +{ + TCollection_AsciiString str(Standard_Integer(myCoplanarFacesPtr->GetFace())); + return CORBA::string_dup( str.ToCString() ); +} + +CORBA::Double CoplanarFaces_i::GetTolerance() const +{ + return myCoplanarFacesPtr->GetTolerance(); +} + +FunctorType CoplanarFaces_i::GetFunctorType() +{ + return SMESH::FT_CoplanarFaces; +} + +/* + Class : Comparator_i + Description : Base class for comparators +*/ +Comparator_i::Comparator_i(): + myNumericalFunctor( NULL ) +{} + +Comparator_i::~Comparator_i() +{ + if ( myNumericalFunctor ) + myNumericalFunctor->UnRegister(); +} + +void Comparator_i::SetMargin( CORBA::Double theValue ) +{ + myComparatorPtr->SetMargin( theValue ); + TPythonDump()<GetMargin(); +} + +void Comparator_i::SetNumFunctor( NumericalFunctor_ptr theFunct ) +{ + if ( myNumericalFunctor ) + myNumericalFunctor->UnRegister(); + + myNumericalFunctor = DownCast(theFunct); + + if ( myNumericalFunctor ) + { + myComparatorPtr->SetNumFunctor( myNumericalFunctor->GetNumericalFunctor() ); + myNumericalFunctor->Register(); + TPythonDump()<" +*/ +MoreThan_i::MoreThan_i() +{ + myComparatorPtr.reset( new Controls::MoreThan() ); + myFunctorPtr = myPredicatePtr = myComparatorPtr; +} + +FunctorType MoreThan_i::GetFunctorType() +{ + return SMESH::FT_MoreThan; +} + + +/* + Class : EqualTo_i + Description : Comparator "=" +*/ +EqualTo_i::EqualTo_i() +: myEqualToPtr( new Controls::EqualTo() ) +{ + myFunctorPtr = myPredicatePtr = myComparatorPtr = myEqualToPtr; +} + +void EqualTo_i::SetTolerance( CORBA::Double theToler ) +{ + myEqualToPtr->SetTolerance( theToler ); + TPythonDump()<GetTolerance(); +} + +FunctorType EqualTo_i::GetFunctorType() +{ + return SMESH::FT_EqualTo; +} + +/* + Class : LogicalNOT_i + Description : Logical NOT predicate +*/ +LogicalNOT_i::LogicalNOT_i() +: myPredicate( NULL ), + myLogicalNOTPtr( new Controls::LogicalNOT() ) +{ + myFunctorPtr = myPredicatePtr = myLogicalNOTPtr; +} + +LogicalNOT_i::~LogicalNOT_i() +{ + if ( myPredicate ) + myPredicate->UnRegister(); +} + +void LogicalNOT_i::SetPredicate( Predicate_ptr thePredicate ) +{ + if ( myPredicate ) + myPredicate->UnRegister(); + + myPredicate = SMESH::GetPredicate(thePredicate); + + if ( myPredicate ){ + myLogicalNOTPtr->SetPredicate(myPredicate->GetPredicate()); + myPredicate->Register(); + TPythonDump()<UnRegister(); + + if ( myPredicate2 ) + myPredicate2->UnRegister(); +} + +void LogicalBinary_i::SetMesh( SMESH_Mesh_ptr theMesh ) +{ + if ( myPredicate1 ) + myPredicate1->SetMesh( theMesh ); + + if ( myPredicate2 ) + myPredicate2->SetMesh( theMesh ); +} + +void LogicalBinary_i::SetPredicate1( Predicate_ptr thePredicate ) +{ + if ( myPredicate1 ) + myPredicate1->UnRegister(); + + myPredicate1 = SMESH::GetPredicate(thePredicate); + + if ( myPredicate1 ){ + myLogicalBinaryPtr->SetPredicate1(myPredicate1->GetPredicate()); + myPredicate1->Register(); + TPythonDump()<UnRegister(); + + myPredicate2 = SMESH::GetPredicate(thePredicate); + + if ( myPredicate2 ){ + myLogicalBinaryPtr->SetPredicate2(myPredicate2->GetPredicate()); + myPredicate2->Register(); + TPythonDump()<activate_object( this ); +} + + +FilterManager_i::~FilterManager_i() +{ + //TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + return anObj._retn(); +} + + +/* + FILTER +*/ + +//======================================================================= +// name : Filter_i::Filter_i +// Purpose : Constructor +//======================================================================= +Filter_i::Filter_i() +: myPredicate( NULL ) +{} + +//======================================================================= +// name : Filter_i::~Filter_i +// Purpose : Destructor +//======================================================================= +Filter_i::~Filter_i() +{ + if ( myPredicate ) + myPredicate->UnRegister(); + + if(!CORBA::is_nil(myMesh)) + myMesh->UnRegister(); + + //TPythonDump()<UnRegister(); + + myPredicate = SMESH::GetPredicate(thePredicate); + + if ( myPredicate ) + { + myFilter.SetPredicate( myPredicate->GetPredicate() ); + myPredicate->Register(); + if ( const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh)) + myPredicate->GetPredicate()->SetMesh( aMesh ); + TPythonDump()<::iterator i = myWaiters.begin(); + for ( ; i != myWaiters.end(); ++i ) + (*i)->PredicateChanged(); +} + +//======================================================================= +// name : Filter_i::GetElementType +// Purpose : Get entity type +//======================================================================= +SMESH::ElementType Filter_i::GetElementType() +{ + return myPredicate != 0 ? myPredicate->GetElementType() : SMESH::ALL; +} + +//======================================================================= +// name : Filter_i::SetMesh +// Purpose : Set mesh +//======================================================================= +void +Filter_i:: +SetMesh( SMESH_Mesh_ptr theMesh ) +{ + if(!CORBA::is_nil(theMesh)) + theMesh->Register(); + + if(!CORBA::is_nil(myMesh)) + myMesh->UnRegister(); + + myMesh = SMESH_Mesh::_duplicate( theMesh ); + TPythonDump()<GetPredicate()->SetMesh( aMesh ); +} + +SMESH::long_array* +Filter_i:: +GetIDs() +{ + return GetElementsId(myMesh); +} + +//======================================================================= +// name : Filter_i::GetElementsId +// Purpose : Get ids of entities +//======================================================================= +void +Filter_i:: +GetElementsId( Predicate_i* thePredicate, + const SMDS_Mesh* theMesh, + Controls::Filter::TIdSequence& theSequence ) +{ + if (thePredicate) + Controls::Filter::GetElementsId(theMesh,thePredicate->GetPredicate(),theSequence); +} + +void +Filter_i:: +GetElementsId( Predicate_i* thePredicate, + SMESH_Mesh_ptr theMesh, + Controls::Filter::TIdSequence& theSequence ) +{ + if (thePredicate) + if(const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(theMesh)) + Controls::Filter::GetElementsId(aMesh,thePredicate->GetPredicate(),theSequence); +} + +SMESH::long_array* +Filter_i:: +GetElementsId( SMESH_Mesh_ptr theMesh ) +{ + SMESH::long_array_var anArray = new SMESH::long_array; + if(!CORBA::is_nil(theMesh) && myPredicate){ + Controls::Filter::TIdSequence aSequence; + GetElementsId(myPredicate,theMesh,aSequence); + long i = 0, iEnd = aSequence.size(); + anArray->length( iEnd ); + for ( ; i < iEnd; i++ ) + anArray[ i ] = aSequence[i]; + } + return anArray._retn(); +} + +template +static void collectMeshInfo(const TIterator& theItr, + TPredicate& thePred, + SMESH::long_array& theRes) +{ + if (!theItr) + return; + while (theItr->more()) { + const SMDS_MeshElement* anElem = theItr->next(); + if ( thePred->IsSatisfy( anElem->GetID() ) ) + theRes[ anElem->GetEntityType() ]++; + } +} + +//============================================================================= +/*! + * \brief Returns statistic of mesh elements + */ +//============================================================================= +SMESH::long_array* ::Filter_i::GetMeshInfo() +{ + SMESH::long_array_var aRes = new SMESH::long_array(); + aRes->length(SMESH::Entity_Last); + for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++) + aRes[i] = 0; + + if(!CORBA::is_nil(myMesh) && myPredicate) { + const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh); + SMDS_ElemIteratorPtr it; + switch( GetElementType() ) + { + case SMDSAbs_Node: + collectMeshInfo(aMesh->nodesIterator(),myPredicate,aRes); + break; + case SMDSAbs_Edge: + collectMeshInfo(aMesh->edgesIterator(),myPredicate,aRes); + break; + case SMDSAbs_Face: + collectMeshInfo(aMesh->facesIterator(),myPredicate,aRes); + break; + case SMDSAbs_Volume: + collectMeshInfo(aMesh->volumesIterator(),myPredicate,aRes); + break; + case SMDSAbs_All: + default: + collectMeshInfo(aMesh->elementsIterator(),myPredicate,aRes); + break; + } + } + + return aRes._retn(); +} + +//================================================================================ +/*! + * \brief Return GetElementType() within an array + * Implement SMESH_IDSource interface + */ +//================================================================================ + +SMESH::array_of_ElementType* Filter_i::GetTypes() +{ + SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType; + + // check if any element passes through the filter + if ( !CORBA::is_nil(myMesh) && myPredicate ) + { + const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh); + SMDS_ElemIteratorPtr it = aMesh->elementsIterator( SMDSAbs_ElementType( GetElementType() )); + bool satisfies = false; + while ( !satisfies && it->more() ) + satisfies = myPredicate->IsSatisfy( it->next()->GetID() ); + if ( satisfies ) { + types->length( 1 ); + types[0] = GetElementType(); + } + } + return types._retn(); +} + +//======================================================================= +//function : GetMesh +//purpose : Returns mesh +//======================================================================= + +SMESH::SMESH_Mesh_ptr Filter_i::GetMesh() +{ + return SMESH_Mesh::_duplicate( myMesh ); +} + +//================================================================================ +/*! + * \brief Stores an object to be notified on change of predicate + */ +//================================================================================ + +void Filter_i::AddWaiter( TPredicateChangeWaiter* waiter ) +{ + if ( waiter ) + myWaiters.push_back( waiter ); +} + +//================================================================================ +/*! + * \brief Removes an object to be notified on change of predicate + */ +//================================================================================ + +void Filter_i::RemoveWaiter( TPredicateChangeWaiter* waiter ) +{ + myWaiters.remove( waiter ); +} + +//======================================================================= +// name : getCriteria +// Purpose : Retrieve criterions from predicate +//======================================================================= +static inline bool getCriteria( Predicate_i* thePred, + SMESH::Filter::Criteria_out theCriteria ) +{ + int aFType = thePred->GetFunctorType(); + + switch ( aFType ) + { + case FT_FreeBorders: + case FT_FreeEdges: + case FT_FreeFaces: + case FT_LinearOrQuadratic: + case FT_FreeNodes: + case FT_EqualEdges: + case FT_EqualFaces: + case FT_EqualVolumes: + case FT_BadOrientedVolume: + case FT_BareBorderVolume: + case FT_BareBorderFace: + case FT_OverConstrainedVolume: + case FT_OverConstrainedFace: + { + CORBA::ULong i = theCriteria->length(); + theCriteria->length( i + 1 ); + + theCriteria[ i ] = createCriterion(); + + theCriteria[ i ].Type = aFType; + theCriteria[ i ].TypeOfElement = thePred->GetElementType(); + return true; + } + case FT_BelongToGeom: + { + BelongToGeom_i* aPred = dynamic_cast( thePred ); + + CORBA::ULong i = theCriteria->length(); + theCriteria->length( i + 1 ); + + theCriteria[ i ] = createCriterion(); + + theCriteria[ i ].Type = FT_BelongToGeom; + theCriteria[ i ].ThresholdStr = aPred->GetShapeName(); + theCriteria[ i ].ThresholdID = aPred->GetShapeID(); + theCriteria[ i ].TypeOfElement = aPred->GetElementType(); + theCriteria[ i ].Tolerance = aPred->GetTolerance(); + + return true; + } + case FT_BelongToPlane: + case FT_BelongToCylinder: + case FT_BelongToGenSurface: + { + BelongToSurface_i* aPred = dynamic_cast( thePred ); + + CORBA::ULong i = theCriteria->length(); + theCriteria->length( i + 1 ); + + theCriteria[ i ] = createCriterion(); + + theCriteria[ i ].Type = aFType; + theCriteria[ i ].ThresholdStr = aPred->GetShapeName(); + theCriteria[ i ].ThresholdID = aPred->GetShapeID(); + theCriteria[ i ].TypeOfElement = aPred->GetElementType(); + theCriteria[ i ].Tolerance = aPred->GetTolerance(); + + return true; + } + case FT_LyingOnGeom: + { + LyingOnGeom_i* aPred = dynamic_cast( 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 ].ThresholdID = aPred->GetShapeID(); + theCriteria[ i ].TypeOfElement = aPred->GetElementType(); + theCriteria[ i ].Tolerance = aPred->GetTolerance(); + + return true; + } + case FT_CoplanarFaces: + { + CoplanarFaces_i* aPred = dynamic_cast( thePred ); + + CORBA::ULong i = theCriteria->length(); + theCriteria->length( i + 1 ); + + theCriteria[ i ] = createCriterion(); + CORBA::String_var faceId = aPred->GetFaceAsString(); + + theCriteria[ i ].Type = FT_CoplanarFaces; + theCriteria[ i ].ThresholdID = faceId; + theCriteria[ i ].Tolerance = aPred->GetTolerance(); + + return true; + } + case FT_EqualNodes: + { + EqualNodes_i* aPred = dynamic_cast( thePred ); + + CORBA::ULong i = theCriteria->length(); + theCriteria->length( i + 1 ); + + theCriteria[ i ] = createCriterion(); + + theCriteria[ i ].Type = FT_EqualNodes; + theCriteria[ i ].Tolerance = aPred->GetTolerance(); + + return true; + } + case FT_RangeOfIds: + { + RangeOfIds_i* aPred = dynamic_cast( thePred ); + + CORBA::ULong i = theCriteria->length(); + theCriteria->length( i + 1 ); + + theCriteria[ i ] = createCriterion(); + + theCriteria[ i ].Type = FT_RangeOfIds; + theCriteria[ i ].ThresholdStr = aPred->GetRangeStr(); + theCriteria[ i ].TypeOfElement = aPred->GetElementType(); + + return true; + } + case FT_LessThan: + case FT_MoreThan: + case FT_EqualTo: + { + Comparator_i* aCompar = dynamic_cast( thePred ); + + CORBA::ULong i = theCriteria->length(); + theCriteria->length( i + 1 ); + + theCriteria[ i ] = createCriterion(); + + theCriteria[ i ].Type = aCompar->GetNumFunctor_i()->GetFunctorType(); + theCriteria[ i ].Compare = aFType; + theCriteria[ i ].Threshold = aCompar->GetMargin(); + theCriteria[ i ].TypeOfElement = aCompar->GetElementType(); + + if ( aFType == FT_EqualTo ) + { + EqualTo_i* aCompar = dynamic_cast( thePred ); + theCriteria[ i ].Tolerance = aCompar->GetTolerance(); + } + } + return true; + + case FT_LogicalNOT: + { + Predicate_i* aPred = ( dynamic_cast( thePred ) )->GetPredicate_i(); + getCriteria( aPred, theCriteria ); + theCriteria[ theCriteria->length() - 1 ].UnaryOp = FT_LogicalNOT; + } + return true; + + case FT_LogicalAND: + case FT_LogicalOR: + { + Predicate_i* aPred1 = ( dynamic_cast( thePred ) )->GetPredicate1_i(); + Predicate_i* aPred2 = ( dynamic_cast( thePred ) )->GetPredicate2_i(); + if ( !getCriteria( aPred1, theCriteria ) ) + return false; + theCriteria[ theCriteria->length() - 1 ].BinaryOp = aFType; + return getCriteria( aPred2, theCriteria ); + } + case FT_GroupColor: + { + CORBA::ULong i = theCriteria->length(); + theCriteria->length( i + 1 ); + + theCriteria[ i ] = createCriterion(); + + GroupColor_i* aPred = dynamic_cast( thePred ); + theCriteria[ i ].Type = aFType; + theCriteria[ i ].TypeOfElement = aPred->GetElementType(); + theCriteria[ i ].ThresholdStr = aPred->GetColorStr(); + + return true; + } + case FT_ElemGeomType: + { + CORBA::ULong i = theCriteria->length(); + theCriteria->length( i + 1 ); + + theCriteria[ i ] = createCriterion(); + + ElemGeomType_i* aPred = dynamic_cast( thePred ); + theCriteria[ i ].Type = aFType; + theCriteria[ i ].TypeOfElement = aPred->GetElementType(); + theCriteria[ i ].Threshold = (double)aPred->GetGeometryType(); + return true; + } + case FT_EntityType: + { + CORBA::ULong i = theCriteria->length(); + theCriteria->length( i + 1 ); + + theCriteria[ i ] = createCriterion(); + + ElemEntityType_i* aPred = dynamic_cast( thePred ); + theCriteria[ i ].Type = aFType; + theCriteria[ i ].Threshold = (double)aPred->GetEntityType(); + return true; + } + + case FT_Undefined: + return false; + default: + return false; + } +} + +//======================================================================= +// name : Filter_i::GetCriteria +// Purpose : Retrieve criterions from predicate +//======================================================================= +CORBA::Boolean Filter_i::GetCriteria( SMESH::Filter::Criteria_out theCriteria ) +{ + theCriteria = new SMESH::Filter::Criteria; + return myPredicate != 0 ? getCriteria( myPredicate, theCriteria ) : true; +} + +//======================================================================= +// name : Filter_i::SetCriteria +// Purpose : Create new predicate and set criterions in it +//======================================================================= +CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria ) +{ + if ( myPredicate != 0 ) + myPredicate->UnRegister(); + + SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i(); + FilterManager_ptr aFilterMgr = aFilter->_this(); + + // CREATE two lists ( PREDICATES and LOG OP ) + + // Criterion + TPythonDump()<<"aCriteria = []"; + std::list aPredicates; + std::list aBinaries; + for ( int i = 0, n = theCriteria.length(); i < n; i++ ) + { + int aCriterion = theCriteria[ i ].Type; + int aCompare = theCriteria[ i ].Compare; + double aThreshold = theCriteria[ i ].Threshold; + const char* aThresholdStr = theCriteria[ i ].ThresholdStr; + const char* aThresholdID = theCriteria[ i ].ThresholdID; + int aUnary = theCriteria[ i ].UnaryOp; + int aBinary = theCriteria[ i ].BinaryOp; + double aTolerance = theCriteria[ i ].Tolerance; + ElementType aTypeOfElem = theCriteria[ i ].TypeOfElement; + long aPrecision = theCriteria[ i ].Precision; + + { + TPythonDump pd; + pd << "aCriterion = SMESH.Filter.Criterion(" + << aCriterion << ", " + << aCompare << ", " + << aThreshold << ", '" + << aThresholdStr << "', '"; + if (aThresholdID) pd << aThresholdID; + pd << "', " + << aUnary << ", " + << aBinary << ", " + << aTolerance << ", " + << aTypeOfElem << ", " + << aPrecision << ")"; + } + TPythonDump pd; + + SMESH::Predicate_ptr aPredicate = SMESH::Predicate::_nil(); + SMESH::NumericalFunctor_ptr aFunctor = SMESH::NumericalFunctor::_nil(); + + switch ( aCriterion ) + { + // Functors + + 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; + case SMESH::FT_MinimumAngle: + aFunctor = aFilterMgr->CreateMinimumAngle(); + break; + case SMESH::FT_Taper: + aFunctor = aFilterMgr->CreateTaper(); + break; + case SMESH::FT_Skew: + aFunctor = aFilterMgr->CreateSkew(); + break; + case SMESH::FT_Area: + aFunctor = aFilterMgr->CreateArea(); + break; + case SMESH::FT_Volume3D: + aFunctor = aFilterMgr->CreateVolume3D(); + break; + case SMESH::FT_MaxElementLength2D: + aFunctor = aFilterMgr->CreateMaxElementLength2D(); + break; + case SMESH::FT_MaxElementLength3D: + aFunctor = aFilterMgr->CreateMaxElementLength3D(); + break; + case SMESH::FT_BallDiameter: + aFunctor = aFilterMgr->CreateBallDiameter(); + break; + + // Predicates + + case SMESH::FT_FreeBorders: + aPredicate = aFilterMgr->CreateFreeBorders(); + break; + case SMESH::FT_FreeEdges: + aPredicate = aFilterMgr->CreateFreeEdges(); + break; + case SMESH::FT_FreeFaces: + aPredicate = aFilterMgr->CreateFreeFaces(); + break; + case SMESH::FT_FreeNodes: + aPredicate = aFilterMgr->CreateFreeNodes(); + break; + case SMESH::FT_EqualNodes: + { + SMESH::EqualNodes_ptr pred = aFilterMgr->CreateEqualNodes(); + pred->SetTolerance( aTolerance ); + aPredicate = pred; + break; + } + case SMESH::FT_EqualEdges: + aPredicate = aFilterMgr->CreateEqualEdges(); + break; + case SMESH::FT_EqualFaces: + aPredicate = aFilterMgr->CreateEqualFaces(); + break; + case SMESH::FT_EqualVolumes: + aPredicate = aFilterMgr->CreateEqualVolumes(); + break; + case SMESH::FT_BelongToGeom: + { + SMESH::BelongToGeom_ptr tmpPred = aFilterMgr->CreateBelongToGeom(); + tmpPred->SetElementType( aTypeOfElem ); + tmpPred->SetShape( aThresholdID, aThresholdStr ); + tmpPred->SetTolerance( aTolerance ); + aPredicate = tmpPred; + } + break; + case SMESH::FT_BelongToPlane: + case SMESH::FT_BelongToCylinder: + case SMESH::FT_BelongToGenSurface: + { + SMESH::BelongToSurface_ptr tmpPred; + switch ( aCriterion ) { + case SMESH::FT_BelongToPlane: + tmpPred = aFilterMgr->CreateBelongToPlane(); break; + case SMESH::FT_BelongToCylinder: + tmpPred = aFilterMgr->CreateBelongToCylinder(); break; + default: + tmpPred = aFilterMgr->CreateBelongToGenSurface(); + } + tmpPred->SetShape( aThresholdID, aThresholdStr, aTypeOfElem ); + tmpPred->SetTolerance( aTolerance ); + aPredicate = tmpPred; + } + break; + case SMESH::FT_LyingOnGeom: + { + SMESH::LyingOnGeom_ptr tmpPred = aFilterMgr->CreateLyingOnGeom(); + tmpPred->SetElementType( aTypeOfElem ); + tmpPred->SetShape( aThresholdID, aThresholdStr ); + tmpPred->SetTolerance( aTolerance ); + aPredicate = tmpPred; + } + break; + case SMESH::FT_RangeOfIds: + { + SMESH::RangeOfIds_ptr tmpPred = aFilterMgr->CreateRangeOfIds(); + tmpPred->SetRangeStr( aThresholdStr ); + tmpPred->SetElementType( aTypeOfElem ); + aPredicate = tmpPred; + } + break; + case SMESH::FT_BadOrientedVolume: + { + aPredicate = aFilterMgr->CreateBadOrientedVolume(); + } + break; + case SMESH::FT_BareBorderVolume: + { + aPredicate = aFilterMgr->CreateBareBorderVolume(); + } + break; + case SMESH::FT_BareBorderFace: + { + aPredicate = aFilterMgr->CreateBareBorderFace(); + } + break; + case SMESH::FT_OverConstrainedVolume: + { + aPredicate = aFilterMgr->CreateOverConstrainedVolume(); + } + break; + case SMESH::FT_OverConstrainedFace: + { + aPredicate = aFilterMgr->CreateOverConstrainedFace(); + } + break; + case SMESH::FT_LinearOrQuadratic: + { + SMESH::LinearOrQuadratic_ptr tmpPred = aFilterMgr->CreateLinearOrQuadratic(); + tmpPred->SetElementType( aTypeOfElem ); + aPredicate = tmpPred; + break; + } + case SMESH::FT_GroupColor: + { + SMESH::GroupColor_ptr tmpPred = aFilterMgr->CreateGroupColor(); + tmpPred->SetElementType( aTypeOfElem ); + tmpPred->SetColorStr( aThresholdStr ); + aPredicate = tmpPred; + break; + } + case SMESH::FT_ElemGeomType: + { + SMESH::ElemGeomType_ptr tmpPred = aFilterMgr->CreateElemGeomType(); + tmpPred->SetElementType( aTypeOfElem ); + tmpPred->SetGeometryType( (GeometryType)(int)(aThreshold + 0.5) ); + aPredicate = tmpPred; + break; + } + case SMESH::FT_EntityType: + { + SMESH::ElemEntityType_ptr tmpPred = aFilterMgr->CreateElemEntityType(); + tmpPred->SetElementType( aTypeOfElem ); + tmpPred->SetEntityType( EntityType( (int (aThreshold + 0.5)))); + aPredicate = tmpPred; + break; + } + case SMESH::FT_CoplanarFaces: + { + SMESH::CoplanarFaces_ptr tmpPred = aFilterMgr->CreateCoplanarFaces(); + tmpPred->SetFace( atol (aThresholdID )); + tmpPred->SetTolerance( aTolerance ); + aPredicate = tmpPred; + break; + } + + default: + continue; + } + + // Comparator + if ( !aFunctor->_is_nil() && aPredicate->_is_nil() ) + { + SMESH::Comparator_ptr aComparator = SMESH::Comparator::_nil(); + + if ( aCompare == SMESH::FT_LessThan ) + aComparator = aFilterMgr->CreateLessThan(); + else if ( aCompare == SMESH::FT_MoreThan ) + aComparator = aFilterMgr->CreateMoreThan(); + else if ( aCompare == SMESH::FT_EqualTo ) + aComparator = aFilterMgr->CreateEqualTo(); + else + continue; + + aComparator->SetNumFunctor( aFunctor ); + aComparator->SetMargin( aThreshold ); + + if ( aCompare == FT_EqualTo ) + { + SMESH::EqualTo_var anEqualTo = SMESH::EqualTo::_narrow( aComparator ); + anEqualTo->SetTolerance( aTolerance ); + } + + aPredicate = aComparator; + + aFunctor->SetPrecision( aPrecision ); + } + + // Logical not + if ( aUnary == FT_LogicalNOT ) + { + SMESH::LogicalNOT_ptr aNotPred = aFilterMgr->CreateLogicalNOT(); + aNotPred->SetPredicate( aPredicate ); + aPredicate = aNotPred; + } + + // logical op + aPredicates.push_back( aPredicate ); + aBinaries.push_back( aBinary ); + pd <<"aCriteria.append(aCriterion)"; + + } // end of for + TPythonDump pd; pd< aResList; + + std::list::iterator aPredIter; + std::list::iterator aBinaryIter; + + SMESH::Predicate_ptr aPrevPredicate = SMESH::Predicate::_nil(); + int aPrevBinary = SMESH::FT_Undefined; + + for ( aPredIter = aPredicates.begin(), aBinaryIter = aBinaries.begin(); + aPredIter != aPredicates.end() && aBinaryIter != aBinaries.end(); + ++aPredIter, ++aBinaryIter ) + { + int aCurrBinary = *aBinaryIter; + + SMESH::Predicate_ptr aCurrPred = SMESH::Predicate::_nil(); + + if ( aPrevBinary == SMESH::FT_LogicalAND ) + { + + SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalAND(); + aBinaryPred->SetPredicate1( aPrevPredicate ); + aBinaryPred->SetPredicate2( *aPredIter ); + aCurrPred = aBinaryPred; + } + else + aCurrPred = *aPredIter; + + if ( aCurrBinary != SMESH::FT_LogicalAND ) + aResList.push_back( aCurrPred ); + + aPrevPredicate = aCurrPred; + aPrevBinary = aCurrBinary; + } + + // combine all "OR" operations + + SMESH::Predicate_ptr aResPredicate = SMESH::Predicate::_nil(); + + if ( aResList.size() == 1 ) + aResPredicate = *aResList.begin(); + else if ( aResList.size() > 1 ) + { + std::list::iterator anIter = aResList.begin(); + aResPredicate = *anIter; + anIter++; + for ( ; anIter != aResList.end(); ++anIter ) + { + SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalOR(); + aBinaryPred->SetPredicate1( aResPredicate ); + aBinaryPred->SetPredicate2( *anIter ); + aResPredicate = aBinaryPred; + } + } + + SetPredicate( aResPredicate ); + + return !aResPredicate->_is_nil(); +} + +//======================================================================= +// name : Filter_i::GetPredicate_i +// Purpose : Get implementation of predicate +//======================================================================= +Predicate_i* Filter_i::GetPredicate_i() +{ + return myPredicate; +} + +//======================================================================= +// name : Filter_i::GetPredicate +// Purpose : Get predicate +//======================================================================= +Predicate_ptr Filter_i::GetPredicate() +{ + if ( myPredicate == 0 ) + return SMESH::Predicate::_nil(); + else + { + SMESH::Predicate_var anObj = myPredicate->_this(); + // if ( SMESH::Functor_i* fun = SMESH::DownCast( anObj )) + // TPythonDump() << fun << " = " << this << ".GetPredicate()"; + return anObj._retn(); + } +} + +/* + FILTER LIBRARY +*/ + +#define ATTR_TYPE "type" +#define ATTR_COMPARE "compare" +#define ATTR_THRESHOLD "threshold" +#define ATTR_UNARY "unary" +#define ATTR_BINARY "binary" +#define ATTR_THRESHOLD_STR "threshold_str" +#define ATTR_TOLERANCE "tolerance" +#define ATTR_ELEMENT_TYPE "ElementType" + +//======================================================================= +// name : toString +// Purpose : Convert bool to LDOMString +//======================================================================= +static inline LDOMString toString( CORBA::Boolean val ) +{ + return val ? "logical not" : ""; +} + +//======================================================================= +// name : toBool +// Purpose : Convert LDOMString to bool +//======================================================================= +static inline bool toBool( const LDOMString& theStr ) +{ + return theStr.equals( "logical not" ); +} + +//======================================================================= +// name : toString +// Purpose : Convert double to LDOMString +//======================================================================= +static inline LDOMString toString( CORBA::Double val ) +{ + char a[ 255 ]; + sprintf( a, "%e", val ); + return LDOMString( a ); +} + +//======================================================================= +// name : toDouble +// Purpose : Convert LDOMString to double +//======================================================================= +static inline double toDouble( const LDOMString& theStr ) +{ + return atof( theStr.GetString() ); +} + +//======================================================================= +// name : toString +// Purpose : Convert functor type to LDOMString +//======================================================================= +static inline LDOMString toString( CORBA::Long theType ) +{ + switch ( theType ) + { + case FT_AspectRatio : return "Aspect ratio"; + case FT_Warping : return "Warping"; + case FT_MinimumAngle : return "Minimum angle"; + case FT_Taper : return "Taper"; + case FT_Skew : return "Skew"; + case FT_Area : return "Area"; + case FT_Volume3D : return "Volume3D"; + case FT_MaxElementLength2D: return "Max element length 2D"; + case FT_MaxElementLength3D: return "Max element length 3D"; + case FT_BelongToGeom : return "Belong to Geom"; + case FT_BelongToPlane : return "Belong to Plane"; + case FT_BelongToCylinder: return "Belong to Cylinder"; + case FT_BelongToGenSurface: return "Belong to Generic Surface"; + case FT_LyingOnGeom : return "Lying on Geom"; + case FT_BadOrientedVolume:return "Bad Oriented Volume"; + case FT_BareBorderVolume: return "Volumes with bare border"; + case FT_BareBorderFace : return "Faces with bare border"; + case FT_OverConstrainedVolume: return "Over-constrained Volumes"; + case FT_OverConstrainedFace : return "Over-constrained Faces"; + case FT_RangeOfIds : return "Range of IDs"; + case FT_FreeBorders : return "Free borders"; + case FT_FreeEdges : return "Free edges"; + case FT_FreeFaces : return "Free faces"; + case FT_FreeNodes : return "Free nodes"; + case FT_EqualNodes : return "Equal nodes"; + case FT_EqualEdges : return "Equal edges"; + case FT_EqualFaces : return "Equal faces"; + case FT_EqualVolumes : return "Equal volumes"; + 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 "Length 2D"; + case FT_LessThan : return "Less than"; + case FT_MoreThan : return "More than"; + case FT_EqualTo : return "Equal to"; + case FT_LogicalNOT : return "Not"; + case FT_LogicalAND : return "And"; + case FT_LogicalOR : return "Or"; + case FT_GroupColor : return "Color of Group"; + case FT_LinearOrQuadratic : return "Linear or Quadratic"; + case FT_ElemGeomType : return "Element geomtry type"; + case FT_EntityType : return "Entity type"; + case FT_Undefined : return ""; + default : return ""; + } +} + +//======================================================================= +// name : toFunctorType +// Purpose : Convert LDOMString to functor type +//======================================================================= +static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr ) +{ + if ( theStr.equals( "Aspect ratio" ) ) return FT_AspectRatio; + else if ( theStr.equals( "Warping" ) ) return FT_Warping; + else if ( theStr.equals( "Minimum angle" ) ) return FT_MinimumAngle; + else if ( theStr.equals( "Taper" ) ) return FT_Taper; + else if ( theStr.equals( "Skew" ) ) return FT_Skew; + else if ( theStr.equals( "Area" ) ) return FT_Area; + else if ( theStr.equals( "Volume3D" ) ) return FT_Volume3D; + else if ( theStr.equals( "Max element length 2D" ) ) return FT_MaxElementLength2D; + else if ( theStr.equals( "Max element length 3D" ) ) return FT_MaxElementLength3D; + 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( "Belong to Generic Surface" ) ) return FT_BelongToGenSurface; + 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( "Free faces" ) ) return FT_FreeFaces; + else if ( theStr.equals( "Free nodes" ) ) return FT_FreeNodes; + else if ( theStr.equals( "Equal nodes" ) ) return FT_EqualNodes; + else if ( theStr.equals( "Equal edges" ) ) return FT_EqualEdges; + else if ( theStr.equals( "Equal faces" ) ) return FT_EqualFaces; + else if ( theStr.equals( "Equal volumes" ) ) return FT_EqualVolumes; + 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( "Bad Oriented Volume" ) ) return FT_BadOrientedVolume; + else if ( theStr.equals( "Volumes with bare border" ) ) return FT_BareBorderVolume; + else if ( theStr.equals( "Faces with bare border" ) ) return FT_BareBorderFace; + else if ( theStr.equals( "Over-constrained Volumes" ) ) return FT_OverConstrainedVolume; + else if ( theStr.equals( "Over-constrained Faces" ) ) return FT_OverConstrainedFace; + else if ( theStr.equals( "Less than" ) ) return FT_LessThan; + else if ( theStr.equals( "More than" ) ) return FT_MoreThan; + else if ( theStr.equals( "Equal to" ) ) return FT_EqualTo; + else if ( theStr.equals( "Not" ) ) return FT_LogicalNOT; + else if ( theStr.equals( "And" ) ) return FT_LogicalAND; + else if ( theStr.equals( "Or" ) ) return FT_LogicalOR; + else if ( theStr.equals( "Color of Group" ) ) return FT_GroupColor; + else if ( theStr.equals( "Linear or Quadratic" ) ) return FT_LinearOrQuadratic; + else if ( theStr.equals( "Element geomtry type" ) ) return FT_ElemGeomType; + else if ( theStr.equals( "Entity type" ) ) return FT_EntityType; + else if ( theStr.equals( "" ) ) return FT_Undefined; + else return FT_Undefined; +} + +//======================================================================= +// name : toFunctorType +// Purpose : Convert LDOMString to value of ElementType enumeration +//======================================================================= +static inline SMESH::ElementType toElementType( const LDOMString& theStr ) +{ + if ( theStr.equals( "NODE" ) ) return SMESH::NODE; + else if ( theStr.equals( "EDGE" ) ) return SMESH::EDGE; + else if ( theStr.equals( "FACE" ) ) return SMESH::FACE; + else if ( theStr.equals( "VOLUME" ) ) return SMESH::VOLUME; + else return SMESH::ALL; +} + +//======================================================================= +// name : toString +// Purpose : Convert ElementType to string +//======================================================================= +static inline LDOMString toString( const SMESH::ElementType theType ) +{ + switch ( theType ) + { + case SMESH::NODE : return "NODE"; + case SMESH::EDGE : return "EDGE"; + case SMESH::FACE : return "FACE"; + case SMESH::VOLUME : return "VOLUME"; + case SMESH::ALL : return "ALL"; + default : return ""; + } +} + +//======================================================================= +// name : findFilter +// Purpose : Find filter in document +//======================================================================= +static LDOM_Element findFilter( const char* theFilterName, + const LDOM_Document& theDoc, + LDOM_Node* theParent = 0 ) +{ + LDOM_Element aRootElement = theDoc.getDocumentElement(); + if ( aRootElement.isNull() || !aRootElement.hasChildNodes() ) + return LDOM_Element(); + + for ( LDOM_Node aTypeNode = aRootElement.getFirstChild(); + !aTypeNode.isNull(); aTypeNode = aTypeNode.getNextSibling() ) + { + for ( LDOM_Node aFilter = aTypeNode.getFirstChild(); + !aFilter.isNull(); aFilter = aFilter.getNextSibling() ) + { + LDOM_Element* anElem = ( LDOM_Element* )&aFilter; + if ( anElem->getTagName().equals( LDOMString( "filter" ) ) && + anElem->getAttribute( "name" ).equals( LDOMString( theFilterName ) ) ) + { + if ( theParent != 0 ) + *theParent = aTypeNode; + return (LDOM_Element&)aFilter; + } + } + } + return LDOM_Element(); +} + +//======================================================================= +// name : getSectionName +// Purpose : Get name of section of filters +//======================================================================= +static const char* getSectionName( const ElementType theType ) +{ + switch ( theType ) + { + case SMESH::NODE : return "Filters for nodes"; + case SMESH::EDGE : return "Filters for edges"; + case SMESH::FACE : return "Filters for faces"; + case SMESH::VOLUME : return "Filters for volumes"; + case SMESH::ALL : return "Filters for elements"; + default : return ""; + } +} + +//======================================================================= +// name : getSection +// Purpose : Create section for filters corresponding to the entity type +//======================================================================= +static LDOM_Node getSection( const ElementType theType, + LDOM_Document& theDoc, + const bool toCreate = false ) +{ + LDOM_Element aRootElement = theDoc.getDocumentElement(); + if ( aRootElement.isNull() ) + return LDOM_Node(); + + // Find section + bool anExist = false; + const char* aSectionName = getSectionName( theType ); + if ( strcmp( aSectionName, "" ) == 0 ) + return LDOM_Node(); + + LDOM_NodeList aSections = theDoc.getElementsByTagName( "section" ); + LDOM_Node aNode; + for ( int i = 0, n = aSections.getLength(); i < n; i++ ) + { + aNode = aSections.item( i ); + LDOM_Element& anItem = ( LDOM_Element& )aNode; + if ( anItem.getAttribute( "name" ).equals( LDOMString( aSectionName ) ) ) + { + anExist = true; + break; + } + } + + // Create new section if necessary + if ( !anExist ) + { + if ( toCreate ) + { + LDOM_Element aNewItem = theDoc.createElement( "section" ); + aNewItem.setAttribute( "name", aSectionName ); + aRootElement.appendChild( aNewItem ); + return aNewItem; + } + else + return LDOM_Node(); + } + return + aNode; +} + +//======================================================================= +// name : createFilterItem +// Purpose : Create filter item or LDOM document +//======================================================================= +static LDOM_Element createFilterItem( const char* theName, + SMESH::Filter_ptr theFilter, + LDOM_Document& theDoc ) +{ + // create new filter in document + LDOM_Element aFilterItem = theDoc.createElement( "filter" ); + aFilterItem.setAttribute( "name", theName ); + + // save filter criterions + SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria; + + if ( !theFilter->GetCriteria( aCriteria ) ) + return LDOM_Element(); + + for ( CORBA::ULong i = 0, n = aCriteria->length(); i < n; i++ ) + { + LDOM_Element aCriterionItem = theDoc.createElement( "criterion" ); + + aCriterionItem.setAttribute( ATTR_TYPE , toString( aCriteria[ i ].Type) ); + aCriterionItem.setAttribute( ATTR_COMPARE , toString( aCriteria[ i ].Compare ) ); + aCriterionItem.setAttribute( ATTR_THRESHOLD , toString( aCriteria[ i ].Threshold ) ); + aCriterionItem.setAttribute( ATTR_UNARY , toString( aCriteria[ i ].UnaryOp ) ); + aCriterionItem.setAttribute( ATTR_BINARY , toString( aCriteria[ i ].BinaryOp ) ); + + aCriterionItem.setAttribute( ATTR_THRESHOLD_STR, (const char*)aCriteria[ i ].ThresholdStr ); + aCriterionItem.setAttribute( ATTR_TOLERANCE , toString( aCriteria[ i ].Tolerance ) ); + aCriterionItem.setAttribute( ATTR_ELEMENT_TYPE , + toString( (SMESH::ElementType)aCriteria[ i ].TypeOfElement ) ); + + aFilterItem.appendChild( aCriterionItem ); + } + + return aFilterItem; +} + +//======================================================================= +// name : FilterLibrary_i::FilterLibrary_i +// Purpose : Constructor +//======================================================================= +FilterLibrary_i::FilterLibrary_i( const char* theFileName ) +{ + myFileName = strdup( theFileName ); + SMESH::FilterManager_i* aFilterMgr = new SMESH::FilterManager_i(); + myFilterMgr = aFilterMgr->_this(); + + LDOMParser aParser; + + // Try to use existing library file + bool anExists = false; + if ( !aParser.parse( myFileName ) ) + { + myDoc = aParser.getDocument(); + anExists = true; + } + // Create a new XML document if it doesn't exist + else + myDoc = LDOM_Document::createDocument( LDOMString() ); + + LDOM_Element aRootElement = myDoc.getDocumentElement(); + if ( aRootElement.isNull() ) + { + // If the existing document is empty --> try to create a new one + if ( anExists ) + myDoc = LDOM_Document::createDocument( LDOMString() ); + } +} + +//======================================================================= +// name : FilterLibrary_i::FilterLibrary_i +// Purpose : Constructor +//======================================================================= +FilterLibrary_i::FilterLibrary_i() +{ + myFileName = 0; + SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i(); + myFilterMgr = aFilter->_this(); + + myDoc = LDOM_Document::createDocument( LDOMString() ); +} + +FilterLibrary_i::~FilterLibrary_i() +{ + delete myFileName; + //TPythonDump()< aCriteria; + + for ( LDOM_Node aCritNode = aFilter.getFirstChild(); + !aCritNode.isNull() ; aCritNode = aCritNode.getNextSibling() ) + { + LDOM_Element* aCrit = (LDOM_Element*)&aCritNode; + + const char* aTypeStr = aCrit->getAttribute( ATTR_TYPE ).GetString(); + const char* aCompareStr = aCrit->getAttribute( ATTR_COMPARE ).GetString(); + const char* aUnaryStr = aCrit->getAttribute( ATTR_UNARY ).GetString(); + const char* aBinaryStr = aCrit->getAttribute( ATTR_BINARY ).GetString(); + const char* anElemTypeStr = aCrit->getAttribute( ATTR_ELEMENT_TYPE ).GetString(); + + SMESH::Filter::Criterion aCriterion = createCriterion(); + + aCriterion.Type = toFunctorType( aTypeStr ); + aCriterion.Compare = toFunctorType( aCompareStr ); + aCriterion.UnaryOp = toFunctorType( aUnaryStr ); + aCriterion.BinaryOp = toFunctorType( aBinaryStr ); + + aCriterion.TypeOfElement = toElementType( anElemTypeStr ); + + LDOMString str = aCrit->getAttribute( ATTR_THRESHOLD ); + int val = 0; + aCriterion.Threshold = str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val ) + ? val : atof( str.GetString() ); + + str = aCrit->getAttribute( ATTR_TOLERANCE ); + aCriterion.Tolerance = str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val ) + ? val : atof( str.GetString() ); + + str = aCrit->getAttribute( ATTR_THRESHOLD_STR ); + if ( str.Type() == LDOMBasicString::LDOM_Integer && str.GetInteger( val ) ) + { + char a[ 255 ]; + sprintf( a, "%d", val ); + aCriterion.ThresholdStr = strdup( a ); + } + else + aCriterion.ThresholdStr = str.GetString(); + + aCriteria.push_back( aCriterion ); + } + + SMESH::Filter::Criteria_var aCriteriaVar = new SMESH::Filter::Criteria; + aCriteriaVar->length( aCriteria.size() ); + + CORBA::ULong i = 0; + std::list::iterator anIter = aCriteria.begin(); + + for( ; anIter != aCriteria.end(); ++anIter ) + aCriteriaVar[ i++ ] = *anIter; + + aRes = myFilterMgr->CreateFilter(); + aRes->SetCriteria( aCriteriaVar.inout() ); + + TPythonDump()<_is_nil() ) + return false; + + // get section corresponding to the filter type + ElementType anEntType = theFilter->GetElementType(); + + LDOM_Node aSection = getSection( anEntType, myDoc, true ); + if ( aSection.isNull() ) + return false; + + // create filter item + LDOM_Element aFilterItem = createFilterItem( theFilterName, theFilter, myDoc ); + if ( aFilterItem.isNull() ) + return false; + else + { + aSection.appendChild( aFilterItem ); + if(Filter_i* aFilter = DownCast(theFilter)) + TPythonDump()<CreateFilter(); + + LDOM_Element aFilterItem = createFilterItem( theFilterName, aFilter, myDoc ); + if ( aFilterItem.isNull() ) + return false; + else + { + aSection.appendChild( aFilterItem ); + TPythonDump()<_is_nil() ) + return false; + + LDOM_Element aNewItem = createFilterItem( theNewName, theFilter, myDoc ); + if ( aNewItem.isNull() ) + return false; + else + { + aFilterItem.ReplaceElement( aNewItem ); + if(Filter_i* aFilter = DownCast(theFilter)) + TPythonDump()<length(); +} + +//======================================================================= +// name : FilterLibrary_i::GetNames +// Purpose : Get names of filters from library +//======================================================================= +string_array* FilterLibrary_i::GetNames( ElementType theType ) +{ + string_array_var anArray = new string_array; + TColStd_SequenceOfHAsciiString aSeq; + + LDOM_Node aSection = getSection( theType, myDoc, false ); + + if ( !aSection.isNull() ) + { + for ( LDOM_Node aFilter = aSection.getFirstChild(); + !aFilter.isNull(); aFilter = aFilter.getNextSibling() ) + { + LDOM_Element& anElem = ( LDOM_Element& )aFilter; + aSeq.Append( new TCollection_HAsciiString( + (Standard_CString)anElem.getAttribute( "name" ).GetString() ) ); + } + } + + anArray->length( aSeq.Length() ); + for ( int i = 1, n = aSeq.Length(); i <= n; i++ ) + anArray[ i - 1 ] = CORBA::string_dup( aSeq( i )->ToCString() ); + + return anArray._retn(); +} + +//======================================================================= +// name : FilterLibrary_i::GetAllNames +// Purpose : Get names of filters from library +//======================================================================= +string_array* FilterLibrary_i::GetAllNames() +{ + string_array_var aResArray = new string_array; + for ( int type = SMESH::ALL; type <= SMESH::VOLUME; type++ ) + { + SMESH::string_array_var aNames = GetNames( (SMESH::ElementType)type ); + + int aPrevLength = aResArray->length(); + aResArray->length( aPrevLength + aNames->length() ); + for ( int i = 0, n = aNames->length(); i < n; i++ ) + aResArray[ aPrevLength + i ] = aNames[ i ]; + } + + return aResArray._retn(); +} + +//================================================================================ +/*! + * \brief Return an array of strings corresponding to items of enum FunctorType + */ +//================================================================================ + +static const char** getFunctNames() +{ + static const char* functName[ SMESH::FT_Undefined + 1 ] = { + // IT's necessary to update this array according to enum FunctorType (SMESH_Filter.idl) + // The order is IMPORTANT !!! + "FT_AspectRatio", + "FT_AspectRatio3D", + "FT_Warping", + "FT_MinimumAngle", + "FT_Taper", + "FT_Skew", + "FT_Area", + "FT_Volume3D", + "FT_MaxElementLength2D", + "FT_MaxElementLength3D", + "FT_FreeBorders", + "FT_FreeEdges", + "FT_FreeNodes", + "FT_FreeFaces", + "FT_EqualNodes", + "FT_EqualEdges", + "FT_EqualFaces", + "FT_EqualVolumes", + "FT_MultiConnection", + "FT_MultiConnection2D", + "FT_Length", + "FT_Length2D", + "FT_BelongToGeom", + "FT_BelongToPlane", + "FT_BelongToCylinder", + "FT_BelongToGenSurface", + "FT_LyingOnGeom", + "FT_RangeOfIds", + "FT_BadOrientedVolume", + "FT_BareBorderVolume", + "FT_BareBorderFace", + "FT_OverConstrainedVolume", + "FT_OverConstrainedFace", + "FT_LinearOrQuadratic", + "FT_GroupColor", + "FT_ElemGeomType", + "FT_EntityType", + "FT_CoplanarFaces", + "FT_BallDiameter", + "FT_LessThan", + "FT_MoreThan", + "FT_EqualTo", + "FT_LogicalNOT", + "FT_LogicalAND", + "FT_LogicalOR", + "FT_Undefined"}; + return functName; +} + +//================================================================================ +/*! + * \brief Return a string corresponding to an item of enum FunctorType + */ +//================================================================================ + +const char* SMESH::FunctorTypeToString(SMESH::FunctorType ft) +{ + if ( ft < 0 || ft > SMESH::FT_Undefined ) + return "FT_Undefined"; + return getFunctNames()[ ft ]; +} + +//================================================================================ +/*! + * \brief Converts a string to FunctorType. This is reverse of FunctorTypeToString() + */ +//================================================================================ + +SMESH::FunctorType SMESH::StringToFunctorType(const char* str) +{ + std::string name( str + 3 ); // skip "FT_" + const char** functNames = getFunctNames(); + int ft = 0; + for ( ; ft < SMESH::FT_Undefined; ++ft ) + if ( name == ( functNames[ft] + 3 )) + break; + + //ASSERT( strcmp( str, FunctorTypeToString( SMESH::FunctorType( ft ))) == 0 ); + + return SMESH::FunctorType( ft ); }