From 2d61a5f020215016f3c312f8e411ccde6d27bdbe Mon Sep 17 00:00:00 2001 From: Alexey SOZINOV Date: Fri, 22 Apr 2022 13:12:04 +0300 Subject: [PATCH] [bos #29473] [EDF] (2022-T1) Advanced geometry features: conformity of non holed-face --- doc/salome/gui/GEOM/CMakeLists.txt | 17 +- idl/GEOM_Gen.idl | 87 ++++- src/GEOMImpl/CMakeLists.txt | 4 + src/GEOMImpl/GEOMImpl_ConformityDriver.cxx | 385 +++++++++++++++++++ src/GEOMImpl/GEOMImpl_ConformityDriver.hxx | 75 ++++ src/GEOMImpl/GEOMImpl_Gen.cxx | 2 + src/GEOMImpl/GEOMImpl_IConformity.cxx | 60 +++ src/GEOMImpl/GEOMImpl_IConformity.hxx | 70 ++++ src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx | 348 +++++++++++++++++ src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx | 23 ++ src/GEOMImpl/GEOMImpl_Types.hxx | 11 + src/GEOM_I/GEOM_IMeasureOperations_i.cc | 200 ++++++++++ src/GEOM_I/GEOM_IMeasureOperations_i.hh | 24 ++ src/GEOM_SWIG/CMakeLists.txt | 1 + src/GEOM_SWIG/CheckConformity.py | 333 ++++++++++++++++ 15 files changed, 1631 insertions(+), 9 deletions(-) create mode 100644 src/GEOMImpl/GEOMImpl_ConformityDriver.cxx create mode 100644 src/GEOMImpl/GEOMImpl_ConformityDriver.hxx create mode 100644 src/GEOMImpl/GEOMImpl_IConformity.cxx create mode 100644 src/GEOMImpl/GEOMImpl_IConformity.hxx create mode 100644 src/GEOM_SWIG/CheckConformity.py diff --git a/doc/salome/gui/GEOM/CMakeLists.txt b/doc/salome/gui/GEOM/CMakeLists.txt index 7343b1cb6..66c2f32a2 100644 --- a/doc/salome/gui/GEOM/CMakeLists.txt +++ b/doc/salome/gui/GEOM/CMakeLists.txt @@ -59,13 +59,14 @@ ENDIF(WIN32) ADD_CUSTOM_TARGET(usr_docs ${CMAKE_COMMAND} -E make_directory tmp COMMAND ${CMAKE_COMMAND} -E make_directory tmp1 - COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/geomBuilder.py ${CMAKE_SOURCE_DIR}/src/GEOM_SWIG/geomBuilder.py - COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/gsketcher.py ${CMAKE_SOURCE_DIR}/src/GEOM_SWIG/gsketcher.py - COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/geomtools.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/geomtools.py - COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/sketcher.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/sketcher.py - COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/structelem.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/structelem/__init__.py - COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/parts.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/structelem/parts.py - COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/orientation.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/structelem/orientation.py + COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/geomBuilder.py ${CMAKE_SOURCE_DIR}/src/GEOM_SWIG/geomBuilder.py + COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/gsketcher.py ${CMAKE_SOURCE_DIR}/src/GEOM_SWIG/gsketcher.py + COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/CheckConformity.py ${CMAKE_SOURCE_DIR}/src/GEOM_SWIG/CheckConformity.py + COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/geomtools.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/geomtools.py + COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/sketcher.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/sketcher.py + COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/structelem.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/structelem/__init__.py + COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/parts.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/structelem/parts.py + COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/orientation.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/structelem/orientation.py COMMAND ${plugins_cmd} COMMAND ${DOXYGEN_EXECUTABLE} doxyfile_tui COMMAND ${DOXYGEN_EXECUTABLE} doxyfile_py @@ -77,7 +78,7 @@ ADD_CUSTOM_TARGET(usr_docs ${CMAKE_COMMAND} -E make_directory tmp ) INSTALL(CODE "EXECUTE_PROCESS(COMMAND \"${CMAKE_COMMAND}\" --build ${PROJECT_BINARY_DIR} --target usr_docs)") -INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/GEOM DESTINATION ${SALOME_INSTALL_DOC}/gui) +INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DESTINATION ${SALOME_INSTALL_DOC}/gui) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/static/SALOME_BOA_PA.pdf DESTINATION ${SALOME_INSTALL_DOC}/gui/GEOM) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/static/ExtractAndRebuild.pdf DESTINATION ${SALOME_INSTALL_DOC}/gui/GEOM) INSTALL(FILES input/geompy_migration.doc input/tui_auto_completion_documentation.doc input/tui_execution_distribution.doc DESTINATION ${SALOME_INSTALL_DOC}/gui/GEOM/input) diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 6af219e02..cf2fe605b 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -4716,6 +4716,91 @@ module GEOM */ double MinSurfaceCurvatureByPoint (in GEOM_Object theShape, in GEOM_Object thePoint); + //! Methods and structure for implement CheckConformity tool + + /*! + * \brief Structure for store shapes from failed checks. + * If failed check on small edges, then second shape is null + */ + struct PairOfShape + { + GEOM_Object first; + GEOM_Object second; + }; + + /*! + * \brief Structure for store result of check + * store type of check as number and failed shapes + */ + struct CheckResult + { + long type; + PairOfShape failedShapes; + }; + + typedef sequence SequenceOfPairOfShape; + typedef sequence CheckResults; + + /*! + * \brief Perform analyse of shape and return all failed checks. + * + * \param theShape Shape for check. + */ + CheckResults checkConformityShape(in GEOM_Object theShape); + + /*! + * \brief Find all self-intersected 2D curves. + * + * \param theResults result of check - list of failed checks and sub-shapes. + */ + SequenceOfPairOfShape selfIntersected2D(in CheckResults theResults); + + /*! + * \brief Find pairs of interfering sub-shapes, by default all pairs of interfering shapes are returned. + * Avaliable types: + * - vertices touched by tolerance; + * - vertex touching an edge in the inner point; + * - vertex lying on the inner point of a face; + * - edges intersecting by inner points; + * - edge touching/intersecting face in the inner point; + * - faces intersection by inner point + * + * \param theResults result of check - list of failed checks and sub-shapes. + * \param theShapeType1 Type of shape. + * \param theShapeType2 Type of shape. + */ + SequenceOfPairOfShape interferingSubshapes(in CheckResults theResults, + in long theShapeType1, in long theShapeType2); + + /*! + * \brief Find edges, which are fully covered by tolerances of vertices. + * + * \param theResults result of check - list of failed checks and sub-shapes. + */ + ListOfGO smallEdges(in CheckResults theResults); + + /*! + * \brief find remote objects (sub-shape on a shape). + * Avaliable types: + * - vertex far from edge; + * - vertex far from face; + * - edge far from face + * + * \param theShape Shape for check. + * \param theShapeType Type of shape. + * \param theSubShapeType Type of sub-shape. + * \param theTolerance tolerance, by default used tolerance of sub-shape. + */ + SequenceOfPairOfShape distantShapes(in GEOM_Object theShape, in long theShapeType, + in long theSubShapeType, in double theTolerance); + + /*! + * \brief Compute possible tolerance for the shape, minimize tolerance of shape as well + * as tolerance of sub-shapes as much as possible + * + * \param theShape Shape for update. + */ + double updateTolerance(in GEOM_Object theShape); }; // # GEOM_IGroupOperations: @@ -4907,7 +4992,7 @@ module GEOM boolean Tesselate(in GEOM_Object shape, in double linearDeflection, in boolean isRelative, in double angularDeflection); }; - + // # GEOM_Gen: /*! * \brief Interface to access other GEOM interfaces. diff --git a/src/GEOMImpl/CMakeLists.txt b/src/GEOMImpl/CMakeLists.txt index 26d37c40f..236c90808 100644 --- a/src/GEOMImpl/CMakeLists.txt +++ b/src/GEOMImpl/CMakeLists.txt @@ -119,6 +119,7 @@ SET(GEOMImpl_HEADERS GEOMImpl_IPipePath.hxx GEOMImpl_IRevolution.hxx GEOMImpl_IMeasure.hxx + GEOMImpl_IConformity.hxx GEOMImpl_IShapes.hxx GEOMImpl_IShapeExtend.hxx GEOMImpl_IFilling.hxx @@ -155,6 +156,7 @@ SET(GEOMImpl_HEADERS GEOMImpl_BlockDriver.hxx GEOMImpl_Block6Explorer.hxx GEOMImpl_MeasureDriver.hxx + GEOMImpl_ConformityDriver.hxx GEOMImpl_PolylineDriver.hxx GEOMImpl_PolylineDumper.hxx GEOMImpl_CircleDriver.hxx @@ -202,6 +204,7 @@ SET(GEOMImpl_SOURCES GEOMImpl_ITestOperations.cxx GEOMImpl_IPolyline2D.cxx GEOMImpl_ITransferData.cxx + GEOMImpl_IConformity.cxx GEOMImpl_Gen.cxx GEOMImpl_PointDriver.cxx GEOMImpl_VectorDriver.cxx @@ -230,6 +233,7 @@ SET(GEOMImpl_SOURCES GEOMImpl_BlockDriver.cxx GEOMImpl_Block6Explorer.cxx GEOMImpl_MeasureDriver.cxx + GEOMImpl_ConformityDriver.cxx GEOMImpl_PolylineDriver.cxx GEOMImpl_PolylineDumper.cxx GEOMImpl_CircleDriver.cxx diff --git a/src/GEOMImpl/GEOMImpl_ConformityDriver.cxx b/src/GEOMImpl/GEOMImpl_ConformityDriver.cxx new file mode 100644 index 000000000..87fd774f0 --- /dev/null +++ b/src/GEOMImpl/GEOMImpl_ConformityDriver.cxx @@ -0,0 +1,385 @@ +// Copyright (C) 2013-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 +// + +#include "GEOMImpl_ConformityDriver.hxx" + +// internal includes +#include "GEOMImpl_IConformity.hxx" + +// KERNEL includes +#include +#include + +// GEOM includes +#include "GEOM_Function.hxx" +#include "GEOMImpl_Types.hxx" + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace +{ + //======================================================================= + //function : GetPairsOfFaultyShapes + //purpose : + //======================================================================= + NCollection_List> GetPairsOfFaultyShapes( + const BOPAlgo_ArgumentAnalyzer& theAnalyzer, + const BOPAlgo_CheckStatus theErrorStatus) + { + NCollection_List> aResList; + + const BOPAlgo_ListOfCheckResult& aResult = theAnalyzer.GetCheckResult(); + BOPAlgo_ListIteratorOfListOfCheckResult anIt(aResult); + for (; anIt.More(); anIt.Next()) + { + if (anIt.Value().GetCheckStatus() == theErrorStatus) + { + auto aFaultyShapes = anIt.Value().GetFaultyShapes1(); + + aResList.Append({ aFaultyShapes.First(), + aFaultyShapes.Size() == 1 ? TopoDS_Shape() : aFaultyShapes.Last() }); + } + } + + return aResList; + } + + //======================================================================= + //function : GetListOfSmallEdges + //purpose : + //======================================================================= + TopTools_ListOfShape GetListOfSmallEdges(const BOPAlgo_ArgumentAnalyzer& theAnalyzer) + { + TopTools_ListOfShape aResList; + + const BOPAlgo_ListOfCheckResult& aResult = theAnalyzer.GetCheckResult(); + BOPAlgo_ListIteratorOfListOfCheckResult anIt(aResult); + for (; anIt.More(); anIt.Next()) + { + if (anIt.Value().GetCheckStatus() == BOPAlgo_CheckStatus::BOPAlgo_TooSmallEdge) + { + auto aFaultyShapes = anIt.Value().GetFaultyShapes1(); + aResList.Append(aFaultyShapes.First()); + } + } + + return aResList; + } + + //======================================================================= + //function : ConvertShapesToIndices + //purpose : Convert sub-shapes of shapes to sequence of indices + //======================================================================= + Handle(TColStd_HArray1OfInteger) ConvertShapesToIndices(const TopoDS_Shape& theShape, + const TopTools_ListOfShape& theShapes) + { + Handle(TColStd_HArray1OfInteger) aSeqOfIDs = new TColStd_HArray1OfInteger(1, theShapes.Size()); + + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(theShape, anIndices); + + TopTools_ListIteratorOfListOfShape itSub(theShapes); + for (int index = 1; itSub.More(); itSub.Next(), ++index) + { + int id = anIndices.FindIndex(itSub.Value()); + aSeqOfIDs->SetValue(index, id); + } + + return aSeqOfIDs; + } + + //======================================================================= + //function : ConvertShapesToIndices + //purpose : Convert list of pair shapes to sequence of indices + //======================================================================= + Handle(TColStd_HArray2OfInteger) ConvertShapesToIndices( + const TopoDS_Shape& theShape, + const NCollection_List>& theShapes) + { + Handle(TColStd_HArray2OfInteger) aSeqOfIDs = new TColStd_HArray2OfInteger(1, theShapes.Size(), 1, 2); + + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(theShape, anIndices); + + NCollection_List>::Iterator itSub(theShapes); + for (int index = 1; itSub.More(); itSub.Next(), ++index) + { + int anID1 = anIndices.FindIndex(itSub.Value().first); + aSeqOfIDs->SetValue(index, 1, anID1); + + int anID2 = anIndices.FindIndex(itSub.Value().second); + aSeqOfIDs->SetValue(index, 2, anID2); + } + + return aSeqOfIDs; + } +} + +//======================================================================= +//function : GetID +//purpose : +//======================================================================= +const Standard_GUID& GEOMImpl_ConformityDriver::GetID() +{ + static Standard_GUID aGUID("B77BABDA-C0A1-4E65-9B1E-7EFC4448077E"); + return aGUID; +} + +//======================================================================= +//function : GEOMImpl_ConformityDriver +//purpose : +//======================================================================= +GEOMImpl_ConformityDriver::GEOMImpl_ConformityDriver() +{ +} + +//======================================================================= +//function : Execute +//purpose : +//======================================================================= +Standard_Integer GEOMImpl_ConformityDriver::Execute(Handle(TFunction_Logbook)& log) const +{ + if (Label().IsNull()) return 0; + Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label()); + GEOMImpl_IConformity aCI(aFunction); + + Standard_Integer aType = aFunction->GetType(); + + Handle(GEOM_Function) aRefShape = aCI.GetShape(); + if (aRefShape.IsNull()) return 0; + + TopoDS_Shape aShape = aRefShape->GetValue(); + + switch (aType) + { + case CONFORMITY_DISTANT_SHAPES: + { + Standard_Integer aType1 = aCI.GetShapeType1(); + Standard_Integer aType2 = aCI.GetShapeType2(); + NCollection_List> aRes; + if (aType1 == -1 && aType2 == -1) + { + aRes = distantShapes(aShape); + } + else if (aType1 == -1) + { + aRes = distantShapes(aShape, (TopAbs_ShapeEnum)aType2); + } + else if (aType2 == -1) + { + aRes = distantShapes(aShape, (TopAbs_ShapeEnum)aType1); + } + else + { + aRes = distantShapes(aShape, (TopAbs_ShapeEnum)aType1, (TopAbs_ShapeEnum)aType2); + } + if (!aRes.IsEmpty()) + { + Handle(TColStd_HArray2OfInteger) anArray = ConvertShapesToIndices(aShape, aRes); + aCI.SetListOfShapesIndices(anArray); + } + } + break; + case CONFORMITY_UPDATE_TOL: + { + Standard_Real aTolerance = updateTolerance(aShape); + aFunction->SetReal(CHECKCONFORMITY_RET_TOLERANCE, aTolerance); + } + break; + case CONFORMITY_CHECK_SHAPE: + { + NCollection_List> aFailedShape; + Handle(TColStd_HArray1OfInteger) aTypesOfCheck; + checkShape(aShape, aFailedShape, aTypesOfCheck); + + Handle(TColStd_HArray2OfInteger) anArray = ConvertShapesToIndices(aShape, aFailedShape); + aFunction->SetIntegerArray(CHECKCONFORMITY_RET_TYPES_CHECKS, aTypesOfCheck); + aCI.SetListOfShapesIndices(anArray); + } + } + + return 1; +} + +//======================================================================= +//function : distantShapes +//purpose : TODO: Not implemented! Wait for required functionality! +//======================================================================= +NCollection_List> GEOMImpl_ConformityDriver::distantShapes( + const TopoDS_Shape& theShape, + const TopAbs_ShapeEnum theShapeType, + const TopAbs_ShapeEnum theSubShapeType, + Standard_Real theTolerance) const +{ + // TODO: Not implemented! Wait for required functionality! + return NCollection_List>(); +} + +//======================================================================= +//function : distantShapes +//purpose : TODO: Not implemented! Wait for required functionality! +//======================================================================= +NCollection_List> GEOMImpl_ConformityDriver::distantShapes( + const TopoDS_Shape& theShape, + const TopAbs_ShapeEnum theShapeType, + Standard_Real theTolerance) const +{ + NCollection_List> aDistShapes; + switch (theShapeType) + { + case TopAbs_VERTEX: + aDistShapes.Append(distantShapes(theShape, TopAbs_EDGE, theShapeType, theTolerance)); + aDistShapes.Append(distantShapes(theShape, TopAbs_FACE, theShapeType, theTolerance)); + break; + case TopAbs_EDGE: + aDistShapes.Append(distantShapes(theShape, theShapeType, TopAbs_VERTEX, theTolerance)); + aDistShapes.Append(distantShapes(theShape, TopAbs_FACE, theShapeType, theTolerance)); + break; + case TopAbs_FACE: + aDistShapes.Append(distantShapes(theShape, theShapeType, TopAbs_VERTEX, theTolerance)); + aDistShapes.Append(distantShapes(theShape, theShapeType, TopAbs_EDGE, theTolerance)); + break; + } + + return aDistShapes; +} + +//======================================================================= +//function : distantShapes +//purpose : TODO: Not implemented! Wait for required functionality! +//======================================================================= +NCollection_List> GEOMImpl_ConformityDriver::distantShapes( + const TopoDS_Shape& theShape, + Standard_Real theTolerance) const +{ + NCollection_List> aDistShapes; + + aDistShapes.Append(distantShapes(theShape, TopAbs_EDGE, TopAbs_VERTEX, theTolerance)); + aDistShapes.Append(distantShapes(theShape, TopAbs_FACE, TopAbs_VERTEX, theTolerance)); + aDistShapes.Append(distantShapes(theShape, TopAbs_FACE, TopAbs_EDGE, theTolerance)); + + return aDistShapes; +} + +void GEOMImpl_ConformityDriver::checkShape(const TopoDS_Shape & theShape, + NCollection_List>& theFailedShape, + Handle(TColStd_HArray1OfInteger)& theTypesOfCheck) const +{ + BOPAlgo_ArgumentAnalyzer anAnalyzer; + performAnalyze(theShape, anAnalyzer); + + const BOPAlgo_ListOfCheckResult& aResult = anAnalyzer.GetCheckResult(); + theTypesOfCheck = new TColStd_HArray1OfInteger(1, aResult.Size()); + + BOPAlgo_ListOfCheckResult::Iterator anIter(aResult); + for (int index = 1; anIter.More(); anIter.Next(), ++index) + { + theTypesOfCheck->SetValue(index, anIter.Value().GetCheckStatus()); + std::pair aPair; + aPair.first = anIter.Value().GetFaultyShapes1().First(); + if (anIter.Value().GetFaultyShapes1().Size() != 1) + aPair.second = anIter.Value().GetFaultyShapes1().Last(); + theFailedShape.Append(aPair); + } +} + +//======================================================================= +//function : updateTolerance +//purpose : +//======================================================================= +Standard_Real GEOMImpl_ConformityDriver::updateTolerance(const TopoDS_Shape& theShape) const +{ + Standard_Real aTolerance = INFINITY; + + TopoDS_Shape aResShape = theShape; + + BRepLib::UpdateTolerances(aResShape, Standard_False); + + for (const auto& aType : { TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE }) + { + for (TopExp_Explorer anExp(aResShape, aType); anExp.More(); anExp.Next()) + { + Standard_Real aCurTolerance = INFINITY; + switch (aType) + { + case TopAbs_VERTEX: + aCurTolerance = BRep_Tool::Tolerance(TopoDS::Vertex(anExp.Value())); + break; + case TopAbs_EDGE: + aCurTolerance = BRep_Tool::Tolerance(TopoDS::Edge(anExp.Value())); + break; + case TopAbs_FACE: + aCurTolerance = BRep_Tool::Tolerance(TopoDS::Face(anExp.Value())); + break; + } + aTolerance = Min(aTolerance, aCurTolerance); + } + } + + TopoDS_Shape aShape = theShape; + GEOMUtils::FixShapeTolerance(aShape, aTolerance, Standard_True); + + Standard_Real aResTol = 0.; + for (const auto& aType : { TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE }) + { + for (TopExp_Explorer anExp(aShape, aType); anExp.More(); anExp.Next()) + { + Standard_Real aCurTolerance = INFINITY; + switch (aType) + { + case TopAbs_VERTEX: + aCurTolerance = BRep_Tool::Tolerance(TopoDS::Vertex(anExp.Value())); + break; + case TopAbs_EDGE: + aCurTolerance = BRep_Tool::Tolerance(TopoDS::Edge(anExp.Value())); + break; + case TopAbs_FACE: + aCurTolerance = BRep_Tool::Tolerance(TopoDS::Face(anExp.Value())); + break; + } + aResTol = Max(aResTol, aCurTolerance); + } + } + + return aResTol; +} + +//======================================================================= +//function : performAnalyze +//purpose : +//======================================================================= +void GEOMImpl_ConformityDriver::performAnalyze(const TopoDS_Shape& theShape, + BOPAlgo_ArgumentAnalyzer& theAnalyzer) const +{ + theAnalyzer.SetShape1(theShape); + + theAnalyzer.CurveOnSurfaceMode() = Standard_True; + theAnalyzer.SelfInterMode() = Standard_True; + theAnalyzer.SmallEdgeMode() = Standard_True; + + theAnalyzer.Perform(); +} diff --git a/src/GEOMImpl/GEOMImpl_ConformityDriver.hxx b/src/GEOMImpl/GEOMImpl_ConformityDriver.hxx new file mode 100644 index 000000000..3c015649e --- /dev/null +++ b/src/GEOMImpl/GEOMImpl_ConformityDriver.hxx @@ -0,0 +1,75 @@ +// Copyright (C) 2013-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 +// + +#ifndef _GEOMImpl_ConformityDriver_HXX_ +#define _GEOMImpl_ConformityDriver_HXX_ + +#include "GEOM_BaseDriver.hxx" + +#include +#include + +#include + +DEFINE_STANDARD_HANDLE(GEOMImpl_ConformityDriver, GEOM_BaseDriver) + +class GEOMImpl_ConformityDriver : public GEOM_BaseDriver +{ + +public: + Standard_EXPORT GEOMImpl_ConformityDriver(); + Standard_EXPORT ~GEOMImpl_ConformityDriver() {}; + + Standard_EXPORT static const Standard_GUID& GetID(); + Standard_EXPORT virtual Standard_Integer Execute(Handle(TFunction_Logbook)& log) const; + Standard_EXPORT Standard_Boolean MustExecute(const Handle(TFunction_Logbook)&) const { return Standard_True; } + Standard_EXPORT virtual void Validate(Handle(TFunction_Logbook)&) const {} + +private: + + Standard_EXPORT NCollection_List> distantShapes(const TopoDS_Shape& theShape, + const TopAbs_ShapeEnum theShapeType, + const TopAbs_ShapeEnum theSubShapeType, + Standard_Real theTolerance = -1.) const; + + Standard_EXPORT NCollection_List> distantShapes(const TopoDS_Shape& theShape, + const TopAbs_ShapeEnum theShapeType, + Standard_Real theTolerance = -1.) const; + + Standard_EXPORT NCollection_List> distantShapes(const TopoDS_Shape& theShape, + Standard_Real theTolerance = -1.) const; + + Standard_EXPORT void checkShape(const TopoDS_Shape& theShape, + NCollection_List>& theFailedShape, + Handle(TColStd_HArray1OfInteger)& theTypesOfCheck) const; + + Standard_EXPORT Standard_Real updateTolerance(const TopoDS_Shape& theShape) const; + + Standard_EXPORT virtual bool GetCreationInformation(std::string& theOperationName, + std::vector& params) + { + return Standard_False; + } + +private: + void performAnalyze(const TopoDS_Shape& theShape, BOPAlgo_ArgumentAnalyzer& theAnalyzer) const; + +}; + +#endif // _GEOMImpl_ConformityDriver_HXX_ diff --git a/src/GEOMImpl/GEOMImpl_Gen.cxx b/src/GEOMImpl/GEOMImpl_Gen.cxx index e61e220a8..d3e83427b 100644 --- a/src/GEOMImpl/GEOMImpl_Gen.cxx +++ b/src/GEOMImpl/GEOMImpl_Gen.cxx @@ -82,6 +82,7 @@ #include #include #include +#include //============================================================================= /*! @@ -161,6 +162,7 @@ GEOMImpl_Gen::GEOMImpl_Gen() // Measurements TFunction_DriverTable::Get()->AddDriver(GEOMImpl_MeasureDriver::GetID(), new GEOMImpl_MeasureDriver()); + TFunction_DriverTable::Get()->AddDriver(GEOMImpl_ConformityDriver::GetID(), new GEOMImpl_ConformityDriver()); // Field TFunction_DriverTable::Get()->AddDriver(GEOMImpl_FieldDriver::GetID(), new GEOMImpl_FieldDriver()); diff --git a/src/GEOMImpl/GEOMImpl_IConformity.cxx b/src/GEOMImpl/GEOMImpl_IConformity.cxx new file mode 100644 index 000000000..4a80e95d9 --- /dev/null +++ b/src/GEOMImpl/GEOMImpl_IConformity.cxx @@ -0,0 +1,60 @@ +// Copyright (C) 2013-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 +// +#include "GEOMImpl_IConformity.hxx" + +//============================================================================= +/*! + * SetListOfShapesIndices + * Input 2D array of indexes converted into 1D array + */ + //============================================================================= +void GEOMImpl_IConformity::SetListOfShapesIndices(const Handle(TColStd_HArray2OfInteger)& theArrayOfIndexes) +{ + Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1, theArrayOfIndexes->Size()); + + for (Standard_Integer aRow = 1; aRow <= theArrayOfIndexes->NbRows(); ++aRow) + { + anArray->SetValue(2 * aRow - 1, theArrayOfIndexes->Value(aRow, 1)); + anArray->SetValue(2 * aRow, theArrayOfIndexes->Value(aRow, 2)); + } + + _func->SetIntegerArray(CHECKCONFORMITY_RET_LIST_OF_INDEXES, anArray); +} + +//============================================================================= +/*! + * GetListOfShapesIndices + * Get cached 1D array of indexes and converted into 2D array of indexes + */ + //============================================================================= +Handle(TColStd_HArray2OfInteger) GEOMImpl_IConformity::GetListOfShapesIndices() +{ + Handle(TColStd_HArray1OfInteger) anArray = _func->GetIntegerArray(CHECKCONFORMITY_RET_LIST_OF_INDEXES); + + Standard_Integer aLength = anArray->Size() / 2; + Handle(TColStd_HArray2OfInteger) aResArray = new TColStd_HArray2OfInteger(1, aLength, 1, 2); + + for (Standard_Integer anIndex = 1; anIndex <= aLength; ++anIndex) + { + aResArray->SetValue(anIndex, 1, anArray->Value(2 * anIndex - 1)); + aResArray->SetValue(anIndex, 2, anArray->Value(2 * anIndex)); + } + + return aResArray; +} \ No newline at end of file diff --git a/src/GEOMImpl/GEOMImpl_IConformity.hxx b/src/GEOMImpl/GEOMImpl_IConformity.hxx new file mode 100644 index 000000000..f9f343519 --- /dev/null +++ b/src/GEOMImpl/GEOMImpl_IConformity.hxx @@ -0,0 +1,70 @@ +// Copyright (C) 2013-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 +// + +#ifndef _GEOMImpl_IConformity_HXX_ +#define _GEOMImpl_IConformity_HXX_ + +#include "GEOM_Function.hxx" +#include +#include + +#define CHECKCONFORMITY_ARG_SHAPE 1 +#define CHECKCONFORMITY_ARG_SHAPETYPE_1 2 +#define CHECKCONFORMITY_ARG_SHAPETYPE_2 3 +#define CHECKCONFORMITY_ARG_TOLERANCE 4 + +#define CHECKCONFORMITY_RET_TOLERANCE 5 +#define CHECKCONFORMITY_RET_ISVALID 6 +#define CHECKCONFORMITY_RET_SHAPES_IDS 7 +#define CHECKCONFORMITY_RET_TYPES_CHECKS 8 +#define CHECKCONFORMITY_RET_LIST_OF_INDEXES 9 +#define CHECKCONFORMITY_RET_LIST_SHAPES 10 + +class GEOMImpl_IConformity +{ +public: + GEOMImpl_IConformity(Handle(GEOM_Function) theFunction) + : _func(theFunction) + { + } + + void SetShape(Handle(GEOM_Function) theRef) + { + _func->SetReference(CHECKCONFORMITY_ARG_SHAPE, theRef); + } + Handle(GEOM_Function) GetShape() + { + return _func->GetReference(CHECKCONFORMITY_ARG_SHAPE); + } + + void SetShapeType1(int theShapeType) { _func->SetInteger(CHECKCONFORMITY_ARG_SHAPETYPE_1, theShapeType); } + Standard_Integer GetShapeType1() { return _func->GetInteger(CHECKCONFORMITY_ARG_SHAPETYPE_1); } + void SetShapeType2(int theShapeType) { _func->SetInteger(CHECKCONFORMITY_ARG_SHAPETYPE_2, theShapeType); } + Standard_Integer GetShapeType2() { return _func->GetInteger(CHECKCONFORMITY_ARG_SHAPETYPE_2); } + void SetTolerance(double theTolerance) { _func->SetReal(CHECKCONFORMITY_ARG_TOLERANCE, theTolerance); } + Standard_Real GetTolerance() { return _func->GetReal(CHECKCONFORMITY_ARG_TOLERANCE); } + + void SetListOfShapesIndices(const Handle(TColStd_HArray2OfInteger)& theArrayOfIndexes); + Handle(TColStd_HArray2OfInteger) GetListOfShapesIndices(); + +private: + Handle(GEOM_Function) _func; +}; + +#endif // _GEOMImpl_IConformity_HXX_ diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx index 69c6e409e..5fd63aef3 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx @@ -25,6 +25,9 @@ #include #include +#include +#include + #include #include @@ -2658,6 +2661,351 @@ Standard_Real GEOMImpl_IMeasureOperations::MinSurfaceCurvatureByPoint return getSurfaceCurvatures(aSurf, UV.X(), UV.Y(), false); } +//============================================================================= +/*! + * selfIntersected2D + * Find all self-intersected 2D curves. + * \param theChecks list of failed checks, contains type of check and failed shapes + */ + //============================================================================= +std::list GEOMImpl_IMeasureOperations::selfIntersected2D( + std::list& theChecks) +{ + SetErrorCode(KO); + MESSAGE("GEOMImpl_IMeasureOperations::selfIntersected2D"); + + std::list aSelfInters2D; + Handle(GEOM_Object) aConformity = GetEngine()->AddObject(GEOM_CHECKCONFORMITY); + Handle(GEOM_Function) aFunction = aConformity->AddFunction(GEOMImpl_ConformityDriver::GetID(), CONFORMITY_SELFINTERSECTED); + if (aFunction.IsNull()) return aSelfInters2D; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_ConformityDriver::GetID()) return aSelfInters2D; + + GEOMImpl_IConformity aCI(aFunction); + try + { + OCC_CATCH_SIGNALS; + for (std::list::iterator anIter(theChecks.begin()); + anIter != theChecks.end(); ++anIter) + { + if (anIter->TypeOfCheck == BOPAlgo_CheckStatus::BOPAlgo_InvalidCurveOnSurface) + aSelfInters2D.push_back(anIter->FailedShapes); + } + } + catch (Standard_Failure& aFail) + { + SetErrorCode(aFail.GetMessageString()); + return aSelfInters2D; + } + + SetErrorCode(OK); + return aSelfInters2D; +} + +//============================================================================= +/*! + * interferingSubshapes + * Find pairs of interfering sub-shapes, by default all pairs of interfering shapes are returned. + * \param theChecks list of failed checks, contains type of check and failed shapes + * \param theShapeType1 Type of shape. + * \param theShapeType2 Type of shape. + */ + //============================================================================= +std::list GEOMImpl_IMeasureOperations::interferingSubshapes( + std::list& theChecks, + const int theShapeType1, + const int theShapeType2) +{ + SetErrorCode(KO); + MESSAGE("GEOMImpl_IMeasureOperations::interferingSubshapes"); + + std::list < GEOMImpl_IMeasureOperations::FailedShapes> anInterfer; + try + { + OCC_CATCH_SIGNALS; + for (std::list::iterator anIter(theChecks.begin()); + anIter != theChecks.end(); ++anIter) + { + if (anIter->TypeOfCheck == BOPAlgo_CheckStatus::BOPAlgo_SelfIntersect && + checkTypes(anIter->FailedShapes, theShapeType1, theShapeType2)) + anInterfer.push_back(anIter->FailedShapes); + } + } + catch (Standard_Failure& aFail) + { + SetErrorCode(aFail.GetMessageString()); + return anInterfer; + } + + SetErrorCode(OK); + return anInterfer; +} + +//============================================================================= +/*! + * smallEdges + * Find edges, which are fully covered by tolerances of vertices. + * \param theChecks list of failed checks, contains type of check and failed shapes + */ + //============================================================================= +Handle(TColStd_HSequenceOfTransient) GEOMImpl_IMeasureOperations::smallEdges(std::list& theChecks) +{ + SetErrorCode(KO); + MESSAGE("GEOMImpl_IMeasureOperations::smallEdges"); + + Handle(TColStd_HSequenceOfTransient) aSmallEdges = new TColStd_HSequenceOfTransient; + try + { + OCC_CATCH_SIGNALS; + for (std::list::iterator anIter(theChecks.begin()); + anIter != theChecks.end(); ++anIter) + { + if (anIter->TypeOfCheck == BOPAlgo_CheckStatus::BOPAlgo_TooSmallEdge) + aSmallEdges->Append(anIter->FailedShapes.first); + } + } + catch (Standard_Failure& aFail) + { + SetErrorCode(aFail.GetMessageString()); + return NULL; + } + + SetErrorCode(OK); + return aSmallEdges; +} + +//============================================================================= +/*! + * distantShapes + * find remote objects (sub-shape on a shape). + * \param theShape Shape for check. + * \param theShapeType Type of shape. + * \param theSubShapeType Type of sub-shape. + * \param theTolerance tolerance. + */ + //============================================================================= +std::list GEOMImpl_IMeasureOperations::distantShapes( + Handle(GEOM_Object) theShape, + const int theShapeType, + const int theSubShapeType, + double theTolerance) +{ + SetErrorCode(KO); + MESSAGE("GEOMImpl_IMeasureOperations::distantShapes"); + + std::list aDistantS; + + Handle(GEOM_Object) aConformity = GetEngine()->AddObject(GEOM_CHECKCONFORMITY); + Handle(GEOM_Function) aFunction = aConformity->AddFunction(GEOMImpl_ConformityDriver::GetID(), CONFORMITY_DISTANT_SHAPES); + if (aFunction.IsNull()) return aDistantS; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_ConformityDriver::GetID()) return aDistantS; + + GEOMImpl_IConformity aCI(aFunction); + + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) return aDistantS; + + aCI.SetShape(aRefShape); + aCI.SetShapeType1(theShapeType); + aCI.SetShapeType2(theSubShapeType); + aCI.SetTolerance(theTolerance); + + try + { + OCC_CATCH_SIGNALS; + if (!GetSolver()->ComputeFunction(aFunction)) + { + SetErrorCode("Failed: distantShape"); + return aDistantS; + } + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(theShape->GetValue(), anIndices); + Handle(TColStd_HArray1OfInteger) aRes = aFunction->GetIntegerArray(CHECKCONFORMITY_RET_SHAPES_IDS); + if (aRes.IsNull()) + return aDistantS; + for (Standard_Integer anIndex = 1; anIndex <= aRes->Size() / 2; ++anIndex) + { + std::pair aPair; + Handle(TColStd_HArray1OfInteger) anArray; + anArray = new TColStd_HArray1OfInteger(1, 1); + anArray->SetValue(1, aRes->Value(2 * anIndex - 1)); + + Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray); + if (!anObj.IsNull()) + aPair.first = anObj; + + anArray = new TColStd_HArray1OfInteger(1, 1); + anArray->SetValue(1, aRes->Value(2 * anIndex)); + + anObj = GetEngine()->AddSubShape(theShape, anArray); + if (!anObj.IsNull()) + aPair.second = anObj; + aDistantS.push_back(aPair); + } + } + catch (Standard_Failure& aFail) + { + SetErrorCode(aFail.GetMessageString()); + return aDistantS; + } + + SetErrorCode(OK); + return aDistantS; +} + +//============================================================================= +/*! + * checkConformityShape + * Perform analyse of shape and find imperfections in the shape. + * \param theShape Shape for analyse. + */ + //============================================================================= +void GEOMImpl_IMeasureOperations::checkConformityShape(Handle(GEOM_Object) theShape, std::list& theChecks) +{ + SetErrorCode(KO); + MESSAGE("GEOMImpl_IMeasureOperations::checkShape"); + + Handle(GEOM_Object) aConformity = GetEngine()->AddObject(GEOM_CHECKCONFORMITY); + Handle(GEOM_Function) aFunction = aConformity->AddFunction(GEOMImpl_ConformityDriver::GetID(), CONFORMITY_CHECK_SHAPE); + if (aFunction.IsNull()) return; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_ConformityDriver::GetID()) return; + + GEOMImpl_IConformity aCI(aFunction); + + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) return; + + aCI.SetShape(aRefShape); + + try + { + OCC_CATCH_SIGNALS; + if (!GetSolver()->ComputeFunction(aFunction)) + { + SetErrorCode("Failed: checkShape"); + return; + } + Handle(TColStd_HArray1OfInteger) aTypesChecks = aFunction->GetIntegerArray(CHECKCONFORMITY_RET_TYPES_CHECKS); + Handle(TColStd_HArray2OfInteger) aRes = aCI.GetListOfShapesIndices(); + if (aRes.IsNull()) + return; + + for (Standard_Integer anIndex = 1; anIndex <= aRes->NbRows(); ++anIndex) + { + std::pair aPair; + Handle(TColStd_HArray1OfInteger) anArray; + anArray = new TColStd_HArray1OfInteger(1, 1); + anArray->SetValue(1, aRes->Value(anIndex, 1)); + + Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray); + if (!anObj.IsNull()) + aPair.first = anObj; + + anArray = new TColStd_HArray1OfInteger(1, 1); + anArray->SetValue(1, aRes->Value(anIndex, 2)); + + anObj = GetEngine()->AddSubShape(theShape, anArray); + if (!anObj.IsNull()) + aPair.second = anObj; + theChecks.push_back({ aTypesChecks->Value(anIndex), aPair }); + } + } + catch (Standard_Failure& aFail) + { + SetErrorCode(aFail.GetMessageString()); + return; + } + + SetErrorCode(OK); + return; +} + +//============================================================================= +/*! + * updateTolerance + * Compute possible tolerance for the shape, minimize tolerance of shape as well + * as tolerance of sub-shapes as much as possible + * \param theShape Shape for compute tolerance. + */ + //============================================================================= +double GEOMImpl_IMeasureOperations::updateTolerance(Handle(GEOM_Object) theShape) +{ + SetErrorCode(KO); + MESSAGE("GEOMImpl_IMeasureOperations::updateTolerance"); + + double aResTol = -1; + Handle(GEOM_Object) aConformity = GetEngine()->AddObject(GEOM_CHECKCONFORMITY); + Handle(GEOM_Function) aFunction = aConformity->AddFunction(GEOMImpl_ConformityDriver::GetID(), CONFORMITY_UPDATE_TOL); + if (aFunction.IsNull()) return aResTol; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_ConformityDriver::GetID()) return aResTol; + + GEOMImpl_IConformity aCI(aFunction); + + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) return aResTol; + + aCI.SetShape(aRefShape); + + try + { + OCC_CATCH_SIGNALS; + if (!GetSolver()->ComputeFunction(aFunction)) + { + SetErrorCode("Failed: updateTolerance"); + return aResTol; + } + aResTol = aFunction->GetReal(CHECKCONFORMITY_RET_TOLERANCE); + } + catch (Standard_Failure& aFail) + { + SetErrorCode(aFail.GetMessageString()); + return aResTol; + } + + SetErrorCode(OK); + return aResTol; +} + +//======================================================================= +//function : checkTypes +//purpose : +//======================================================================= +bool GEOMImpl_IMeasureOperations::checkTypes(const FailedShapes& theShapes, + const int theShapeType1, + const int theShapeType2) +{ + TopAbs_ShapeEnum aShapeType1, aShapeType2; + if (!theShapes.first.IsNull()) + aShapeType1 = theShapes.first->GetValue().ShapeType(); + if (!theShapes.second.IsNull()) + aShapeType2 = theShapes.second->GetValue().ShapeType(); + + if (theShapeType1 == -1 && theShapeType2 == -1) + { + return true; + } + else if (theShapeType1 == -1) + { + return aShapeType1 == theShapeType2 || aShapeType2 == theShapeType2; + } + else if (theShapeType2 == -1) + { + return aShapeType1 == theShapeType1 || aShapeType2 == theShapeType1; + } + else + { + return aShapeType1 == theShapeType1 && aShapeType2 == theShapeType2 || + aShapeType1 == theShapeType2 && aShapeType2 == theShapeType1; + } +} + //======================================================================= //function : FillErrorsSub //purpose : Fill the errors list of subshapes on shape. diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx index 58b27bbda..71f0926fc 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx @@ -215,9 +215,32 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations { Standard_Real& theVParam); Standard_EXPORT Standard_Real MinSurfaceCurvatureByPoint (Handle(GEOM_Object) theSurf, Handle(GEOM_Object) thePoint); + typedef std::pair< Handle(GEOM_Object), Handle(GEOM_Object)> FailedShapes; + struct FailedChecks + { + Standard_Integer TypeOfCheck; + FailedShapes FailedShapes; + }; + + Standard_EXPORT std::list selfIntersected2D(std::list& theChecks); + Standard_EXPORT std::list interferingSubshapes(std::list& theChecks, + const int theShapeType1, + const int theShapeType2); + Standard_EXPORT Handle(TColStd_HSequenceOfTransient) smallEdges(std::list& theChecks); + Standard_EXPORT std::list distantShapes(Handle(GEOM_Object) theShape, + const int theShapeType, + const int theSubShapeType, + double theTolerance); + Standard_EXPORT void checkConformityShape(Handle(GEOM_Object) theShape, std::list& theChecks); + + Standard_EXPORT double updateTolerance(Handle(GEOM_Object) theShape); private: + bool checkTypes(const FailedShapes& theShapes, + const int theShapeType1, + const int theShapeType2); + void FillErrorsSub (const BRepCheck_Analyzer &theAna, const TopoDS_Shape &theShape, diff --git a/src/GEOMImpl/GEOMImpl_Types.hxx b/src/GEOMImpl/GEOMImpl_Types.hxx index 1f64191fa..b6a1f485f 100644 --- a/src/GEOMImpl/GEOMImpl_Types.hxx +++ b/src/GEOMImpl/GEOMImpl_Types.hxx @@ -121,6 +121,8 @@ #define GEOM_EXTRACTION 58 +#define GEOM_CHECKCONFORMITY 59 + //GEOM_Function types #define COPY_WITH_REF 1 @@ -391,6 +393,15 @@ #define TD_GET_IN_PLACE_OLD 2 #define TD_GET_IN_PLACE_BY_HISTORY 3 +// Conformity operations +#define CONFORMITY_IS_VALID 2 +#define CONFORMITY_SELFINTERSECTED 3 +#define CONFORMITY_INTERFERENCE 4 +#define CONFORMITY_SMALL_EDGES 5 +#define CONFORMITY_DISTANT_SHAPES 6 +#define CONFORMITY_UPDATE_TOL 7 +#define CONFORMITY_CHECK_SHAPE 8 + // Plugins specified constants #define PLUGIN_NAME "Plugin Name" diff --git a/src/GEOM_I/GEOM_IMeasureOperations_i.cc b/src/GEOM_I/GEOM_IMeasureOperations_i.cc index c2acb2158..c8e46802b 100644 --- a/src/GEOM_I/GEOM_IMeasureOperations_i.cc +++ b/src/GEOM_I/GEOM_IMeasureOperations_i.cc @@ -1188,3 +1188,203 @@ CORBA::Double GEOM_IMeasureOperations_i::MinSurfaceCurvatureByPoint return GetOperations()->MinSurfaceCurvatureByPoint(aShape,aPoint); } + +//============================================================================= +/*! + * selfIntersected2D + * Find all self-intersected 2D curves. + * \param theShape Shape for check. + */ + //============================================================================= +GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* GEOM_IMeasureOperations_i::selfIntersected2D( + const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts) +{ + GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape_var aSeq = + new GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape; + + // Perform patch face operation + std::list aResults; + ConvertToList(theResuts, aResults); + + std::list aSelfInters = GetOperations()->selfIntersected2D(aResults); + if (!GetOperations()->IsDone() || aSelfInters.empty()) + return aSeq._retn(); + + Standard_Integer aLength = aSelfInters.size(); + aSeq->length(aLength); + std::list::iterator anIter(aSelfInters.begin()); + for (Standard_Integer i = 0; i < aLength; i++, ++anIter) + { + aSeq[i].first = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).first)); + aSeq[i].second = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).second)); + } + + return aSeq._retn(); +} + +//============================================================================= +/*! + * interferingSubshapes + * Find pairs of interfering sub-shapes, by default all pairs of interfering shapes are returned. + * \param theShape Shape for check. + * \param theShapeType1 Type of shape. + * \param theShapeType2 Type of shape. + */ + //============================================================================= +GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* GEOM_IMeasureOperations_i::interferingSubshapes( + const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts, + const CORBA::Long theShapeType1, + const CORBA::Long theShapeType2) +{ + GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape_var aSeq = + new GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape; + + // Perform patch face operation + std::list aResults; + ConvertToList(theResuts, aResults); + + std::list aSelfInterf = + GetOperations()->interferingSubshapes(aResults, theShapeType1, theShapeType2); + if (!GetOperations()->IsDone() || aSelfInterf.empty()) + return aSeq._retn(); + + Standard_Integer aLength = aSelfInterf.size(); + aSeq->length(aLength); + std::list::iterator anIter(aSelfInterf.begin()); + for (Standard_Integer i = 0; i < aLength; i++, ++anIter) + { + aSeq[i].first = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).first)); + aSeq[i].second = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).second)); + } + + return aSeq._retn(); +} + +//============================================================================= +/*! + * smallEdges + * Find edges, which are fully covered by tolerances of vertices. + * \param theShape Shape for check. + */ + //============================================================================= +GEOM::ListOfGO* GEOM_IMeasureOperations_i::smallEdges(const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts) +{ + GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO; + + std::list aResults; + ConvertToList(theResuts, aResults); + + //Get the reference shape + Handle(TColStd_HSequenceOfTransient) aSmallEdges = GetOperations()->smallEdges(aResults); + if (!GetOperations()->IsDone() || aSmallEdges.IsNull()) + return aSeq._retn(); + + Standard_Integer aLength = aSmallEdges->Length(); + aSeq->length(aLength); + for (Standard_Integer i = 1; i <= aLength; i++) + aSeq[i - 1] = GetObject(Handle(::GEOM_Object)::DownCast(aSmallEdges->Value(i))); + + return aSeq._retn(); +} + +//============================================================================= +/*! + * distantShapes + * find remote objects (sub-shape on a shape). + * \param theShape Shape for check. + * \param theShapeType Type of shape. + * \param theSubShapeType Type of sub-shape. + * \param theTolerance tolerance. + */ + //============================================================================= +GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* GEOM_IMeasureOperations_i::distantShapes( + GEOM::GEOM_Object_ptr theShape, + const CORBA::Long theShapeType, + const CORBA::Long theSubShapeType, + const CORBA::Double theTolerance) +{ + GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape_var aSeq = + new GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape; + + //Get the reference shape + Handle(::GEOM_Object) aShapeRef = GetObjectImpl(theShape); + if (aShapeRef.IsNull()) return aSeq._retn(); + + // Perform patch face operation + std::list aDistantS = + GetOperations()->distantShapes(aShapeRef, theShapeType, theSubShapeType, theTolerance); + if (!GetOperations()->IsDone() || aDistantS.empty()) + return aSeq._retn(); + + Standard_Integer aLength = aDistantS.size(); + aSeq->length(aLength); + std::list::iterator anIter(aDistantS.begin()); + for (Standard_Integer i = 0; i < aLength; i++, ++anIter) + { + aSeq[i].first = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).first)); + aSeq[i].second = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).second)); + } + + return aSeq._retn(); +} + +//============================================================================= +/*! + * checkShape + * + */ + //============================================================================= +GEOM::GEOM_IMeasureOperations::CheckResults* GEOM_IMeasureOperations_i::checkConformityShape( + GEOM::GEOM_Object_ptr theShape) +{ + GEOM::GEOM_IMeasureOperations::CheckResults_var aRes = new GEOM::GEOM_IMeasureOperations::CheckResults; + + //Get the reference shape + Handle(::GEOM_Object) aShapeRef = GetObjectImpl(theShape); + if (aShapeRef.IsNull()) return false; + + std::list aChecks; + GetOperations()->checkConformityShape(aShapeRef, aChecks); + + Standard_Integer aLength = aChecks.size(); + aRes->length(aLength); + std::list::const_iterator anIntIt = aChecks.cbegin(); + for (Standard_Integer i = 0; i < aLength; i++, ++anIntIt) + { + aRes[i].type = (*anIntIt).TypeOfCheck; + aRes[i].failedShapes.first = GetObject(Handle(::GEOM_Object)::DownCast((*anIntIt).FailedShapes.first)); + aRes[i].failedShapes.second = GetObject(Handle(::GEOM_Object)::DownCast((*anIntIt).FailedShapes.second)); + } + + return aRes._retn(); +} + +//============================================================================= +/*! + * updateTolerance + * Compute possible tolerance for the shape, minimize tolerance of shape as well + * as tolerance of sub-shapes as much as possible + * \param theShape Shape for check. + */ + //============================================================================= +CORBA::Double GEOM_IMeasureOperations_i::updateTolerance(GEOM::GEOM_Object_ptr theShape) +{ + //Get the reference shape + Handle(::GEOM_Object) aShapeRef = GetObjectImpl(theShape); + if (aShapeRef.IsNull()) return false; + + return GetOperations()->updateTolerance(aShapeRef); +} + +void GEOM_IMeasureOperations_i::ConvertToList(const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts, + std::list& theListOfResults) +{ + for (Standard_Integer i = 0; i < theResuts.length(); ++i) + { + GEOMImpl_IMeasureOperations::FailedChecks aCheck; + aCheck.TypeOfCheck = theResuts[i].type; + aCheck.FailedShapes.first = GetObjectImpl(theResuts[i].failedShapes.first); + aCheck.FailedShapes.second = GetObjectImpl(theResuts[i].failedShapes.second); + theListOfResults.push_back(aCheck); + } +} diff --git a/src/GEOM_I/GEOM_IMeasureOperations_i.hh b/src/GEOM_I/GEOM_IMeasureOperations_i.hh index bebaedeec..7fa72ec47 100644 --- a/src/GEOM_I/GEOM_IMeasureOperations_i.hh +++ b/src/GEOM_I/GEOM_IMeasureOperations_i.hh @@ -164,6 +164,30 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i : CORBA::Double MinSurfaceCurvatureByPoint (GEOM::GEOM_Object_ptr theSurf, GEOM::GEOM_Object_ptr thePoint); + // Methods for class CheckConformity + GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* selfIntersected2D( + const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts); + + GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* interferingSubshapes( + const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts, + const CORBA::Long theShapeType1, + const CORBA::Long theShapeType2); + + GEOM::ListOfGO* smallEdges(const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts); + + GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* distantShapes(GEOM::GEOM_Object_ptr theShape, + const CORBA::Long theShapeType, + const CORBA::Long theSubShapeType, + const CORBA::Double theTolerance); + + GEOM::GEOM_IMeasureOperations::CheckResults* checkConformityShape(GEOM::GEOM_Object_ptr theShape); + + CORBA::Double updateTolerance(GEOM::GEOM_Object_ptr theShape); +private: + void ConvertToList(const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts, + std::list & theListOfResults); + + ::GEOMImpl_IMeasureOperations* GetOperations() { return (::GEOMImpl_IMeasureOperations*)GetImpl(); } }; diff --git a/src/GEOM_SWIG/CMakeLists.txt b/src/GEOM_SWIG/CMakeLists.txt index 963540446..bb21d8b79 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 + CheckConformity.py ) # Advanced scripts diff --git a/src/GEOM_SWIG/CheckConformity.py b/src/GEOM_SWIG/CheckConformity.py new file mode 100644 index 000000000..d542d0b7f --- /dev/null +++ b/src/GEOM_SWIG/CheckConformity.py @@ -0,0 +1,333 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2014-2022 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 +# +# Author : Alexey SOZINOV, Open CASCADE S.A.S. + + +## @defgroup check_conformity CheckConformity - Wrapper to find imperfections in the shape +# @{ +# @details +# This tool provides the user with a simple python API +# to analyze, available shape for Boolean Operations or not. +# Also tool provide advanced output to indicate imperfections in the input shape. +# @n Example: +# @code +# import GEOM +# from salome.geom import geomBuilder +# from salome.geom.CheckConformity import CheckConformity +# +# geompy = geomBuilder.New() +# +# O = geompy.MakeVertex(0, 0, 0) +# OX = geompy.MakeVectorDXDYDZ(1, 0, 0) +# OY = geompy.MakeVectorDXDYDZ(0, 1, 0) +# OZ = geompy.MakeVectorDXDYDZ(0, 0, 1) +# Vertex_1 = geompy.MakeVertex(-30, -70, 0) +# Vertex_2 = geompy.MakeVertex(-30, 50, 0) +# Line_1 = geompy.MakeLineTwoPnt(Vertex_2, Vertex_1) +# Vertex_3 = geompy.MakeVertex(0, -50, 0) +# Vertex_4 = geompy.MakeVertex(-40, -10, 0) +# Vertex_5 = geompy.MakeVertex(0, 40, 0) +# Arc_1 = geompy.MakeArc(Vertex_5, Vertex_4, Vertex_3) +# Vertex_6 = geompy.MakeVertex(10, -50, 4) +# Vertex_7 = geompy.MakeVertex(10, -50, 10) +# Vertex_8 = geompy.MakeVertex(10, 40, 10) +# Arc_1_vertex_3 = geompy.GetSubShape(Arc_1, [3]) +# Line_2 = geompy.MakeLineTwoPnt(Arc_1_vertex_3, Vertex_6) +# Line_3 = geompy.MakeLineTwoPnt(Vertex_6, Vertex_7) +# Line_4 = geompy.MakeLineTwoPnt(Vertex_7, Vertex_8) +# Vertex_9 = geompy.MakeVertex(15, 40, 10) +# Vertex_10 = geompy.MakeVertex(17, 0, 6) +# Vertex_11 = geompy.MakeVertex(17, 0, 3) +# Line_5 = geompy.MakeLineTwoPnt(Vertex_8, Vertex_9) +# Line_6 = geompy.MakeLineTwoPnt(Vertex_9, Vertex_10) +# Line_7 = geompy.MakeLineTwoPnt(Vertex_10, Vertex_11) +# Arc_1_vertex_2 = geompy.GetSubShape(Arc_1, [2]) +# Line_8 = geompy.MakeLineTwoPnt(Vertex_11, Arc_1_vertex_2) +# Wire_1 = geompy.MakeWire([Arc_1, Line_2, Line_3, Line_4, Line_5, Line_6, Line_7, Line_8], 1e-07) +# Wire_2 = geompy.MakeWire([Line_1], 1e-07) +# Compound_1 = geompy.MakeCompound([Wire_1, Wire_2]) +# +# # Create class CheckConformity for check shape +# cc = CheckConformity(Compound_1, geompy) +# valid = cc.isValid() +# dist = cc.distantShapes() +# small = cc.smallEdges() +# interfer = cc.interferingSubshapes() +# intersect = cc.selfIntersected2D() +# +# geompy.addToStudy( O, 'O' ) +# geompy.addToStudy( OX, 'OX' ) +# geompy.addToStudy( OY, 'OY' ) +# geompy.addToStudy( OZ, 'OZ' ) +# geompy.addToStudy( Vertex_1, 'Vertex_1' ) +# geompy.addToStudy( Vertex_2, 'Vertex_2' ) +# geompy.addToStudy( Line_1, 'Line_1' ) +# geompy.addToStudy( Vertex_3, 'Vertex_3' ) +# geompy.addToStudy( Vertex_4, 'Vertex_4' ) +# geompy.addToStudy( Vertex_5, 'Vertex_5' ) +# geompy.addToStudy( Arc_1, 'Arc_1' ) +# geompy.addToStudy( Vertex_6, 'Vertex_6' ) +# geompy.addToStudy( Vertex_7, 'Vertex_7' ) +# geompy.addToStudy( Vertex_8, 'Vertex_8' ) +# geompy.addToStudyInFather( Arc_1, Arc_1_vertex_3, 'Arc_1:vertex_3' ) +# geompy.addToStudy( Line_2, 'Line_2' ) +# geompy.addToStudy( Line_3, 'Line_3' ) +# geompy.addToStudy( Line_4, 'Line_4' ) +# geompy.addToStudy( Vertex_9, 'Vertex_9' ) +# geompy.addToStudy( Vertex_10, 'Vertex_10' ) +# geompy.addToStudy( Vertex_11, 'Vertex_11' ) +# geompy.addToStudy( Line_5, 'Line_5' ) +# geompy.addToStudy( Line_6, 'Line_6' ) +# geompy.addToStudy( Line_7, 'Line_7' ) +# geompy.addToStudyInFather( Arc_1, Arc_1_vertex_2, 'Arc_1:vertex_2' ) +# geompy.addToStudy( Line_8, 'Line_8' ) +# geompy.addToStudy( Wire_1, 'Wire_1' ) +# geompy.addToStudy( Wire_2, 'Wire_2' ) +# geompy.addToStudy( Compound_1, 'Compound_1' ) +# +# salome.sg.updateObjBrowser() +# +# @endcode +# @n Additional examples can be found as unit tests in the source code. +# @} + +try: + import salome + salome.salome_init() + from salome import * +except: + pass + +import GEOM + +from salome.geom import geomBuilder + +geompy = geomBuilder.New() + +## An interface to find imperfections in the shape. +# Use geompy.CheckConformity(shape) method to obtain an instance of this class +# +# @ref tui_check_conformity_page "Example" +# @ingroup check_conformity +class CheckConformity: + """ + Check Conformity interface + + Example of usage: + cc = CheckConformity(Lot4_twistedFace_brep_1, geompy) + valid = cc.isValid() + dist = cc.distantShapes(geompy.ShapeType["EDGE"], geompy.ShapeType["VERTEX"]) !!NOT implemented! + small = cc.smallEdges() + interfer = cc.interferingSubshapes() + interferEV = cc.interferingSubshapes(geompy.ShapeType["EDGE"], geompy.ShapeType["VERTEX"]) + interferVV = cc.interferingSubshapes(geompy.ShapeType["VERTEX], geompy.ShapeType["VERTEX"]) + intersect = cc.selfIntersected2D() + + """ + + def __init__(self, shape, geompy): + self.geompyD = geompy + self.myShape = shape + self.myIsChecked = False; + self.myResults = [] + + ## Perform analyse of shape. + # + # @return New List, which contains pair: type of check and single of pair failed sub-shapes. + def __checkShape(self): + """ + Perform analyse of shape. + + Returns: + New List, which contains pair: type of check and single of pair failed sub-shapes. + """ + anOp = self.geompyD.GetIMeasureOperations() + self.myIsChecked = True + self.myResults = anOp.checkConformityShape(self.myShape) + + ## Check whether the shape is applicable for Boolean Operations. + # + # @return Boolean value True if shape is applicable for Boolean Operations, otherwise - False + def isValid(self): + """ + check whether the shape is applicable for Boolean Operations. + + Returns: + Boolean value True if shape is applicable for Boolean Operations, otherwise - False. + + Example of usage: + Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) + cc = CheckConformity(Box_1, geompy) + isValid = cc.isValid() + """ + if not self.myIsChecked: + self.__checkShape() + + anOp = self.geompyD.GetIMeasureOperations() + return len(self.myResults) == 0 + + ## Find all self-intersected 2D curves. + # + # @return New List, of pair sub-shape, which has self-intersected in 2D + def selfIntersected2D(self): + """ + Find all self-intersected 2D curves. + + Returns: + New List, of pair sub-shape, which has self-intersected in 2D/ + + Example of usage: + Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) + cc = CheckConformity(Box_1, geompy) + selfIntersected2D = cc.selfIntersected2D() + """ + if not self.myIsChecked: + self.__checkShape() + + anOp = self.geompyD.GetIMeasureOperations() + return anOp.selfIntersected2D(self.myResults) + + ## Find pairs of interfering sub-shapes: + # - vertices touched by tolerance; + # - vertex touching an edge in the inner point; + # - vertex lying on the inner point of a face; + # - edges intersecting by inner points; + # - edge touching/intersecting face in the inner point; + # - faces intersection by inner point + # + # Types of interfering shapes could be specified, + # by default all pairs of interfering shapes are returned. + # + # @param shapeType1 first type of shape + # @param shapeType2 second type of shape + # + # @return New List, of pairs of interfering shapes with given types (if they was specified) + def interferingSubshapes(self, shapeType1 = geompy.ShapeType["AUTO"], shapeType2 = geompy.ShapeType["AUTO"]): + """ + Find pairs of interfering sub-shapes: + - vertices touched by tolerance + - vertex touching an edge in the inner point + - vertex lying on the inner point of a face + - edges intersecting by inner points + - edge touching/intersecting face in the inner point + - faces intersection by inner point + + Types of interfering shapes could be specified, by default all pairs of + interfering shapes are returned. + + Parameters: + shapeType1 first type of shape + shapeType2 second type of shape + + Returns: + New List, of pairs of interfering shapes with given types (if they was specified) + + Example of usage: + Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) + cc = CheckConformity(Box_1, geompy) + interferingSubshapes = cc.interferingSubshapes() + interferingSubshapesVV = cc.interferingSubshapes(geompy.ShapeType["VERTEX"], geompy.ShapeType["VERTEX"]) + """ + if not self.myIsChecked: + self.__checkShape() + + anOp = self.geompyD.GetIMeasureOperations() + return anOp.interferingSubshapes(self.myResults, shapeType1, shapeType2) + + ## Find edges, which are fully covered by tolerances of vertices. + # + # @return New List of edges, which are fully covered by tolerances of vertices + def smallEdges(self): + """ + Find edges, which are fully covered by tolerances of vertices. + + Returns: + New List of edges, which are fully covered by tolerances of vertices. + + Example of usage: + Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) + cc = CheckConformity(Box_1, geompy) + smallEdges = cc.smallEdges() + """ + if not self.myIsChecked: + self.__checkShape() + + anOp = self.geompyD.GetIMeasureOperations() + return anOp.smallEdges(self.myResults) + + ## Find remote objects (sub-shape on a shape): + # - vertex far from edge; + # - vertex far from face; + # - edge far from face + # + # Sub-shape which are lying far from its parent shape more than the given tolerance. + # + # @param shapeType type of shape + # @param subShapeType type of sub-shape + # @param tolerance available tolerance, by default used tolerance of sub-shape. + # + # @return New List, of pair of sub-shape with given types, + # that lying far from its parent shape more than the given tolerance. + def distantShapes(self, shapeType = geompy.ShapeType["AUTO"], subShapeType = geompy.ShapeType["AUTO"], tolerance = -1.0): + """ + Find remote objects (sub-shape on a shape): + - vertex far from edge; + - vertex far from face; + - edge far from face + + Sub-shape which are lying far from its parent shape more than the given tolerance. + + Parameters: + shapeType type of shape + subShapeType type of sub-shape + tolerance available tolerance, by default used tolerance of sub-shape. + + Returns: + New List, of pair of sub-shape with given types, + that lying far from its parent shape more than the given tolerance + + Example of usage: + Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) + cc = CheckConformity(Box_1, geompy) + distantShapes = cc.distantShapes(geompy.ShapeType["EDGE"], geompy.ShapeType["VERTEX"]) + """ + anOp = self.geompyD.GetIMeasureOperations() + return anOp.distantShapes(self.myShape, shapeType, subShapeType, tolerance) + + ## Compute possible tolerance for the shape, + # minimize tolerance of shape as well as tolerance of sub-shapes as much as possible . + # + # @return New value of tolerance. + def updateTolerance(self): + """ + Compute possible tolerance for the shape, + minimize tolerance of shape as well as tolerance of sub-shapes as much as possible. + + Returns: + New value of tolerance. + + Example of usage: + Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) + cc = CheckConformity(Box_1, geompy) + toler = cc.updateTolerance() + """ + anOp = self.geompyD.GetIMeasureOperations() + self.myIsChecked = False + print(anOp.updateTolerance(self.myShape)) -- 2.39.2