From: vsv Date: Wed, 15 Jun 2022 14:48:49 +0000 (+0300) Subject: bos #29469: Advanced geometry features: Detect type of shape X-Git-Tag: V9_10_0a1~2^2 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;ds=sidebyside;h=bb74bfbe1eb20b371dd4d310ee2292ccfa7cc454;p=modules%2Fgeom.git bos #29469: Advanced geometry features: Detect type of shape --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 9fd233644..21b0c03ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -204,7 +204,8 @@ SALOME_ACCUMULATE_ENVIRONMENT(LD_LIBRARY_PATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${ # =============== SET(GEOM_TEST_DIR ${SALOME_INSTALL_SCRIPT_SCRIPTS}/test) IF(SALOME_BUILD_TESTS) - INSTALL(FILES CTestTestfileInstall.cmake + CONFIGURE_FILE(CTestTestfileInstall.cmake.in CTestTestfileInstall.cmake @ONLY) + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/CTestTestfileInstall.cmake DESTINATION ${GEOM_TEST_DIR} RENAME CTestTestfile.cmake) ENDIF() diff --git a/CTestTestfileInstall.cmake b/CTestTestfileInstall.cmake deleted file mode 100644 index cba60b0ca..000000000 --- a/CTestTestfileInstall.cmake +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (C) 2017-2022 CEA/DEN, EDF R&D, OPEN CASCADE -# -# 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, or (at your option) any later version. -# -# 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 -# - -SET(PYTHON_TEST_DRIVER "$ENV{KERNEL_ROOT_DIR}/bin/salome/appliskel/python_test_driver.py") -SET(COMPONENT_NAME GEOM) -SET(TIMEOUT 300) - -SUBDIRS(examples xao other) diff --git a/CTestTestfileInstall.cmake.in b/CTestTestfileInstall.cmake.in new file mode 100644 index 000000000..c47c8b151 --- /dev/null +++ b/CTestTestfileInstall.cmake.in @@ -0,0 +1,27 @@ +# Copyright (C) 2017-2022 CEA/DEN, EDF R&D, OPEN CASCADE +# +# 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, or (at your option) any later version. +# +# 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 +# + +SET(OpenCASCADE_VERSION @OpenCASCADE_VERSION@) +SET(OpenCASCADE_SP_VERSION @OpenCASCADE_SP_VERSION@) + +SET(PYTHON_TEST_DRIVER "$ENV{KERNEL_ROOT_DIR}/bin/salome/appliskel/python_test_driver.py") +SET(COMPONENT_NAME GEOM) +SET(TIMEOUT 300) + +SUBDIRS(examples xao other) diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 98b0086b9..7423266a4 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -4937,6 +4937,48 @@ module GEOM in boolean isRelative, in double angularDeflection); }; + // # GEOM_ICanonicalRecognition: + /*! + * \brief Interface for canonical recognition operations. + */ + interface GEOM_ICanonicalRecognition : GEOM_IOperations + { + /*! + * check if the shape is planar + */ + boolean isPlane(in GEOM_Object shape, in double tolerance, inout ListOfDouble normal, inout ListOfDouble origin); + + /*! + * check if shape is spherical + */ + boolean isSphere(in GEOM_Object shape, in double tolerance, inout ListOfDouble origin, inout double radius); + + /*! + * check if shape is conical + */ + boolean isCone(in GEOM_Object shape, in double tolerance, inout ListOfDouble axis, inout ListOfDouble apex, inout double halfAngle); + + /*! + * check if shape is cylinder + */ + boolean isCylinder(in GEOM_Object shape, in double tolerance, inout ListOfDouble axis, inout ListOfDouble origin, inout double radius); + + /*! + * check if edge / wire is line + */ + boolean isLine(in GEOM_Object edge, in double tolerance, inout ListOfDouble direction, inout ListOfDouble origin); + + /*! + * check if edge / wire is circle + */ + boolean isCircle(in GEOM_Object edge, in double tolerance, inout ListOfDouble normal, inout ListOfDouble origin, inout double radius); + + /*! + * check if edge / wire is ellipse + */ + boolean isEllipse(in GEOM_Object edge, in double tolerance, inout ListOfDouble normal, inout ListOfDouble dirX, inout ListOfDouble origin, inout double majorRadius, inout double minorRadius); + }; + // # GEOM_Gen: /*! * \brief Interface to access other GEOM interfaces. @@ -5050,20 +5092,21 @@ module GEOM // # Methods to access interfaces for objects creation and transformation - GEOM_IBasicOperations GetIBasicOperations () raises (SALOME::SALOME_Exception); - GEOM_ITransformOperations GetITransformOperations() raises (SALOME::SALOME_Exception); - GEOM_I3DPrimOperations GetI3DPrimOperations () raises (SALOME::SALOME_Exception); - GEOM_IShapesOperations GetIShapesOperations () raises (SALOME::SALOME_Exception); - GEOM_IBooleanOperations GetIBooleanOperations () raises (SALOME::SALOME_Exception); - GEOM_ICurvesOperations GetICurvesOperations () raises (SALOME::SALOME_Exception); - GEOM_ILocalOperations GetILocalOperations () raises (SALOME::SALOME_Exception); - GEOM_IHealingOperations GetIHealingOperations () raises (SALOME::SALOME_Exception); - GEOM_IInsertOperations GetIInsertOperations () raises (SALOME::SALOME_Exception); - GEOM_IMeasureOperations GetIMeasureOperations () raises (SALOME::SALOME_Exception); - GEOM_IBlocksOperations GetIBlocksOperations () raises (SALOME::SALOME_Exception); - GEOM_IGroupOperations GetIGroupOperations () raises (SALOME::SALOME_Exception); - GEOM_IFieldOperations GetIFieldOperations () raises (SALOME::SALOME_Exception); - GEOM_ITestOperations GetITestOperations () raises (SALOME::SALOME_Exception); + GEOM_IBasicOperations GetIBasicOperations () raises (SALOME::SALOME_Exception); + GEOM_ITransformOperations GetITransformOperations () raises (SALOME::SALOME_Exception); + GEOM_I3DPrimOperations GetI3DPrimOperations () raises (SALOME::SALOME_Exception); + GEOM_IShapesOperations GetIShapesOperations () raises (SALOME::SALOME_Exception); + GEOM_IBooleanOperations GetIBooleanOperations () raises (SALOME::SALOME_Exception); + GEOM_ICurvesOperations GetICurvesOperations () raises (SALOME::SALOME_Exception); + GEOM_ILocalOperations GetILocalOperations () raises (SALOME::SALOME_Exception); + GEOM_IHealingOperations GetIHealingOperations () raises (SALOME::SALOME_Exception); + GEOM_IInsertOperations GetIInsertOperations () raises (SALOME::SALOME_Exception); + GEOM_IMeasureOperations GetIMeasureOperations () raises (SALOME::SALOME_Exception); + GEOM_IBlocksOperations GetIBlocksOperations () raises (SALOME::SALOME_Exception); + GEOM_IGroupOperations GetIGroupOperations () raises (SALOME::SALOME_Exception); + GEOM_IFieldOperations GetIFieldOperations () raises (SALOME::SALOME_Exception); + GEOM_ITestOperations GetITestOperations () raises (SALOME::SALOME_Exception); + GEOM_ICanonicalRecognition GetICanonicalRecognition() raises (SALOME::SALOME_Exception); GEOM_IOperations GetPluginOperations (in string theLibName) raises (SALOME::SALOME_Exception); diff --git a/src/GEOMImpl/CMakeLists.txt b/src/GEOMImpl/CMakeLists.txt index 43faf7ab8..98e47cea3 100644 --- a/src/GEOMImpl/CMakeLists.txt +++ b/src/GEOMImpl/CMakeLists.txt @@ -182,6 +182,7 @@ SET(GEOMImpl_HEADERS GEOMImpl_PatchFaceDriver.hxx GEOMImpl_Types.hxx GEOM_GEOMImpl.hxx + GEOMImpl_ICanonicalRecognition.hxx ) # --- sources --- @@ -257,6 +258,7 @@ SET(GEOMImpl_SOURCES GEOMImpl_GlueDriver.cxx GEOMImpl_PatchFaceDriver.cxx GEOMImpl_FieldDriver.cxx + GEOMImpl_ICanonicalRecognition.cxx ) # --- rules --- diff --git a/src/GEOMImpl/GEOMImpl_Gen.cxx b/src/GEOMImpl/GEOMImpl_Gen.cxx index 867f7b9eb..74aceaf12 100644 --- a/src/GEOMImpl/GEOMImpl_Gen.cxx +++ b/src/GEOMImpl/GEOMImpl_Gen.cxx @@ -185,6 +185,7 @@ GEOMImpl_Gen::GEOMImpl_Gen() _GroupOperations = new GEOMImpl_IGroupOperations( this ); _FieldOperations = new GEOMImpl_IFieldOperations( this ); _TestOperations = new GEOMImpl_ITestOperations( this ); + _CanonicalRecognition = new GEOMImpl_ICanonicalRecognition( this ); } //============================================================================= @@ -210,6 +211,7 @@ GEOMImpl_Gen::~GEOMImpl_Gen() delete _MeasureOperations; delete _GroupOperations; delete _FieldOperations; + delete _CanonicalRecognition; } //============================================================================= @@ -351,3 +353,13 @@ GEOMImpl_ITestOperations* GEOMImpl_Gen::GetITestOperations() { return _TestOperations; } + +//============================================================================= +/*! + * GetICanonicalRecognition + */ +//============================================================================= +GEOMImpl_ICanonicalRecognition* GEOMImpl_Gen::GetICanonicalRecognition() +{ + return _CanonicalRecognition; +} diff --git a/src/GEOMImpl/GEOMImpl_Gen.hxx b/src/GEOMImpl/GEOMImpl_Gen.hxx index dcd430f19..86237a72e 100644 --- a/src/GEOMImpl/GEOMImpl_Gen.hxx +++ b/src/GEOMImpl/GEOMImpl_Gen.hxx @@ -41,6 +41,7 @@ #include "GEOMImpl_IGroupOperations.hxx" #include "GEOMImpl_IFieldOperations.hxx" #include "GEOMImpl_ITestOperations.hxx" +#include "GEOMImpl_ICanonicalRecognition.hxx" #include "GEOM_Engine.hxx" class GEOMIMPL_EXPORT GEOMImpl_Gen : public GEOM_Engine @@ -77,22 +78,25 @@ class GEOMIMPL_EXPORT GEOMImpl_Gen : public GEOM_Engine GEOMImpl_ITestOperations* GetITestOperations(); + GEOMImpl_ICanonicalRecognition* GetICanonicalRecognition(); + private: - GEOMImpl_IBasicOperations* _BasicOperations; - GEOMImpl_ITransformOperations* _TransformOperations; - GEOMImpl_I3DPrimOperations* _3DPrimOperations; - GEOMImpl_IShapesOperations* _ShapesOperations; - GEOMImpl_IBlocksOperations* _BlocksOperations; - GEOMImpl_IBooleanOperations* _BooleanOperations; - GEOMImpl_IHealingOperations* _HealingOperations; - GEOMImpl_ICurvesOperations* _CurvesOperations; - GEOMImpl_ILocalOperations* _LocalOperations; - GEOMImpl_IInsertOperations* _InsertOperations; - GEOMImpl_IMeasureOperations* _MeasureOperations; - GEOMImpl_IGroupOperations* _GroupOperations; - GEOMImpl_IFieldOperations* _FieldOperations; - GEOMImpl_ITestOperations* _TestOperations; + GEOMImpl_IBasicOperations* _BasicOperations; + GEOMImpl_ITransformOperations* _TransformOperations; + GEOMImpl_I3DPrimOperations* _3DPrimOperations; + GEOMImpl_IShapesOperations* _ShapesOperations; + GEOMImpl_IBlocksOperations* _BlocksOperations; + GEOMImpl_IBooleanOperations* _BooleanOperations; + GEOMImpl_IHealingOperations* _HealingOperations; + GEOMImpl_ICurvesOperations* _CurvesOperations; + GEOMImpl_ILocalOperations* _LocalOperations; + GEOMImpl_IInsertOperations* _InsertOperations; + GEOMImpl_IMeasureOperations* _MeasureOperations; + GEOMImpl_IGroupOperations* _GroupOperations; + GEOMImpl_IFieldOperations* _FieldOperations; + GEOMImpl_ITestOperations* _TestOperations; + GEOMImpl_ICanonicalRecognition* _CanonicalRecognition; }; #endif diff --git a/src/GEOMImpl/GEOMImpl_ICanonicalRecognition.cxx b/src/GEOMImpl/GEOMImpl_ICanonicalRecognition.cxx new file mode 100644 index 000000000..73cead135 --- /dev/null +++ b/src/GEOMImpl/GEOMImpl_ICanonicalRecognition.cxx @@ -0,0 +1,262 @@ +// Copyright (C) 2007-2022 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 +// +// 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, or (at your option) any later version. +// +// 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 +// + +#include "GEOMImpl_ICanonicalRecognition.hxx" + +#include + +#include "GEOM_Function.hxx" +#include "GEOM_Object.hxx" +#include "GEOM_PythonDump.hxx" + +#if OCC_VERSION_LARGE > 0x07050303 +#include +#endif + +#include +#include + +#include + + +//============================================================================= +/*! + * constructor: + */ +//============================================================================= +GEOMImpl_ICanonicalRecognition::GEOMImpl_ICanonicalRecognition (GEOM_Engine* theEngine) +: GEOM_IOperations(theEngine) +{ + MESSAGE("GEOMImpl_ICanonicalRecognition::GEOMImpl_ICanonicalRecognition"); +} + +//============================================================================= +/*! + * destructor + */ +//============================================================================= +GEOMImpl_ICanonicalRecognition::~GEOMImpl_ICanonicalRecognition() +{ + MESSAGE("GEOMImpl_ICanonicalRecognition::~GEOMImpl_ICanonicalRecognition"); +} + +//============================================================================= +/*! + * \brief Check if the shape is planar + */ + //============================================================================= +bool GEOMImpl_ICanonicalRecognition::isPlane(const Handle(GEOM_Object)& theShape, double theTolerance, gp_Pln& thePln) +{ + SetErrorCode(KO); + if (theShape.IsNull()) { + SetErrorCode("Error: NULL shape"); + return false; + } + TopoDS_Shape aShape = theShape->GetValue(); + if (aShape.IsNull()) { + SetErrorCode("Error: NULL shape"); + return false; + } + +#if OCC_VERSION_LARGE < 0x07050304 + SetErrorCode("Shape type detection aborted. Improper OCCT version: please, use OCCT 7.5.3p5 or newer."); + return false; +#else + ShapeAnalysis_CanonicalRecognition aRecognition(aShape); + SetErrorCode(OK); + return aRecognition.GetStatus() == 0 && aRecognition.IsPlane(theTolerance, thePln); +#endif +} + +//============================================================================= +/*! + * \brief Check if shape is spherical + */ + //============================================================================= +bool GEOMImpl_ICanonicalRecognition::isSphere(const Handle(GEOM_Object)& theShape, double theTolerance, + gp_Sphere& theSphere) +{ + SetErrorCode(KO); + if (theShape.IsNull()) { + SetErrorCode("Error: NULL shape"); + return false; + } + TopoDS_Shape aShape = theShape->GetValue(); + if (aShape.IsNull()) { + SetErrorCode("Error: NULL shape"); + return false; + } + +#if OCC_VERSION_LARGE < 0x07050304 + SetErrorCode("Shape type detection aborted. Improper OCCT version: please, use OCCT 7.5.3p5 or newer."); + return false; +#else + ShapeAnalysis_CanonicalRecognition aRecognition(aShape); + SetErrorCode(OK); + return aRecognition.GetStatus() == 0 && aRecognition.IsSphere(theTolerance, theSphere); +#endif +} + +//============================================================================= +/*! + * \brief Check if shape is conical + */ + //============================================================================= +bool GEOMImpl_ICanonicalRecognition::isCone(const Handle(GEOM_Object)& theShape, double theTolerance, + gp_Cone& theCone) +{ + SetErrorCode(KO); + if (theShape.IsNull()) { + SetErrorCode("Error: NULL shape"); + return false; + } + TopoDS_Shape aShape = theShape->GetValue(); + if (aShape.IsNull()) { + SetErrorCode("Error: NULL shape"); + return false; + } + +#if OCC_VERSION_LARGE < 0x07050304 + SetErrorCode("Shape type detection aborted. Improper OCCT version: please, use OCCT 7.5.3p5 or newer."); + return false; +#else + ShapeAnalysis_CanonicalRecognition aRecognition(aShape); + SetErrorCode(OK); + return aRecognition.GetStatus() == 0 && aRecognition.IsCone(theTolerance, theCone); +#endif +} + +//============================================================================= +/*! + * \brief Check if shape is cylinder + */ + //============================================================================= +bool GEOMImpl_ICanonicalRecognition::isCylinder(const Handle(GEOM_Object)& theShape, double theTolerance, + gp_Cylinder& theCylinder) +{ + SetErrorCode(KO); + if (theShape.IsNull()) { + SetErrorCode("Error: NULL shape"); + return false; + } + TopoDS_Shape aShape = theShape->GetValue(); + if (aShape.IsNull()) { + SetErrorCode("Error: NULL shape"); + return false; + } + +#if OCC_VERSION_LARGE < 0x07050304 + SetErrorCode("Shape type detection aborted. Improper OCCT version: please, use OCCT 7.5.3p5 or newer."); + return false; +#else + ShapeAnalysis_CanonicalRecognition aRecognition(aShape); + SetErrorCode(OK); + return aRecognition.GetStatus() == 0 && aRecognition.IsCylinder(theTolerance, theCylinder); +#endif +} + +//============================================================================= +/*! + * \brief Check if edge / wire is line + */ + //============================================================================= +bool GEOMImpl_ICanonicalRecognition::isLine(const Handle(GEOM_Object)& theEdge, double theTolerance, + gp_Lin& theLine) +{ + SetErrorCode(KO); + if (theEdge.IsNull()) { + SetErrorCode("Error: NULL edge"); + return false; + } + TopoDS_Shape aShape = theEdge->GetValue(); + if (aShape.IsNull()) { + SetErrorCode("Error: NULL shape"); + return false; + } + +#if OCC_VERSION_LARGE < 0x07050304 + SetErrorCode("Shape type detection aborted. Improper OCCT version: please, use OCCT 7.5.3p5 or newer."); + return false; +#else + ShapeAnalysis_CanonicalRecognition aRecognition(aShape); + SetErrorCode(OK); + return aRecognition.GetStatus() == 0 && aRecognition.IsLine(theTolerance, theLine); +#endif +} + +//============================================================================= +/*! + * \brief Check if edge / wire is circle + */ + //============================================================================= +bool GEOMImpl_ICanonicalRecognition::isCircle(const Handle(GEOM_Object)& theEdge, double theTolerance, + gp_Circ& theCircle) +{ + SetErrorCode(KO); + if (theEdge.IsNull()) { + SetErrorCode("Error: NULL edge"); + return false; + } + TopoDS_Shape aShape = theEdge->GetValue(); + if (aShape.IsNull()) { + SetErrorCode("Error: NULL shape"); + return false; + } + +#if OCC_VERSION_LARGE < 0x07050304 + SetErrorCode("Shape type detection aborted. Improper OCCT version: please, use OCCT 7.5.3p5 or newer."); + return false; +#else + ShapeAnalysis_CanonicalRecognition aRecognition(aShape); + SetErrorCode(OK); + return aRecognition.GetStatus() == 0 && aRecognition.IsCircle(theTolerance, theCircle); +#endif +} + +//============================================================================= +/*! + * \brief Check if edge / wire is ellipse + */ + //============================================================================= +bool GEOMImpl_ICanonicalRecognition::isEllipse(const Handle(GEOM_Object)& theEdge, double theTolerance, + gp_Elips& theElips) +{ + SetErrorCode(KO); + if (theEdge.IsNull()) { + SetErrorCode("Error: NULL edge"); + return false; + } + TopoDS_Shape aShape = theEdge->GetValue(); + if (aShape.IsNull()) { + SetErrorCode("Error: NULL shape"); + return false; + } + +#if OCC_VERSION_LARGE < 0x07050304 + SetErrorCode("Shape type detection aborted. Improper OCCT version: please, use OCCT 7.5.3p5 or newer."); + return false; +#else + ShapeAnalysis_CanonicalRecognition aRecognition(aShape); + SetErrorCode(OK); + return aRecognition.GetStatus() == 0 && aRecognition.IsEllipse(theTolerance, theElips); +#endif +} diff --git a/src/GEOMImpl/GEOMImpl_ICanonicalRecognition.hxx b/src/GEOMImpl/GEOMImpl_ICanonicalRecognition.hxx new file mode 100644 index 000000000..b4d482dcf --- /dev/null +++ b/src/GEOMImpl/GEOMImpl_ICanonicalRecognition.hxx @@ -0,0 +1,86 @@ +// Copyright (C) 2007-2022 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 +// +// 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, or (at your option) any later version. +// +// 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 +// + +#ifndef _GEOMImpl_ICanonicalRecognition_HXX_ +#define _GEOMImpl_ICanonicalRecognition_HXX_ + +#include "GEOM_IOperations.hxx" + +#include + +#include +#include + +#include + +class GEOM_Object; + +class GEOMImpl_ICanonicalRecognition : public GEOM_IOperations { + public: + Standard_EXPORT GEOMImpl_ICanonicalRecognition(GEOM_Engine* theEngine); + Standard_EXPORT ~GEOMImpl_ICanonicalRecognition(); + + /*! + * \brief Check if the shape is planar + */ + Standard_EXPORT bool isPlane(const Handle(GEOM_Object)& theShape, double theTolerance, + gp_Pln& thePln); + + /*! + * \brief Check if shape is spherical + */ + Standard_EXPORT bool isSphere(const Handle(GEOM_Object)& theShape, double theTolerance, + gp_Sphere& theSphere); + + /*! + * \brief Check if shape is conical + */ + Standard_EXPORT bool isCone(const Handle(GEOM_Object)& theShape, double theTolerance, + gp_Cone& theCone); + + /*! + * \brief Check if shape is cylinder + */ + Standard_EXPORT bool isCylinder(const Handle(GEOM_Object)& theShape, double theTolerance, + gp_Cylinder& theCylinder); + + /*! + * \brief Check if edge / wire is line + */ + Standard_EXPORT bool isLine(const Handle(GEOM_Object)& theEdge, double theTolerance, + gp_Lin& theLine); + + /*! + * \brief Check if edge / wire is circle + */ + Standard_EXPORT bool isCircle(const Handle(GEOM_Object)& theEdge, double theTolerance, + gp_Circ& theCircle); + + /*! + * \brief Check if edge / wire is ellipse + */ + Standard_EXPORT bool isEllipse(const Handle(GEOM_Object)& theEdge, double theTolerance, + gp_Elips& theElips); + +}; + +#endif diff --git a/src/GEOM_I/CMakeLists.txt b/src/GEOM_I/CMakeLists.txt index 32ca28479..7aec8371b 100644 --- a/src/GEOM_I/CMakeLists.txt +++ b/src/GEOM_I/CMakeLists.txt @@ -78,6 +78,7 @@ SET(GEOMEngine_HEADERS GEOM_IMeasureOperations_i.hh GEOM_IGroupOperations_i.hh GEOM_ITestOperations_i.hh + GEOM_ICanonicalRecognition_i.hh GEOM_Gen_i.hh GEOM_Gen_Session_i.hh GEOM_Gen_No_Session_i.hh @@ -105,6 +106,7 @@ SET(GEOMEngine_SOURCES GEOM_IGroupOperations_i.cc GEOM_IFieldOperations_i.cc GEOM_ITestOperations_i.cc + GEOM_ICanonicalRecognition_i.cc GEOM_Gen_i.cc GEOM_Gen_Session_i.cc GEOM_Gen_No_Session_i.cc diff --git a/src/GEOM_I/GEOM_Gen_i.cc b/src/GEOM_I/GEOM_Gen_i.cc index c4a5599bb..00e58ed8a 100644 --- a/src/GEOM_I/GEOM_Gen_i.cc +++ b/src/GEOM_I/GEOM_Gen_i.cc @@ -2485,6 +2485,25 @@ GEOM::GEOM_ITestOperations_ptr GEOM_Gen_i::GetITestOperations() return operations._retn(); } +//============================================================================ +// function : GetICanonicalRecognition +// purpose : +//============================================================================ +GEOM::GEOM_ICanonicalRecognition_ptr GEOM_Gen_i::GetICanonicalRecognition() +{ + Unexpect aCatch(SALOME_SalomeException); + MESSAGE("GEOM_Gen_i::GetICanonicalRecognition"); + + GEOM::GEOM_Gen_ptr engine = _this(); + + GEOM_ICanonicalRecognition_i* aServant = + new GEOM_ICanonicalRecognition_i(_poa, engine, _impl->GetICanonicalRecognition()); + + // activate the CORBA servant + GEOM::GEOM_ICanonicalRecognition_var operations = aServant->_this(); + return operations._retn(); +} + //============================================================================ // function : GetPluginOperations // purpose : diff --git a/src/GEOM_I/GEOM_Gen_i.hh b/src/GEOM_I/GEOM_Gen_i.hh index cfe4b62ab..a956ed911 100644 --- a/src/GEOM_I/GEOM_Gen_i.hh +++ b/src/GEOM_I/GEOM_Gen_i.hh @@ -52,6 +52,7 @@ #include "GEOM_IGroupOperations_i.hh" #include "GEOM_IFieldOperations_i.hh" #include "GEOM_ITestOperations_i.hh" +#include "GEOM_ICanonicalRecognition_i.hh" #include "GEOMUtils.hxx" #include @@ -259,6 +260,8 @@ class GEOM_I_EXPORT GEOM_Gen_i : public POA_GEOM::GEOM_Gen, public Engines_Compo virtual GEOM::GEOM_ITestOperations_ptr GetITestOperations() ; + virtual GEOM::GEOM_ICanonicalRecognition_ptr GetICanonicalRecognition(); + //Returns a pointer to corresponding plugin operations interface virtual GEOM::GEOM_IOperations_ptr GetPluginOperations (const char* theLibName) ; diff --git a/src/GEOM_I/GEOM_ICanonicalRecognition_i.cc b/src/GEOM_I/GEOM_ICanonicalRecognition_i.cc new file mode 100644 index 000000000..d8ab9b288 --- /dev/null +++ b/src/GEOM_I/GEOM_ICanonicalRecognition_i.cc @@ -0,0 +1,325 @@ +// Copyright (C) 2007-2022 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 +// +// 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, or (at your option) any later version. +// +// 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 +// + +#include "GEOM_ICanonicalRecognition_i.hh" + +#include "utilities.h" +#include "OpUtil.hxx" +#include "Utils_ExceptHandlers.hxx" + +#include "GEOM_Engine.hxx" +#include "GEOM_Object.hxx" +#include "GEOM_Field.hxx" + +#include "gp_Pln.hxx" +#include "gp_Sphere.hxx" +#include "gp_Cone.hxx" +#include "gp_Cylinder.hxx" +#include "gp_Circ.hxx" +#include "gp_Elips.hxx" + +//============================================================================= +/* + * constructor: + */ +//============================================================================= +GEOM_ICanonicalRecognition_i::GEOM_ICanonicalRecognition_i (PortableServer::POA_ptr thePOA, + GEOM::GEOM_Gen_ptr theEngine, + ::GEOMImpl_ICanonicalRecognition* theImpl) + :GEOM_IOperations_i(thePOA, theEngine, theImpl) +{ + MESSAGE("GEOM_ICanonicalRecognition_i::GEOM_ICanonicalRecognition_i"); +} + +//============================================================================= +/* + * destructor + */ +//============================================================================= +GEOM_ICanonicalRecognition_i::~GEOM_ICanonicalRecognition_i() +{ + MESSAGE("GEOM_ICanonicalRecognition_i::~GEOM_ICanonicalRecognition_i"); +} + +static bool isValidDirection(const GEOM::ListOfDouble& theDir) +{ + return (theDir.length() == 3) && (gp_Vec(theDir[0], theDir[1], theDir[2]).Magnitude() > 0.); +} + +//============================================================================= +/* + * \brief Check if the shape is planar + */ + //============================================================================= +CORBA::Boolean GEOM_ICanonicalRecognition_i::isPlane(GEOM::GEOM_Object_ptr theShape, CORBA::Double theTolerance, + GEOM::ListOfDouble& theNormal, GEOM::ListOfDouble& theOrigin) +{ + Handle(::GEOM_Object) go = GetObjectImpl(theShape); + + bool aIsValidNormal = isValidDirection(theNormal); + bool aIsValidOrigin = theOrigin.length() == 3; + gp_Pln aPln; + if (aIsValidNormal && aIsValidOrigin) { + aPln = gp_Pln(gp_Pnt(theOrigin[0], theOrigin[1], theOrigin[2]), + gp_Dir(theNormal[0], theNormal[1], theNormal[2])); + } + bool aResult = GetOperation()->isPlane(go, theTolerance, aPln); + gp_Pnt aOrig = aPln.Location(); + theOrigin[0] = aOrig.X(); + theOrigin[1] = aOrig.Y(); + theOrigin[2] = aOrig.Z(); + + gp_Dir aNorm = aPln.Axis().Direction(); + theNormal[0] = aNorm.X(); + theNormal[1] = aNorm.Y(); + theNormal[2] = aNorm.Z(); + + return aResult; +} + +//============================================================================= +/* + * \brief Check if shape is spherical + */ + //============================================================================= +CORBA::Boolean GEOM_ICanonicalRecognition_i::isSphere(GEOM::GEOM_Object_ptr theShape, CORBA::Double theTolerance, + GEOM::ListOfDouble& theOrigin, CORBA::Double& theRadius) +{ + Handle(::GEOM_Object) go = GetObjectImpl(theShape); + + bool aIsValidOrigin = theOrigin.length() == 3; + bool aIsValidRadius = theRadius > 0; + gp_Sphere aSphere; + if (aIsValidOrigin && aIsValidRadius) + { + aSphere.SetLocation(gp_Pnt(theOrigin[0], theOrigin[1], theOrigin[2])); + aSphere.SetRadius(theRadius); + } + else + aSphere.SetRadius(1.0); + bool aResult = GetOperation()->isSphere(go, theTolerance, aSphere); + gp_Pnt aLoc = aSphere.Location(); + theOrigin[0] = aLoc.X(); + theOrigin[1] = aLoc.Y(); + theOrigin[2] = aLoc.Z(); + theRadius = aSphere.Radius(); + + return aResult; +} + +//============================================================================= +/* + * \brief Check if shape is conical + */ + //============================================================================= +CORBA::Boolean GEOM_ICanonicalRecognition_i::isCone(GEOM::GEOM_Object_ptr theShape, CORBA::Double theTolerance, + GEOM::ListOfDouble& theAxis, GEOM::ListOfDouble& theApex, CORBA::Double& theHalfAngle) +{ + Handle(::GEOM_Object) go = GetObjectImpl(theShape); + + bool aIsValidAxis = isValidDirection(theAxis); + bool aIsValidApex = theApex.length() == 3; + bool aIsValidAngle = theHalfAngle > 0; + gp_Cone aCone; + if (aIsValidAxis && aIsValidApex && aIsValidAngle) + { + gp_Pnt aLoc(theApex[0], theApex[1], theApex[2]); + gp_Ax3 aAx3(aLoc, gp_Dir(theAxis[0], theAxis[1], theAxis[2])); + aCone.SetPosition(aAx3); + } + else + aCone.SetRadius(1.0); + bool aResult = GetOperation()->isCone(go, theTolerance, aCone); + gp_Dir aDir = aCone.Axis().Direction(); + theAxis[0] = aDir.X(); + theAxis[1] = aDir.Y(); + theAxis[2] = aDir.Z(); + + gp_Pnt aApex = aCone.Apex(); + theApex[0] = aApex.X(); + theApex[1] = aApex.Y(); + theApex[2] = aApex.Z(); + + theHalfAngle = aCone.SemiAngle(); + return aResult; +} + +//============================================================================= +/*! + * \brief Check if shape is cylinder + */ + //============================================================================= +CORBA::Boolean GEOM_ICanonicalRecognition_i::isCylinder(GEOM::GEOM_Object_ptr theShape, CORBA::Double theTolerance, + GEOM::ListOfDouble& theAxis, GEOM::ListOfDouble& theOrigin, CORBA::Double& theRadius) +{ + Handle(::GEOM_Object) go = GetObjectImpl(theShape); + + bool aIsValidAxis = isValidDirection(theAxis); + bool aIsValidOrigin = theOrigin.length() == 3; + bool aIsValidRadius = theRadius > 0; + gp_Cylinder aCylinder; + if (aIsValidAxis && aIsValidOrigin && aIsValidRadius) + { + gp_Pnt aLoc(theOrigin[0], theOrigin[0], theOrigin[0]); + gp_Ax3 aAx3(aLoc, gp_Dir(theAxis[0], theAxis[1], theAxis[2])); + aCylinder.SetPosition(aAx3); + aCylinder.SetRadius(theRadius); + } + else + aCylinder.SetRadius(1.0); + bool aResult = GetOperation()->isCylinder(go, theTolerance, aCylinder); + gp_Dir aDir = aCylinder.Axis().Direction(); + theAxis[0] = aDir.X(); + theAxis[1] = aDir.Y(); + theAxis[2] = aDir.Z(); + + gp_Pnt aLoc = aCylinder.Location(); + theOrigin[0] = aLoc.X(); + theOrigin[1] = aLoc.Y(); + theOrigin[2] = aLoc.Z(); + + theRadius = aCylinder.Radius(); + + return aResult; +} + +//============================================================================= +/*! + * \brief Check if edge / wire is line + */ + //============================================================================= +CORBA::Boolean GEOM_ICanonicalRecognition_i::isLine(GEOM::GEOM_Object_ptr theEdge, CORBA::Double theTolerance, + GEOM::ListOfDouble& theDir, GEOM::ListOfDouble& theOrigin) +{ + Handle(::GEOM_Object) go = GetObjectImpl(theEdge); + + bool aIsValidDir = isValidDirection(theDir); + bool aIsValidOrigin = theOrigin.length() == 3; + gp_Lin aLine; + if (aIsValidDir && aIsValidOrigin) + { + aLine.SetLocation(gp_Pnt(theOrigin[0], theOrigin[1], theOrigin[2])); + aLine.SetDirection(gp_Dir(theDir[0], theDir[1], theDir[2])); + } + bool aResult = GetOperation()->isLine(go, theTolerance, aLine); + gp_Pnt aLoc = aLine.Location(); + theOrigin[0] = aLoc.X(); + theOrigin[1] = aLoc.Y(); + theOrigin[2] = aLoc.Z(); + + gp_Dir aDir = aLine.Direction(); + theDir[0] = aDir.X(); + theDir[1] = aDir.Y(); + theDir[2] = aDir.Z(); + + return aResult; +} + +//============================================================================= +/*! + * \brief Check if edge / wire is circle + */ + //============================================================================= +CORBA::Boolean GEOM_ICanonicalRecognition_i::isCircle(GEOM::GEOM_Object_ptr theEdge, CORBA::Double theTolerance, + GEOM::ListOfDouble& theNormal, GEOM::ListOfDouble& theOrigin, CORBA::Double& theRadius) +{ + Handle(::GEOM_Object) go = GetObjectImpl(theEdge); + bool aIsValidNormal = isValidDirection(theNormal); + bool aIsValidOrigin = theOrigin.length() == 3; + bool aIsValidRadius = theRadius > 0; + gp_Circ aCircle; + if (aIsValidNormal && aIsValidOrigin && aIsValidRadius) + { + gp_Ax2 aAx2(gp_Pnt(theOrigin[0], theOrigin[1], theOrigin[2]), + gp_Dir(theNormal[0], theNormal[1], theNormal[2])); + aCircle.SetPosition(aAx2); + aCircle.SetRadius(theRadius); + } + else + aCircle.SetRadius(1.0); + bool aResult = GetOperation()->isCircle(go, theTolerance, aCircle); + gp_Pnt aLoc = aCircle.Location(); + theOrigin[0] = aLoc.X(); + theOrigin[1] = aLoc.Y(); + theOrigin[2] = aLoc.Z(); + + gp_Dir aDir = aCircle.Axis().Direction(); + theNormal[0] = aDir.X(); + theNormal[1] = aDir.Y(); + theNormal[2] = aDir.Z(); + theRadius = aCircle.Radius(); + + return aResult; +} + +//============================================================================= +/*! + * \brief Check if edge / wire is ellipse + */ + //============================================================================= +CORBA::Boolean GEOM_ICanonicalRecognition_i::isEllipse(GEOM::GEOM_Object_ptr theEdge, CORBA::Double theTolerance, + GEOM::ListOfDouble& theNormal, GEOM::ListOfDouble& theDirX, GEOM::ListOfDouble& theOrigin, + CORBA::Double& theMajorRadius, CORBA::Double& theMinorRadius) +{ + Handle(::GEOM_Object) go = GetObjectImpl(theEdge); + bool aIsValidNormal = isValidDirection(theNormal); + bool aIsValidOrigin = theOrigin.length() == 3; + bool aIsValidDirX = isValidDirection(theDirX); + bool aIsValidRad1 = (theMajorRadius > 0) && (theMajorRadius > theMinorRadius); + bool aIsValidRad2 = (theMinorRadius > 0) && (theMajorRadius > theMinorRadius); + + gp_Elips aElips; + if (aIsValidNormal && aIsValidOrigin && aIsValidDirX && aIsValidRad1 && aIsValidRad2) + { + gp_Pnt anOrigin(theOrigin[0], theOrigin[1], theOrigin[2]); + gp_XYZ aNormal(theNormal[0], theNormal[1], theNormal[2]); + gp_XYZ aDirX(theDirX[0], theDirX[1], theDirX[2]); + Standard_Boolean isCollinear = + aNormal.CrossSquareMagnitude(aDirX) < Precision::SquareConfusion(); + gp_Ax2 aAx2 = isCollinear ? gp_Ax2(anOrigin, aNormal) : gp_Ax2(anOrigin, aNormal, aDirX); + aElips = gp_Elips(aAx2, theMajorRadius, theMinorRadius); + } + else + aElips.SetMajorRadius(1.0); + bool aResult = GetOperation()->isEllipse(go, theTolerance, aElips); + gp_Pnt aLoc = aElips.Position().Location(); + if (theOrigin.length() != 3) + theOrigin.allocbuf(3); + theOrigin[0] = aLoc.X(); + theOrigin[1] = aLoc.Y(); + theOrigin[2] = aLoc.Z(); + + gp_Dir aNorm = aElips.Position().Direction(); + theNormal[0] = aNorm.X(); + theNormal[1] = aNorm.Y(); + theNormal[2] = aNorm.Z(); + + gp_Dir aDirX = aElips.Position().XDirection(); + theDirX[0] = aDirX.X(); + theDirX[1] = aDirX.Y(); + theDirX[2] = aDirX.Z(); + + theMajorRadius = aElips.MajorRadius(); + theMinorRadius = aElips.MinorRadius(); + + return aResult; +} diff --git a/src/GEOM_I/GEOM_ICanonicalRecognition_i.hh b/src/GEOM_I/GEOM_ICanonicalRecognition_i.hh new file mode 100644 index 000000000..a237f7d18 --- /dev/null +++ b/src/GEOM_I/GEOM_ICanonicalRecognition_i.hh @@ -0,0 +1,96 @@ +// Copyright (C) 2007-2022 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 +// +// 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, or (at your option) any later version. +// +// 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 +// + +#ifndef _GEOM_ICanonicalRecognition_i_HeaderFile +#define _GEOM_ICanonicalRecognition_i_HeaderFile + +#include "GEOMImpl_Gen.hxx" + +#include + +#include CORBA_SERVER_HEADER(GEOM_Gen) +#include "GEOM_IOperations_i.hh" +#include "GEOM_Object_i.hh" + +#include "GEOMImpl_ICanonicalRecognition.hxx" + +class GEOM_I_EXPORT GEOM_ICanonicalRecognition_i : + public virtual POA_GEOM::GEOM_ICanonicalRecognition, + public virtual GEOM_IOperations_i +{ + public: + GEOM_ICanonicalRecognition_i (PortableServer::POA_ptr thePOA, GEOM::GEOM_Gen_ptr theEngine, + ::GEOMImpl_ICanonicalRecognition* theImpl); + ~GEOM_ICanonicalRecognition_i(); + + /*! + * \brief Check if the shape is planar + */ + CORBA::Boolean isPlane(GEOM::GEOM_Object_ptr theShape, CORBA::Double theTolerance, + GEOM::ListOfDouble& theNormal, GEOM::ListOfDouble& theOrigin); + + /*! + * \brief Check if shape is spherical + */ + CORBA::Boolean isSphere(GEOM::GEOM_Object_ptr theShape, CORBA::Double theTolerance, + GEOM::ListOfDouble& theOrigin, CORBA::Double& theRadius); + + /*! + * \brief Check if shape is conical + */ + CORBA::Boolean isCone(GEOM::GEOM_Object_ptr theShape, CORBA::Double theTolerance, + GEOM::ListOfDouble& theAxis, GEOM::ListOfDouble& theApex, + CORBA::Double& theHalfAngle); + + /*! + * \brief Check if shape is cylinder + */ + CORBA::Boolean isCylinder(GEOM::GEOM_Object_ptr theShape, CORBA::Double theTolerance, + GEOM::ListOfDouble& theAxis, GEOM::ListOfDouble& theOrigin, + CORBA::Double& theRadius); + + /*! + * \brief Check if edge / wire is line + */ + CORBA::Boolean isLine(GEOM::GEOM_Object_ptr theEdge, CORBA::Double theTolerance, + GEOM::ListOfDouble& theDir, GEOM::ListOfDouble& theOrigin); + + /*! + * \brief Check if edge / wire is circle + */ + CORBA::Boolean isCircle(GEOM::GEOM_Object_ptr theEdge, CORBA::Double theTolerance, + GEOM::ListOfDouble& theNormal, GEOM::ListOfDouble& theOrigin, + CORBA::Double& theRadius); + + /*! + * \brief Check if edge / wire is ellipse + */ + CORBA::Boolean isEllipse(GEOM::GEOM_Object_ptr theEdge, CORBA::Double theTolerance, + GEOM::ListOfDouble& theNormal, GEOM::ListOfDouble& theDirX, + GEOM::ListOfDouble& theOrigin, + CORBA::Double& theMajorRadius, CORBA::Double& theMinorRadius); + + ::GEOMImpl_ICanonicalRecognition* GetOperation() + { return (::GEOMImpl_ICanonicalRecognition*)GetImpl(); } +}; + +#endif diff --git a/src/GEOM_SWIG/CMakeLists.txt b/src/GEOM_SWIG/CMakeLists.txt index 963540446..39f3ac6af 100644 --- a/src/GEOM_SWIG/CMakeLists.txt +++ b/src/GEOM_SWIG/CMakeLists.txt @@ -71,6 +71,7 @@ SET(_other_SCRIPTS SET(_python_SCRIPTS geomBuilder.py gsketcher.py + canonicalrecognition.py ) # Advanced scripts diff --git a/src/GEOM_SWIG/GEOM_example8.py b/src/GEOM_SWIG/GEOM_example8.py new file mode 100644 index 000000000..925f070e3 --- /dev/null +++ b/src/GEOM_SWIG/GEOM_example8.py @@ -0,0 +1,11 @@ +import salome +salome.salome_init() +import GEOM +from salome.geom import geomBuilder + +geompy = geomBuilder.New() +aCircle = geompy.MakeCircleR(150.) +aCylinder = geompy.MakeCylinderRH(100.,200.) + +aCR = geompy.CanonicalRecognition() +aCR.isCylinder(aCylinder, 0.1) diff --git a/src/GEOM_SWIG/canonicalrecognition.py b/src/GEOM_SWIG/canonicalrecognition.py new file mode 100644 index 000000000..69aaa1832 --- /dev/null +++ b/src/GEOM_SWIG/canonicalrecognition.py @@ -0,0 +1,90 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +# +# 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, or (at your option) any later version. +# +# 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 +# +# File : GEOM_CanonicalRecognition.py +# Author : Vitaly SMETANNIKOV, Open CASCADE S.A.S. +# Module : GEOM_SWIG + +def setVectorSize(theVec): + "We have to set the vector size because we need to have output values in this vector" + if len(theVec) != 3: + theVec = [0,0,0] + return theVec + +class CanonicalRecognition: + "The class provides recognition of canonical shapes" + + def __init__(self, geompyD): + self.CR = geompyD.GetICanonicalRecognition() + + def isPlane(self, shape, tolerance, normal = [], origin = []): + """ + Check if shape is planar + Usage: + > CR.isPlane(shape, tolerance, normal, origin) + """ + return self.CR.isPlane(shape, tolerance, setVectorSize(normal), setVectorSize(origin)) + + def isSphere(self, shape, tolerance, origin = [], radius = 0.0): + """ + Check if shape is spherical + Usage: + > CR.isSphere(shape, tolerance, origin, radius) + """ + return self.CR.isSphere(shape, tolerance, setVectorSize(origin), radius) + + def isCone(self, shape, tolerance, axis = [], apex = [], halfAngle = 0.0): + """ + Check if shape is conical + Usage: + > CR.isCone(shape, tolerance, axis, apex, halfAngle) + """ + return self.CR.isCone(shape, tolerance, setVectorSize(axis), setVectorSize(apex), halfAngle) + + def isCylinder(self, shape, tolerance, axis = [], origin = [], radius = 0.0): + """ + Check if shape is cylinder + Usage: + > CR.isCylinder(shape, tolerance, axis, origin, radius) + """ + return self.CR.isCylinder(shape, tolerance, setVectorSize(axis), setVectorSize(origin), radius) + + def isLine(self, edge, tolerance, direction = [], origin = []): + """ + Check if edge/wire is line + Usage: + > CR.isLine(edge, tolerance, direction, origin) + """ + return self.CR.isLine(edge, tolerance, setVectorSize(direction), setVectorSize(origin)) + + def isCircle(self, edge, tolerance, normal = [], origin = [], radius = 0.0): + """ + Check if edge/wire is circle + Usage: + > CR.isCircle(edge, tolerance, normal, origin, radius) + """ + return self.CR.isCircle(edge, tolerance, setVectorSize(normal), setVectorSize(origin), radius) + + def isEllipse(self, edge, tolerance, normal = [], dirX = [], origin = [], majorRadius = 0.0, minorRadius = 0.0): + """ + Check if edge/wire is ellipse + Usage: + > CR.isEllipse(edge, tolerance, normal, dirX, origin, majorRadius, minorRadius) + """ + return self.CR.isEllipse(edge, tolerance, setVectorSize(normal), setVectorSize(dirX), setVectorSize(origin), majorRadius, minorRadius) diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index e80d9f60a..49115d58a 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -260,6 +260,7 @@ import os import functools from salome.geom.gsketcher import Sketcher3D, Sketcher2D, Polyline2D +from salome.geom.canonicalrecognition import CanonicalRecognition # In case the omniORBpy EnumItem class does not fully support Python 3 # (for instance in version 4.2.1-2), the comparison ordering methods must be @@ -11839,6 +11840,22 @@ class geomBuilder(GEOM._objref_GEOM_Gen): aDescr = self.MeasuOp.IsGoodForSolid(theShell) return aDescr + ## Obtain a canonical recognition interface. + # @return An instance of + # @ref canonicalrecognition.CanonicalRecognition "CanonicalRecognition" interface + # + # @ref tui_3dsketcher_page "Example" + def CanonicalRecognition (self): + """ + Obtain a canonical recognition interface. + + Example of usage: + cr = geompy.CanonicalRecognition() + cr.isLine(aLine, tolerance) + """ + cr = CanonicalRecognition (self) + return cr + # end of l2_measure ## @} diff --git a/test/test_CR.py b/test/test_CR.py new file mode 100644 index 000000000..cf58efed7 --- /dev/null +++ b/test/test_CR.py @@ -0,0 +1,104 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +# +# 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, or (at your option) any later version. +# +# 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 +# + +import salome +### +salome.salome_init() + +import GEOM +from salome.geom import geomBuilder +import math +import SALOMEDS + +geompy = geomBuilder.New() + +import unittest + +def GetShapeType(theShape): + CR = geompy.CanonicalRecognition() + if CR.isLine(theShape, 0.1)[0]: + return "Line" + if CR.isPlane(theShape, 0.1)[0]: + if CR.isCircle(theShape, 0.1)[0]: + return ("Plane","Circle") + if CR.isEllipse(theShape, 0.1)[0]: + return ("Plane","Ellipse") + return "Plane" + if CR.isSphere(theShape, 0.1)[0]: + return "Sphere" + if CR.isCone(theShape, 0.1)[0]: + return "Cone" + if CR.isCylinder(theShape, 0.1)[0]: + return "Cylinder" + return "Not defined" + +class GEOMTestCR(unittest.TestCase): + def testBasic(self): + """ + Acceptance test for tuleap29469 + """ + O = geompy.MakeVertex(0, 0, 0) + OX = geompy.MakeVectorDXDYDZ(1, 0, 0) + OY = geompy.MakeVectorDXDYDZ(0, 1, 0) + OZ = geompy.MakeVectorDXDYDZ(0, 0, 1) + Cylinder_1 = geompy.MakeCylinderRH(100, 300) + [Face_1,Face_2,Face_3] = geompy.ExtractShapes(Cylinder_1, geompy.ShapeType["FACE"], True) + [Edge_1,Edge_2,Edge_3] = geompy.ExtractShapes(Cylinder_1, geompy.ShapeType["EDGE"], True) + Sphere_1 = geompy.MakeSphereR(100) + [Shell_1] = geompy.ExtractShapes(Sphere_1, geompy.ShapeType["SHELL"], True) + Cone_1 = geompy.MakeConeR1R2H(100, 0, 300) + [Shell_2] = geompy.ExtractShapes(Cone_1, geompy.ShapeType["SHELL"], True) + [Face_4,Face_5] = geompy.ExtractShapes(Shell_2, geompy.ShapeType["FACE"], True) + + ## Create ellips + Cylinder_2 = geompy.MakeCylinderRH(100, 300) + Plane_1 = geompy.MakePlaneLCS(None, 350, 1) + Translation_1 = geompy.MakeTranslation(Plane_1, 0, 0, 150) + Rotation_1 = geompy.MakeRotation(Translation_1, OX, 20*math.pi/180.0) + Partition_1 = geompy.MakePartition([Cylinder_2], [Rotation_1], [], [], geompy.ShapeType["SOLID"], 0, [], 0) + [Edge_4,Edge_5,Edge_6,Edge_7,Edge_8] = geompy.ExtractShapes(Partition_1, geompy.ShapeType["EDGE"], True) + + assert GetShapeType(Face_1) == "Plane" + assert GetShapeType(Face_2) == "Cylinder" + assert GetShapeType(Edge_3) == "Line" + assert GetShapeType(Edge_2)[1] == "Circle" + assert GetShapeType(Shell_1) == "Sphere" + assert GetShapeType(Shell_2) == "Cone" + assert GetShapeType(Edge_5)[1] == "Ellipse" + + def testOnSetOfPtsOnCyl(self): + import numpy as np + tab = [[49.9999999999997, 86.6025403784442, 0.0], [1.43524931876432e-12, 100.0, 0.0], [6.12323399573677e-15, 100.0, 300.0], [50.0, 86.6025403784439, 300.0], [34.20201433256674, 93.96926207859089, 300.0], [17.364817766692976, 98.48077530122082, 300.0], [0.0, 100.0, 19.999999999999854], [0.0, 100.0, 39.99999999999963], [0.0, 100.0, 59.99999999999965], [0.0, 100.0, 79.99999999999966], [0.0, 100.0, 99.9999999999997], [0.0, 100.0, 119.99999999999973], [0.0, 100.0, 139.99999999999974], [0.0, 100.0, 159.99999999999977], [0.0, 100.0, 179.9999999999998], [0.0, 100.0, 199.99999999999983], [0.0, 100.0, 219.9999999999999], [0.0, 100.0, 239.99999999999994], [0.0, 100.0, 259.9999999999999], [0.0, 100.0, 279.99999999999994], [34.20201433256736, 93.96926207859066, 0.0], [17.364817766694355, 98.48077530122058, 0.0], [50.0, 86.60254037844386, 19.999999999999854], [50.0, 86.60254037844386, 39.99999999999963], [50.0, 86.60254037844386, 59.99999999999965], [50.0, 86.60254037844386, 79.99999999999966], [50.0, 86.60254037844386, 99.9999999999997], [50.0, 86.60254037844386, 119.99999999999973], [50.0, 86.60254037844386, 139.99999999999974], [50.0, 86.60254037844386, 159.99999999999977], [50.0, 86.60254037844386, 179.9999999999998], [50.0, 86.60254037844386, 199.99999999999983], [50.0, 86.60254037844386, 219.9999999999999], [50.0, 86.60254037844386, 239.99999999999994], [50.0, 86.60254037844386, 259.9999999999999], [50.0, 86.60254037844386, 279.99999999999994], [29.61877316560949, 95.5129743865417, 277.8870679979398], [17.205660214608802, 98.50870650140234, 30.630206624576903], [16.710324551353793, 98.59394024679419, 72.64745394595525], [17.100883188710984, 98.52694958317781, 107.80372339391727], [17.635764230289126, 98.4326156312716, 152.57612984579256], [13.644784679867689, 99.06472556384563, 189.91477232835643], [17.211909165765633, 98.50761484712454, 226.50789445170153], [16.947190833941324, 98.55350182940215, 264.31714685564623], [33.70205726794775, 94.14972828377132, 23.514274138894333], [33.9866992950552, 94.04735121749837, 45.6467424308921], [33.80199583830124, 94.11389417799832, 66.95510896864648], [31.934324162661458, 94.76391159230425, 89.88408369489096], [34.465261348238855, 93.8730299936973, 112.129816095113], [37.584878577685345, 92.66810078069287, 129.81302524607864], [34.76442821196357, 93.76264997905739, 147.223574108196], [33.921830158958535, 94.07076824745704, 167.36545102566686], [31.81206857237576, 94.80502251013108, 189.95083125203968], [33.807919537982364, 94.11176640842159, 212.57124554127284], [34.08001408422917, 94.01357689195078, 233.1435048617797], [33.7912654017101, 94.11774743666143, 253.72564508639465], [17.227853600937443, 98.50482759897946, 52.4555873421884], [13.783376774516714, 99.04553763139313, 90.1191962222661], [19.72881682971234, 98.03455404345786, 129.98468730013374], [16.735452147700688, 98.58967816872119, 172.6689841537882], [16.664342186017773, 98.60172259908703, 207.05379129229303], [17.201463406704146, 98.50943942926392, 246.03943188659505]] + + vtx = [ geompy.MakeVertex(x,y,z) for x,y,z in tab] + + theShape = geompy.MakeSmoothingSurface( vtx, 2, 8, 0) + CR = geompy.CanonicalRecognition() + recog,axis,pt,radius = CR.isCylinder(theShape, 0.1) + self.assertTrue( recog ) + self.assertTrue( np.isclose(100,radius,rtol=1e-2, atol = 0) ) + axisA = np.array(axis).reshape(1,3) + self.assertTrue( np.isclose( np.linalg.norm( axisA ) , 1.0 , rtol=1e-10, atol = 0 ) ) + self.assertTrue( np.isclose( np.abs( np.dot( axisA.reshape(3), np.array([0,0,1]) ) ), 1.0 , rtol=1e-7, atol = 0 ) ) + relDistOfPtToIdealAxis = np.linalg.norm( np.cross( axisA.reshape(3), np.array(pt) )/np.linalg.norm( np.array(pt) ) ) + self.assertTrue( np.isclose( relDistOfPtToIdealAxis, 0.0, rtol = 0, atol = 1e-3 ) ) + +if __name__ == '__main__': + unittest.main() diff --git a/test/tests.set b/test/tests.set index 761c34213..b87d630e2 100644 --- a/test/tests.set +++ b/test/tests.set @@ -19,5 +19,11 @@ SET(ALL_TESTS test_perf_01.py - test_point_cloud_on_face.py ) + +IF(${OpenCASCADE_VERSION}.${OpenCASCADE_SP_VERSION} VERSION_GREATER "7.5.3.3") + LIST(APPEND ALL_TESTS + test_point_cloud_on_face.py + test_CR.py + ) +ENDIF()