From 01a78f8c80163318d804a13d9b402cc52f106ad9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me?= Date: Wed, 4 Nov 2020 15:31:17 +0100 Subject: [PATCH] Implementation of inspection of duplicated faces --- .../ConnectorPlugin_PublishToStudyFeature.py | 82 +- src/FeaturesAPI/CMakeLists.txt | 2 + src/FeaturesAPI/FeaturesAPI.i | 2 + .../FeaturesAPI_DuplicatedFaces.cpp | 94 ++ src/FeaturesAPI/FeaturesAPI_DuplicatedFaces.h | 86 ++ src/FeaturesAPI/FeaturesAPI_swig.h | 1 + src/FeaturesPlugin/CMakeLists.txt | 37 +- .../FeaturesPlugin_CommonDuplicatedFaces.cpp | 144 +++ .../FeaturesPlugin_CommonDuplicatedFaces.h | 72 ++ .../FeaturesPlugin_DuplicatedFaces.cpp | 202 ++++ .../FeaturesPlugin_DuplicatedFaces.h | 143 +++ .../FeaturesPlugin_GroupDuplicatedFaces.cpp | 146 +++ .../FeaturesPlugin_GroupDuplicatedFaces.h | 124 ++ src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp | 30 +- src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts | 136 +++ .../Test/TestCheckDuplicatedFaces.py | 92 ++ src/FeaturesPlugin/doc/FeaturesPlugin.rst | 1 + .../doc/TUI_DuplicatedFacesFeature.rst | 11 + .../doc/checkDuplicatedFaceFeature.rst | 54 + .../doc/examples/checkDuplicatedFaces.py | 29 + .../checkduplicatedFacesPropertyPanel.png | Bin 0 -> 27797 bytes .../doc/images/duplicatedFacesResult.png | Bin 0 -> 8086 bytes .../doc/images/duplicated_shapes.png | Bin 0 -> 947 bytes .../duplicated_faces_macro_widget.xml | 40 + .../duplicated_faces_widget.xml | 37 + src/FeaturesPlugin/icons/duplicatedFaces.png | Bin 0 -> 947 bytes src/FeaturesPlugin/plugin-Features.xml | 10 +- src/FeaturesPlugin/tests.set | 3 +- src/GeomAlgoAPI/CMakeLists.txt | 26 + src/GeomAlgoAPI/GEOMAlgo_AlgoTools.cxx | 1006 +++++++++++++++++ src/GeomAlgoAPI/GEOMAlgo_AlgoTools.hxx | 198 ++++ src/GeomAlgoAPI/GEOMAlgo_BndSphere.cxx | 57 + src/GeomAlgoAPI/GEOMAlgo_BndSphere.hxx | 73 ++ src/GeomAlgoAPI/GEOMAlgo_BndSphere.lxx | 108 ++ src/GeomAlgoAPI/GEOMAlgo_BndSphereTree.cxx | 89 ++ src/GeomAlgoAPI/GEOMAlgo_BndSphereTree.hxx | 53 + src/GeomAlgoAPI/GEOMAlgo_CoupleOfShapes.cxx | 85 ++ src/GeomAlgoAPI/GEOMAlgo_CoupleOfShapes.hxx | 64 ++ .../GEOMAlgo_IndexedDataMapOfIntegerShape.hxx | 45 + ...ndexedDataMapOfPassKeyShapeListOfShape.hxx | 46 + ...EOMAlgo_IndexedDataMapOfShapeBndSphere.hxx | 46 + ...IndexedDataMapOfShapeIndexedMapOfShape.hxx | 50 + .../GEOMAlgo_ListOfCoupleOfShapes.hxx | 34 + src/GeomAlgoAPI/GEOMAlgo_PassKey.cxx | 240 ++++ src/GeomAlgoAPI/GEOMAlgo_PassKey.hxx | 105 ++ src/GeomAlgoAPI/GEOMAlgo_PassKeyMapHasher.cxx | 47 + src/GeomAlgoAPI/GEOMAlgo_PassKeyMapHasher.hxx | 51 + src/GeomAlgoAPI/GEOMAlgo_PassKeyShape.cxx | 229 ++++ src/GeomAlgoAPI/GEOMAlgo_PassKeyShape.hxx | 105 ++ .../GEOMAlgo_PassKeyShapeMapHasher.cxx | 47 + .../GEOMAlgo_PassKeyShapeMapHasher.hxx | 52 + src/GeomAlgoAPI/GeomAlgoAPI_Algo.cpp | 82 ++ src/GeomAlgoAPI/GeomAlgoAPI_Algo.h | 68 ++ .../GeomAlgoAPI_DuplicatedFaces.cpp | 142 +++ src/GeomAlgoAPI/GeomAlgoAPI_DuplicatedFaces.h | 38 + src/GeomAlgoAPI/GeomAlgoAPI_GlueDetector.cpp | 594 ++++++++++ src/GeomAlgoAPI/GeomAlgoAPI_GlueDetector.h | 91 ++ src/GeomAlgoAPI/GeomAlgoAPI_GluerAlgo.cpp | 138 +++ src/GeomAlgoAPI/GeomAlgoAPI_GluerAlgo.h | 91 ++ src/ModelHighAPI/CMakeLists.txt | 6 +- src/PythonAPI/model/features/__init__.py | 1 + 61 files changed, 5624 insertions(+), 61 deletions(-) create mode 100644 src/FeaturesAPI/FeaturesAPI_DuplicatedFaces.cpp create mode 100644 src/FeaturesAPI/FeaturesAPI_DuplicatedFaces.h create mode 100644 src/FeaturesPlugin/FeaturesPlugin_CommonDuplicatedFaces.cpp create mode 100644 src/FeaturesPlugin/FeaturesPlugin_CommonDuplicatedFaces.h create mode 100644 src/FeaturesPlugin/FeaturesPlugin_DuplicatedFaces.cpp create mode 100644 src/FeaturesPlugin/FeaturesPlugin_DuplicatedFaces.h create mode 100644 src/FeaturesPlugin/FeaturesPlugin_GroupDuplicatedFaces.cpp create mode 100644 src/FeaturesPlugin/FeaturesPlugin_GroupDuplicatedFaces.h create mode 100644 src/FeaturesPlugin/Test/TestCheckDuplicatedFaces.py create mode 100644 src/FeaturesPlugin/doc/TUI_DuplicatedFacesFeature.rst create mode 100644 src/FeaturesPlugin/doc/checkDuplicatedFaceFeature.rst create mode 100644 src/FeaturesPlugin/doc/examples/checkDuplicatedFaces.py create mode 100644 src/FeaturesPlugin/doc/images/checkduplicatedFacesPropertyPanel.png create mode 100644 src/FeaturesPlugin/doc/images/duplicatedFacesResult.png create mode 100644 src/FeaturesPlugin/doc/images/duplicated_shapes.png create mode 100644 src/FeaturesPlugin/duplicated_faces_macro_widget.xml create mode 100644 src/FeaturesPlugin/duplicated_faces_widget.xml create mode 100644 src/FeaturesPlugin/icons/duplicatedFaces.png create mode 100644 src/GeomAlgoAPI/GEOMAlgo_AlgoTools.cxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_AlgoTools.hxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_BndSphere.cxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_BndSphere.hxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_BndSphere.lxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_BndSphereTree.cxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_BndSphereTree.hxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_CoupleOfShapes.cxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_CoupleOfShapes.hxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_IndexedDataMapOfIntegerShape.hxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_IndexedDataMapOfShapeBndSphere.hxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape.hxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_ListOfCoupleOfShapes.hxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_PassKey.cxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_PassKey.hxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_PassKeyMapHasher.cxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_PassKeyMapHasher.hxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_PassKeyShape.cxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_PassKeyShape.hxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_PassKeyShapeMapHasher.cxx create mode 100644 src/GeomAlgoAPI/GEOMAlgo_PassKeyShapeMapHasher.hxx create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_Algo.cpp create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_Algo.h create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_DuplicatedFaces.cpp create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_DuplicatedFaces.h create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_GlueDetector.cpp create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_GlueDetector.h create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_GluerAlgo.cpp create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_GluerAlgo.h diff --git a/src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py b/src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py index a721ad73b..0468a9f6c 100644 --- a/src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py +++ b/src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py @@ -163,51 +163,55 @@ class PublishToStudyFeature(ModelAPI.ModelAPI_Feature): # If theFields is true, the same is performed for Fields. def processGroups(self, theRes, theEngine, thePartFeatureId, theStudyShape, theFields): allGroupsProcessed = [] + allRefGroups = [] if theFields: - aRefGroups = ModelAPI.referencedFeatures(theRes, "Field", True) + allRefGroups.append(ModelAPI.referencedFeatures(theRes, "Field", True)) else: - aRefGroups = ModelAPI.referencedFeatures(theRes, "Group", True) - for aRef in aRefGroups: - aGroupIndices = [] - aGroupHasIndex = {} - aResShape = theRes.shape() - if theFields: - aSelList = aRef.selectionList("selected") - else: - aSelList = aRef.selectionList("group_list") - aSelType = GeomAPI_Shape.shapeTypeByStr(aSelList.selectionType()) - for aGroupRes in aRef.results(): - aShape = aGroupRes.shape() - anExplorer = GeomAPI_ShapeExplorer(aShape, aSelType) - while anExplorer.more(): - anId = GeomAlgoAPI.GeomAlgoAPI_CompoundBuilder.id(aResShape, anExplorer.current()) - if anId > 0 and not anId in aGroupHasIndex: - aGroupIndices.append(anId) - aGroupHasIndex[anId] = 0 - anExplorer.next() - if len(aGroupIndices): # create group - aGroupFeatureId = aRef.data().featureId() + allRefGroups.append(ModelAPI.referencedFeatures(theRes, "Group", True)) + allRefGroups.append(ModelAPI.referencedFeatures(theRes, "Shared_faces", True)) + allRefGroups.append(ModelAPI.referencedFeatures(theRes, "Duplicated_faces", True)) + for aRefGroups in allRefGroups: + for aRef in aRefGroups: + aGroupIndices = [] + aGroupHasIndex = {} + aResShape = theRes.shape() if theFields: - aFieldOp = theEngine.GetIFieldOperations() - aGroupEntry = "field" + str(thePartFeatureId) + ":" + str(aGroupFeatureId) - aGroup = aFieldOp.FindField(theStudyShape, aGroupEntry) + aSelList = aRef.selectionList("selected") else: - aGroupOp = theEngine.GetIGroupOperations() - aGroupEntry = "group" + str(thePartFeatureId) + ":" + str(aGroupFeatureId) - aGroup = aGroupOp.FindGroup(theStudyShape, aGroupEntry) - if not aGroup: # create a new + aSelList = aRef.selectionList("group_list") + aSelType = GeomAPI_Shape.shapeTypeByStr(aSelList.selectionType()) + for aGroupRes in aRef.results(): + aShape = aGroupRes.shape() + anExplorer = GeomAPI_ShapeExplorer(aShape, aSelType) + while anExplorer.more(): + anId = GeomAlgoAPI.GeomAlgoAPI_CompoundBuilder.id(aResShape, anExplorer.current()) + if anId > 0 and not anId in aGroupHasIndex: + aGroupIndices.append(anId) + aGroupHasIndex[anId] = 0 + anExplorer.next() + if len(aGroupIndices): # create group + aGroupFeatureId = aRef.data().featureId() if theFields: - aGroup = aFieldOp.CreateFieldByType(theStudyShape, aSelType) + aFieldOp = theEngine.GetIFieldOperations() + aGroupEntry = "field" + str(thePartFeatureId) + ":" + str(aGroupFeatureId) + aGroup = aFieldOp.FindField(theStudyShape, aGroupEntry) else: - aGroup = aGroupOp.CreateGroup(theStudyShape, aSelType) - aGroup.SetEntry(aGroupEntry) - theEngine.AddInStudy(aGroup, aRef.firstResult().data().name(), theStudyShape) - aGroup.SetSelection(aGroupIndices) - if theFields: - self.fillField(aGroup, aRef, theEngine, aGroupIndices) - # a group takes shape from the main result - #aGroup.SetShapeByStream(aRef.firstResult().shape().getShapeStream(False)) # group shape - allGroupsProcessed.append(aGroupEntry) + aGroupOp = theEngine.GetIGroupOperations() + aGroupEntry = "group" + str(thePartFeatureId) + ":" + str(aGroupFeatureId) + aGroup = aGroupOp.FindGroup(theStudyShape, aGroupEntry) + if not aGroup: # create a new + if theFields: + aGroup = aFieldOp.CreateFieldByType(theStudyShape, aSelType) + else: + aGroup = aGroupOp.CreateGroup(theStudyShape, aSelType) + aGroup.SetEntry(aGroupEntry) + theEngine.AddInStudy(aGroup, aRef.firstResult().data().name(), theStudyShape) + aGroup.SetSelection(aGroupIndices) + if theFields: + self.fillField(aGroup, aRef, theEngine, aGroupIndices) + # a group takes shape from the main result + #aGroup.SetShapeByStream(aRef.firstResult().shape().getShapeStream(False)) # group shape + allGroupsProcessed.append(aGroupEntry) # check all existing groups: if some does not processed, remove it from the tree aSOIter = SHAPERSTUDY_utils.getStudy().NewChildIterator(theStudyShape.GetSO()) while aSOIter.More(): diff --git a/src/FeaturesAPI/CMakeLists.txt b/src/FeaturesAPI/CMakeLists.txt index 6cd9ba368..88e1dfb3a 100644 --- a/src/FeaturesAPI/CMakeLists.txt +++ b/src/FeaturesAPI/CMakeLists.txt @@ -33,6 +33,7 @@ SET(PROJECT_HEADERS FeaturesAPI_Intersection.h FeaturesAPI_Measurement.h FeaturesAPI_NormalToFace.h + FeaturesAPI_DuplicatedFaces.h FeaturesAPI_MultiRotation.h FeaturesAPI_MultiTranslation.h FeaturesAPI_Partition.h @@ -70,6 +71,7 @@ SET(PROJECT_SOURCES FeaturesAPI_Intersection.cpp FeaturesAPI_Measurement.cpp FeaturesAPI_NormalToFace.cpp + FeaturesAPI_DuplicatedFaces.cpp FeaturesAPI_MultiRotation.cpp FeaturesAPI_MultiTranslation.cpp FeaturesAPI_Partition.cpp diff --git a/src/FeaturesAPI/FeaturesAPI.i b/src/FeaturesAPI/FeaturesAPI.i index d9fa7c0b5..5c566c243 100644 --- a/src/FeaturesAPI/FeaturesAPI.i +++ b/src/FeaturesAPI/FeaturesAPI.i @@ -64,6 +64,7 @@ %shared_ptr(FeaturesAPI_BooleanFill) %shared_ptr(FeaturesAPI_Chamfer) %shared_ptr(FeaturesAPI_NormalToFace) +%shared_ptr(FeaturesAPI_DuplicatedFaces) %shared_ptr(FeaturesAPI_Extrusion) %shared_ptr(FeaturesAPI_ExtrusionBoolean) %shared_ptr(FeaturesAPI_ExtrusionCut) @@ -214,6 +215,7 @@ %include "FeaturesAPI_Intersection.h" %include "FeaturesAPI_Measurement.h" %include "FeaturesAPI_NormalToFace.h" +%include "FeaturesAPI_DuplicatedFaces.h" %include "FeaturesAPI_MultiRotation.h" %include "FeaturesAPI_MultiTranslation.h" %include "FeaturesAPI_Partition.h" diff --git a/src/FeaturesAPI/FeaturesAPI_DuplicatedFaces.cpp b/src/FeaturesAPI/FeaturesAPI_DuplicatedFaces.cpp new file mode 100644 index 000000000..0aa69855a --- /dev/null +++ b/src/FeaturesAPI/FeaturesAPI_DuplicatedFaces.cpp @@ -0,0 +1,94 @@ +// Copyright (C) 2018-2021 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 "FeaturesAPI_DuplicatedFaces.h" + +#include + +#include +#include + +#include +#include +#include + +//================================================================================================= +FeaturesAPI_DuplicatedFaces:: + FeaturesAPI_DuplicatedFaces(const std::shared_ptr& theFeature) + : ModelHighAPI_Interface(theFeature) +{ + initialize(); +} + +//================================================================================================= +FeaturesAPI_DuplicatedFaces::~FeaturesAPI_DuplicatedFaces() +{ +} + +//================================================================================================= +FeaturesAPI_DuplicatedFaces::FeaturesAPI_DuplicatedFaces( + const std::shared_ptr& theFeature, + const ModelHighAPI_Selection& theObject, + const ModelHighAPI_Double& theTolerance, + const std::string & theNameGroup) +:ModelHighAPI_Interface(theFeature) +{ + if (initialize()) { + fillAttribute(theObject, myobjectselected); + fillAttribute(theTolerance, mytolerance); + fillAttribute(theNameGroup, mygroupname); + + execute(); + } +} + +//================================================================================================= +void FeaturesAPI_DuplicatedFaces::dump(ModelHighAPI_Dumper& theDumper) const +{ + FeaturePtr aBase = feature(); + const std::string& aDocName = theDumper.name(aBase->document()); + + AttributeSelectionPtr anAttrObject; + anAttrObject = aBase->selection(FeaturesPlugin_GroupDuplicatedFaces::OBJECT_ID()); + + theDumper << aBase << " = model.getDuplicatedFaces(" << aDocName << ", " << anAttrObject; + theDumper << ", " << aBase->real(FeaturesPlugin_GroupDuplicatedFaces::TOLERANCE_ID()); + theDumper << ", " << aBase->string(FeaturesPlugin_GroupDuplicatedFaces::GROUP_NAME_ID()); + theDumper << ")" << std::endl; +} + +//================================================================================================= +DuplicatedFacesPtr getDuplicatedFaces(const std::shared_ptr& thePart, + const ModelHighAPI_Selection& theObject, + const ModelHighAPI_Double& theTolerance, + const std::string & theNameGroup) +{ + + FeaturePtr aFeature = thePart->addFeature(FeaturesPlugin_GroupDuplicatedFaces::ID()); + + DuplicatedFacesPtr aDuplicatedFaces; + + aDuplicatedFaces.reset(new FeaturesAPI_DuplicatedFaces(aFeature, + theObject, + theTolerance, + theNameGroup)); + + return aDuplicatedFaces; +} + diff --git a/src/FeaturesAPI/FeaturesAPI_DuplicatedFaces.h b/src/FeaturesAPI/FeaturesAPI_DuplicatedFaces.h new file mode 100644 index 000000000..f3c426d93 --- /dev/null +++ b/src/FeaturesAPI/FeaturesAPI_DuplicatedFaces.h @@ -0,0 +1,86 @@ +// Copyright (C) 2018-2021 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 FeaturesAPI_DuplicatedFaces_H_ +#define FeaturesAPI_DuplicatedFaces_H_ + +#include "FeaturesAPI.h" +#include "FeaturesPlugin_GroupDuplicatedFaces.h" + +#include +#include +#include +#include + +#include + +class ModelAPI_Document; +class ModelHighAPI_Selection; + +/// \class FeaturesAPI_DuplicatedFaces +/// \ingroup CPPHighAPI +/// \brief Interface to find duplicated faces +class FeaturesAPI_DuplicatedFaces: public ModelHighAPI_Interface +{ +public: + /// Constructor without values. + FEATURESAPI_EXPORT + explicit FeaturesAPI_DuplicatedFaces(const std::shared_ptr& theFeature); + + FEATURESAPI_EXPORT + explicit FeaturesAPI_DuplicatedFaces(const std::shared_ptr& theFeature, + const ModelHighAPI_Selection& theobject, + const ModelHighAPI_Double& theTolerance, + const std::string & theNameGroup); + + /// Destructor. + FEATURESAPI_EXPORT + virtual ~FeaturesAPI_DuplicatedFaces(); + + INTERFACE_3(FeaturesPlugin_GroupDuplicatedFaces::ID(), + objectselected, FeaturesPlugin_GroupDuplicatedFaces::OBJECT_ID(), + ModelAPI_AttributeSelection, + /** object selected*/, + tolerance, FeaturesPlugin_GroupDuplicatedFaces::TOLERANCE_ID(), + ModelAPI_AttributeDouble, + /** tolerance*/, + groupname, FeaturesPlugin_GroupDuplicatedFaces::GROUP_NAME_ID(), + ModelAPI_AttributeString, + /** group name*/) + + /// Dump wrapped feature + FEATURESAPI_EXPORT + virtual void dump(ModelHighAPI_Dumper& theDumper) const; + +}; + +/// Pointer on the SharedFaces object. +typedef std::shared_ptr DuplicatedFacesPtr; + +/// \ingroup CPPHighAPI +/// \brief get the duplicated Faces +/// \param thePart the part +/// \param theobject the object selected +FEATURESAPI_EXPORT +DuplicatedFacesPtr getDuplicatedFaces(const std::shared_ptr& thePart, + const ModelHighAPI_Selection& theObject, + const ModelHighAPI_Double& theTolerance, + const std::string & theNameGroup); + +#endif // FeaturesAPI_DuplicatedFaces_H_ diff --git a/src/FeaturesAPI/FeaturesAPI_swig.h b/src/FeaturesAPI/FeaturesAPI_swig.h index ede8f2c11..8e63c34ca 100644 --- a/src/FeaturesAPI/FeaturesAPI_swig.h +++ b/src/FeaturesAPI/FeaturesAPI_swig.h @@ -36,6 +36,7 @@ #include "FeaturesAPI_Intersection.h" #include "FeaturesAPI_Measurement.h" #include "FeaturesAPI_NormalToFace.h" + #include "FeaturesAPI_DuplicatedFaces.h" #include "FeaturesAPI_MultiRotation.h" #include "FeaturesAPI_MultiTranslation.h" #include "FeaturesAPI_Partition.h" diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index e3f25e81d..f758c2d4e 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -19,6 +19,16 @@ INCLUDE(Common) INCLUDE(UnitTest) +INCLUDE(UseQtExt) + +# additional include directories +INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/GeomDataAPI + ${PROJECT_SOURCE_DIR}/src/Locale + ${QT_INCLUDES}) + +# additional preprocessor / compiler flags +ADD_DEFINITIONS(${QT_DEFINITIONS}) + SET(PROJECT_HEADERS @@ -60,6 +70,9 @@ SET(PROJECT_HEADERS FeaturesPlugin_Fillet.h FeaturesPlugin_Fillet1D.h FeaturesPlugin_Measurement.h + FeaturesPlugin_DuplicatedFaces.h + FeaturesPlugin_CommonDuplicatedFaces.h + FeaturesPlugin_GroupDuplicatedFaces.h FeaturesPlugin_FusionFaces.h FeaturesPlugin_RemoveResults.h FeaturesPlugin_Chamfer.h @@ -114,6 +127,9 @@ SET(PROJECT_SOURCES FeaturesPlugin_Fillet.cpp FeaturesPlugin_Fillet1D.cpp FeaturesPlugin_Measurement.cpp + FeaturesPlugin_DuplicatedFaces.cpp + FeaturesPlugin_CommonDuplicatedFaces.cpp + FeaturesPlugin_GroupDuplicatedFaces.cpp FeaturesPlugin_FusionFaces.cpp FeaturesPlugin_RemoveResults.cpp FeaturesPlugin_Chamfer.cpp @@ -159,6 +175,8 @@ SET(XML_RESOURCES fillet_widget.xml fillet1d_widget.xml measurement_widget.xml + duplicated_faces_widget.xml + duplicated_faces_macro_widget.xml fusion_faces_widget.xml chamfer_widget.xml copy_widget.xml @@ -178,6 +196,12 @@ SET(TEXT_RESOURCES FeaturesPlugin_msg_ru.ts ) +# sources / moc wrappings +QT_WRAP_MOC(PROJECT_AUTOMOC ${PROJECT_MOC_HEADERS}) + +#QT5_ADD_TRANSLATION(QM_RESOURCES ${TEXT_RESOURCES}) + +SOURCE_GROUP ("Generated Files" FILES ${PROJECT_AUTOMOC} ${PROJECT_COMPILED_RESOURCES} ${QM_RESOURCES}) SOURCE_GROUP ("XML Files" FILES ${XML_RESOURCES}) SOURCE_GROUP ("Resource Files" FILES ${TEXT_RESOURCES}) @@ -204,7 +228,12 @@ SET(PROJECT_LIBRARIES ) ADD_DEFINITIONS(-DFEATURESPLUGIN_EXPORTS) -ADD_LIBRARY(FeaturesPlugin MODULE ${PROJECT_SOURCES} ${PROJECT_HEADERS} ${XML_RESOURCES} ${TEXT_RESOURCES}) +ADD_LIBRARY(FeaturesPlugin MODULE + ${PROJECT_SOURCES} + ${PROJECT_HEADERS} + ${XML_RESOURCES} + ${TEXT_RESOURCES} + ${PROJECT_AUTOMOC}) TARGET_LINK_LIBRARIES(FeaturesPlugin ${PROJECT_LIBRARIES}) INSTALL(TARGETS FeaturesPlugin DESTINATION ${SHAPER_INSTALL_PLUGIN_FILES}) @@ -221,16 +250,16 @@ ADD_UNIT_TESTS( IF(${HAVE_SALOME}) enable_testing() set(TEST_INSTALL_DIRECTORY "${SALOME_SHAPER_INSTALL_TESTS}/FeaturesPlugin") - + install(FILES CTestTestfileInstall.cmake DESTINATION ${TEST_INSTALL_DIRECTORY} RENAME CTestTestfile.cmake) install(FILES tests.set DESTINATION ${TEST_INSTALL_DIRECTORY}) - + set(TMP_TESTS_NAMES) foreach(tfile ${TEST_NAMES}) list(APPEND TMP_TESTS_NAMES "Test/${tfile}") endforeach(tfile ${TEST_NAMES}) - + install(FILES ${TMP_TESTS_NAMES} DESTINATION ${TEST_INSTALL_DIRECTORY}) ENDIF(${HAVE_SALOME}) diff --git a/src/FeaturesPlugin/FeaturesPlugin_CommonDuplicatedFaces.cpp b/src/FeaturesPlugin/FeaturesPlugin_CommonDuplicatedFaces.cpp new file mode 100644 index 000000000..bc66326c7 --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_CommonDuplicatedFaces.cpp @@ -0,0 +1,144 @@ +// Copyright (C) 2018-2021 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 "FeaturesPlugin_CommonDuplicatedFaces.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +//================================================================================================= +void explode(const GeomShapePtr& theCompound, ListOfShape& theSubs) +{ + if (theCompound->isCompound() || theCompound->isCompSolid()) { + GeomAPI_ShapeIterator anIt(theCompound); + for (; anIt.more(); anIt.next()) + explode(anIt.current(), theSubs); + } else + theSubs.push_back(theCompound); +} + +//================================================================================================= +void FeaturesPlugin_CommonDuplicatedFaces::updateFaces() +{ + AttributeSelectionPtr ancompSolidAttr = + std::dynamic_pointer_cast(attributObject()); + + AttributeSelectionListPtr aFacesListAttr = + std::dynamic_pointer_cast + (attributListFaces()); + + GeomShapePtr aShape = ancompSolidAttr->value(); + + AttributeDoublePtr aToleranceAttr = + std::dynamic_pointer_cast + (attributTolerance()); + + AttributeBooleanPtr anIsCompute = + std::dynamic_pointer_cast(attributIsCompute()); + if (!anIsCompute->value()) { + myShape = aShape; + anIsCompute->setValue(true); + } + if (aShape.get() && ancompSolidAttr->context().get() + && aToleranceAttr.get() && !aShape->isEqual(myShape)) { + + if (aFacesListAttr->isInitialized()) + aFacesListAttr->clear(); + + aShape = ancompSolidAttr->context()->shape(); + if (aShape) { + std::string anError; + ListOfShape aFaces; + ListOfShape theSubs; + explode(aShape, theSubs); + + if (!GetDuplicatedFaces(theSubs, + aToleranceAttr->value(), + aFaces, + anError)) + setError("Error in duplicated faces calculation :" + anError); + + myShape = aShape; + aFacesListAttr->setSelectionType("face"); + + ListOfShape::const_iterator anIt = aFaces.cbegin(); + for (; anIt != aFaces.cend(); ++anIt) { + + GeomShapePtr aFacePtr = *anIt; + + if (!aFacePtr.get()) { + setError("GetDuplicatedFaces : An invalid face found " + anError); + } + aFacesListAttr->append(ancompSolidAttr->context(), aFacePtr); + } + std::stringstream alabel; + alabel << aFacesListAttr->size(); + AttributeStringPtr aNumberFacesAttr = + std::dynamic_pointer_cast + (attributNumberFaces()); + aNumberFacesAttr->setValue(alabel.str()); + } + } +} + +//================================================================================================= +void FeaturesPlugin_CommonDuplicatedFaces::setFacesGroup(const std::wstring& theName) +{ + std::vector aColor; + ResultGroupPtr aGroup = document()->createGroup(data()); + // clean the result of the operation + aGroup->data()->setName(theName); + aGroup->store(GeomShapePtr()); + + // shapes containing in group + ListOfShape aFaces; + AttributeSelectionListPtr aFacesListAttr = + std::dynamic_pointer_cast + (attributListFaces()); + + for (int anI =0; anI< aFacesListAttr->size(); anI++) { + AttributeSelectionPtr aAtt = aFacesListAttr->value(anI); + aFaces.push_back(aAtt->value()); + } + GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aFaces); + + aGroup->store(aCompound); + aColor = {255,0,0}; + setResult(aGroup); + ModelAPI_Tools::setColor(lastResult(),aColor); +} + diff --git a/src/FeaturesPlugin/FeaturesPlugin_CommonDuplicatedFaces.h b/src/FeaturesPlugin/FeaturesPlugin_CommonDuplicatedFaces.h new file mode 100644 index 000000000..c01b6a8b2 --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_CommonDuplicatedFaces.h @@ -0,0 +1,72 @@ +// Copyright (C) 2018-2021 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 FeaturesPlugin_CommonDuplicatedFaces_H_ +#define FeaturesPlugin_CommonDuplicatedFaces_H_ + +#include "FeaturesPlugin.h" + +#include +#include +#include + +#include +#include + + +/// \class FeaturesPlugin_CommonDuplicatedFaces +/// \ingroup Plugins +/// \brief Feature to check the duplicated faces of solid + +class FeaturesPlugin_CommonDuplicatedFaces : public ModelAPI_Feature +{ +public: + + /// Performs the algorithm and stores results it in the data structure. + FEATURESPLUGIN_EXPORT virtual void execute(){}; + + /// Return Attribut values of result. + virtual AttributePtr attributObject() = 0; + + /// Return Attribut values of result. + virtual AttributePtr attributListFaces() = 0; + + /// Return Attribut values of result. + virtual AttributePtr attributNumberFaces() = 0; + + /// Return Attribut values of tolerance. + virtual AttributePtr attributTolerance() = 0; + + /// Return Attribut values of IsCompute. + virtual AttributePtr attributIsCompute() = 0; + + protected: + FeaturesPlugin_CommonDuplicatedFaces() {} + + //Set group of faces + void setFacesGroup(const std::wstring& theName); + + // Update the list of faces + void updateFaces(); + + // the shape studied + GeomShapePtr myShape; +}; + +#endif diff --git a/src/FeaturesPlugin/FeaturesPlugin_DuplicatedFaces.cpp b/src/FeaturesPlugin/FeaturesPlugin_DuplicatedFaces.cpp new file mode 100644 index 000000000..badca1158 --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_DuplicatedFaces.cpp @@ -0,0 +1,202 @@ +// Copyright (C) 2018-2021 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 "FeaturesPlugin_DuplicatedFaces.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +//================================================================================================= +FeaturesPlugin_DuplicatedFaces::FeaturesPlugin_DuplicatedFaces() +{ +} + +void FeaturesPlugin_DuplicatedFaces::initAttributes() +{ + // attribute for object selected + data()->addAttribute(OBJECT_ID(), ModelAPI_AttributeSelection::typeId()); + AttributeSelectionListPtr aList = std::dynamic_pointer_cast( + data()->addAttribute(LIST_FACES_ID(), ModelAPI_AttributeSelectionList::typeId())); + + data()->addAttribute(NUMBER_FACES_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(TRANSPARENCY_ID(), ModelAPI_AttributeInteger::typeId()); + data()->addAttribute(TOLERANCE_ID(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(CREATE_GROUP_ID(), ModelAPI_AttributeBoolean::typeId()); + data()->addAttribute(GROUP_NAME_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(COMPUTE_ID(), ModelAPI_AttributeBoolean::typeId()); + + + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), GROUP_NAME_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), COMPUTE_ID()); + data()->boolean(COMPUTE_ID())->setValue(true); +} + +//================================================================================================= +AttributePtr FeaturesPlugin_DuplicatedFaces::attributIsCompute() +{ + return attribute(COMPUTE_ID()); +} + +//================================================================================================= +AttributePtr FeaturesPlugin_DuplicatedFaces::attributObject() +{ + return attribute(OBJECT_ID()); +} + +//================================================================================================= +AttributePtr FeaturesPlugin_DuplicatedFaces::attributListFaces() +{ + return attribute(LIST_FACES_ID()); +} + +//================================================================================================= +AttributePtr FeaturesPlugin_DuplicatedFaces::attributNumberFaces() +{ + return attribute(NUMBER_FACES_ID()); +} + +//================================================================================================= +AttributePtr FeaturesPlugin_DuplicatedFaces::attributTolerance() +{ + return attribute(TOLERANCE_ID()); +} + + +//================================================================================================= +void FeaturesPlugin_DuplicatedFaces::execute() +{ + if (boolean(CREATE_GROUP_ID())->value()) { + + if (string(GROUP_NAME_ID())->value() != "" + && selectionList(LIST_FACES_ID())->isInitialized()) { + + if (lastResult().get()) { + eraseResultFromList(lastResult()); + } + + if (!myCreateGroupFeature.get()) + createGroup(); + updateGroup(); + } + + } else { + if (selectionList(LIST_FACES_ID())->isInitialized()) { + + if (myCreateGroupFeature.get()) { + myCreateGroupFeature->eraseResults(); + SessionPtr aSession = ModelAPI_Session::get(); + DocumentPtr aDoc = aSession->activeDocument(); + aDoc->removeFeature(myCreateGroupFeature); + myCreateGroupFeature.reset(); + } + + if (lastResult().get()) + eraseResultFromList(lastResult()); + setFacesGroup(L"Group_DuplicatedFaces"); + } + } + + if (selection(OBJECT_ID())->isInitialized()) { + AttributeSelectionPtr ancompSolidAttr = selection(OBJECT_ID()); + ResultPtr aResult = ancompSolidAttr->context(); + + double aTranparency = integer(TRANSPARENCY_ID())->value()/100.0; + ModelAPI_Tools::setTransparency(aResult, aTranparency); + + ResultBodyPtr aResultBody = std::dynamic_pointer_cast(aResult); + std::list allRes; + ModelAPI_Tools::allSubs(aResultBody, allRes); + std::list::iterator aRes; + for (aRes = allRes.begin(); aRes != allRes.end(); aRes++) { + ModelAPI_Tools::setTransparency(*aRes, aTranparency); + } + } +} + +//================================================================================================= +void FeaturesPlugin_DuplicatedFaces::attributeChanged(const std::string& theID) +{ + if (theID == OBJECT_ID() + || theID == TOLERANCE_ID()) { + updateFaces(); + if (myCreateGroupFeature.get()) + updateGroup(); + } +} + +//================================================================================================= +void FeaturesPlugin_DuplicatedFaces::createGroup() +{ + SessionPtr aSession = ModelAPI_Session::get(); + + DocumentPtr aDoc = aSession->activeDocument(); + + if (aDoc.get()) { + myCreateGroupFeature = aDoc->addFeature(FeaturesPlugin_GroupDuplicatedFaces::ID()); + } +} + +//================================================================================================= +void FeaturesPlugin_DuplicatedFaces::updateGroup() +{ + myCreateGroupFeature-> + boolean(FeaturesPlugin_GroupDuplicatedFaces::COMPUTE_ID())->setValue(false); + myCreateGroupFeature->string(FeaturesPlugin_GroupDuplicatedFaces::GROUP_NAME_ID()) + ->setValue(string(GROUP_NAME_ID())->value()); + + myCreateGroupFeature->selection(FeaturesPlugin_GroupDuplicatedFaces::OBJECT_ID()) + ->setValue(selection(OBJECT_ID())->context(), + selection(OBJECT_ID())->value()); + + AttributeSelectionListPtr aFacesFeatures = + std::dynamic_pointer_cast + (myCreateGroupFeature->attribute(LIST_FACES_ID())); + AttributeSelectionListPtr aFaces = + std::dynamic_pointer_cast(attribute(LIST_FACES_ID())); + + aFaces->copyTo(aFacesFeatures); + + myCreateGroupFeature->integer(FeaturesPlugin_GroupDuplicatedFaces::TRANSPARENCY_ID()) + ->setValue(integer(TRANSPARENCY_ID())->value()); + + myCreateGroupFeature->real(FeaturesPlugin_GroupDuplicatedFaces::TOLERANCE_ID()) + ->setValue(real(TOLERANCE_ID())->value()); + + myCreateGroupFeature->execute(); + myCreateGroupFeature + ->boolean(FeaturesPlugin_GroupDuplicatedFaces::COMPUTE_ID())->setValue(true); +} diff --git a/src/FeaturesPlugin/FeaturesPlugin_DuplicatedFaces.h b/src/FeaturesPlugin/FeaturesPlugin_DuplicatedFaces.h new file mode 100644 index 000000000..666a66f06 --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_DuplicatedFaces.h @@ -0,0 +1,143 @@ +// Copyright (C) 2018-2021 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 FeaturesPlugin_DuplicatedFaces_H_ +#define FeaturesPlugin_DuplicatedFaces_H_ + +#include + +/// \class FeaturesPlugin_DuplicatedFaces +/// \ingroup Plugins +/// \brief Feature to check the duplicated faces of solid + +class FeaturesPlugin_DuplicatedFaces : public FeaturesPlugin_CommonDuplicatedFaces +{ +public: + inline static const std::string& ID() + { + static const std::string MY_ID("Duplicated_faces_macro"); + return MY_ID; + } + + /// \return the kind of a feature. + virtual const std::string& getKind() + { + return ID(); + } + + /// Attribute name for object selected. + inline static const std::string& OBJECT_ID() + { + static const std::string MY_OBJECT_ID("main_object"); + return MY_OBJECT_ID; + } + + /// Attribute name for number of faces. + inline static const std::string& NUMBER_FACES_ID() + { + static const std::string MY_NUMBER_FACES_ID("number_duplicated_faces"); + return MY_NUMBER_FACES_ID; + } + + /// Attribute name for z coodinate. + inline static const std::string& LIST_FACES_ID() + { + static const std::string MY_LIST_FACES_ID("group_list"); + return MY_LIST_FACES_ID; + } + + /// Attribute name for transparency. + inline static const std::string& TRANSPARENCY_ID() + { + static const std::string MY_TRANSPARENCY_ID("transparency"); + return MY_TRANSPARENCY_ID; + } + + /// Attribute name for tolerance. + inline static const std::string& TOLERANCE_ID() + { + static const std::string MY_TOLERANCE_ID("tolerance"); + return MY_TOLERANCE_ID; + } + + /// Attribute name for checkbox create group. + inline static const std::string& CREATE_GROUP_ID() + { + static const std::string MY_CREATE_GROUP_ID("create_group"); + return MY_CREATE_GROUP_ID; + } + + /// Attribute name for group name. + inline static const std::string& GROUP_NAME_ID() + { + static const std::string MY_GROUP_NAME_ID("group_name"); + return MY_GROUP_NAME_ID; + } + + /// Attribute name for indicate to launch the algo. + inline static const std::string& COMPUTE_ID() + { + static const std::string MY_COMPUTE_ID("compute"); + return MY_COMPUTE_ID; + } + + /// Performs the algorithm and stores results it in the data structure. + FEATURESPLUGIN_EXPORT virtual void execute(); + + /// Request for initialization of data model of the feature: adding all attributes + FEATURESPLUGIN_EXPORT virtual void initAttributes(); + + /// Called on change of any argument-attribute of this object + /// \param theID identifier of changed attribute + FEATURESPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID); + + /// Reimplemented from ModelAPI_Feature::isMacro(). Returns true. + FEATURESPLUGIN_EXPORT virtual bool isMacro() const { return true; } + + /// Use plugin manager for features creation + FeaturesPlugin_DuplicatedFaces(); + + private: + + /// Return Attribut values of object. + virtual AttributePtr attributObject(); + + /// Return Attribut values of list of faces. + virtual AttributePtr attributListFaces(); + + /// Return Attribut values of number of faces. + virtual AttributePtr attributNumberFaces(); + + /// Return Attribut values of tolerance. + virtual AttributePtr attributTolerance(); + + /// Return Attribut values of IsCompute. + virtual AttributePtr attributIsCompute(); + + /// Create group + void createGroup(); + + /// Update group + void updateGroup(); + + /// Feature to create group + FeaturePtr myCreateGroupFeature; +}; + +#endif diff --git a/src/FeaturesPlugin/FeaturesPlugin_GroupDuplicatedFaces.cpp b/src/FeaturesPlugin/FeaturesPlugin_GroupDuplicatedFaces.cpp new file mode 100644 index 000000000..4b0e1e351 --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_GroupDuplicatedFaces.cpp @@ -0,0 +1,146 @@ +// Copyright (C) 2018-2021 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 "FeaturesPlugin_GroupDuplicatedFaces.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +//================================================================================================= +FeaturesPlugin_GroupDuplicatedFaces::FeaturesPlugin_GroupDuplicatedFaces() +{ +} + +//================================================================================================= +void FeaturesPlugin_GroupDuplicatedFaces::initAttributes() +{ + // attribute for object selected + data()->addAttribute(OBJECT_ID(), ModelAPI_AttributeSelection::typeId()); + AttributeSelectionListPtr aList = std::dynamic_pointer_cast( + data()->addAttribute(LIST_FACES_ID(), ModelAPI_AttributeSelectionList::typeId())); + + data()->addAttribute(NUMBER_FACES_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(TRANSPARENCY_ID(), ModelAPI_AttributeInteger::typeId()); + data()->addAttribute(TOLERANCE_ID(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(GROUP_NAME_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(COMPUTE_ID(), ModelAPI_AttributeBoolean::typeId()); + + + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TRANSPARENCY_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), COMPUTE_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), NUMBER_FACES_ID()); + data()->boolean(COMPUTE_ID())->setValue(true); +} + + +//================================================================================================= +AttributePtr FeaturesPlugin_GroupDuplicatedFaces::attributObject() +{ + return attribute(OBJECT_ID()); +} + +//================================================================================================= +AttributePtr FeaturesPlugin_GroupDuplicatedFaces::attributIsCompute() +{ + return attribute(COMPUTE_ID()); +} + +//================================================================================================= +AttributePtr FeaturesPlugin_GroupDuplicatedFaces::attributListFaces() +{ + return attribute(LIST_FACES_ID()); +} + +//================================================================================================= +AttributePtr FeaturesPlugin_GroupDuplicatedFaces::attributNumberFaces() +{ + return attribute(NUMBER_FACES_ID()); +} + +//================================================================================================= +AttributePtr FeaturesPlugin_GroupDuplicatedFaces::attributTolerance() +{ + return attribute(TOLERANCE_ID()); +} + +//================================================================================================= +void FeaturesPlugin_GroupDuplicatedFaces::execute() +{ + if (selectionList(LIST_FACES_ID())->isInitialized() + && string(GROUP_NAME_ID())->value() != "") { + AttributeStringPtr aNameAtt = string(GROUP_NAME_ID()) ; + std::wstring aNameFace = aNameAtt->isUValue() ? + Locale::Convert::toWString(aNameAtt->valueU()) : + Locale::Convert::toWString(aNameAtt->value()); + + if (lastResult().get()) + eraseResultFromList(lastResult()); + setFacesGroup(aNameFace); + + } else { + if (lastResult().get()) { + eraseResultFromList(lastResult()); + } + + } + if (selection(OBJECT_ID())->isInitialized()) { + AttributeSelectionPtr ancompSolidAttr = selection(OBJECT_ID()); + ResultPtr aResult = ancompSolidAttr->context(); + + if(integer(TRANSPARENCY_ID())->isInitialized()){ + double aTranparency = integer(TRANSPARENCY_ID())->value()/100.0; + ModelAPI_Tools::setTransparency(aResult, aTranparency); + + + ResultBodyPtr aResultBody = std::dynamic_pointer_cast(aResult); + std::list allRes; + ModelAPI_Tools::allSubs(aResultBody, allRes); + std::list::iterator aRes; + for(aRes = allRes.begin(); aRes != allRes.end(); aRes++) { + ModelAPI_Tools::setTransparency(*aRes, aTranparency); + } + } + } +} + +//================================================================================================= +void FeaturesPlugin_GroupDuplicatedFaces::attributeChanged(const std::string& theID) +{ + if (theID == OBJECT_ID() + || theID == TOLERANCE_ID()) { + updateFaces(); + } +} diff --git a/src/FeaturesPlugin/FeaturesPlugin_GroupDuplicatedFaces.h b/src/FeaturesPlugin/FeaturesPlugin_GroupDuplicatedFaces.h new file mode 100644 index 000000000..0a45bd243 --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_GroupDuplicatedFaces.h @@ -0,0 +1,124 @@ +// Copyright (C) 2018-2021 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 FeaturesPlugin_GroupDuplicatedFaces_H_ +#define FeaturesPlugin_GroupDuplicatedFaces_H_ + +#include + +/// \class FeaturesPlugin_GroupDuplicatedFaces +/// \ingroup Plugins +/// \brief Feature to check the duplicated faces of solid + +class FeaturesPlugin_GroupDuplicatedFaces : public FeaturesPlugin_CommonDuplicatedFaces +{ +public: + inline static const std::string& ID() + { + static const std::string MY_ID("Duplicated_faces"); + return MY_ID; + } + + /// \return the kind of a feature. + virtual const std::string& getKind() + { + return ID(); + } + + /// Attribute name for object selected. + inline static const std::string& OBJECT_ID() + { + static const std::string MY_OBJECT_ID("main_object"); + return MY_OBJECT_ID; + } + + /// Attribute name for number of faces. + inline static const std::string& NUMBER_FACES_ID() + { + static const std::string MY_NUMBER_FACES_ID("number_duplicated_faces"); + return MY_NUMBER_FACES_ID; + } + + /// Attribute name for list of faces + inline static const std::string& LIST_FACES_ID() + { + static const std::string MY_LIST_FACES_ID("group_list"); + return MY_LIST_FACES_ID; + } + + /// Attribute name for transparency. + inline static const std::string& TRANSPARENCY_ID() + { + static const std::string MY_TRANSPARENCY_ID("transparency"); + return MY_TRANSPARENCY_ID; + } + + /// Attribute name for tolerance. + inline static const std::string& TOLERANCE_ID() + { + static const std::string MY_TOLERANCE_ID("tolerance"); + return MY_TOLERANCE_ID; + } + + /// Attribute name for group name. + inline static const std::string& GROUP_NAME_ID() + { + static const std::string MY_GROUP_NAME_ID("group_name"); + return MY_GROUP_NAME_ID; + } + + /// Attribute name for indicate to launch the algo. + inline static const std::string& COMPUTE_ID() + { + static const std::string MY_COMPUTE_ID("compute"); + return MY_COMPUTE_ID; + } + + /// Performs the algorithm and stores results it in the data structure. + FEATURESPLUGIN_EXPORT virtual void execute(); + + /// Request for initialization of data model of the feature: adding all attributes + FEATURESPLUGIN_EXPORT virtual void initAttributes(); + + /// Called on change of any argument-attribute of this object + /// \param theID identifier of changed attribute + FEATURESPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID); + + /// Use plugin manager for features creation + FeaturesPlugin_GroupDuplicatedFaces(); + + private: + + /// Return Attribut values of object. + virtual AttributePtr attributObject(); + + /// Return Attribut values of list of faces. + virtual AttributePtr attributListFaces(); + + /// Return Attribut values of number of faces. + virtual AttributePtr attributNumberFaces(); + + /// Return Attribut values of tolerance. + virtual AttributePtr attributTolerance(); + + /// Return Attribut values of IsCompute. + virtual AttributePtr attributIsCompute(); +}; + +#endif diff --git a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp index 3d00700d6..82a7b2b83 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp @@ -19,52 +19,53 @@ #include +#include #include +#include #include -#include #include -#include #include #include +#include #include -#include +#include #include #include -#include +#include #include +#include +#include #include +#include +#include #include #include #include #include -#include #include #include #include #include #include #include +#include #include +#include #include -#include #include #include +#include #include #include #include #include #include -#include -#include -#include -#include -#include #include +#include #include #include - #include // the only created instance of this plugin @@ -193,6 +194,10 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(std::string theFeatureID) return FeaturePtr(new FeaturesPlugin_Fillet1D); } else if (theFeatureID == FeaturesPlugin_Measurement::ID()) { return FeaturePtr(new FeaturesPlugin_Measurement); + } else if (theFeatureID == FeaturesPlugin_DuplicatedFaces::ID()) { + return FeaturePtr(new FeaturesPlugin_DuplicatedFaces); + } else if (theFeatureID == FeaturesPlugin_GroupDuplicatedFaces::ID()) { + return FeaturePtr(new FeaturesPlugin_GroupDuplicatedFaces); } else if (theFeatureID == FeaturesPlugin_RemoveResults::ID()) { return FeaturePtr(new FeaturesPlugin_RemoveResults); } else if (theFeatureID == FeaturesPlugin_Chamfer::ID()) { @@ -217,7 +222,6 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(std::string theFeatureID) return FeaturePtr(new FeaturesPlugin_NormalToFace); } - // feature of such kind is not found return FeaturePtr(); } diff --git a/src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts b/src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts index 878c1f4d5..796e5cb83 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts +++ b/src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts @@ -143,6 +143,10 @@ Rotation Rotation + + Check duplicated faces + Vérifier les faces dupliquées + Symmetry Symétrie @@ -4966,6 +4970,138 @@ + + + Duplicated_faces_macro + + Check duplicated faces + Vérifier les faces dupliquées + + + Duplicated faces + Faces dupliquées + + + Number of duplicated faces : + Nombre de faces dupliquées : + + + + Duplicated_faces_macro:create_group + + Create group + Créer un groupe + + + + Duplicated_faces_macro:group_name + + Group name + Nom du groupe + + + + Duplicated_faces_macro:main_object + + Object + Objet + + + Duplicated faces + Faces dupliquées + + + + Duplicated_faces_macro:group_list + + Duplicated faces + Faces dupliquées + + + List of faces : + Liste des faces : + + + + Duplicated_faces_macro:transparency + + Transparency + Transparence + + + + Duplicated_faces_macro:tolerance + + Tolerance + Tolérance + + + + Duplicated_faces + + Check duplicated faces + Vérifier les faces dupliquées + + + Duplicated faces + Faces dupliquées + + + Number of duplicated faces : + Nombre de faces dupliquées : + + + + Duplicated_faces:create_group + + Create group + Créer un groupe + + + + Duplicated_faces:group_name + + Group name + Nom du groupe + + + + Duplicated_faces:main_object + + Object + Objet + + + Duplicated faces + Faces dupliquées + + + + Duplicated_faces:group_list + + Duplicatedfaces + Faces dupliquées + + + List of faces : + Liste des faces : + + + + Duplicated_faces:transparency + + Transparency + Transparence + + + + Duplicated_faces:tolerance + + Tolerance + Tolérance + + + Symmetry diff --git a/src/FeaturesPlugin/Test/TestCheckDuplicatedFaces.py b/src/FeaturesPlugin/Test/TestCheckDuplicatedFaces.py new file mode 100644 index 000000000..6029eed19 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestCheckDuplicatedFaces.py @@ -0,0 +1,92 @@ +# Copyright (C) 2014-2021 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 +# + +""" + Unit test of Check Duplicated faces +""" +#========================================================================= +# Initialization of the test +#========================================================================= + + +import os +import math + +from ModelAPI import * +from GeomAPI import * +from salome.shaper import model + + +__updated__ = "2020-11-12" + + +if __name__ == '__main__': + + model.begin() + partSet = model.moduleDocument() + Part_1 = model.addPart(partSet) + Part_1_doc = Part_1.document() + ### Create Box + Box_1 = model.addBox(Part_1_doc, 100, 50, 100) + ### Create Point + Point_1 = model.addPoint(Part_1_doc, 100, 0, 0) + ### Create Point + Point_2 = model.addPoint(Part_1_doc, 250, 50, 100) + ### Create Box + Box_2 = model.addBox(Part_1_doc, model.selection("VERTEX", "all-in-Point_1"), model.selection("VERTEX", "all-in-Point_2")) + ### Create Point + Point_3 = model.addPoint(Part_1_doc, 100, 50, 250) + ### Create Box + Box_3 = model.addBox(Part_1_doc, model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "Point_3")) + ### Create Compound + Compound_1_objects = [model.selection("SOLID", "Box_1_1"), + model.selection("SOLID", "Box_2_1"), + model.selection("SOLID", "Box_3_1")] + Compound_1 = model.addCompound(Part_1_doc, Compound_1_objects) + ### Create Duplicated_faces + Duplicated_faces_1 = model.getDuplicatedFaces(Part_1_doc, model.selection("COMPOUND", "Compound_1_1"), 0.001, "mygroup") + + model.do() + # Check results + Duplicated_faces_1_Feature = Duplicated_faces_1.feature() + assert Duplicated_faces_1_Feature.error() == '' + assert Duplicated_faces_1_Feature.name() == "Duplicated_faces_1" + + aSelectionList = Duplicated_faces_1_Feature.selectionList("group_list") + assert aSelectionList.size() == 2 + + assert(Part_1_doc.size("Groups") == 1) + + #assert Part_1_doc.object("Groups", 0).name() == "mygroup" + resShape = modelAPI_Result(Part_1_doc.object("Groups", 0)).shape() + assert(not resShape.isNull()) + + # the group result is a face, check that this is one face + aShapeExplorer = GeomAPI_ShapeExplorer(resShape, GeomAPI_Shape.FACE) + assert(aShapeExplorer.more()) + assert(aShapeExplorer.current().isFace()) + aShapeExplorer.next() + aShapeExplorer.next() + assert(not aShapeExplorer.more()) + + model.end() + + #========================================================================= + # End of test + #========================================================================= diff --git a/src/FeaturesPlugin/doc/FeaturesPlugin.rst b/src/FeaturesPlugin/doc/FeaturesPlugin.rst index 6fc8177bd..41f6a03d8 100644 --- a/src/FeaturesPlugin/doc/FeaturesPlugin.rst +++ b/src/FeaturesPlugin/doc/FeaturesPlugin.rst @@ -27,6 +27,7 @@ Features plug-in provides a set of common topological operations. It implements linearCopyFeature.rst measurementFeature.rst normalToFaceFeature.rst + checkDuplicatedFaceFeature.rst pipeFeature.rst placementFeature.rst pointCoordinatesFeature.rst diff --git a/src/FeaturesPlugin/doc/TUI_DuplicatedFacesFeature.rst b/src/FeaturesPlugin/doc/TUI_DuplicatedFacesFeature.rst new file mode 100644 index 000000000..369057369 --- /dev/null +++ b/src/FeaturesPlugin/doc/TUI_DuplicatedFacesFeature.rst @@ -0,0 +1,11 @@ + + .. _tui_duplicated_faces: + +Check duplicated faces +====================== + +.. literalinclude:: examples/checkDuplicatedFaces.py + :linenos: + :language: python + +:download:`Download this script ` diff --git a/src/FeaturesPlugin/doc/checkDuplicatedFaceFeature.rst b/src/FeaturesPlugin/doc/checkDuplicatedFaceFeature.rst new file mode 100644 index 000000000..2ed808af3 --- /dev/null +++ b/src/FeaturesPlugin/doc/checkDuplicatedFaceFeature.rst @@ -0,0 +1,54 @@ +.. |duplicated_shapes.icon| image:: images/duplicated_shapes.png + +Check duplicated faces +====================== + +The **Check duplicated faces** feature find the duplicated faces within a composolid or compound. + +The result is a list of faces. A group can be created with a name specified. + +To check duplicated faces in the active part: + +#. select in the Main Menu *Inspection - > Check duplicated faces* item or +#. click |duplicated_shapes.icon| **Check duplicated faces** button in the toolbar + +The property panel is shown below. + +.. figure:: images/checkduplicatedFacesPropertyPanel.png + :align: center + + Check duplicated faces + + +Input fields: + +- **Object** contains composolid or compound selected in 3D OCC viewer or object browser. +- **Number of duplicated faces** indicate the number of found faces. +- **List of faces** the list of found faces. +- **Transparency** set the transparency of selected object. +- **Tolerance** set the tolerance for the algorithme. +- **Create group** check-box allow the creation with the group of found faces. +- **Group name** specified the name of the group created. + + +**TUI Command**: + +.. py:function:: model.getDuplicatedFaces(Part_doc, shape, tolerance, nameGroup) + + :param part: The current part object. + :param object: A composolid or compound in format *model.selection("Type", shape)*. + :param number: value of the tolerance. + :param string: name of group created. + :return: Created group. + +Result +"""""" + +Result of **Check duplicated faces** where **Create group** is checked. + +.. figure:: images/duplicatedFacesResult.png + :align: center + + Duplicated faces + +**See Also** a sample TUI Script of :ref:`tui_duplicated_faces` operation. diff --git a/src/FeaturesPlugin/doc/examples/checkDuplicatedFaces.py b/src/FeaturesPlugin/doc/examples/checkDuplicatedFaces.py new file mode 100644 index 000000000..b12dc2d09 --- /dev/null +++ b/src/FeaturesPlugin/doc/examples/checkDuplicatedFaces.py @@ -0,0 +1,29 @@ +from salome.shaper import model +import os + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +### Create Box +Box_1 = model.addBox(Part_1_doc, 100, 50, 100) +### Create Point +Point_1 = model.addPoint(Part_1_doc, 100, 0, 0) +### Create Point +Point_2 = model.addPoint(Part_1_doc, 250, 50, 100) +### Create Box +Box_2 = model.addBox(Part_1_doc, model.selection("VERTEX", "all-in-Point_1"), model.selection("VERTEX", "all-in-Point_2")) +### Create Point +Point_3 = model.addPoint(Part_1_doc, 100, 50, 250) +### Create Box +Box_3 = model.addBox(Part_1_doc, model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "Point_3")) +### Create Compound +Compound_1_objects = [model.selection("SOLID", "Box_1_1"), + model.selection("SOLID", "Box_2_1"), + model.selection("SOLID", "Box_3_1")] +Compound_1 = model.addCompound(Part_1_doc, Compound_1_objects) +### Create Duplicated_faces +Duplicated_faces_1 = model.getDuplicatedFaces(Part_1_doc, model.selection("COMPOUND", "Compound_1_1"), 0.001, "mygroup") + +model.do() +model.end() diff --git a/src/FeaturesPlugin/doc/images/checkduplicatedFacesPropertyPanel.png b/src/FeaturesPlugin/doc/images/checkduplicatedFacesPropertyPanel.png new file mode 100644 index 0000000000000000000000000000000000000000..439d7508943ca8905214eb31b90592f4d93ae295 GIT binary patch literal 27797 zcmbq)bC4%Z*Jby#ZQHipJ=3;r+qP}n=Cs|vY1{U+ZF~E9zkN5pjc*YfTM-qRmAF}d zWYxX*oRbmqvSM)1*w8>gKyVV`!iqpZz#!juEhPANOR|#D+jjx#^ix6^^850JG!FlM z#&Q->cUH19b#^mwGyyWRwX-pyb24%?F|l5dujF3n{y2pKrQ(PcDD` zxmm`;;_!m`NtzJ6G7#M@snGaXDN~_Q#9o8WW~mfeSTdw`f!%DTe1S*|Ni6E>_|y#$ zAZ1F_=716?I(l*6pOw5ky5q`ox;pZi=E|GqvXhWB%tjJI{Jh)8Za&pX6G9Ar^1s)? z5d1EKAi)C(frv371LH+=pL9qaDu3ySa;%N@*n-uMyuky{2-6pC9i^pvnKPlCJGRs? zxeDYheMB%keMu;_b`9{5)I(^>JE;xzafUrmbZJ$o){ql3Gp_^QUY=*Vy;?b1bhz&V z0~AE|r@*{B&0)l9H%JtAqvb+gov~RHdzx(~)&_?K54AITi=cOnQo?d5`=3j7?VJU! zj6@@((;Rb82)-tRA0&rxJNk}Zwgsy(KJ{ueo3ZNx!DMus-kvVZ7AqGSy2)GDyGNqy zWatzC52dr$AZ;!m5g$i&PH*q@=za?6*AHgli`~8m1TYmkOqwlKabX9Y^b(KG5=f*P zuSkC>fAoe?5;G^h!kwDEdwunMMCWl*?U{X77VP8&lwb&bI#Gt>SbTSj(>~dKcS&V& z1#%Bu89Z$m8OgIvZlmu&Wwb`!E@*Zyss(qH;~ixnSo|bVc<1?@Iw&AsYIPt*x}y}U zcOcof=1VVx|W~3Gxb`RV=21b7sxwp6a>=hi>r7kx~8A>?Fo~9^u~dPW7mQ z6LG9w5w&d)aW2bQFcjay0i{hv*?vHu2U$$+A2!M-a&nmXjTiIKto(>#uXTw(JC#Z= zB`+=WT*NGs?WQ**x?id-P<~P`myK`8?>=bYl3TJhkGmZ>&o%m46+YeSw7!DApq0oA zGCn|j_WHoZd∾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 N#uRgMfq`TAe*vifBAWmJ literal 0 HcmV?d00001 diff --git a/src/FeaturesPlugin/doc/images/duplicated_shapes.png b/src/FeaturesPlugin/doc/images/duplicated_shapes.png new file mode 100644 index 0000000000000000000000000000000000000000..0d66a119b07a8dab28ea41d5bf263d8b4bd272e8 GIT binary patch literal 947 zcmV;k15EshP)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ^@RCwBA{Qv(y12q9a05LI882|(j)eQs)AQl*d zk&zKaA|)jS92S57{)OXz|Nb%j`SXY2`}gk*-@big`1I)$!-o$a7~Z^j1ERqO00a;V zHd{c3$(e^Ru<=VU{QmnNXxKl7zyJQj@sD4B8NUDe!|?UTABL@MfnY;{KpBW%00a<* zmlG2c|Es#^GW`1e2cq#OP$Lk30c!pRV*mIJWdCOP{Ovc`Fr$nmFs&XyECCQeC@zeO ziu$kOp2zU(&p(E5Kuyf-e;9rO4gC#rA<(7&fGOe+kOsMKTU!8wY4&o4-`~H$w5tFy z4?qAh!jeruK)`=yW@d0W{rdF_97dl%e`fgl^(&YU3OktGmoHx!)@f)kd&a07n;4GB3mi{TGY!%V|uhOZBAFm#*bG5q}V7wk=# zPyYS=&A@OvfT7PakD=rAG_b+Q03d*vkX`r>h-Vq5F#P=e4~YMO!w%Un5Dj)I$bV;N zF#H0tYt(~L3B22E-um|NakgA;@DO7kzX#||DXo`1%}<7 z{qtakfl~Ji5DgGOa05Zkes}*I1E+u#!>_L(!@dLYPZSq|*dT9$0GeSJfcOZ=P=Ek} z=M-RRLuyHjY}gJc{S_d9kn^$u5GO!sVgQC=AVGitVnI`IhXfbCfO->d7zh9a7y!=r V1ZfMRt}p-q002ovPDHLkV1iQBlSu#o literal 0 HcmV?d00001 diff --git a/src/FeaturesPlugin/duplicated_faces_macro_widget.xml b/src/FeaturesPlugin/duplicated_faces_macro_widget.xml new file mode 100644 index 000000000..532fcc37a --- /dev/null +++ b/src/FeaturesPlugin/duplicated_faces_macro_widget.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + diff --git a/src/FeaturesPlugin/duplicated_faces_widget.xml b/src/FeaturesPlugin/duplicated_faces_widget.xml new file mode 100644 index 000000000..c742ea4a7 --- /dev/null +++ b/src/FeaturesPlugin/duplicated_faces_widget.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + diff --git a/src/FeaturesPlugin/icons/duplicatedFaces.png b/src/FeaturesPlugin/icons/duplicatedFaces.png new file mode 100644 index 0000000000000000000000000000000000000000..0d66a119b07a8dab28ea41d5bf263d8b4bd272e8 GIT binary patch literal 947 zcmV;k15EshP)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ^@RCwBA{Qv(y12q9a05LI882|(j)eQs)AQl*d zk&zKaA|)jS92S57{)OXz|Nb%j`SXY2`}gk*-@big`1I)$!-o$a7~Z^j1ERqO00a;V zHd{c3$(e^Ru<=VU{QmnNXxKl7zyJQj@sD4B8NUDe!|?UTABL@MfnY;{KpBW%00a<* zmlG2c|Es#^GW`1e2cq#OP$Lk30c!pRV*mIJWdCOP{Ovc`Fr$nmFs&XyECCQeC@zeO ziu$kOp2zU(&p(E5Kuyf-e;9rO4gC#rA<(7&fGOe+kOsMKTU!8wY4&o4-`~H$w5tFy z4?qAh!jeruK)`=yW@d0W{rdF_97dl%e`fgl^(&YU3OktGmoHx!)@f)kd&a07n;4GB3mi{TGY!%V|uhOZBAFm#*bG5q}V7wk=# zPyYS=&A@OvfT7PakD=rAG_b+Q03d*vkX`r>h-Vq5F#P=e4~YMO!w%Un5Dj)I$bV;N zF#H0tYt(~L3B22E-um|NakgA;@DO7kzX#||DXo`1%}<7 z{qtakfl~Ji5DgGOa05Zkes}*I1E+u#!>_L(!@dLYPZSq|*dT9$0GeSJfcOZ=P=Ek} z=M-RRLuyHjY}gJc{S_d9kn^$u5GO!sVgQC=AVGitVnI`IhXfbCfO->d7zh9a7y!=r V1ZfMRt}p-q002ovPDHLkV1iQBlSu#o literal 0 HcmV?d00001 diff --git a/src/FeaturesPlugin/plugin-Features.xml b/src/FeaturesPlugin/plugin-Features.xml index 87e47c378..400b36a65 100644 --- a/src/FeaturesPlugin/plugin-Features.xml +++ b/src/FeaturesPlugin/plugin-Features.xml @@ -134,7 +134,7 @@ + icon="icons/Features/fusion_faces.png" auto_preview="true" helpfile="FeaturesPlugin/fusionFacesFeature.html"> + + + + + + diff --git a/src/FeaturesPlugin/tests.set b/src/FeaturesPlugin/tests.set index 1274228bc..ed0d0ee82 100644 --- a/src/FeaturesPlugin/tests.set +++ b/src/FeaturesPlugin/tests.set @@ -178,7 +178,7 @@ SET(TEST_NAMES TestMeasurementAngle3Points.py TestMeasurementPresentation.py TestFusionFaces.py - TestFusionFaces2697.py + TestFusionFaces2697.py Test1379.py Test1922.py Test1942.py @@ -526,4 +526,5 @@ SET(TEST_NAMES TestBoundingBox.py Test23885.py TestNormalToFace.py + TestCheckDuplicatedFaces.py ) diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index 17eec671e..c2013da68 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -33,6 +33,7 @@ SET(PROJECT_HEADERS GeomAlgoAPI_Prism.h GeomAlgoAPI_Revolution.h GeomAlgoAPI_Boolean.h + GeomAlgoAPI_DuplicatedFaces.h GeomAlgoAPI_ThroughAll.h GeomAlgoAPI_Rotation.h GeomAlgoAPI_Translation.h @@ -82,6 +83,21 @@ SET(PROJECT_HEADERS GeomAlgoAPI_Fillet1D.h GeomAlgoAPI_SortListOfShapes.h GeomAlgoAPI_Filling.h + GeomAlgoAPI_GlueDetector.h + GeomAlgoAPI_GluerAlgo.h + GeomAlgoAPI_Algo.h + GEOMAlgo_BndSphereTree.hxx + GEOMAlgo_BndSphere.hxx + GEOMAlgo_BndSphere.lxx + GEOMAlgo_IndexedDataMapOfShapeBndSphere.hxx + GEOMAlgo_IndexedDataMapOfIntegerShape.hxx + GEOMAlgo_PassKeyShape.hxx + GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx + GEOMAlgo_PassKeyShapeMapHasher.hxx + GEOMAlgo_CoupleOfShapes.hxx + GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape.hxx + GEOMAlgo_ListOfCoupleOfShapes.hxx + GEOMAlgo_AlgoTools.hxx GeomAlgoAPI_CurveBuilder.h GeomAlgoAPI_NExplode.h GeomAlgoAPI_Offset.h @@ -105,6 +121,7 @@ SET(PROJECT_SOURCES GeomAlgoAPI_Prism.cpp GeomAlgoAPI_Revolution.cpp GeomAlgoAPI_Boolean.cpp + GeomAlgoAPI_DuplicatedFaces.cpp GeomAlgoAPI_ThroughAll.cpp GeomAlgoAPI_Rotation.cpp GeomAlgoAPI_Translation.cpp @@ -154,6 +171,15 @@ SET(PROJECT_SOURCES GeomAlgoAPI_Fillet1D.cpp GeomAlgoAPI_SortListOfShapes.cpp GeomAlgoAPI_Filling.cpp + GeomAlgoAPI_GlueDetector.cpp + GeomAlgoAPI_GluerAlgo.cpp + GeomAlgoAPI_Algo.cpp + GEOMAlgo_BndSphereTree.cxx + GEOMAlgo_BndSphere.cxx + GEOMAlgo_PassKeyShapeMapHasher.cxx + GEOMAlgo_CoupleOfShapes.cxx + GEOMAlgo_PassKeyShape.cxx + GEOMAlgo_AlgoTools.cxx GeomAlgoAPI_CurveBuilder.cpp GeomAlgoAPI_NExplode.cpp GeomAlgoAPI_Offset.cpp diff --git a/src/GeomAlgoAPI/GEOMAlgo_AlgoTools.cxx b/src/GeomAlgoAPI/GEOMAlgo_AlgoTools.cxx new file mode 100644 index 000000000..788e8d6e4 --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_AlgoTools.cxx @@ -0,0 +1,1006 @@ +// Copyright (C) 2007-2021 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 +// +// File : GEOMAlgo_AlgoTools.cxx +// Created : +// Author : Peter KURNEV + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include + +#include +#include + +#include + +#include + +#include + +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include + + +static + void GetCount(const TopoDS_Shape& aS, + Standard_Integer& iCnt); +static + void CopySource(const TopoDS_Shape& aS, + TopTools_IndexedDataMapOfShapeShape& aMapSS, + TopoDS_Shape& aSC); + +//======================================================================= +//function : CopyShape +//purpose : +//======================================================================= +void GEOMAlgo_AlgoTools::CopyShape(const TopoDS_Shape& aS, + TopoDS_Shape& aSC) +{ + TopTools_IndexedDataMapOfShapeShape aMapSS; + // + CopySource(aS, aMapSS, aSC); +} +//======================================================================= +//function : CopyShape +//purpose : +//======================================================================= +void GEOMAlgo_AlgoTools::CopyShape(const TopoDS_Shape& aS, + TopoDS_Shape& aSC, + TopTools_IndexedDataMapOfShapeShape& aMapSS) +{ + CopySource(aS, aMapSS, aSC); +} +//======================================================================= +//function : CopySource +//purpose : +//======================================================================= +void CopySource(const TopoDS_Shape& aS, + TopTools_IndexedDataMapOfShapeShape& aMapSS, + TopoDS_Shape& aSC) +{ + Standard_Boolean bFree; + TopAbs_ShapeEnum aT; + TopoDS_Iterator aIt; + TopoDS_Shape aSF; + BRep_Builder BB; + // + aT=aS.ShapeType(); + // + if (aMapSS.Contains(aS)) { + aSC=aMapSS.ChangeFromKey(aS); + aSC.Orientation(aS.Orientation()); + return; + } + else { + aSC=aS.EmptyCopied(); + aMapSS.Add(aS, aSC); + } + // + bFree=aSC.Free(); + aSC.Free(Standard_True); + aSF=aS; + if (aT==TopAbs_EDGE){ + TopAbs_Orientation aOr; + // + aOr=aS.Orientation(); + if(aOr==TopAbs_INTERNAL) { + aSF.Orientation(TopAbs_FORWARD); + } + } + aIt.Initialize(aSF); + for (; aIt.More(); aIt.Next()) { + TopoDS_Shape aSCx; + // + const TopoDS_Shape& aSx=aIt.Value(); + // + CopySource (aSx, aMapSS, aSCx); + // + aSCx.Orientation(aSx.Orientation()); + BB.Add(aSC, aSCx); + } + aSC.Free(bFree); +} +//======================================================================= +//function : FaceNormal +//purpose : +//======================================================================= +void GEOMAlgo_AlgoTools::FaceNormal (const TopoDS_Face& aF, + const Standard_Real U, + const Standard_Real V, + gp_Vec& aN) +{ + gp_Pnt aPnt ; + gp_Vec aD1U, aD1V; + Handle(Geom_Surface) aSurface; + + aSurface=BRep_Tool::Surface(aF); + aSurface->D1 (U, V, aPnt, aD1U, aD1V); + aN=aD1U.Crossed(aD1V); + aN.Normalize(); + if (aF.Orientation() == TopAbs_REVERSED){ + aN.Reverse(); + } + return; +} +//======================================================================= +//function : BuildPCurveForEdgeOnFace +//purpose : +//======================================================================= +Standard_Integer GEOMAlgo_AlgoTools::BuildPCurveForEdgeOnFace + (const TopoDS_Edge& aEold, + const TopoDS_Edge& aEnew, + const TopoDS_Face& aF, + const Handle(IntTools_Context)& aCtx) +{ + Standard_Boolean bIsClosed, bUClosed, bHasOld; + Standard_Integer iRet, aNbPoints; + Standard_Real aTS, aTS1, aTS2, aT, aT1, aT2, aScPr, aTol; + Standard_Real aU, aV, aUS1, aVS1, aUS2, aVS2; + gp_Pnt aP; + gp_Pnt2d aP2DS1, aP2DS2, aP2D; + gp_Vec2d aV2DS1, aV2DS2; + Handle(Geom2d_Curve) aC2D, aC2DS1, aC2DS2; + Handle(Geom_Surface) aS; + TopoDS_Edge aES; + // + iRet=0; + // + bHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface(aEnew, aF, aC2D, aT1, aT2, aTol); + if (bHasOld) { + return iRet; + } + // + // Try to copy PCurve from old edge to the new one. + iRet = BOPTools_AlgoTools2D::AttachExistingPCurve(aEold, aEnew, aF, aCtx); + + if (iRet) { + // Do PCurve using projection algorithm. + iRet = 0; + } else { + // The PCurve is attached successfully. + return iRet; + } + // + BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aEnew, aF); + aC2D=BRep_Tool::CurveOnSurface(aEnew, aF, aT1, aT2); + if (aC2D.IsNull()){ + iRet=1; + return iRet; + } + // + bIsClosed=BRep_Tool::IsClosed(aEold, aF); + if (!bIsClosed) { + return iRet; + } + // + aTol=1.e-7; + // + // 1. bUClosed - direction of closeness + // + aES=aEold; + aES.Orientation(TopAbs_FORWARD); + aC2DS1=BRep_Tool::CurveOnSurface(aES, aF, aTS1, aTS2); + // + aES.Orientation(TopAbs_REVERSED); + aC2DS2=BRep_Tool::CurveOnSurface(aES, aF, aTS1, aTS2); + // + aTS=IntTools_Tools::IntermediatePoint(aTS1, aTS2); + // + aC2DS1->D1(aTS, aP2DS1, aV2DS1); + aC2DS2->D1(aTS, aP2DS2, aV2DS2); + // + gp_Vec2d aV2DS12(aP2DS1, aP2DS2); + gp_Dir2d aD2DS12(aV2DS12); + const gp_Dir2d& aD2DX=gp::DX2d(); + // + aScPr=aD2DS12*aD2DX; + bUClosed=Standard_True; + if (fabs(aScPr) < aTol) { + bUClosed=!bUClosed; + } + // + // 2. aP2D - point on curve aC2D, that corresponds to aP2DS1 + aP2DS1.Coord(aUS1, aVS1); + aP2DS2.Coord(aUS2, aVS2); + // + aS=BRep_Tool::Surface(aF); + aS->D0(aUS1, aVS1, aP); + // + GeomAPI_ProjectPointOnCurve& aProjPC=aCtx->ProjPC(aEnew); + // + aProjPC.Perform(aP); + aNbPoints=aProjPC.NbPoints(); + if (!aNbPoints) { + iRet=2; + return iRet; + } + // + aT=aProjPC.LowerDistanceParameter(); + + // + // 3. Build the second 2D curve + Standard_Boolean bRevOrder; + gp_Vec2d aV2DT, aV2D; + Handle(Geom2d_Curve) aC2Dnew; + Handle(Geom2d_TrimmedCurve) aC2DTnew; + BRep_Builder aBB; + // + aC2D->D1(aT, aP2D, aV2D); + aP2D.Coord(aU, aV); + // + aC2Dnew=Handle(Geom2d_Curve)::DownCast(aC2D->Copy()); + aC2DTnew = new Geom2d_TrimmedCurve(aC2Dnew, aT1, aT2); + // + aV2DT=aV2DS12; + if (!bUClosed) { // V Closed + if (fabs(aV-aVS2)Translate(aV2DT); + // + // 4 Order the 2D curves + bRevOrder=Standard_False; + aScPr=aV2D*aV2DS1; + if(aScPr<0.) { + bRevOrder=!bRevOrder; + } + // + // 5. Update the edge + aTol=BRep_Tool::Tolerance(aEnew); + if (!bRevOrder) { + aBB.UpdateEdge(aEnew, aC2D, aC2DTnew, aF, aTol); + } + else { + aBB.UpdateEdge(aEnew, aC2DTnew, aC2D , aF, aTol); + } + // + return iRet; +} +////////////////////////////////////////////////////////////////////////// +//======================================================================= +// function: MakeContainer +// purpose: +//======================================================================= +void GEOMAlgo_AlgoTools::MakeContainer(const TopAbs_ShapeEnum theType, + TopoDS_Shape& theC) +{ + BRep_Builder aBB; + // + switch(theType) { + case TopAbs_COMPOUND:{ + TopoDS_Compound aC; + aBB.MakeCompound(aC); + theC=aC; + } + break; + // + case TopAbs_COMPSOLID:{ + TopoDS_CompSolid aCS; + aBB.MakeCompSolid(aCS); + theC=aCS; + } + break; + // + case TopAbs_SOLID:{ + TopoDS_Solid aSolid; + aBB.MakeSolid(aSolid); + theC=aSolid; + } + break; + // + // + case TopAbs_SHELL:{ + TopoDS_Shell aShell; + aBB.MakeShell(aShell); + theC=aShell; + } + break; + // + case TopAbs_WIRE: { + TopoDS_Wire aWire; + aBB.MakeWire(aWire); + theC=aWire; + } + break; + // + default: + break; + } +} +//======================================================================= +//function : IsUPeriodic +//purpose : +//======================================================================= +Standard_Boolean GEOMAlgo_AlgoTools::IsUPeriodic(const Handle(Geom_Surface) &aS) +{ + Standard_Boolean bRet; + GeomAbs_SurfaceType aType; + GeomAdaptor_Surface aGAS; + // + aGAS.Load(aS); + aType=aGAS.GetType(); + bRet=(aType==GeomAbs_Cylinder|| + aType==GeomAbs_Cone || + aType==GeomAbs_Sphere); + // + return bRet; +} + +//======================================================================= +//function : RefinePCurveForEdgeOnFace +//purpose : +//======================================================================= +void GEOMAlgo_AlgoTools::RefinePCurveForEdgeOnFace(const TopoDS_Edge& aE, + const TopoDS_Face& aF, + const Standard_Real aUMin, + const Standard_Real aUMax) +{ + Standard_Real aT1, aT2, aTx, aUx, aTol; + gp_Pnt2d aP2D; + Handle(Geom_Surface) aS; + Handle(Geom2d_Curve) aC2D; + BRep_Builder aBB; + // + aC2D=BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2); + if (!aC2D.IsNull()) { + if (BRep_Tool::IsClosed(aE, aF)) { + return; + } + aTx=IntTools_Tools::IntermediatePoint(aT1, aT2); + aC2D->D0(aTx, aP2D); + aUx=aP2D.X(); + if (aUx < aUMin || aUx > aUMax) { + // need to rebuild + Handle(Geom2d_Curve) aC2Dx; + // + aTol=BRep_Tool::Tolerance(aE); + aBB.UpdateEdge(aE, aC2Dx, aF, aTol); + } + } +} +//======================================================================= +//function :IsSplitToReverse +//purpose : +//======================================================================= +Standard_Boolean GEOMAlgo_AlgoTools::IsSplitToReverse + (const TopoDS_Edge& aEF1, + const TopoDS_Edge& aEF2, + const Handle(IntTools_Context)& aContext) +{ + Standard_Boolean aFlag; + Standard_Real aT1, aT2, aScPr, a, b; + gp_Vec aV1, aV2; + gp_Pnt aP; + + + Handle(Geom_Curve)aC1=BRep_Tool::Curve(aEF1, a, b); + aT1=IntTools_Tools::IntermediatePoint(a, b); + aC1->D0(aT1, aP); + aFlag=BOPTools_AlgoTools2D::EdgeTangent(aEF1, aT1, aV1); + + if(!aFlag) { + return Standard_False; + } + + gp_Dir aDT1(aV1); + // + aFlag=aContext->ProjectPointOnEdge(aP, aEF2, aT2); + if(!aFlag) { + return Standard_False; + } + // + aFlag=BOPTools_AlgoTools2D::EdgeTangent(aEF2, aT2, aV2); + if(!aFlag) { + return Standard_False; + } + + gp_Dir aDT2(aV2); + + aScPr=aDT1*aDT2; + + return (aScPr<0.); +} + + +//======================================================================= +//function : ProjectPointOnShape +//purpose : +//======================================================================= +Standard_Boolean GEOMAlgo_AlgoTools::ProjectPointOnShape + (const gp_Pnt& aP1, + const TopoDS_Shape& aS, + gp_Pnt& aP2, + const Handle(IntTools_Context)& aCtx) +{ + Standard_Boolean bIsDone = Standard_False; + Standard_Real aT2; + TopAbs_ShapeEnum aType; + // + aType = aS.ShapeType(); + switch (aType) + { + case TopAbs_EDGE: + { + const TopoDS_Edge& aE2 = TopoDS::Edge(aS); + // + if (BRep_Tool::Degenerated(aE2)) { // jfa + return Standard_True; + } + else { + Standard_Real f, l; + Handle(Geom_Curve) aC3D = BRep_Tool::Curve (aE2, f, l); + if (aC3D.IsNull()) { + return Standard_True; + } + bIsDone = aCtx->ProjectPointOnEdge(aP1, aE2, aT2); + } + if (!bIsDone) { + return bIsDone; + } + // + GEOMAlgo_AlgoTools::PointOnEdge(aE2, aT2, aP2); + } + break; + // + case TopAbs_FACE: + { + const TopoDS_Face& aF2 = TopoDS::Face(aS); + GeomAPI_ProjectPointOnSurf& aProj = aCtx->ProjPS(aF2); + // + aProj.Perform(aP1); + bIsDone = aProj.IsDone(); + if (!bIsDone) { + return bIsDone; + } + // + aP2 = aProj.NearestPoint(); + } + break; + // + default: + break; // Err + } + return bIsDone; +} + +//======================================================================= +//function : PointOnEdge +//purpose : +//======================================================================= +void GEOMAlgo_AlgoTools::PointOnEdge(const TopoDS_Edge& aE, + gp_Pnt& aP3D) +{ + Standard_Real aTx, aT1, aT2; + // + BRep_Tool::Curve(aE, aT1, aT2); + aTx=IntTools_Tools::IntermediatePoint(aT1, aT2); + GEOMAlgo_AlgoTools::PointOnEdge(aE, aTx, aP3D); +} +//======================================================================= +//function : PointOnEdge +//purpose : +//======================================================================= +void GEOMAlgo_AlgoTools::PointOnEdge(const TopoDS_Edge& aE, + const Standard_Real aT, + gp_Pnt& aP3D) +{ + Standard_Real aT1, aT2; + Handle(Geom_Curve) aC3D; + // + aC3D=BRep_Tool::Curve(aE, aT1, aT2); + aC3D->D0(aT, aP3D); +} +//======================================================================= +//function : PointOnFace +//purpose : +//======================================================================= +void GEOMAlgo_AlgoTools::PointOnFace(const TopoDS_Face& aF, + const Standard_Real aU, + const Standard_Real aV, + gp_Pnt& aP3D) +{ + Handle(Geom_Surface) aS; + // + aS=BRep_Tool::Surface(aF); + aS->D0(aU, aV, aP3D); +} +//======================================================================= +//function : PointOnFace +//purpose : +//======================================================================= +void GEOMAlgo_AlgoTools::PointOnFace(const TopoDS_Face& aF, + gp_Pnt& aP3D) +{ + Standard_Real aU, aV, aUMin, aUMax, aVMin, aVMax; + // + BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax); + // + aU=IntTools_Tools::IntermediatePoint(aUMin, aUMax); + aV=IntTools_Tools::IntermediatePoint(aVMin, aVMax); + // + GEOMAlgo_AlgoTools::PointOnFace(aF, aU, aV, aP3D); +} +//======================================================================= +//function : PointOnShape +//purpose : +//======================================================================= +void GEOMAlgo_AlgoTools::PointOnShape(const TopoDS_Shape& aS, + gp_Pnt& aP3D) +{ + TopAbs_ShapeEnum aType; + // + aP3D.SetCoord(99.,99.,99.); + aType=aS.ShapeType(); + switch(aType) { + case TopAbs_EDGE: { + const TopoDS_Edge& aE=TopoDS::Edge(aS); + GEOMAlgo_AlgoTools::PointOnEdge(aE, aP3D); + } + break; + // + case TopAbs_FACE: { + const TopoDS_Face& aF=TopoDS::Face(aS); + GEOMAlgo_AlgoTools::PointOnFace(aF, aP3D); + } + break; + // + default: + break; // Err + } +} +//======================================================================= +//function : FindSDShapes +//purpose : +//======================================================================= +Standard_Integer GEOMAlgo_AlgoTools::FindSDShapes + (const TopoDS_Shape& aE1, + const TopTools_ListOfShape& aLE, + const Standard_Real aTol, + TopTools_ListOfShape& aLESD, + const Handle(IntTools_Context)& aCtx) +{ + Standard_Boolean bIsDone; + Standard_Real aTol2, aD2; + gp_Pnt aP1, aP2; + TopTools_ListIteratorOfListOfShape aIt; + // + aTol2=aTol*aTol; + GEOMAlgo_AlgoTools::PointOnShape(aE1, aP1); + // + aIt.Initialize(aLE); + for (; aIt.More(); aIt.Next()) { + const TopoDS_Shape& aE2=aIt.Value(); + if (aE2.IsSame(aE1)) { + aLESD.Append(aE2); + } + else { + bIsDone=GEOMAlgo_AlgoTools::ProjectPointOnShape(aP1, aE2, aP2, aCtx); + if (!bIsDone) { + //return 1; + continue; // jfa BUG 20361 + } + aD2=aP1.SquareDistance(aP2); + if(aD21); + // + return bRet; +} +//======================================================================= +//function : GetCount +//purpose : +//======================================================================= +void GetCount(const TopoDS_Shape& aS, + Standard_Integer& iCnt) +{ + TopoDS_Iterator aIt; + TopAbs_ShapeEnum aTS; + // + aTS=aS.ShapeType(); + // + if (aTS==TopAbs_SHAPE) { + return; + } + if (aTS!=TopAbs_COMPOUND) { + ++iCnt; + return; + } + // + aIt.Initialize(aS); + for (; aIt.More(); aIt.Next()) { + const TopoDS_Shape& aSx=aIt.Value(); + GetCount(aSx, iCnt); + } +} +//======================================================================= +//function : PntInFace +//purpose : +//======================================================================= +Standard_Integer GEOMAlgo_AlgoTools::PntInFace(const TopoDS_Face& aF, + gp_Pnt& theP, + gp_Pnt2d& theP2D) +{ + Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint; + Standard_Integer iErr, aIx, aNbDomains, i; + Standard_Real aUMin, aUMax, aVMin, aVMax; + Standard_Real aVx, aUx, aV1, aV2, aU1, aU2, aEpsT; + Standard_Real aTotArcIntr, aTolTangfIntr, aTolHatch2D, aTolHatch3D; + gp_Dir2d aD2D (0., 1.); + gp_Pnt2d aP2D; + gp_Pnt aPx; + Handle(Geom2d_Curve) aC2D; + Handle(Geom2d_TrimmedCurve) aCT2D; + Handle(Geom2d_Line) aL2D; + Handle(Geom_Surface) aS; + TopAbs_Orientation aOrE; + TopoDS_Face aFF; + TopExp_Explorer aExp; + // + aTolHatch2D=1.e-8; + aTolHatch3D=1.e-8; + aTotArcIntr=1.e-10; + aTolTangfIntr=1.e-10; + // + Geom2dHatch_Intersector aIntr(aTotArcIntr, aTolTangfIntr); + Geom2dHatch_Hatcher aHatcher(aIntr, + aTolHatch2D, aTolHatch3D, + Standard_True, Standard_False); + // + iErr=0; + aEpsT=1.e-12; + // + aFF=aF; + aFF.Orientation (TopAbs_FORWARD); + // + aS=BRep_Tool::Surface(aFF); + BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax); + // + // 1 + aExp.Init (aFF, TopAbs_EDGE); + for (; aExp.More() ; aExp.Next()) { + const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current()); + aOrE=aE.Orientation(); + // + aC2D=BRep_Tool::CurveOnSurface (aE, aFF, aU1, aU2); + if (aC2D.IsNull() ) { + iErr=1; + return iErr; + } + if (fabs(aU1-aU2) < aEpsT) { + iErr=2; + return iErr; + } + // + aCT2D=new Geom2d_TrimmedCurve(aC2D, aU1, aU2); + aHatcher.AddElement(aCT2D, aOrE); + }// for (; aExp.More() ; aExp.Next()) { + // + // 2 + aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax); + aP2D.SetCoord(aUx, 0.); + aL2D=new Geom2d_Line (aP2D, aD2D); + Geom2dAdaptor_Curve aHCur(aL2D); + // + aIx=aHatcher.AddHatching(aHCur) ; + // + // 3. + aHatcher.Trim(); + bIsDone=aHatcher.TrimDone(aIx); + if (!bIsDone) { + iErr=3; + return iErr; + } + // + aHatcher.ComputeDomains(aIx); + bIsDone=aHatcher.IsDone(aIx); + if (!bIsDone) { + iErr=4; + return iErr; + } + // + // 4. + aVx=aVMin; + aNbDomains=aHatcher.NbDomains(aIx); + if (!aNbDomains) { + iErr=5; + return iErr; + } + // + i=1; + const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, i) ; + bHasFirstPoint=aDomain.HasFirstPoint(); + if (!bHasFirstPoint) { + iErr=5; + return iErr; + } + // + aV1=aDomain.FirstPoint().Parameter(); + // + bHasSecondPoint=aDomain.HasSecondPoint(); + if (!bHasSecondPoint) { + iErr=6; + return iErr; + } + // + aV2=aDomain.SecondPoint().Parameter(); + // + aVx=IntTools_Tools::IntermediatePoint(aV1, aV2); + // + aS->D0(aUx, aVx, aPx); + // + theP2D.SetCoord(aUx, aVx); + theP=aPx; + // + return iErr; +} diff --git a/src/GeomAlgoAPI/GEOMAlgo_AlgoTools.hxx b/src/GeomAlgoAPI/GEOMAlgo_AlgoTools.hxx new file mode 100644 index 000000000..2470d1c41 --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_AlgoTools.hxx @@ -0,0 +1,198 @@ +// Copyright (C) 2007-2021 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 +// +// File : GEOMAlgo_AlgoTools.hxx +// Created : +// Author : Peter KURNEV + +#ifndef _GEOMAlgo_AlgoTools_HeaderFile +#define _GEOMAlgo_AlgoTools_HeaderFile + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +//! Auxiliary tools for Algorithms
+//======================================================================= +//class : GEOMAlgo_AlgoTools +//purpose : +//======================================================================= +class GEOMAlgo_AlgoTools { + public: + + Standard_EXPORT + static void FaceNormal (const TopoDS_Face& aF, + const Standard_Real U, + const Standard_Real V, + gp_Vec& aN); + + //! Computes a point inside the face .
+ //! - 2D representation of
+ //! on the surface of
+ //! Returns 0 in case of success.
+ Standard_EXPORT + static Standard_Integer PntInFace(const TopoDS_Face& theF, + gp_Pnt& theP, + gp_Pnt2d& theP2D) ; + + Standard_EXPORT + static Standard_Boolean IsCompositeShape(const TopoDS_Shape& aS) ; + + + Standard_EXPORT + static Standard_Boolean BuildTriangulation(const TopoDS_Shape& aS) ; + + Standard_EXPORT + static Standard_Integer RefineSDShapes + (GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape& aMSD, + const Standard_Real aTol, + const Handle(IntTools_Context)& aCtx) ; + + Standard_EXPORT + static Standard_Integer FindSDShapes(const TopTools_ListOfShape& aLE, + const Standard_Real aTol, + TopTools_IndexedDataMapOfShapeListOfShape& aMEE, + const Handle(IntTools_Context)& aCtx) ; + Standard_EXPORT + static Standard_Integer FindSDShapes(const TopoDS_Shape& aE1, + const TopTools_ListOfShape& aLE, + const Standard_Real aTol, + TopTools_ListOfShape& aLESD, + const Handle(IntTools_Context)& aCtx) ; + + Standard_EXPORT + static void PointOnShape(const TopoDS_Shape& aS, + gp_Pnt& aP3D) ; + + Standard_EXPORT + static void PointOnEdge(const TopoDS_Edge& aE, + gp_Pnt& aP3D) ; + + Standard_EXPORT + static void PointOnEdge(const TopoDS_Edge& aE, + const Standard_Real aT,gp_Pnt& aP3D) ; + + Standard_EXPORT + static void PointOnFace(const TopoDS_Face& aF, + gp_Pnt& aP3D) ; + + Standard_EXPORT + static void PointOnFace(const TopoDS_Face& aF, + const Standard_Real aU, + const Standard_Real aV, + gp_Pnt& aP3D) ; + Standard_EXPORT + static Standard_Boolean ProjectPointOnShape(const gp_Pnt& aP1, + const TopoDS_Shape& aS, + gp_Pnt& aP2, + const Handle(IntTools_Context)& aCtx) ; + + Standard_EXPORT + static void CorrectTolerances(const TopoDS_Shape& aShape, + const Standard_Real aMaxTol=0.0001); + + Standard_EXPORT + static void CorrectPointOnCurve(const TopoDS_Shape& S, + const Standard_Real aMaxTol=0.0001); + + Standard_EXPORT + static void CorrectCurveOnSurface(const TopoDS_Shape& S, + const Standard_Real aMaxTol=0.0001); + + + Standard_EXPORT + static Standard_Boolean IsSplitToReverse1 (const TopoDS_Edge& aEF1, + const TopoDS_Edge& aEF2, + const Handle(IntTools_Context)& aCtx) ; + Standard_EXPORT + static void RefinePCurveForEdgeOnFace(const TopoDS_Edge& aE, + const TopoDS_Face& aF, + const Standard_Real aUMin, + const Standard_Real aUMax); + + Standard_EXPORT + static Standard_Boolean IsUPeriodic(const Handle(Geom_Surface) &aS); + + Standard_EXPORT + static void MakeContainer(const TopAbs_ShapeEnum theType, + TopoDS_Shape& theC); + + Standard_EXPORT + static Standard_Boolean IsSplitToReverse(const TopoDS_Edge& theSplit, + const TopoDS_Edge& theEdge, + const Handle(IntTools_Context)& theCtx) ; + + Standard_EXPORT + static Standard_Boolean IsSplitToReverse (const TopoDS_Face& theFSp, + const TopoDS_Face& theFSr, + const Handle(IntTools_Context)& theCtx) ; + + Standard_EXPORT + static Standard_Boolean IsSplitToReverse (const TopoDS_Shape& theSp, + const TopoDS_Shape& theSr, + const Handle(IntTools_Context)& theCtx) ; + Standard_EXPORT + static Standard_Integer BuildPCurveForEdgeOnFace (const TopoDS_Edge& aEold, + const TopoDS_Edge& aEnew, + const TopoDS_Face& aF, + const Handle(IntTools_Context)& aCtx) ; + +// + Standard_EXPORT + static void FindChains(const GEOMAlgo_ListOfCoupleOfShapes& aLCS, + GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape& aMapChains); + + Standard_EXPORT + static void FindChains(const GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape& aMCV, + GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape& aMapChains); + + Standard_EXPORT + static void CopyShape(const TopoDS_Shape& aS, + TopoDS_Shape& aSC) ; + + Standard_EXPORT + static void CopyShape(const TopoDS_Shape& aS, + TopoDS_Shape& aSC, + TopTools_IndexedDataMapOfShapeShape& aMSS) ; +}; +#endif diff --git a/src/GeomAlgoAPI/GEOMAlgo_BndSphere.cxx b/src/GeomAlgoAPI/GEOMAlgo_BndSphere.cxx new file mode 100644 index 000000000..e13b84bf9 --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_BndSphere.cxx @@ -0,0 +1,57 @@ +// Copyright (C) 2007-2021 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: GEOMAlgo_BndSphere.cxx +// Created: +// Author: Peter KURNEV +// +// +#include + +//======================================================================= +//function : +//purpose : +//======================================================================= + GEOMAlgo_BndSphere::GEOMAlgo_BndSphere() +{ + myCenter.SetCoord(0., 0., 0.); + myRadius=0.; + myGap=0.; +} +//======================================================================= +//function : ~ +//purpose : +//======================================================================= + GEOMAlgo_BndSphere::~GEOMAlgo_BndSphere() +{ +} +//======================================================================= +//function : IsOut +//purpose : +//======================================================================= + Standard_Boolean GEOMAlgo_BndSphere::IsOut(const GEOMAlgo_BndSphere& theOther)const +{ + Standard_Real aD2, aT2; + // + aD2=myCenter.SquareDistance(theOther.myCenter); + aT2=myRadius+myGap+theOther.myRadius+theOther.myGap; + aT2=aT2*aT2; + // + return aD2>aT2; +} diff --git a/src/GeomAlgoAPI/GEOMAlgo_BndSphere.hxx b/src/GeomAlgoAPI/GEOMAlgo_BndSphere.hxx new file mode 100644 index 000000000..3ab7e3784 --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_BndSphere.hxx @@ -0,0 +1,73 @@ +// Copyright (C) 2007-2021 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: GEOMAlgo_BndSphere.hxx +// Created: +// Author: Peter KURNEV +// + +#ifndef _GEOMAlgo_BndSphere_HeaderFile +#define _GEOMAlgo_BndSphere_HeaderFile + +#include +#include +#include +#include +#include + +//======================================================================= +//class : GEOMAlgo_BndSphere +//purpose : +//======================================================================= +class GEOMAlgo_BndSphere { + public: + Standard_EXPORT + GEOMAlgo_BndSphere(); + + Standard_EXPORT + virtual ~GEOMAlgo_BndSphere(); + + void SetCenter(const gp_Pnt& theP) ; + + const gp_Pnt& Center() const; + + void SetRadius(const Standard_Real theR) ; + + Standard_Real Radius() const; + + void SetGap(const Standard_Real theGap) ; + + Standard_Real Gap() const; + + void Add(const GEOMAlgo_BndSphere& theOther) ; + + Standard_EXPORT + Standard_Boolean IsOut(const GEOMAlgo_BndSphere& theOther) const; + + Standard_Real SquareExtent() const; + + protected: + gp_Pnt myCenter; + Standard_Real myRadius; + Standard_Real myGap; +}; + +#include + +#endif diff --git a/src/GeomAlgoAPI/GEOMAlgo_BndSphere.lxx b/src/GeomAlgoAPI/GEOMAlgo_BndSphere.lxx new file mode 100644 index 000000000..bc9b62ee7 --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_BndSphere.lxx @@ -0,0 +1,108 @@ +// Copyright (C) 2007-2021 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: GEOMAlgo_BndSphere.lxx +// Created: +// Author: Peter KURNEV +// +//======================================================================= +//function : SetCenter +//purpose : +//======================================================================= + inline void GEOMAlgo_BndSphere::SetCenter(const gp_Pnt& theP) +// +{ + myCenter=theP; +} +//======================================================================= +//function : Center +//purpose : +//======================================================================= + inline const gp_Pnt& GEOMAlgo_BndSphere::Center()const +{ + return myCenter; +} +//======================================================================= +//function : SetRadius +//purpose : +//======================================================================= + inline void GEOMAlgo_BndSphere::SetRadius(const Standard_Real theR) +{ + myRadius=theR; +} +//======================================================================= +//function : Radius +//purpose : +//======================================================================= + inline Standard_Real GEOMAlgo_BndSphere::Radius()const +{ + return myRadius; +} +//======================================================================= +//function : SetGap +//purpose : +//======================================================================= + inline void GEOMAlgo_BndSphere::SetGap(const Standard_Real theGap) +{ + myGap=theGap; +} +//======================================================================= +//function : Gap +//purpose : +//======================================================================= + inline Standard_Real GEOMAlgo_BndSphere::Gap()const +{ + return myGap; +} +//======================================================================= +//function : Add +//purpose : +//======================================================================= + inline void GEOMAlgo_BndSphere::Add(const GEOMAlgo_BndSphere& theOther) +{ + Standard_Real aTmax, aR, aT, aTOther; + gp_Pnt aPc; + // + aPc.SetXYZ(0.5*(myCenter.XYZ()+theOther.myCenter.XYZ())); + // + aR=aPc.Distance(myCenter); + // + aT=myRadius+myGap; + aTOther=theOther.myRadius+theOther.myGap; + aTmax=(aT>aTOther) ? aT: aTOther; + // + aR=aR+aTmax; + // + myCenter=aPc; + myRadius=aR; +} +//======================================================================= +//function : SquareExtent +//purpose : +//======================================================================= + inline Standard_Real GEOMAlgo_BndSphere::SquareExtent()const +{ + Standard_Real aD; + // + aD=myRadius+myGap; + aD=aD+aD; + aD=aD*aD; + // + return aD; +} diff --git a/src/GeomAlgoAPI/GEOMAlgo_BndSphereTree.cxx b/src/GeomAlgoAPI/GEOMAlgo_BndSphereTree.cxx new file mode 100644 index 000000000..fa9c1fdbe --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_BndSphereTree.cxx @@ -0,0 +1,89 @@ +// Copyright (C) 2007-2021 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: GEOMAlgo_BndSphereTree.cxx +// Created: +// Author: Peter KURNEV +// +// +#include +//======================================================================= +//function : +//purpose : +//======================================================================= + GEOMAlgo_BndSphereTreeSelector::GEOMAlgo_BndSphereTreeSelector() +{ +} +//======================================================================= +//function : ~ +//purpose : +//======================================================================= + GEOMAlgo_BndSphereTreeSelector::~GEOMAlgo_BndSphereTreeSelector() +{ +} +//======================================================================= +//function : Reject +//purpose : +//======================================================================= + Standard_Boolean GEOMAlgo_BndSphereTreeSelector::Reject (const GEOMAlgo_BndSphere& aBox) const +{ + Standard_Boolean bRet; + // + bRet=myBox.IsOut(aBox); + return bRet; +} +//======================================================================= +//function : Accept +//purpose : +//======================================================================= + Standard_Boolean GEOMAlgo_BndSphereTreeSelector::Accept (const Standard_Integer& aIndex) +{ + Standard_Boolean bRet=Standard_False; + // + if (myFence.Add(aIndex)) { + myIndices.Append(aIndex); + bRet=!bRet; + } + return bRet; +} +//======================================================================= +//function : SetBox +//purpose : +//======================================================================= + void GEOMAlgo_BndSphereTreeSelector::SetBox(const GEOMAlgo_BndSphere& aBox) +{ + myBox=aBox; +} +//======================================================================= +//function : Clear +//purpose : +//======================================================================= + void GEOMAlgo_BndSphereTreeSelector::Clear() +{ + myFence.Clear(); + myIndices.Clear(); +} +//======================================================================= +//function : Indices +//purpose : +//======================================================================= + const TColStd_ListOfInteger& GEOMAlgo_BndSphereTreeSelector::Indices() const +{ + return myIndices; +} diff --git a/src/GeomAlgoAPI/GEOMAlgo_BndSphereTree.hxx b/src/GeomAlgoAPI/GEOMAlgo_BndSphereTree.hxx new file mode 100644 index 000000000..9a7a45723 --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_BndSphereTree.hxx @@ -0,0 +1,53 @@ +// Copyright (C) 2007-2021 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: GEOMAlgo_BndSphereTree.hxx +// Created: +// Author: Peter KURNEV +// +// +#ifndef GEOMAlgo_BndSphereTree_HeaderFile +#define GEOMAlgo_BndSphereTree_HeaderFile + +#include +#include +#include +#include + +typedef NCollection_UBTree GEOMAlgo_BndSphereTree; + + class GEOMAlgo_BndSphereTreeSelector : public GEOMAlgo_BndSphereTree::Selector { + public: + Standard_EXPORT GEOMAlgo_BndSphereTreeSelector(); + Standard_EXPORT virtual Standard_Boolean Reject(const GEOMAlgo_BndSphere&) const; + Standard_EXPORT virtual Standard_Boolean Accept(const Standard_Integer &); + Standard_EXPORT virtual ~GEOMAlgo_BndSphereTreeSelector(); + + Standard_EXPORT void Clear(); + Standard_EXPORT void SetBox(const GEOMAlgo_BndSphere&); + Standard_EXPORT const TColStd_ListOfInteger& Indices() const; + + protected: + GEOMAlgo_BndSphere myBox; + TColStd_MapOfInteger myFence; + TColStd_ListOfInteger myIndices; + + }; + +#endif diff --git a/src/GeomAlgoAPI/GEOMAlgo_CoupleOfShapes.cxx b/src/GeomAlgoAPI/GEOMAlgo_CoupleOfShapes.cxx new file mode 100644 index 000000000..00db0ccf5 --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_CoupleOfShapes.cxx @@ -0,0 +1,85 @@ +// Copyright (C) 2007-2021 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 +// +// File: GEOMAlgo_CoupleOfShapes.cxx +// Created: Wed Dec 15 13:03:52 2004 +// Author: Peter KURNEV +// +// +#include +//======================================================================= +//function : GEOMAlgo_CoupleOfShapes +//purpose : +//======================================================================= +GEOMAlgo_CoupleOfShapes::GEOMAlgo_CoupleOfShapes() +{} +//======================================================================= +//function : SetShapes +//purpose : +//======================================================================= +void GEOMAlgo_CoupleOfShapes::SetShapes(const TopoDS_Shape& aS1, + const TopoDS_Shape& aS2) +{ + myShape1=aS1; + myShape2=aS2; +} +//======================================================================= +//function : Shapes +//purpose : +//======================================================================= +void GEOMAlgo_CoupleOfShapes::Shapes(TopoDS_Shape& aS1, + TopoDS_Shape& aS2)const +{ + aS1=myShape1; + aS2=myShape2; +} +//======================================================================= +//function : SetShape1 +//purpose : +//======================================================================= +void GEOMAlgo_CoupleOfShapes::SetShape1(const TopoDS_Shape& aS1) +{ + myShape1=aS1; +} +//======================================================================= +//function : SetShape2 +//purpose : +//======================================================================= +void GEOMAlgo_CoupleOfShapes::SetShape2(const TopoDS_Shape& aS2) +{ + myShape2=aS2; +} +//======================================================================= +//function : Shape1 +//purpose : +//======================================================================= +const TopoDS_Shape& GEOMAlgo_CoupleOfShapes::Shape1()const +{ + return myShape1; +} +//======================================================================= +//function : Shape2 +//purpose : +//======================================================================= +const TopoDS_Shape& GEOMAlgo_CoupleOfShapes::Shape2()const +{ + return myShape2; +} diff --git a/src/GeomAlgoAPI/GEOMAlgo_CoupleOfShapes.hxx b/src/GeomAlgoAPI/GEOMAlgo_CoupleOfShapes.hxx new file mode 100644 index 000000000..e7736becc --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_CoupleOfShapes.hxx @@ -0,0 +1,64 @@ +// Copyright (C) 2007-2021 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: GEOMAlgo_CoupleOfShapes.hxx +// Created: Wed Dec 15 13:03:52 2004 +// Author: Peter KURNEV +// +// + +#ifndef _GEOMAlgo_CoupleOfShapes_HeaderFile +#define _GEOMAlgo_CoupleOfShapes_HeaderFile + +#include +#include +#include + +//======================================================================= +//class : GEOMAlgo_CoupleOfShapes +//purpose : +//======================================================================= +class GEOMAlgo_CoupleOfShapes +{ + public: + Standard_EXPORT + GEOMAlgo_CoupleOfShapes(); + + Standard_EXPORT + void SetShapes(const TopoDS_Shape& aS1,const TopoDS_Shape& aS2) ; + + Standard_EXPORT + void SetShape1(const TopoDS_Shape& aS1) ; + + Standard_EXPORT + void SetShape2(const TopoDS_Shape& aS2) ; + + Standard_EXPORT + void Shapes(TopoDS_Shape& aS1,TopoDS_Shape& aS2) const; + + Standard_EXPORT + const TopoDS_Shape& Shape1() const; + + Standard_EXPORT + const TopoDS_Shape& Shape2() const; + +protected: + TopoDS_Shape myShape1; + TopoDS_Shape myShape2; +}; +#endif diff --git a/src/GeomAlgoAPI/GEOMAlgo_IndexedDataMapOfIntegerShape.hxx b/src/GeomAlgoAPI/GEOMAlgo_IndexedDataMapOfIntegerShape.hxx new file mode 100644 index 000000000..47797b496 --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_IndexedDataMapOfIntegerShape.hxx @@ -0,0 +1,45 @@ +// Copyright (C) 2007-2021 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: GEOMAlgo_IndexedDataMapOfIntegerShape.hxx +// Created: Wed Feb 22 11:22:18 2012 +// Author: +// + + +#ifndef GEOMAlgo_IndexedDataMapOfIntegerShape_HeaderFile +#define GEOMAlgo_IndexedDataMapOfIntegerShape_HeaderFile + + + +#include +#include +#include + +#define _NCollection_MapHasher +#include + + +typedef NCollection_IndexedDataMap + GEOMAlgo_IndexedDataMapOfIntegerShape; + +#undef _NCollection_MapHasher + + + +#endif diff --git a/src/GeomAlgoAPI/GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx b/src/GeomAlgoAPI/GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx new file mode 100644 index 000000000..8ee4b3a80 --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx @@ -0,0 +1,46 @@ +// Copyright (C) 2007-2021 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: GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx +// Created: Wed Feb 22 11:24:27 2012 +// Author: +// + + +#ifndef GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape_HeaderFile +#define GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape_HeaderFile + +#include +#include +#include + + +#define _NCollection_MapHasher +#include + + +typedef NCollection_IndexedDataMap + GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape; + +#undef _NCollection_MapHasher + + + +#endif diff --git a/src/GeomAlgoAPI/GEOMAlgo_IndexedDataMapOfShapeBndSphere.hxx b/src/GeomAlgoAPI/GEOMAlgo_IndexedDataMapOfShapeBndSphere.hxx new file mode 100644 index 000000000..15d4f02eb --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_IndexedDataMapOfShapeBndSphere.hxx @@ -0,0 +1,46 @@ +// Copyright (C) 2007-2021 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: GEOMAlgo_IndexedDataMapOfShapeBndSphere.hxx +// Created: Mon Feb 20 09:17:01 2012 +// Author: +// + + +#ifndef GEOMAlgo_IndexedDataMapOfShapeBndSphere_HeaderFile +#define GEOMAlgo_IndexedDataMapOfShapeBndSphere_HeaderFile + +#include +#include +#include + +#define _NCollection_MapHasher +#include + + + +typedef NCollection_IndexedDataMap + GEOMAlgo_IndexedDataMapOfShapeBndSphere; + +#undef _NCollection_MapHasher + + + + +#endif diff --git a/src/GeomAlgoAPI/GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape.hxx b/src/GeomAlgoAPI/GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape.hxx new file mode 100644 index 000000000..fe13edeab --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape.hxx @@ -0,0 +1,50 @@ +// Copyright (C) 2007-2021 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: GEOMAlgo_IndexedDataMapOfIndexedMapOfInteger.hxx +// Created: Mon Feb 20 09:20:07 2012 +// Author: +// +// File: GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape.hxx +// Created: Mon Feb 20 11:59:23 2012 +// Author: +// + + +#ifndef GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape_HeaderFile +#define GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape_HeaderFile + + +#include +#include +#include + +#define _NCollection_MapHasher +#include + + +typedef NCollection_IndexedDataMap + GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape; + +#undef _NCollection_MapHasher + + +#endif + diff --git a/src/GeomAlgoAPI/GEOMAlgo_ListOfCoupleOfShapes.hxx b/src/GeomAlgoAPI/GEOMAlgo_ListOfCoupleOfShapes.hxx new file mode 100644 index 000000000..ba97333f5 --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_ListOfCoupleOfShapes.hxx @@ -0,0 +1,34 @@ +// Copyright (C) 2007-2021 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: GEOMAlgo_ListOfCoupleOfShapes.hxx +// Created: Wed Feb 22 08:23:27 2012 +// Author: +// + +#ifndef GEOMAlgo_ListOfCoupleOfShapes_HeaderFile +#define GEOMAlgo_ListOfCoupleOfShapes_HeaderFile + +#include +#include + +typedef NCollection_List GEOMAlgo_ListOfCoupleOfShapes; +typedef GEOMAlgo_ListOfCoupleOfShapes::Iterator GEOMAlgo_ListIteratorOfListOfCoupleOfShapes; + +#endif diff --git a/src/GeomAlgoAPI/GEOMAlgo_PassKey.cxx b/src/GeomAlgoAPI/GEOMAlgo_PassKey.cxx new file mode 100644 index 000000000..4351e1bf5 --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_PassKey.cxx @@ -0,0 +1,240 @@ +// Copyright (C) 2007-2021 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 +// + +// File: GEOMAlgo_PassKey.cxx +// Created: +// Author: Peter KURNEV +// +// +#include + +#include +#include +#include +#include + +#ifdef WIN32 +#pragma warning( disable : 4101) +#endif + +static + Standard_Integer NormalizedId(const Standard_Integer aId, + const Standard_Integer aDiv); + +//======================================================================= +//function : +//purpose : +//======================================================================= + GEOMAlgo_PassKey::GEOMAlgo_PassKey() +{ + Clear(); +} +//======================================================================= +//function : +//purpose : +//======================================================================= + GEOMAlgo_PassKey::GEOMAlgo_PassKey(const GEOMAlgo_PassKey& aOther) +{ + myNbIds=aOther.myNbIds; + mySum=aOther.mySum; + myMap=aOther.myMap; +} +//======================================================================= +//function :Assign +//purpose : +//======================================================================= + GEOMAlgo_PassKey& GEOMAlgo_PassKey::Assign(const GEOMAlgo_PassKey& aOther) +{ + myNbIds=aOther.myNbIds; + mySum=aOther.mySum; + myMap=aOther.myMap; + return *this; +} +//======================================================================= +//function :~ +//purpose : +//======================================================================= + GEOMAlgo_PassKey::~GEOMAlgo_PassKey() +{ +} +//======================================================================= +//function :Clear +//purpose : +//======================================================================= + void GEOMAlgo_PassKey::Clear() +{ + myNbIds=0; + mySum=0; + myMap.Clear(); +} +//======================================================================= +//function :SetIds +//purpose : +//======================================================================= + void GEOMAlgo_PassKey::SetIds(const Standard_Integer aId1) + +{ + Clear(); + myNbIds=1; + myMap.Add(aId1); + mySum=NormalizedId(aId1, myNbIds); +} +//======================================================================= +//function :SetIds +//purpose : +//======================================================================= + void GEOMAlgo_PassKey::SetIds(const Standard_Integer aId1, + const Standard_Integer aId2) +{ + TColStd_ListOfInteger aLI; + // + aLI.Append(aId1); + aLI.Append(aId2); + SetIds(aLI); +} +//======================================================================= +//function :SetIds +//purpose : +//======================================================================= + void GEOMAlgo_PassKey::SetIds(const Standard_Integer aId1, + const Standard_Integer aId2, + const Standard_Integer aId3) +{ + TColStd_ListOfInteger aLI; + // + aLI.Append(aId1); + aLI.Append(aId2); + aLI.Append(aId3); + SetIds(aLI); +} +//======================================================================= +//function :SetIds +//purpose : +//======================================================================= + void GEOMAlgo_PassKey::SetIds(const Standard_Integer aId1, + const Standard_Integer aId2, + const Standard_Integer aId3, + const Standard_Integer aId4) +{ + TColStd_ListOfInteger aLI; + // + aLI.Append(aId1); + aLI.Append(aId2); + aLI.Append(aId3); + aLI.Append(aId4); + SetIds(aLI); +} +//======================================================================= +//function :SetIds +//purpose : +//======================================================================= + void GEOMAlgo_PassKey::SetIds(const TColStd_ListOfInteger& aLI) +{ + Standard_Integer i, aId, aIdN; + TColStd_ListIteratorOfListOfInteger aIt; + // + Clear(); + aIt.Initialize(aLI); + for (; aIt.More(); aIt.Next()) { + aId=aIt.Value(); + myMap.Add(aId); + } + myNbIds=myMap.Extent(); + for(i=1; i<=myNbIds; ++i) { + aId=myMap(i); + aIdN=NormalizedId(aId, myNbIds); + mySum+=aIdN; + } +} +//======================================================================= +//function :NbIds +//purpose : +//======================================================================= + Standard_Integer GEOMAlgo_PassKey::NbIds()const +{ + return myNbIds; +} +//======================================================================= +//function :Id +//purpose : +//======================================================================= + Standard_Integer GEOMAlgo_PassKey::Id(const Standard_Integer aIndex) const +{ + if (aIndex<1 || aIndex>myNbIds) { + return -1; + } + return myMap(aIndex); +} +//======================================================================= +//function :IsEqual +//purpose : +//======================================================================= + Standard_Boolean GEOMAlgo_PassKey::IsEqual(const GEOMAlgo_PassKey& aOther) const +{ + Standard_Boolean bRet; + Standard_Integer i, aId; + // + bRet=Standard_False; + // + if (myNbIds!=aOther.myNbIds) { + return bRet; + } + for (i=1; i<=myNbIds; ++i) { + aId=myMap(i); + if (!aOther.myMap.Contains(aId)) { + return bRet; + } + } + return !bRet; +} +//======================================================================= +//function : HashCode +//purpose : +//======================================================================= + Standard_Integer GEOMAlgo_PassKey::HashCode(const Standard_Integer aUpper) const +{ + return ::HashCode(mySum, aUpper); +} +//======================================================================= +//function : Dump +//purpose : +//======================================================================= + void GEOMAlgo_PassKey::Dump(const Standard_Integer )const +{ +} +//======================================================================= +// function: NormalizedId +// purpose : +//======================================================================= +Standard_Integer NormalizedId(const Standard_Integer aId, + const Standard_Integer aDiv) +{ + Standard_Integer aMax, aTresh, aIdRet; + // + aIdRet=aId; + aMax=::IntegerLast(); + aTresh=aMax/aDiv; + if (aId>aTresh) { + aIdRet=aId%aTresh; + } + return aIdRet; +} diff --git a/src/GeomAlgoAPI/GEOMAlgo_PassKey.hxx b/src/GeomAlgoAPI/GEOMAlgo_PassKey.hxx new file mode 100644 index 000000000..eef809475 --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_PassKey.hxx @@ -0,0 +1,105 @@ +// Copyright (C) 2007-2021 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 +// + +// File: GEOMAlgo_PassKey.hxx +// Created: +// Author: Peter KURNEV +// +// +#ifndef _GEOMAlgo_PassKey_HeaderFile +#define _GEOMAlgo_PassKey_HeaderFile + +#include +#include +#include +#include + +#include +#include + +//======================================================================= +//class : GEOMAlgo_PassKey +//purpose : +//======================================================================= +class GEOMAlgo_PassKey { + public: + Standard_EXPORT + GEOMAlgo_PassKey(); + + Standard_EXPORT + virtual ~GEOMAlgo_PassKey(); + + Standard_EXPORT + GEOMAlgo_PassKey(const GEOMAlgo_PassKey& Other); + + Standard_EXPORT + GEOMAlgo_PassKey& Assign(const GEOMAlgo_PassKey& Other) ; + + GEOMAlgo_PassKey& operator =(const GEOMAlgo_PassKey& Other) { + return Assign(Other); + } + + Standard_EXPORT + void Clear() ; + + Standard_EXPORT + void SetIds(const Standard_Integer aI1) ; + + Standard_EXPORT + void SetIds(const Standard_Integer aI1, + const Standard_Integer aI2) ; + + Standard_EXPORT + void SetIds(const Standard_Integer aI1, + const Standard_Integer aI2, + const Standard_Integer aI3) ; + + Standard_EXPORT + void SetIds(const Standard_Integer aI1, + const Standard_Integer aI2, + const Standard_Integer aI3, + const Standard_Integer aI4) ; + + Standard_EXPORT + void SetIds(const TColStd_ListOfInteger& aLS) ; + + Standard_EXPORT + Standard_Integer NbIds() const; + + Standard_EXPORT + Standard_Boolean IsEqual(const GEOMAlgo_PassKey& aOther) const; + + Standard_EXPORT + Standard_Integer HashCode(const Standard_Integer Upper) const; + + Standard_EXPORT + Standard_Integer Id(const Standard_Integer aIndex) const; + + Standard_EXPORT + void Dump(const Standard_Integer aHex = 0) const; + + protected: + Standard_Integer myNbIds; + Standard_Integer mySum; + TColStd_IndexedMapOfInteger myMap; +}; +#endif diff --git a/src/GeomAlgoAPI/GEOMAlgo_PassKeyMapHasher.cxx b/src/GeomAlgoAPI/GEOMAlgo_PassKeyMapHasher.cxx new file mode 100644 index 000000000..af2dd2b12 --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_PassKeyMapHasher.cxx @@ -0,0 +1,47 @@ +// Copyright (C) 2007-2021 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 +// + +// File: GEOMAlgo_PassKeyMapHasher.cxx +// Created: +// Author: Peter KURNEV +// +// +#include + +//======================================================================= +//function : HashCode +//purpose : +//======================================================================= + Standard_Integer GEOMAlgo_PassKeyMapHasher::HashCode(const GEOMAlgo_PassKey& aPK, + const Standard_Integer Upper) +{ + return aPK.HashCode(Upper); +} +//======================================================================= +//function :IsEqual +//purpose : +//======================================================================= + Standard_Boolean GEOMAlgo_PassKeyMapHasher::IsEqual(const GEOMAlgo_PassKey& aPK1, + const GEOMAlgo_PassKey& aPK2) +{ + return aPK1.IsEqual(aPK2); +} diff --git a/src/GeomAlgoAPI/GEOMAlgo_PassKeyMapHasher.hxx b/src/GeomAlgoAPI/GEOMAlgo_PassKeyMapHasher.hxx new file mode 100644 index 000000000..b320f6f55 --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_PassKeyMapHasher.hxx @@ -0,0 +1,51 @@ +// Copyright (C) 2007-2021 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 +// + +// File: GEOMAlgo_PassKeyMapHasher.hxx +// Created: +// Author: Peter KURNEV +// +// +#ifndef _GEOMAlgo_PassKeyMapHasher_HeaderFile +#define _GEOMAlgo_PassKeyMapHasher_HeaderFile + +#include +#include +#include +#include +#include + +//======================================================================= +//class : GEOMAlgo_PassKeyMapHasher +//purpose : +//======================================================================= +class GEOMAlgo_PassKeyMapHasher { + public: + Standard_EXPORT + static Standard_Integer HashCode(const GEOMAlgo_PassKey& aPKey, + const Standard_Integer Upper) ; + + Standard_EXPORT + static Standard_Boolean IsEqual(const GEOMAlgo_PassKey& aPKey1, + const GEOMAlgo_PassKey& aPKey2) ; +}; +#endif diff --git a/src/GeomAlgoAPI/GEOMAlgo_PassKeyShape.cxx b/src/GeomAlgoAPI/GEOMAlgo_PassKeyShape.cxx new file mode 100644 index 000000000..bbfb279ba --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_PassKeyShape.cxx @@ -0,0 +1,229 @@ +// Copyright (C) 2007-2021 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 +// + +// File: GEOMAlgo_PassKeyShape.cxx +// Created: +// Author: Peter KURNEV +// +// +#include + +#include +#include + + +static + Standard_Integer NormalizedId(const Standard_Integer aId, + const Standard_Integer aDiv); +//======================================================================= +//function : +//purpose : +//======================================================================= + GEOMAlgo_PassKeyShape::GEOMAlgo_PassKeyShape() +{ + myUpper=432123; +} +//======================================================================= +//function : +//purpose : +//======================================================================= + GEOMAlgo_PassKeyShape::GEOMAlgo_PassKeyShape(const GEOMAlgo_PassKeyShape& aOther) +{ + myUpper=432123; + myNbIds=aOther.myNbIds; + mySum=aOther.mySum; + myMap=aOther.myMap; +} +//======================================================================= +//function :~ +//purpose : +//======================================================================= + GEOMAlgo_PassKeyShape::~GEOMAlgo_PassKeyShape() +{ +} +//======================================================================= +//function :Assign +//purpose : +//======================================================================= + GEOMAlgo_PassKeyShape& GEOMAlgo_PassKeyShape::Assign(const GEOMAlgo_PassKeyShape& aOther) +{ + myUpper=432123; + myNbIds=aOther.myNbIds; + mySum=aOther.mySum; + myMap=aOther.myMap; + return *this; +} +//======================================================================= +//function :Clear +//purpose : +//======================================================================= + void GEOMAlgo_PassKeyShape::Clear() +{ + myNbIds=0; + mySum=0; + myMap.Clear(); +} +//======================================================================= +//function :SetShapes +//purpose : +//======================================================================= + void GEOMAlgo_PassKeyShape::SetShapes(const TopoDS_Shape& aS1) + +{ + Standard_Integer aHC; + // + Clear(); + myNbIds=1; + myMap.Add(aS1); + aHC=aS1.HashCode(myUpper); + mySum=NormalizedId(aHC, myNbIds); +} +//======================================================================= +//function :SetShapes +//purpose : +//======================================================================= + void GEOMAlgo_PassKeyShape::SetShapes(const TopoDS_Shape& aS1, + const TopoDS_Shape& aS2) +{ + TopTools_ListOfShape aLS; + // + aLS.Append(aS1); + aLS.Append(aS2); + SetShapes(aLS); +} +//======================================================================= +//function :SetShapes +//purpose : +//======================================================================= + void GEOMAlgo_PassKeyShape::SetShapes(const TopoDS_Shape& aS1, + const TopoDS_Shape& aS2, + const TopoDS_Shape& aS3) +{ + TopTools_ListOfShape aLS; + // + aLS.Append(aS1); + aLS.Append(aS2); + aLS.Append(aS3); + SetShapes(aLS); +} +//======================================================================= +//function :SetShapes +//purpose : +//======================================================================= + void GEOMAlgo_PassKeyShape::SetShapes(const TopoDS_Shape& aS1, + const TopoDS_Shape& aS2, + const TopoDS_Shape& aS3, + const TopoDS_Shape& aS4) +{ + TopTools_ListOfShape aLS; + // + aLS.Append(aS1); + aLS.Append(aS2); + aLS.Append(aS3); + aLS.Append(aS4); + SetShapes(aLS); +} +//======================================================================= +//function :SetShapes +//purpose : +//======================================================================= + void GEOMAlgo_PassKeyShape::SetShapes(const TopTools_ListOfShape& aLS) +{ + Standard_Integer i, aId, aIdN; + TopTools_ListIteratorOfListOfShape aIt; + // + Clear(); + aIt.Initialize(aLS); + for (; aIt.More(); aIt.Next()) { + const TopoDS_Shape& aS=aIt.Value(); + myMap.Add(aS); + } + myNbIds=myMap.Extent(); + for(i=1; i<=myNbIds; ++i) { + const TopoDS_Shape& aS=myMap(i); + aId=aS.HashCode(myUpper); + aIdN=NormalizedId(aId, myNbIds); + mySum+=aIdN; + } +} +//======================================================================= +//function :NbIds +//purpose : +//======================================================================= + Standard_Integer GEOMAlgo_PassKeyShape::NbIds()const +{ + return myNbIds; +} +//======================================================================= +//function :IsEqual +//purpose : +//======================================================================= + Standard_Boolean GEOMAlgo_PassKeyShape::IsEqual(const GEOMAlgo_PassKeyShape& aOther) const +{ + Standard_Boolean bRet; + Standard_Integer i; + // + bRet=Standard_False; + // + if (myNbIds!=aOther.myNbIds) { + return bRet; + } + for (i=1; i<=myNbIds; ++i) { + const TopoDS_Shape& aS=myMap(i); + if (!aOther.myMap.Contains(aS)) { + return bRet; + } + } + return !bRet; +} +//======================================================================= +//function : HashCode +//purpose : +//======================================================================= + Standard_Integer GEOMAlgo_PassKeyShape::HashCode(const Standard_Integer aUpper) const +{ + return ::HashCode(mySum, aUpper); +} +//======================================================================= +//function : Dump +//purpose : +//======================================================================= + void GEOMAlgo_PassKeyShape::Dump(const Standard_Integer)const +{ +} +//======================================================================= +// function: NormalizedId +// purpose : +//======================================================================= +Standard_Integer NormalizedId(const Standard_Integer aId, + const Standard_Integer aDiv) +{ + Standard_Integer aMax, aTresh, aIdRet; + // + aIdRet=aId; + aMax=::IntegerLast(); + aTresh=aMax/aDiv; + if (aId>aTresh) { + aIdRet=aId%aTresh; + } + return aIdRet; +} diff --git a/src/GeomAlgoAPI/GEOMAlgo_PassKeyShape.hxx b/src/GeomAlgoAPI/GEOMAlgo_PassKeyShape.hxx new file mode 100644 index 000000000..aca56f261 --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_PassKeyShape.hxx @@ -0,0 +1,105 @@ + +// Copyright (C) 2007-2020 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 +// + +// File: GEOMAlgo_PassKeyShape.hxx +// Created: +// Author: Peter KURNEV +// +// +#ifndef _GEOMAlgo_PassKeyShape_HeaderFile +#define _GEOMAlgo_PassKeyShape_HeaderFile + +#include +#include +#include +#include +#include +#include +#include + + +//======================================================================= +//class : GEOMAlgo_PassKeyShape +//purpose : +//======================================================================= +class GEOMAlgo_PassKeyShape { + public: + Standard_EXPORT + GEOMAlgo_PassKeyShape(); + + Standard_EXPORT + virtual ~GEOMAlgo_PassKeyShape(); + + Standard_EXPORT + GEOMAlgo_PassKeyShape(const GEOMAlgo_PassKeyShape& Other); + + Standard_EXPORT + GEOMAlgo_PassKeyShape& Assign(const GEOMAlgo_PassKeyShape& Other) ; + + GEOMAlgo_PassKeyShape& operator =(const GEOMAlgo_PassKeyShape& Other) { + return Assign(Other); + } + + Standard_EXPORT + void SetShapes(const TopoDS_Shape& aS) ; + + Standard_EXPORT + void SetShapes(const TopoDS_Shape& aS1, + const TopoDS_Shape& aS2) ; + + Standard_EXPORT + void SetShapes(const TopoDS_Shape& aS1, + const TopoDS_Shape& aS2, + const TopoDS_Shape& aS3) ; + + Standard_EXPORT + void SetShapes(const TopoDS_Shape& aS1, + const TopoDS_Shape& aS2, + const TopoDS_Shape& aS3, + const TopoDS_Shape& aS4) ; + + Standard_EXPORT + void SetShapes(const TopTools_ListOfShape& aLS) ; + + Standard_EXPORT + void Clear() ; + + Standard_EXPORT + Standard_Integer NbIds() const; + + Standard_EXPORT + Standard_Boolean IsEqual(const GEOMAlgo_PassKeyShape& aOther) const; + + Standard_EXPORT + Standard_Integer HashCode(const Standard_Integer Upper) const; + + Standard_EXPORT + void Dump(const Standard_Integer aHex = 0) const; + +protected: + Standard_Integer myNbIds; + Standard_Integer mySum; + Standard_Integer myUpper; + TopTools_IndexedMapOfShape myMap; +}; +#endif diff --git a/src/GeomAlgoAPI/GEOMAlgo_PassKeyShapeMapHasher.cxx b/src/GeomAlgoAPI/GEOMAlgo_PassKeyShapeMapHasher.cxx new file mode 100644 index 000000000..756abe524 --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_PassKeyShapeMapHasher.cxx @@ -0,0 +1,47 @@ +// Copyright (C) 2007-2021 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 +// + +// File: GEOMAlgo_PassKeyMapHasher.cxx +// Created: +// Author: Peter KURNEV +// +// +#include + +//======================================================================= +//function : HashCode +//purpose : +//======================================================================= + Standard_Integer GEOMAlgo_PassKeyShapeMapHasher::HashCode(const GEOMAlgo_PassKeyShape& aPK, + const Standard_Integer Upper) +{ + return aPK.HashCode(Upper); +} +//======================================================================= +//function :IsEqual +//purpose : +//======================================================================= + Standard_Boolean GEOMAlgo_PassKeyShapeMapHasher::IsEqual(const GEOMAlgo_PassKeyShape& aPK1, + const GEOMAlgo_PassKeyShape& aPK2) +{ + return aPK1.IsEqual(aPK2); +} diff --git a/src/GeomAlgoAPI/GEOMAlgo_PassKeyShapeMapHasher.hxx b/src/GeomAlgoAPI/GEOMAlgo_PassKeyShapeMapHasher.hxx new file mode 100644 index 000000000..ae6bc592e --- /dev/null +++ b/src/GeomAlgoAPI/GEOMAlgo_PassKeyShapeMapHasher.hxx @@ -0,0 +1,52 @@ +// Copyright (C) 2007-2021 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 +// + +// File: GEOMAlgo_PassKeyMapHasher.hxx +// Created: +// Author: Peter KURNEV +// +// +#ifndef _GEOMAlgo_PassKeyShapeMapHasher_HeaderFile +#define _GEOMAlgo_PassKeyShapeMapHasher_HeaderFile + +#include +#include +#include +#include +#include + +//======================================================================= +//class : GEOMAlgo_PassKeyShapeMapHasher +//purpose : +//======================================================================= +class GEOMAlgo_PassKeyShapeMapHasher +{ + public: + Standard_EXPORT + static Standard_Integer HashCode(const GEOMAlgo_PassKeyShape& aPKey, + const Standard_Integer Upper) ; + + Standard_EXPORT + static Standard_Boolean IsEqual(const GEOMAlgo_PassKeyShape& aPKey1, + const GEOMAlgo_PassKeyShape& aPKey2) ; +}; +#endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Algo.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Algo.cpp new file mode 100644 index 000000000..d49ceef5f --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Algo.cpp @@ -0,0 +1,82 @@ +// Copyright (C) 2014-2021 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 + +//======================================================================= +// function: +// purpose: +//======================================================================= +GeomAlgoAPI_Algo::GeomAlgoAPI_Algo() +: + myErrorStatus(1), + myWarningStatus(0), + myComputeInternalShapes(Standard_True) +{} +//======================================================================= +// function: ~ +// purpose: +//======================================================================= +GeomAlgoAPI_Algo::~GeomAlgoAPI_Algo() +{ +} +//======================================================================= +// function: CheckData +// purpose: +//======================================================================= +void GeomAlgoAPI_Algo::CheckData() +{ + myErrorStatus=0; +} +//======================================================================= +// function: CheckResult +// purpose: +//======================================================================= +void GeomAlgoAPI_Algo::CheckResult() +{ + myErrorStatus=0; +} +//======================================================================= +// function: ErrorStatus +// purpose: +//======================================================================= +Standard_Integer GeomAlgoAPI_Algo::ErrorStatus()const +{ + return myErrorStatus; +} +//======================================================================= +// function: WarningStatus +// purpose: +//======================================================================= +Standard_Integer GeomAlgoAPI_Algo::WarningStatus()const +{ + return myWarningStatus; +} +// myErrorStatus +// +// 1 - object is just initialized + +//======================================================================= +//function : ComputeInternalShapes +//purpose : +//======================================================================= +void GeomAlgoAPI_Algo::ComputeInternalShapes(const Standard_Boolean theFlag) +{ + myComputeInternalShapes = theFlag; +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Algo.h b/src/GeomAlgoAPI/GeomAlgoAPI_Algo.h new file mode 100644 index 000000000..c4ce84051 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Algo.h @@ -0,0 +1,68 @@ +// Copyright (C) 2014-2021 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_ALGO_H_ +#define GEOMALGOAPI_ALGO_H_ + +#include +#include +#include +#include +#include + +//======================================================================= +//class : GeomAlgoAPI_Algo +//purpose : +//======================================================================= +class GeomAlgoAPI_Algo +{ + public: + Standard_EXPORT + virtual void Perform() = 0; + + Standard_EXPORT + Standard_Integer ErrorStatus() const; + + Standard_EXPORT + Standard_Integer WarningStatus() const; + + //! Allows to omit of creation of internal shapes (manifold topology).
+ //! Needed for the SALOME/TRIPOLI module.
+ Standard_EXPORT + void ComputeInternalShapes(const Standard_Boolean theFlag) ; + +protected: + Standard_EXPORT + GeomAlgoAPI_Algo(); + + Standard_EXPORT + virtual ~GeomAlgoAPI_Algo(); + + Standard_EXPORT + virtual void CheckData() ; + + Standard_EXPORT + virtual void CheckResult() ; + + + Standard_Integer myErrorStatus; + Standard_Integer myWarningStatus; + Standard_Boolean myComputeInternalShapes; +}; +#endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_DuplicatedFaces.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_DuplicatedFaces.cpp new file mode 100644 index 000000000..17f862f9b --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_DuplicatedFaces.cpp @@ -0,0 +1,142 @@ +// Copyright (C) 2014-2021 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_DuplicatedFaces.h" + +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include + +//================================================================================================= +bool GetDuplicatedFaces(const ListOfShape& theShapes, + const Standard_Real& theTolerance, + ListOfShape & theFaces, + std::string& theError) +{ + #ifdef _DEBUG + std::cout << "GetDuplicatedFaces " << std::endl; + #endif + + TopoDS_Shape aShape; + TopTools_SequenceOfShape aShapesSeq; + + ListOfShape::const_iterator anIt = theShapes.cbegin(); + + for (; anIt != theShapes.cend(); ++anIt) { + + GeomShapePtr aShapePtr = *anIt; + + if (!aShapePtr.get()) { + theError = "GetDuplicatedFaces : An invalid argument"; + return false; + } + aShape = aShapePtr->impl(); + aShapesSeq.Append( aShape ); + } + + if (aShapesSeq.Length() > 1){ + TopoDS_Compound aCompound; + BRep_Builder aBuilder; + aBuilder.MakeCompound( aCompound ); + for (int i = 1; i <= aShapesSeq.Length(); ++i) + aBuilder.Add( aCompound, aShapesSeq( i ) ); + + aShape = aCompound; + } + + GeomAlgoAPI_GlueDetector aGluer; + aGluer.SetArgument(aShape); + aGluer.SetTolerance(theTolerance); + aGluer.Perform(); + Standard_Integer iErr = aGluer.ErrorStatus(); + if (iErr) return NULL; + + std::vector< TopTools_IndexedMapOfShape* > anIndices( aShapesSeq.Length(), NULL ); + Handle(TColStd_HArray1OfInteger) anArray; + GeomShapePtr anObj; + + ListOfShape listOnePerSet; + + const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images(); + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages); + for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) { + // some key shape + + // list of shapes of the argument that can be glued + const TopTools_ListOfShape& aLSD = aItDMSLS.Value(); + + //listShape.Append(aLSD.First()); + TopoDS_Shape aValue = aLSD.First(); + + if (aValue.ShapeType() == TopAbs_FACE) { + GeomShapePtr aS(new GeomAPI_Shape); + aS->setImpl(new TopoDS_Shape(aValue)); + listOnePerSet.push_back(aS); + } + } + + // for stable order of returned entities + GeomAlgoAPI_SortListOfShapes::sort(listOnePerSet); + + //TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet); + ListOfShape::const_iterator aListIt = listOnePerSet.cbegin(); + for (; aListIt != listOnePerSet.cend(); ++aListIt) { + TopoDS_Shape aValue = (*aListIt)->impl(); + // find a shape to add aValue as a sub-shape + anObj.reset(); + + anIt = theShapes.cbegin(); + GeomShapePtr aShapePtr; + for (int i = 0; i < theShapes.size(); ++i, ++anIt) { + aShapePtr = *anIt; + if (!anIndices[i]) { + anIndices[i] = new TopTools_IndexedMapOfShape; + aShape = aShapePtr->impl(); + TopExp::MapShapes( aShape, *anIndices[i]); + } + if (int index = anIndices[i]->FindIndex( aValue )) { + + const TopoDS_Shape& aSelShape = anIndices[i]->FindKey(index); + GeomShapePtr aS(new GeomAPI_Shape); + aS->setImpl(new TopoDS_Shape(aSelShape)); + // GeomAlgoAPI_ShapeBuilder::add(aShapePtr,aS); + if (aS.get()) + theFaces.push_back(aS); + break; + } + } + } + for (size_t i = 0 ; i < anIndices.size(); ++i) + delete anIndices[i]; + + return true; +} + diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_DuplicatedFaces.h b/src/GeomAlgoAPI/GeomAlgoAPI_DuplicatedFaces.h new file mode 100644 index 000000000..b5d8b580d --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_DuplicatedFaces.h @@ -0,0 +1,38 @@ +// Copyright (C) 2014-2021 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_DUPLICATEDFACES_H_ +#define GEOMALGOAPI_DUPLICATEDFACES_H_ + +#include +#include +#include + +/// get the boundin box of theshape. +/// \param theShape the shape +/// \param theTolerance precise TRUE for precise computation; FALSE for fast one. +/// \param theFaces the duplicated faces +/// \param theError error +GEOMALGOAPI_EXPORT +bool GetDuplicatedFaces(const ListOfShape& theShapes, + const Standard_Real& theTolerance, + ListOfShape & theFaces, + std::string& theError); + +#endif //GEOMALGOAPI_DUPLICATEDFACES_H_ diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_GlueDetector.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_GlueDetector.cpp new file mode 100644 index 000000000..857d54614 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_GlueDetector.cpp @@ -0,0 +1,594 @@ +// Copyright (C) 2014-2021 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 + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +// +static + Standard_Integer CheckAncesstors + (const TopoDS_Shape& aVSD, + const TopTools_MapOfShape& aMVSD, + const TopTools_IndexedDataMapOfShapeListOfShape& aMVE, + const TopTools_IndexedDataMapOfShapeListOfShape& aMEV, + TopTools_IndexedDataMapOfShapeListOfShape& aMEVZ); + +//======================================================================= +//function : +//purpose : +//======================================================================= +GeomAlgoAPI_GlueDetector::GeomAlgoAPI_GlueDetector() +: + GeomAlgoAPI_GluerAlgo(), + GeomAlgoAPI_Algo() +{} +//======================================================================= +//function : ~ +//purpose : +//======================================================================= +GeomAlgoAPI_GlueDetector::~GeomAlgoAPI_GlueDetector() +{} +//======================================================================= +//function : StickedShapes +//purpose : +//======================================================================= +const TopTools_IndexedDataMapOfShapeListOfShape& + GeomAlgoAPI_GlueDetector::StickedShapes() +{ + return myStickedShapes; +} +//======================================================================= +//function : Perform +//purpose : +//======================================================================= +void GeomAlgoAPI_GlueDetector::Perform() +{ + myErrorStatus=0; + myWarningStatus=0; + myStickedShapes.Clear(); + // + CheckData(); + if (myErrorStatus) { + return; + } + // + // Initialize the context + GeomAlgoAPI_GluerAlgo::Perform(); + // + DetectVertices(); + if (myErrorStatus) { + return; + } + // + CheckDetected(); + if (myErrorStatus) { + return; + } + // + DetectEdges(); + if (myErrorStatus) { + return; + } + // + DetectFaces(); + if (myErrorStatus) { + return; + } +} +//======================================================================= +//function : DetectVertices +//purpose : +//======================================================================= +void GeomAlgoAPI_GlueDetector::DetectVertices() +{ + Standard_Integer j, i, aNbV, aNbVSD; + Standard_Real aTolV; + gp_Pnt aPV; + TColStd_ListIteratorOfListOfInteger aIt; + TopoDS_Shape aVF; + TopTools_IndexedMapOfShape aMV; + TopTools_MapOfShape aMVProcessed; + TopTools_ListIteratorOfListOfShape aItS; + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm; + TopTools_DataMapOfShapeListOfShape aMVV; + GEOMAlgo_IndexedDataMapOfIntegerShape aMIS; + GEOMAlgo_IndexedDataMapOfShapeBndSphere aMSB; + GEOMAlgo_BndSphereTreeSelector aSelector; + GEOMAlgo_BndSphereTree aBBTree; + NCollection_UBTreeFiller aTreeFiller(aBBTree); + // + myErrorStatus=0; + // + TopExp::MapShapes(myArgument, TopAbs_VERTEX, aMV); + aNbV=aMV.Extent(); + if (!aNbV) { + myErrorStatus=2; // no vertices in source shape + return; + } + // + for (i=1; i<=aNbV; ++i) { + GEOMAlgo_BndSphere aBox; + // + const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMV(i)); + aPV=BRep_Tool::Pnt(aV); + aTolV=BRep_Tool::Tolerance(aV); + // + aBox.SetGap(myTolerance); + aBox.SetCenter(aPV); + aBox.SetRadius(aTolV); + // + aTreeFiller.Add(i, aBox); + // + aMIS.Add(i, aV); + aMSB.Add(aV, aBox); + } + // + aTreeFiller.Fill(); + // + //--------------------------------------------------- + // Chains + for (i=1; i<=aNbV; ++i) { + const TopoDS_Shape& aV=aMV(i); + // + if (aMVProcessed.Contains(aV)) { + continue; + } + // + Standard_Integer aNbIP, aIP, aNbIP1, aIP1; + TopTools_ListOfShape aLVSD; + TColStd_MapOfInteger aMIP, aMIP1, aMIPC; + TColStd_MapIteratorOfMapOfInteger aIt1; + // + aMIP.Add(i); + for(;;) { + aNbIP=aMIP.Extent(); + aIt1.Initialize(aMIP); + for(; aIt1.More(); aIt1.Next()) { + aIP=aIt1.Key(); + if (aMIPC.Contains(aIP)) { + continue; + } + // + const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP); + const GEOMAlgo_BndSphere& aBoxVP=aMSB.FindFromKey(aVP); + // + aSelector.Clear(); + aSelector.SetBox(aBoxVP); + // + aNbVSD=aBBTree.Select(aSelector); + if (!aNbVSD) { + continue; // it should not be so [at least IP itself] + } + // + const TColStd_ListOfInteger& aLI=aSelector.Indices(); + aIt.Initialize(aLI); + for (; aIt.More(); aIt.Next()) { + aIP1=aIt.Value(); + if (aMIP.Contains(aIP1)) { + continue; + } + aMIP1.Add(aIP1); + } //for (; aIt.More(); aIt.Next()) { + }//for(; aIt1.More(); aIt1.Next()) { + // + aNbIP1=aMIP1.Extent(); + if (!aNbIP1) { + break; + } + // + aIt1.Initialize(aMIP); + for(; aIt1.More(); aIt1.Next()) { + aIP=aIt1.Key(); + aMIPC.Add(aIP); + } + // + aMIP.Clear(); + aIt1.Initialize(aMIP1); + for(; aIt1.More(); aIt1.Next()) { + aIP=aIt1.Key(); + aMIP.Add(aIP); + } + aMIP1.Clear(); + }// while(1) + // + // Fill myImages + aNbIP=aMIPC.Extent(); + // + if (!aNbIP) {// no SD vertices is found + aMVProcessed.Add(aV); + continue; + } + //else { // SD vertices founded [ aMIPC ] + aIt1.Initialize(aMIPC); + for(j=0; aIt1.More(); aIt1.Next(), ++j) { + aIP=aIt1.Key(); + const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP); + if (!j) { + aVF=aVP; + } + aLVSD.Append(aVP); + aMVProcessed.Add(aVP); + } + //} + myImages.Bind(aVF, aLVSD); + }// for (i=1; i<=aNbV; ++i) { + //------------------------------ + // Origins + aItIm.Initialize(myImages); + for (; aItIm.More(); aItIm.Next()) { + const TopoDS_Shape& aV=aItIm.Key(); + const TopTools_ListOfShape& aLVSD=aItIm.Value(); + aItS.Initialize(aLVSD); + for (; aItS.More(); aItS.Next()) { + const TopoDS_Shape& aVSD=aItS.Value(); + if (!myOrigins.IsBound(aVSD)) { + myOrigins.Bind(aVSD, aV); + } + } + } +} +//======================================================================= +//function : DetectFaces +//purpose : +//======================================================================= +void GeomAlgoAPI_GlueDetector::DetectFaces() +{ + DetectShapes(TopAbs_FACE); +} +//======================================================================= +//function : DetectEdges +//purpose : +//======================================================================= +void GeomAlgoAPI_GlueDetector::DetectEdges() +{ + DetectShapes(TopAbs_EDGE); +} +//======================================================================= +//function : DetectShapes +//purpose : +//======================================================================= +void GeomAlgoAPI_GlueDetector::DetectShapes(const TopAbs_ShapeEnum aType) +{ + Standard_Boolean bDegenerated; + Standard_Integer i, aNbF, aNbSDF, iErr; + TopTools_IndexedMapOfShape aMF; + TopTools_ListIteratorOfListOfShape aItLS; + GEOMAlgo_PassKeyShape aPKF; + GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape aMPKLF; + // + myErrorStatus=0; + // + TopExp::MapShapes(myArgument, aType, aMF); + // + aNbF=aMF.Extent(); + for (i=1; i<=aNbF; ++i) { + const TopoDS_Shape& aS=aMF(i); + // + if (aType==TopAbs_FACE) { + const TopoDS_Face& aF=*((TopoDS_Face*)&aS); + FacePassKey(aF, aPKF); + } + else if (aType==TopAbs_EDGE) { + const TopoDS_Edge& aE=*((TopoDS_Edge*)&aS); + EdgePassKey(aE, aPKF); + } + // + if (myErrorStatus) { + return; + } + // + if (aMPKLF.Contains(aPKF)) { + TopTools_ListOfShape& aLSDF=aMPKLF.ChangeFromKey(aPKF); + aLSDF.Append(aS); + } + else { + TopTools_ListOfShape aLSDF; + // + aLSDF.Append(aS); + aMPKLF.Add(aPKF, aLSDF); + } + } + // check geometric coincidence + if (myCheckGeometry) { + iErr=GEOMAlgo_AlgoTools::RefineSDShapes(aMPKLF, myTolerance, myContext); + if (iErr) { + myErrorStatus=200; + return; + } + } + // + // Images/Origins + aNbF=aMPKLF.Extent(); + for (i=1; i<=aNbF; ++i) { + const TopTools_ListOfShape& aLSDF=aMPKLF(i); + aNbSDF=aLSDF.Extent(); + if (!aNbSDF) { + myErrorStatus=4; // it must not be + } + // + if (aNbSDF==1) { + continue; + } + // + const TopoDS_Shape& aS1=aLSDF.First(); + // + if (aType==TopAbs_EDGE) { + const TopoDS_Edge& aE1=*((TopoDS_Edge*)&aS1); + bDegenerated=BRep_Tool::Degenerated(aE1); + if (bDegenerated) { + continue; + } + } + // + myImages.Bind(aS1, aLSDF); + // + // origins + aItLS.Initialize(aLSDF); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aFSD=aItLS.Value(); + if (!myOrigins.IsBound(aFSD)) { + myOrigins.Bind(aFSD, aS1); + } + } + }// for (i=1; i<=aNbF; ++i) +} +//======================================================================= +//function : FacePassKey +//purpose : +//======================================================================= +void GeomAlgoAPI_GlueDetector::FacePassKey(const TopoDS_Face& aF, + GEOMAlgo_PassKeyShape& aPK) +{ + Standard_Integer i, aNbE; + TopoDS_Shape aER; + TopTools_ListOfShape aLE; + TopTools_IndexedMapOfShape aME; + // + TopExp::MapShapes(aF, TopAbs_EDGE, aME); + // + aNbE=aME.Extent(); + for (i=1; i<=aNbE; ++i) { + const TopoDS_Shape& aE=aME(i); + // + const TopoDS_Edge& aEE=*((TopoDS_Edge*)&aE); + if (BRep_Tool::Degenerated(aEE)) { + continue; + } + // + if (myOrigins.IsBound(aE)) { + aER=myOrigins.Find(aE); + } + else { + aER=aE; + } + aLE.Append(aER); + } + aPK.SetShapes(aLE); +} +//======================================================================= +//function : EdgePassKey +//purpose : +//======================================================================= +void GeomAlgoAPI_GlueDetector::EdgePassKey(const TopoDS_Edge& aE, + GEOMAlgo_PassKeyShape& aPK) +{ + TopAbs_Orientation aOr; + TopoDS_Shape aVR; + TopoDS_Iterator aIt; + TopTools_ListOfShape aLV; + // + aIt.Initialize(aE); + for (; aIt.More(); aIt.Next()) { + const TopoDS_Shape& aV=aIt.Value(); + aOr=aV.Orientation(); + if (aOr==TopAbs_FORWARD || aOr==TopAbs_REVERSED) { + if (myOrigins.IsBound(aV)) { + aVR=myOrigins.Find(aV); + } + else { + aVR=aV; + } + aLV.Append(aVR); + } + } + // + aPK.SetShapes(aLV); +} +//======================================================================= +//function : CheckDetected +//purpose : +//======================================================================= +void GeomAlgoAPI_GlueDetector::CheckDetected() +{ + TopoDS_Iterator aItA; + TopExp_Explorer aExp; + TopTools_ListOfShape aLV; + TopTools_MapOfShape aMFence; + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm; + TopTools_IndexedDataMapOfShapeListOfShape aMVE, aMEV; + // + // 1. aMVE, aMEV + TopExp::MapShapesAndAncestors(myArgument, TopAbs_VERTEX, TopAbs_EDGE, aMVE); + // + aExp.Init(myArgument, TopAbs_EDGE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shape& aE=aExp.Current(); + // + aLV.Clear(); + aMFence.Clear(); + aItA.Initialize(aE); + for (; aItA.More(); aItA.Next()) { + const TopoDS_Shape& aV=aItA.Value(); + if (aMFence.Add(aV)) { + aLV.Append(aV); + } + } + // + aMEV.Add(aE, aLV); + } + // 2. Checking + aItIm.Initialize(myImages); + for (; aItIm.More(); aItIm.Next()) { + //const TopoDS_Shape& aV=aItIm.Key(); + const TopTools_ListOfShape& aLVSD=aItIm.Value(); + CheckDetected(aLVSD, aMVE, aMEV); + } +} +//======================================================================= +//function : CheckDetected +//purpose : +//======================================================================= +void GeomAlgoAPI_GlueDetector::CheckDetected + (const TopTools_ListOfShape& aLVSD, + const TopTools_IndexedDataMapOfShapeListOfShape& aMVE, + const TopTools_IndexedDataMapOfShapeListOfShape& aMEV) +{ + Standard_Integer aNbVSD, iRet; + TopExp_Explorer aExp, aExpA; + TopTools_MapOfShape aMFence, aMVSD; + TopTools_ListOfShape aLV; + TopTools_ListIteratorOfListOfShape aItLS; + // + myErrorStatus=0; + // + aNbVSD=aLVSD.Extent(); + if (aNbVSD < 2) { + return ; + } + // + aItLS.Initialize(aLVSD); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aVSD=aItLS.Value(); + aMVSD.Add(aVSD); + } + // + aItLS.Initialize(aLVSD); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aVSD=aItLS.Value(); + // + iRet=CheckAncesstors(aVSD, aMVSD, aMVE, aMEV, myStickedShapes); + if (iRet) { + // Sticked shapes detected + myWarningStatus=2; + } + } +} +//======================================================================= +//function : CheckAncesstors +//purpose : +//======================================================================= +Standard_Integer CheckAncesstors + (const TopoDS_Shape& aVSD, + const TopTools_MapOfShape& aMVSD, + const TopTools_IndexedDataMapOfShapeListOfShape& aMVE, + const TopTools_IndexedDataMapOfShapeListOfShape& aMEV, + TopTools_IndexedDataMapOfShapeListOfShape& aMEVZ) +{ + TopTools_ListOfShape *pLE, *pLV, *pLVZ; + Standard_Integer iRet, aNbVX; + TopTools_ListIteratorOfListOfShape aItLE, aItLV; + TopTools_MapOfShape aMFence; + TopTools_ListOfShape aLVX; + // + iRet=0; + // + pLE=const_cast(aMVE).ChangeSeek(aVSD); + if (!pLE) { + return iRet; + } + aItLE.Initialize(*pLE); + for (; aItLE.More(); aItLE.Next()) { + const TopoDS_Shape& aE=aItLE.Value(); + // + pLV=const_cast(aMEV).ChangeSeek(aE); + if (!pLV) { + continue; // it should be not so + } + aLVX.Clear(); + aItLV.Initialize(*pLV); + for (; aItLV.More(); aItLV.Next()) { + const TopoDS_Shape& aV=aItLV.Value(); + if (!aV.IsSame(aVSD)) { + if (aMVSD.Contains(aV)) { + if (aMFence.Add(aV)) { + aLVX.Append(aV); + } + } + } + } + // + aNbVX=aLVX.Extent(); + if (!aNbVX) { + continue; + } + // + iRet=1; + // + pLVZ=aMEVZ.ChangeSeek(aE); + if (!pLVZ) { + aMEVZ.Add(aE, aLVX); + } + else { + TopTools_ListOfShape& aLVZ=*pLVZ; + aLVZ.Append(aLVX); + } + } + // + return iRet; +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_GlueDetector.h b/src/GeomAlgoAPI/GeomAlgoAPI_GlueDetector.h new file mode 100644 index 000000000..42764d257 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_GlueDetector.h @@ -0,0 +1,91 @@ +// Copyright (C) 2014-2021 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_GLUEDETECTOR_H_ +#define GEOMALGOAPI_GLUEDETECTOR_H_ + +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +//======================================================================= +//function : GEOMAlgoAPI_GlueDetector +//purpose : +//======================================================================= +class GeomAlgoAPI_GlueDetector : public GeomAlgoAPI_GluerAlgo, + public GeomAlgoAPI_Algo +{ +public: + GEOMALGOAPI_EXPORT + GeomAlgoAPI_GlueDetector(); + + GEOMALGOAPI_EXPORT virtual + ~GeomAlgoAPI_GlueDetector(); + + GEOMALGOAPI_EXPORT virtual + void Perform() ; + + GEOMALGOAPI_EXPORT + const TopTools_IndexedDataMapOfShapeListOfShape& StickedShapes(); + +protected: + GEOMALGOAPI_EXPORT + void DetectVertices() ; + + GEOMALGOAPI_EXPORT + void DetectEdges() ; + + GEOMALGOAPI_EXPORT + void DetectFaces() ; + + GEOMALGOAPI_EXPORT + void DetectShapes(const TopAbs_ShapeEnum aType) ; + + GEOMALGOAPI_EXPORT + void EdgePassKey(const TopoDS_Edge& aE, + GEOMAlgo_PassKeyShape& aPK) ; + + GEOMALGOAPI_EXPORT + void FacePassKey(const TopoDS_Face& aF, + GEOMAlgo_PassKeyShape& aPK) ; + + GEOMALGOAPI_EXPORT + void CheckDetected(); + // + GEOMALGOAPI_EXPORT + void CheckDetected + (const TopTools_ListOfShape& aLVSD, + const TopTools_IndexedDataMapOfShapeListOfShape& aMVE, + const TopTools_IndexedDataMapOfShapeListOfShape& aMEV); + + + protected: + TopTools_IndexedDataMapOfShapeListOfShape myStickedShapes; + +}; +#endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_GluerAlgo.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_GluerAlgo.cpp new file mode 100644 index 000000000..1245fe419 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_GluerAlgo.cpp @@ -0,0 +1,138 @@ +// Copyright (C) 2014-2021 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 +#include + +//======================================================================= +//function : GeomAlgoAPI_GluerAlgo +//purpose : +//======================================================================= +GeomAlgoAPI_GluerAlgo::GeomAlgoAPI_GluerAlgo() +{ + myTolerance=0.0001; + myCheckGeometry=Standard_True; +} +//======================================================================= +//function : ~GeomAlgoAPI_GluerAlgo +//purpose : +//======================================================================= +GeomAlgoAPI_GluerAlgo::~GeomAlgoAPI_GluerAlgo() +{ +} +//======================================================================= +//function : SetArgument +//purpose : +//======================================================================= +void GeomAlgoAPI_GluerAlgo::SetArgument(const TopoDS_Shape& theShape) +{ + myArgument=theShape; +} +//======================================================================= +//function : Argument +//purpose : +//======================================================================= +const TopoDS_Shape& GeomAlgoAPI_GluerAlgo::Argument()const +{ + return myArgument; +} +//======================================================================= +//function : SetTolerance +//purpose : +//======================================================================= +void GeomAlgoAPI_GluerAlgo::SetTolerance(const Standard_Real aT) +{ + myTolerance=aT; +} +//======================================================================= +//function : Tolerance +//purpose : +//======================================================================= +Standard_Real GeomAlgoAPI_GluerAlgo::Tolerance()const +{ + return myTolerance; +} + +//======================================================================= +//function : SetCheckGeometry +//purpose : +//======================================================================= +void GeomAlgoAPI_GluerAlgo::SetCheckGeometry(const Standard_Boolean aFlag) +{ + myCheckGeometry=aFlag; +} +//======================================================================= +//function : CheckGeometry +//purpose : +//======================================================================= +Standard_Boolean GeomAlgoAPI_GluerAlgo::CheckGeometry() const +{ + return myCheckGeometry; +} +//======================================================================= +//function : SetContext +//purpose : +//======================================================================= +void GeomAlgoAPI_GluerAlgo::SetContext(const Handle(IntTools_Context)& theContext) +{ + myContext=theContext; +} +//======================================================================= +//function : Context +//purpose : +//======================================================================= +const Handle(IntTools_Context)& GeomAlgoAPI_GluerAlgo::Context() +{ + return myContext; +} +//======================================================================= +//function : Images +//purpose : +//======================================================================= +const TopTools_DataMapOfShapeListOfShape& GeomAlgoAPI_GluerAlgo::Images()const +{ + return myImages; +} +//======================================================================= +//function : Origins +//purpose : +//======================================================================= +const TopTools_DataMapOfShapeShape& GeomAlgoAPI_GluerAlgo::Origins()const +{ + return myOrigins; +} +//======================================================================= +//function : Clear +//purpose : +//======================================================================= +void GeomAlgoAPI_GluerAlgo::Clear() +{ + myImages.Clear(); + myOrigins.Clear(); +} +//======================================================================= +//function : Perform +//purpose : +//======================================================================= +void GeomAlgoAPI_GluerAlgo::Perform() +{ + if (myContext.IsNull()) { + myContext=new IntTools_Context; + } +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_GluerAlgo.h b/src/GeomAlgoAPI/GeomAlgoAPI_GluerAlgo.h new file mode 100644 index 000000000..5cbaa687f --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_GluerAlgo.h @@ -0,0 +1,91 @@ +// Copyright (C) 2014-2021 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_GLUERALGO_H_ +#define GEOMALGOAPI_GLUERALGO_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +//class : GEOMAlgo_GluerAlgo +//purpose : +//======================================================================= +class GeomAlgoAPI_GluerAlgo { +public: + + GEOMALGOAPI_EXPORT + GeomAlgoAPI_GluerAlgo(); + + GEOMALGOAPI_EXPORT + virtual ~GeomAlgoAPI_GluerAlgo(); + + GEOMALGOAPI_EXPORT + virtual void SetArgument(const TopoDS_Shape& theShape) ; + + GEOMALGOAPI_EXPORT + const TopoDS_Shape& Argument() const; + + GEOMALGOAPI_EXPORT + void SetTolerance(const Standard_Real aT) ; + + GEOMALGOAPI_EXPORT + Standard_Real Tolerance() const; + + GEOMALGOAPI_EXPORT + void SetCheckGeometry(const Standard_Boolean aFlag) ; + + GEOMALGOAPI_EXPORT + Standard_Boolean CheckGeometry() const; + + GEOMALGOAPI_EXPORT + virtual void Perform() ; + + GEOMALGOAPI_EXPORT + virtual void Clear() ; + + GEOMALGOAPI_EXPORT + void SetContext(const Handle(IntTools_Context)&) ; + + GEOMALGOAPI_EXPORT + const Handle(IntTools_Context)& Context() ; + + GEOMALGOAPI_EXPORT + const TopTools_DataMapOfShapeListOfShape& Images() const; + + GEOMALGOAPI_EXPORT + const TopTools_DataMapOfShapeShape& Origins() const; + +protected: + TopoDS_Shape myArgument; + Standard_Real myTolerance; + Standard_Boolean myCheckGeometry; + Handle(IntTools_Context) myContext; + TopTools_DataMapOfShapeListOfShape myImages; + TopTools_DataMapOfShapeShape myOrigins; + +private: +}; +#endif diff --git a/src/ModelHighAPI/CMakeLists.txt b/src/ModelHighAPI/CMakeLists.txt index 07adac9db..a918cd4dc 100644 --- a/src/ModelHighAPI/CMakeLists.txt +++ b/src/ModelHighAPI/CMakeLists.txt @@ -125,16 +125,16 @@ ADD_UNIT_TESTS(${TEST_NAMES}) if(${HAVE_SALOME}) enable_testing() set(TEST_INSTALL_DIRECTORY "${SALOME_SHAPER_INSTALL_TESTS}/ModelHighAPI") - + install(FILES CTestTestfileInstall.cmake DESTINATION ${TEST_INSTALL_DIRECTORY} RENAME CTestTestfile.cmake) install(FILES tests.set DESTINATION ${TEST_INSTALL_DIRECTORY}) - + set(TMP_TESTS_NAMES) foreach(tfile ${TEST_NAMES}) list(APPEND TMP_TESTS_NAMES "Test/${tfile}") endforeach(tfile ${TEST_NAMES}) - + install(FILES ${TMP_TESTS_NAMES} DESTINATION ${TEST_INSTALL_DIRECTORY}) endif(${HAVE_SALOME}) diff --git a/src/PythonAPI/model/features/__init__.py b/src/PythonAPI/model/features/__init__.py index 62a0ca1a8..eddd2efe6 100644 --- a/src/PythonAPI/model/features/__init__.py +++ b/src/PythonAPI/model/features/__init__.py @@ -32,6 +32,7 @@ from FeaturesAPI import addFusionFaces from FeaturesAPI import measureLength, measureDistance, measureRadius, measureAngle from FeaturesAPI import getPointCoordinates, getGeometryCalculation, getBoundingBox from FeaturesAPI import getNormal +from FeaturesAPI import getDuplicatedFaces from FeaturesAPI import addRemoveResults from FeaturesAPI import addCopy, addImportResult from FeaturesAPI import addDefeaturing -- 2.39.2