From a5131a6fefdec7c1005e601b8e63df5714efceb6 Mon Sep 17 00:00:00 2001 From: vsv Date: Mon, 20 Jun 2022 12:31:26 +0300 Subject: [PATCH] bos #29469: [EDF] (2022-T1) Advanced geometry features: Detect type of shape --- src/GeomAlgoAPI/CMakeLists.txt | 2 + src/GeomAlgoAPI/GeomAlgoAPI.i | 109 +++++- .../GeomAlgoAPI_CanonicalRecognition.cpp | 342 ++++++++++++++++++ .../GeomAlgoAPI_CanonicalRecognition.h | 80 ++++ src/GeomAlgoAPI/GeomAlgoAPI_swig.h | 1 + src/PythonAPI/Test/TestCR.py | 105 ++++++ src/PythonAPI/geom/CanonicalRecognition.py | 32 ++ src/PythonAPI/geom/__init__.py | 1 + 8 files changed, 666 insertions(+), 6 deletions(-) create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_CanonicalRecognition.cpp create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_CanonicalRecognition.h create mode 100644 src/PythonAPI/Test/TestCR.py create mode 100644 src/PythonAPI/geom/CanonicalRecognition.py diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index ef574969c..78e3e8fdc 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -94,6 +94,7 @@ SET(PROJECT_HEADERS GeomAlgoAPI_NormalToFace.h GeomAlgoAPI_Tube.h GeomAlgoAPI_ShapeInfo.h + GeomAlgoAPI_CanonicalRecognition.h ) SET(PROJECT_SOURCES @@ -167,6 +168,7 @@ SET(PROJECT_SOURCES GeomAlgoAPI_NormalToFace.cpp GeomAlgoAPI_Tube.cpp GeomAlgoAPI_ShapeInfo.cpp + GeomAlgoAPI_CanonicalRecognition.cpp ) SET(PROJECT_LIBRARIES diff --git a/src/GeomAlgoAPI/GeomAlgoAPI.i b/src/GeomAlgoAPI/GeomAlgoAPI.i index 153bf5b89..2524c6ce8 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI.i +++ b/src/GeomAlgoAPI/GeomAlgoAPI.i @@ -34,6 +34,7 @@ %include "std_string.i" %include "std_list.i" %include "std_shared_ptr.i" +%include "std_vector.i" %exceptionclass GeomAlgoAPI_Exception; @@ -48,6 +49,107 @@ } } +%typemap(out) std::list< std::shared_ptr< GeomAPI_Shape > >::value_type & { + $result = SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr(*$1)), $descriptor(std::shared_ptr *), SWIG_POINTER_OWN | 0 ); +} + +%template(ShapeList) std::list >; +%template(ValuesList) std::list; +%template(VectorOfDouble) std::vector; + +%typemap(in) std::vector& (std::vector temp) { + if (PyList_Check($input)) { + for (Py_ssize_t i = 0; i < PyList_Size($input); ++i) { + PyObject * item = PySequence_GetItem($input, i); + if (PyNumber_Check(item)) { + temp.push_back(PyFloat_AsDouble(item)); + } else { + PyErr_SetString(PyExc_TypeError, "argument must be double value."); + return NULL; + } + Py_DECREF(item); + } + $1 = &temp; + } else { + PyErr_SetString(PyExc_ValueError, "argument must be a list of double values."); + return NULL; + } +} + +%typemap(argout) std::vector& { + PyObject* outList = PyList_New(0); + int error; + std::vector::iterator it; + for ( it=$1->begin() ; it != $1->end(); it++ ) + { + error = PyList_Append(outList, PyFloat_FromDouble(*it)); + if (error) + SWIG_fail; + } + if ((!$result) || ($result == Py_None)) { + $result = outList; + } else { + PyObject *aObj1, *aObj2; + if (!PyTuple_Check($result)) { + PyObject* aObj = $result; + $result = PyTuple_New(1); + PyTuple_SetItem($result,0,aObj); + } + aObj2 = PyTuple_New(1); + PyTuple_SetItem(aObj2,0,outList); + aObj1 = $result; + $result = PySequence_Concat(aObj1,aObj2); + Py_DECREF(aObj1); + Py_DECREF(aObj2); + } +} + +%typecheck(SWIG_TYPECHECK_POINTER) std::vector, const std::vector& { + if (PyTuple_Check($input)) { + for (Py_ssize_t i = 0; i < PyTuple_Size($input); ++i) { + PyObject * item = PySequence_GetItem($input, i); + if (PyNumber_Check(item)) { + $1 = 1; + } else { + $1 = 0; + break; + } + Py_DECREF(item); + } + } else { + $1 = 0; + } +} + +%typemap(in) double& (double temp) { + if (PyFloat_Check($input)) { + temp = PyFloat_AsDouble($input); + $1 = &temp; + } else { + PyErr_SetString(PyExc_ValueError, "argument must be a double value."); + return NULL; + } +} + +%typemap(argout) double& { + if ((!$result) || ($result == Py_None)) { + $result = PyFloat_FromDouble(*$1); + } else { + PyObject *aObj1, *aObj2; + if (!PyTuple_Check($result)) { + PyObject* aObj = $result; + $result = PyTuple_New(1); + PyTuple_SetItem($result,0,aObj); + } + aObj2 = PyTuple_New(1); + PyTuple_SetItem(aObj2,0,PyFloat_FromDouble(*$1)); + aObj1 = $result; + $result = PySequence_Concat(aObj1,aObj2); + Py_DECREF(aObj1); + Py_DECREF(aObj2); + } +} + // shared pointers %shared_ptr(GeomAlgoAPI_Boolean) %shared_ptr(GeomAlgoAPI_Intersection) @@ -114,9 +216,4 @@ %include "GeomAlgoAPI_Box.h" %include "GeomAlgoAPI_MapShapesAndAncestors.h" %include "GeomAlgoAPI_ShapeInfo.h" - -%typemap(out) std::list< std::shared_ptr< GeomAPI_Shape > >::value_type & { - $result = SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr(*$1)), $descriptor(std::shared_ptr *), SWIG_POINTER_OWN | 0 ); -} -%template(ShapeList) std::list >; -%template(ValuesList) std::list; +%include "GeomAlgoAPI_CanonicalRecognition.h" diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_CanonicalRecognition.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_CanonicalRecognition.cpp new file mode 100644 index 000000000..430e326e4 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_CanonicalRecognition.cpp @@ -0,0 +1,342 @@ +// Copyright (C) 2014-2022 CEA/DEN, EDF R&D +// +// 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 "GeomAlgoAPI_CanonicalRecognition.h" + +#include +#include +#include +#include +#include +#include +#include + +bool GeomAlgoAPI_CanonicalRecognition::isPlane(const GeomShapePtr& theShape, double theTolerance, + std::vector& theNormal, std::vector& theOrigin) +{ + if (!theShape.get()) + return false; + + const TopoDS_Shape& aShape = theShape->impl(); + if (aShape.IsNull()) + return false; + + bool aIsValidNormal = theNormal.size() == 3; + bool aIsValidOrigin = theOrigin.size() == 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])); + } + + ShapeAnalysis_CanonicalRecognition aRecognition(aShape); + bool aResult = false; + try { + aResult = aRecognition.IsPlane(theTolerance, aPln); + } + catch (...) { + return false; + } + if (aResult && aIsValidNormal && aIsValidOrigin) + { + 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; +} + +bool GeomAlgoAPI_CanonicalRecognition::isSphere(const GeomShapePtr& theShape, double theTolerance, + std::vector& theOrigin, double& theRadius) +{ + if (!theShape.get()) + return false; + + const TopoDS_Shape& aShape = theShape->impl(); + if (aShape.IsNull()) + return false; + + bool aIsValidOrigin = theOrigin.size() == 3; + bool aIsValidRadius = theRadius > 0; + gp_Sphere aSphere; + if (aIsValidOrigin && aIsValidRadius) + { + aSphere.SetLocation(gp_Pnt(theOrigin[0], theOrigin[1], theOrigin[2])); + aSphere.SetRadius(theRadius); + } + ShapeAnalysis_CanonicalRecognition aRecognition(aShape); + bool aResult = false; + try { + aResult = aRecognition.IsSphere(theTolerance, aSphere); + } + catch (...) { + return false; + } + if (aResult && aIsValidOrigin && aIsValidRadius) + { + gp_Pnt aLoc = aSphere.Location(); + theOrigin[0] = aLoc.X(); + theOrigin[1] = aLoc.Y(); + theOrigin[2] = aLoc.Z(); + theRadius = aSphere.Radius(); + } + return aResult; +} + +bool GeomAlgoAPI_CanonicalRecognition::isCone(const GeomShapePtr& theShape, double theTolerance, + std::vector& theAxis, std::vector& theApex, + double& theHalfAngle) +{ + if (!theShape.get()) + return false; + + const TopoDS_Shape& aShape = theShape->impl(); + if (aShape.IsNull()) + return false; + + bool aIsValidAxis = theAxis.size() == 3; + bool aIsValidApex = theApex.size() == 3; + bool aIsValidAngle = theHalfAngle > 0; + gp_Cone aCone; + if (aIsValidAxis && aIsValidApex && aIsValidAngle) + { + gp_Pnt aLoc(theApex[0], theApex[1], theApex[2]); + aCone.SetLocation(aLoc); + aCone.SetAxis(gp_Ax1(aLoc, gp_Dir(theAxis[0], theAxis[1], theAxis[2]))); + } + ShapeAnalysis_CanonicalRecognition aRecognition(aShape); + bool aResult = false; + try { + aResult = aRecognition.IsCone(theTolerance, aCone); + } + catch (...) { + return false; + } + if (aResult && aIsValidAxis && aIsValidApex && aIsValidAngle) + { + 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; +} + +bool GeomAlgoAPI_CanonicalRecognition::isCylinder(const GeomShapePtr& theShape, double theTolerance, + std::vector& theAxis, std::vector& theOrigin, + double& theRadius) +{ + if (!theShape.get()) + return false; + + const TopoDS_Shape& aShape = theShape->impl(); + if (aShape.IsNull()) + return false; + + bool aIsValidAxis = theAxis.size() == 3; + bool aIsValidOrigin = theOrigin.size() == 3; + bool aIsValidRadius = theRadius > 0; + gp_Cylinder aCylinder; + if (aIsValidAxis && aIsValidOrigin && aIsValidRadius) + { + gp_Pnt aLoc(theOrigin[0], theOrigin[0], theOrigin[0]); + aCylinder.SetLocation(aLoc); + aCylinder.SetAxis(gp_Ax1(aLoc, gp_Dir(theAxis[0], theAxis[1], theAxis[2]))); + aCylinder.SetRadius(theRadius); + } + ShapeAnalysis_CanonicalRecognition aRecognition(aShape); + bool aResult = false; + try { + aResult = aRecognition.IsCylinder(theTolerance, aCylinder); + } + catch (...) { + return false; + } + if (aResult && aIsValidAxis && aIsValidOrigin && aIsValidRadius) + { + 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; +} + +bool GeomAlgoAPI_CanonicalRecognition::isLine(const GeomShapePtr& theEdge, double theTolerance, + std::vector& theDir, std::vector& theOrigin) +{ + if (!theEdge.get()) + return false; + + const TopoDS_Shape& aShape = theEdge->impl(); + if (aShape.IsNull()) + return false; + + bool aIsValidDir = theDir.size() == 3; + bool aIsValidOrigin = theOrigin.size() == 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])); + } + ShapeAnalysis_CanonicalRecognition aRecognition(aShape); + bool aResult = false; + try { + aResult = aRecognition.IsLine(theTolerance, aLine); + } + catch (...) { + return false; + } + if (aResult && aIsValidDir && aIsValidOrigin) + { + 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; +} + +bool GeomAlgoAPI_CanonicalRecognition::isCircle(const GeomShapePtr& theEdge, double theTolerance, + std::vector& theNormal, std::vector& theOrigin, + double& theRadius) +{ + if (!theEdge.get()) + return false; + + const TopoDS_Shape& aShape = theEdge->impl(); + if (aShape.IsNull()) + return false; + + bool aIsValidNormal = theNormal.size() == 3; + bool aIsValidOrigin = theOrigin.size() == 3; + bool aIsValidRadius = theRadius > 0; + gp_Circ aCircle; + if (aIsValidNormal && aIsValidOrigin && aIsValidRadius) + { + aCircle.SetAxis(gp_Ax1(gp_Pnt(theOrigin[0], theOrigin[1], theOrigin[2]), + gp_Dir(theNormal[0], theNormal[1], theNormal[2]))); + aCircle.SetRadius(theRadius); + } + ShapeAnalysis_CanonicalRecognition aRecognition(aShape); + bool aResult = false; + try { + aResult = aRecognition.IsCircle(theTolerance, aCircle); + } + catch (...) { + return false; + } + if (aResult && aIsValidNormal && aIsValidOrigin && aIsValidRadius) + { + 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; +} + +bool GeomAlgoAPI_CanonicalRecognition::isEllipse(const GeomShapePtr& theEdge, double theTolerance, + std::vector& theNormal, std::vector& theDirX, + std::vector& theOrigin, + double& theMajorRadius, double& theMinorRadius) +{ + if (!theEdge.get()) + return false; + + const TopoDS_Shape& aShape = theEdge->impl(); + if (aShape.IsNull()) + return false; + + bool aIsValidNormal = theNormal.size() == 3; + bool aIsValidOrigin = theOrigin.size() == 3; + bool aIsValidDirX = theDirX.size() == 3; + bool aIsValidRad1 = (theMajorRadius > 0) && (theMajorRadius > theMinorRadius); + bool aIsValidRad2 = (theMinorRadius > 0) && (theMajorRadius > theMinorRadius); + + gp_Elips aElips; + if (aIsValidNormal && aIsValidOrigin && aIsValidDirX && aIsValidRad1 && aIsValidRad2) + { + gp_Ax2 aAx2(gp_Pnt(theOrigin[0], theOrigin[1], theOrigin[2]), + gp_Dir(theNormal[0], theNormal[1], theNormal[2]), + gp_Dir(theDirX[0], theDirX[1], theDirX[2])); + aElips = gp_Elips(aAx2, theMajorRadius, theMinorRadius); + } + ShapeAnalysis_CanonicalRecognition aRecognition(aShape); + bool aResult = false; + try { + aResult = aRecognition.IsEllipse(theTolerance, aElips); + } + catch (...) { + return false; + } + if (aResult && aIsValidNormal && aIsValidOrigin && aIsValidDirX && aIsValidRad1 && aIsValidRad2) + { + gp_Pnt aLoc = aElips.Position().Location(); + 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/GeomAlgoAPI/GeomAlgoAPI_CanonicalRecognition.h b/src/GeomAlgoAPI/GeomAlgoAPI_CanonicalRecognition.h new file mode 100644 index 000000000..e1c860f64 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_CanonicalRecognition.h @@ -0,0 +1,80 @@ +// Copyright (C) 2014-2022 CEA/DEN, EDF R&D +// +// 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 GeomAlgoAPI_CanonicalRecognition_H_ +#define GeomAlgoAPI_CanonicalRecognition_H_ + +#include "GeomAlgoAPI.h" +#include + +#include + +class GeomAlgoAPI_CanonicalRecognition +{ +public: + /*! + * \brief Check if the shape is planar + */ + GEOMALGOAPI_EXPORT static bool isPlane(const GeomShapePtr& theShape, double theTolerance, + std::vector& theNormal, std::vector& theOrigin); + + /*! + * \brief Check if shape is spherical + */ + GEOMALGOAPI_EXPORT static bool isSphere(const GeomShapePtr& theShape, double theTolerance, + std::vector& theOrigin, double& theRadius); + + /*! + * \brief Check if shape is conical + */ + GEOMALGOAPI_EXPORT static bool isCone(const GeomShapePtr& theShape, double theTolerance, + std::vector& theAxis, std::vector& theApex, + double& theHalfAngle); + + /*! + * \brief Check if shape is cylinder + */ + GEOMALGOAPI_EXPORT static bool isCylinder(const GeomShapePtr& theShape, double theTolerance, + std::vector& theAxis, std::vector& theOrigin, + double& theRadius); + + /*! + * \brief Check if edge / wire is line + */ + GEOMALGOAPI_EXPORT static bool isLine(const GeomShapePtr& theEdge, double theTolerance, + std::vector& theDir, std::vector& theOrigin); + + /*! + * \brief Check if edge / wire is circle + */ + GEOMALGOAPI_EXPORT static bool isCircle(const GeomShapePtr& theEdge, double theTolerance, + std::vector& theNormal, std::vector& theOrigin, + double& theRadius); + + /*! + * \brief Check if edge / wire is ellipse + */ + GEOMALGOAPI_EXPORT static bool isEllipse(const GeomShapePtr& theEdge, double theTolerance, + std::vector& theNormal, std::vector& theDirX, + std::vector& theOrigin, + double& theMajorRadius, double& theMinorRadius); + +}; + +#endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_swig.h b/src/GeomAlgoAPI/GeomAlgoAPI_swig.h index a3be80588..d628b267a 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_swig.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_swig.h @@ -64,6 +64,7 @@ #include "GeomAlgoAPI_Symmetry.h" #include "GeomAlgoAPI_MapShapesAndAncestors.h" #include "GeomAlgoAPI_ShapeInfo.h" + #include "GeomAlgoAPI_CanonicalRecognition.h" #include #include diff --git a/src/PythonAPI/Test/TestCR.py b/src/PythonAPI/Test/TestCR.py new file mode 100644 index 000000000..1530ad34a --- /dev/null +++ b/src/PythonAPI/Test/TestCR.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python + +### +### This file is generated automatically by SALOME v9.9.0 with dump python functionality +### + + +### +### SHAPER component +### + +from salome.shaper import model, geom + +def GetShapeType(theShape): + CR = geom.CanonicalRecognition() + if CR.isPlane(theShape, 0.1)[0]: + 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" + if CR.isLine(theShape, 0.1)[0]: + return "Line" + if CR.isCircle(theShape, 0.1)[0]: + return "Circle" + if CR.isEllipse(theShape, 0.1)[0]: + return "Ellipse" + return "Not defined" + + +model.begin() +partSet = model.moduleDocument() + +### Create Part +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() + +### Create Cylinder +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10) + +### Create Shell +Plane_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Cylinder_1_1/Face_2")]) + +### Create Recover +Recover_1 = model.addRecover(Part_1_doc, Plane_1, [Cylinder_1.result()]) + +### Create Shell +Shell_2 = model.addShell(Part_1_doc, [model.selection("FACE", "Recover_1_1/Modified_Face&Cylinder_1_1/Face_1")]) + +### Create Wire +Circle_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "[Recover_1_1/Modified_Face&Cylinder_1_1/Face_1][new_weak_name_2]")], False) + +### Create Recover +Recover_2 = model.addRecover(Part_1_doc, Circle_1, [Shell_2.result()]) + +### Create Edge +Line_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "(Recover_2_1/Modified_Edge&Wire_1_1/Edge)")], False) + +### Create Recover +Cylinder_3 = model.addRecover(Part_1_doc, Line_1, [Recover_2.result()]) + +### Create Sphere +Sphere_1 = model.addSphere(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), 10) +SphereShell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sphere_1_1/Face_1")]) + +### Create Cone +Cone_1 = model.addCone(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 10, 0, 10) +ConeShell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Cone_1_1/Face_1")]) + +### Create Sketch +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) + +### Create SketchProjection +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() + +### Create SketchEllipse +SketchEllipse_1 = Sketch_1.addEllipse(-37.39690313669599, -52.92905511857006, 61.08141071866921, -16.40734649833807, 41.5747486523393) +[SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchPoint_8, SketchLine_1, SketchLine_2] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux") +model.do() + +### Create Wire +EllipseWire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchEllipse_1")], False) + +model.end() + +### Get shapes for tests +aPlaneShape = Plane_1.defaultResult().shape() +aCircleShape = Circle_1.defaultResult().shape() +aLineShape = Line_1.defaultResult().shape() +aCylinderShape = Cylinder_3.defaultResult().shape() +aSphereShape = SphereShell_1.defaultResult().shape() +aConeShape = ConeShell_1.defaultResult().shape() +aEllipseShape = EllipseWire_1.defaultResult().shape() + +### Check shapes types +assert (GetShapeType(aPlaneShape) == "Plane") +assert (GetShapeType(aCircleShape) == "Circle") +assert (GetShapeType(aLineShape) == "Line") +assert (GetShapeType(aCylinderShape) == "Cylinder") +assert (GetShapeType(aSphereShape) == "Sphere") +assert (GetShapeType(aConeShape) == "Cone") +assert (GetShapeType(aEllipseShape) == "Ellipse") diff --git a/src/PythonAPI/geom/CanonicalRecognition.py b/src/PythonAPI/geom/CanonicalRecognition.py new file mode 100644 index 000000000..725a103e5 --- /dev/null +++ b/src/PythonAPI/geom/CanonicalRecognition.py @@ -0,0 +1,32 @@ +from GeomAlgoAPI import GeomAlgoAPI_CanonicalRecognition + +class CanonicalRecognition: + "The class provides recognition of canonical shapes" + + def isPlane(self, shape, tolerance, normal = [], origin = []): + "Check if shape is planar" + return GeomAlgoAPI_CanonicalRecognition.isPlane(shape, tolerance, normal, origin) + + def isSphere(self, shape, tolerance, origin = [], radius = 0.0): + "Check if shape is spherical" + return GeomAlgoAPI_CanonicalRecognition.isSphere(shape, tolerance, origin, radius) + + def isCone(self, shape, tolerance, axis = [], apex = [], halfAngle = 0.0): + "Check if shape is conical" + return GeomAlgoAPI_CanonicalRecognition.isCone(shape, tolerance, axis, apex, halfAngle) + + def isCylinder(self, shape, tolerance, axis = [], origin = [], radius = 0.0): + "Check if shape is cylinder" + return GeomAlgoAPI_CanonicalRecognition.isCylinder(shape, tolerance, axis, origin, radius) + + def isLine(self, edge, tolerance, direction = [], origin = []): + "Check if edge/wire is line" + return GeomAlgoAPI_CanonicalRecognition.isLine(edge, tolerance, direction, origin) + + def isCircle(self, edge, tolerance, normal = [], origin = [], radius = 0.0): + "Check if edge/wire is circle" + return GeomAlgoAPI_CanonicalRecognition.isCircle(edge, tolerance, normal, origin, radius) + + def isEllipse(self, edge, tolerance, normal = [], dirX = [], origin = [], majorRadius = 0.0, minorRadius = 0.0): + "Check if edge/wire is ellipse" + return GeomAlgoAPI_CanonicalRecognition.isEllipse(edge, tolerance, normal, dirX, origin, majorRadius, minorRadius) diff --git a/src/PythonAPI/geom/__init__.py b/src/PythonAPI/geom/__init__.py index 00475f940..ef2c426fa 100644 --- a/src/PythonAPI/geom/__init__.py +++ b/src/PythonAPI/geom/__init__.py @@ -39,3 +39,4 @@ from GeomAPI import GeomAPI_Shape as Shape from GeomAlgoAPI import GeomAlgoAPI_Boolean as Boolean from .ShapeInfo import * +from .CanonicalRecognition import * -- 2.39.2