From: mbs Date: Fri, 9 Dec 2022 19:03:45 +0000 (+0000) Subject: added new GlueFaces feature X-Git-Tag: V9_11_0a1~31 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=9afe243148ea67f2eccbd0afa419541424de451e;p=modules%2Fshaper.git added new GlueFaces feature --- diff --git a/src/FeaturesAPI/CMakeLists.txt b/src/FeaturesAPI/CMakeLists.txt index 1d929468d..985a5c522 100644 --- a/src/FeaturesAPI/CMakeLists.txt +++ b/src/FeaturesAPI/CMakeLists.txt @@ -30,6 +30,7 @@ SET(PROJECT_HEADERS FeaturesAPI_Extrusion.h FeaturesAPI_ExtrusionBoolean.h FeaturesAPI_Fillet.h + FeaturesAPI_GlueFaces.h FeaturesAPI_Intersection.h FeaturesAPI_Measurement.h FeaturesAPI_NormalToFace.h @@ -70,6 +71,7 @@ SET(PROJECT_SOURCES FeaturesAPI_Extrusion.cpp FeaturesAPI_ExtrusionBoolean.cpp FeaturesAPI_Fillet.cpp + FeaturesAPI_GlueFaces.cpp FeaturesAPI_Intersection.cpp FeaturesAPI_Measurement.cpp FeaturesAPI_NormalToFace.cpp diff --git a/src/FeaturesAPI/FeaturesAPI.i b/src/FeaturesAPI/FeaturesAPI.i index 4a4db824a..57806028d 100644 --- a/src/FeaturesAPI/FeaturesAPI.i +++ b/src/FeaturesAPI/FeaturesAPI.i @@ -43,6 +43,7 @@ %feature("kwargs") addCut; %feature("kwargs") addFillet; %feature("kwargs") addFuse; +%feature("kwargs") addGlueFaces; %feature("kwargs") addIntersection; %feature("kwargs") addMultiRotation; %feature("kwargs") addMultiTranslation; @@ -72,6 +73,7 @@ %shared_ptr(FeaturesAPI_Fillet) %shared_ptr(FeaturesAPI_Fillet1D) %shared_ptr(FeaturesAPI_Fillet2D) +%shared_ptr(FeaturesAPI_GlueFaces) %shared_ptr(FeaturesAPI_Intersection) %shared_ptr(FeaturesAPI_MultiRotation) %shared_ptr(FeaturesAPI_MultiTranslation) @@ -215,6 +217,7 @@ %include "FeaturesAPI_Extrusion.h" %include "FeaturesAPI_ExtrusionBoolean.h" %include "FeaturesAPI_Fillet.h" +%include "FeaturesAPI_GlueFaces.h" %include "FeaturesAPI_Intersection.h" %include "FeaturesAPI_Measurement.h" %include "FeaturesAPI_NormalToFace.h" diff --git a/src/FeaturesAPI/FeaturesAPI_GlueFaces.cpp b/src/FeaturesAPI/FeaturesAPI_GlueFaces.cpp new file mode 100644 index 000000000..97b7a399d --- /dev/null +++ b/src/FeaturesAPI/FeaturesAPI_GlueFaces.cpp @@ -0,0 +1,102 @@ +// Copyright (C) 2014-2022 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "FeaturesAPI_GlueFaces.h" + +#include +#include +#include + +//================================================================================================== +FeaturesAPI_GlueFaces::FeaturesAPI_GlueFaces(const std::shared_ptr& theFeature) +: ModelHighAPI_Interface(theFeature) +{ + initialize(); +} + +//================================================================================================== +FeaturesAPI_GlueFaces::FeaturesAPI_GlueFaces(const std::shared_ptr& theFeature, + const std::list& theMainObjects, + const ModelHighAPI_Double& theTolerance, + bool theIsKeepNonSolids=true) +: ModelHighAPI_Interface(theFeature) +{ + if (initialize()) { + fillAttribute(theMainObjects, mainObjects()); + setTolerance(theTolerance); + setKeepNonSolids(theIsKeepNonSolids); + } +} + +//================================================================================================== +FeaturesAPI_GlueFaces::~FeaturesAPI_GlueFaces() +{ +} + +//================================================================================================== +void FeaturesAPI_GlueFaces::setMainObjects(const std::list& theMainObjects) +{ + fillAttribute(theMainObjects, mainObjects()); + execute(); +} + +//================================================================================================== +void FeaturesAPI_GlueFaces::setTolerance(const ModelHighAPI_Double& theTolerance) +{ + fillAttribute(theTolerance, tolerance()); + execute(); +} + +//================================================================================================== +void FeaturesAPI_GlueFaces::setKeepNonSolids(bool theFlag) +{ + fillAttribute(theFlag, keepNonSolids()); + execute(); +} + +//================================================================================================== +void FeaturesAPI_GlueFaces::dump(ModelHighAPI_Dumper& theDumper) const +{ + FeaturePtr aBase = feature(); + const std::string& aDocName = theDumper.name(aBase->document()); + + AttributeSelectionListPtr anAttrObjects = + aBase->selectionList(FeaturesPlugin_GlueFaces::OBJECTS_LIST_ID()); + theDumper << aBase << " = model.addGlueFaces(" << aDocName << ", " << anAttrObjects; + + AttributeDoublePtr anAttrTolerance = aBase->real(FeaturesPlugin_GlueFaces::TOLERANCE_ID()); + theDumper << ", " << anAttrTolerance; + + AttributeBooleanPtr anAttrKeepNonSolids = aBase->boolean(FeaturesPlugin_GlueFaces::KEEP_NON_SOLIDS_ID()); + theDumper << ", " << anAttrKeepNonSolids; + + theDumper << ")" << std::endl; +} + +//================================================================================================== +GlueFacesPtr addGlueFaces(const std::shared_ptr& thePart, + const std::list& theMainObjects, + const ModelHighAPI_Double& theTolerance, + const bool theKeepNonSolids) +{ + std::shared_ptr aFeature = thePart->addFeature(FeaturesAPI_GlueFaces::ID()); + GlueFacesPtr aGlueFaces; + aGlueFaces.reset(new FeaturesAPI_GlueFaces(aFeature, theMainObjects, theTolerance, theKeepNonSolids)); + return aGlueFaces; +} diff --git a/src/FeaturesAPI/FeaturesAPI_GlueFaces.h b/src/FeaturesAPI/FeaturesAPI_GlueFaces.h new file mode 100644 index 000000000..04b2ad6d7 --- /dev/null +++ b/src/FeaturesAPI/FeaturesAPI_GlueFaces.h @@ -0,0 +1,91 @@ +// Copyright (C) 2014-2022 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef FeatureAPI_GlueFaces_H_ +#define FeatureAPI_GlueFaces_H_ + +#include "FeaturesAPI.h" + +#include + +#include +#include + +class ModelHighAPI_Double; +class ModelHighAPI_Dumper; +class ModelHighAPI_Selection; + +/// \class FeaturesAPI_GlueFaces +/// \ingroup CPPHighAPI +/// \brief Interface for Glue Faces feature. +class FeaturesAPI_GlueFaces: public ModelHighAPI_Interface +{ +public: + /// Constructor without values. + FEATURESAPI_EXPORT + explicit FeaturesAPI_GlueFaces(const std::shared_ptr& theFeature); + + /// Constructor with values. + FEATURESAPI_EXPORT + explicit FeaturesAPI_GlueFaces(const std::shared_ptr& theFeature, + const std::list& theMainObjects, + const ModelHighAPI_Double& theTolerance, + bool theIsKeepNonSolids = true); + + /// Destructor. + FEATURESAPI_EXPORT + virtual ~FeaturesAPI_GlueFaces(); + + INTERFACE_3(FeaturesPlugin_GlueFaces::ID(), + mainObjects, FeaturesPlugin_GlueFaces::OBJECTS_LIST_ID(), + ModelAPI_AttributeSelectionList, /** Main objects */, + tolerance, FeaturesPlugin_GlueFaces::TOLERANCE_ID(), + ModelAPI_AttributeDouble, /** Tolerance */, + keepNonSolids, FeaturesPlugin_GlueFaces::KEEP_NON_SOLIDS_ID(), + ModelAPI_AttributeBoolean, /** Keep all non-solid shapes */) + + /// Set main objects. + FEATURESAPI_EXPORT + void setMainObjects(const std::list& theMainObjects); + + /// Set the tolerance. + FEATURESAPI_EXPORT + void setTolerance(const ModelHighAPI_Double& theTolerance); + + /// Set flag whether to keep all non-solid shapes. + FEATURESAPI_EXPORT + void setKeepNonSolids(bool theFlag); + + /// Dump wrapped feature + FEATURESAPI_EXPORT + virtual void dump(ModelHighAPI_Dumper& theDumper) const; +}; + +/// Pointer on Glue Faces object. +typedef std::shared_ptr GlueFacesPtr; + +/// \ingroup CPPHighAPI +/// \brief Create Glue Faces feature. +FEATURESAPI_EXPORT +GlueFacesPtr addGlueFaces(const std::shared_ptr& thePart, + const std::list& theMainObjects, + const ModelHighAPI_Double& theTolerance, + const bool theKeepNonSolids); + +#endif // FeatureAPI_GlueFaces_H_ diff --git a/src/FeaturesAPI/FeaturesAPI_swig.h b/src/FeaturesAPI/FeaturesAPI_swig.h index d46a5c084..3dee6e73f 100644 --- a/src/FeaturesAPI/FeaturesAPI_swig.h +++ b/src/FeaturesAPI/FeaturesAPI_swig.h @@ -54,6 +54,7 @@ #include "FeaturesAPI_Translation.h" #include "FeaturesAPI_Union.h" #include "FeaturesAPI_FusionFaces.h" + #include "FeaturesAPI_GlueFaces.h" #include "FeaturesAPI_RemoveResults.h" #include "FeaturesAPI_Copy.h" #include "FeaturesAPI_ImportResult.h" diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index 3f9fb4e53..6738d6faf 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -77,6 +77,7 @@ SET(PROJECT_HEADERS FeaturesPlugin_InspectBoundingBox.h FeaturesPlugin_NormalToFace.h FeaturesPlugin_InspectNormalToFace.h + FeaturesPlugin_GlueFaces.h ) SET(PROJECT_SOURCES @@ -134,6 +135,7 @@ SET(PROJECT_SOURCES FeaturesPlugin_InspectBoundingBox.cpp FeaturesPlugin_NormalToFace.cpp FeaturesPlugin_InspectNormalToFace.cpp + FeaturesPlugin_GlueFaces.cpp ) SET(XML_RESOURCES @@ -168,6 +170,7 @@ SET(XML_RESOURCES fillet1d_widget.xml measurement_widget.xml fusion_faces_widget.xml + glue_faces_widget.xml chamfer_widget.xml copy_widget.xml import_result_widget.xml diff --git a/src/FeaturesPlugin/FeaturesPlugin_GlueFaces.cpp b/src/FeaturesPlugin/FeaturesPlugin_GlueFaces.cpp new file mode 100644 index 000000000..37d9cbcd8 --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_GlueFaces.cpp @@ -0,0 +1,158 @@ +// Copyright (C) 2014-2022 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "FeaturesPlugin_GlueFaces.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + + +//================================================================================================== +FeaturesPlugin_GlueFaces::FeaturesPlugin_GlueFaces() +{ +} + +//================================================================================================== +void FeaturesPlugin_GlueFaces::initAttributes() +{ + data()->addAttribute(OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); + data()->addAttribute(TOLERANCE_ID(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(KEEP_NON_SOLIDS_ID(), ModelAPI_AttributeBoolean::typeId()); +} + +//================================================================================================== +void FeaturesPlugin_GlueFaces::execute() +{ + // Collect all selected shapes into a single list of shapes + ListOfShape aShapes; + getOriginalShapes(OBJECTS_LIST_ID(), aShapes); + + // Get all other feature arguments + double aTolerance = real(FeaturesPlugin_GlueFaces::TOLERANCE_ID())->value(); + bool isKeepNonSolids = boolean(FeaturesPlugin_GlueFaces::KEEP_NON_SOLIDS_ID())->value(); + + std::shared_ptr aGluingAlgo(new GeomAlgoAPI_GlueFaces(aShapes, aTolerance, isKeepNonSolids)); + + std::string anError; + if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aGluingAlgo, getKind(), anError)) + { + setError(anError); + eraseResults(); + return; + } + + // Store result. + GeomShapePtr aResult = aGluingAlgo->shape(); + + if (!isGlued(aShapes, aResult)) + { + static const std::string anError2 = "Error: No faces were glued."; + setError(anError2); + data()->execState(ModelAPI_ExecState::ModelAPI_StateDone); + eraseResults(); + setResultFromInput(aShapes); + return; + } + + int anIndex = 0; + ResultBodyPtr aResultBody = document()->createBody(data(), anIndex); + aResultBody->storeModified(aShapes, aResult, aGluingAlgo); + + setResult(aResultBody, anIndex); +} + +//================================================================================================= +void FeaturesPlugin_GlueFaces::getOriginalShapes(const std::string& theAttributeName, + ListOfShape& theShapes) +{ + // Collect all selections into a single list of shapes + AttributeSelectionListPtr aSelectionList = selectionList(theAttributeName); + for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) + { + AttributeSelectionPtr aSelection = aSelectionList->value(anIndex); + GeomShapePtr aShape = aSelection->value(); + GeomShapePtr aContext = aSelection->context()->shape(); + if (!aShape.get()) + { + aShape = aContext; + } + theShapes.push_back(aShape); + } +} + +//================================================================================================= +bool FeaturesPlugin_GlueFaces::isGlued(const ListOfShape& theInputs, + const GeomShapePtr theResult) +{ + if (!theResult.get()) + return false; + + // Consider the list of input shapes the same as the result, if + // * the total number of faces did NOT change. + int nbInputFaces = 0; + for (ListOfShape::const_iterator anIt = theInputs.cbegin(); + anIt != theInputs.cend(); + ++anIt) + { + GeomShapePtr aShape = *anIt; + if (aShape.get()) + { + nbInputFaces += aShape->subShapes(GeomAPI_Shape::FACE, true).size(); + } + } + + int nbResultFaces = 0; + nbResultFaces = theResult->subShapes(GeomAPI_Shape::FACE, true).size(); + return(0 < nbResultFaces && nbResultFaces < nbInputFaces); +} + +//================================================================================================= +void FeaturesPlugin_GlueFaces::setResultFromInput(const ListOfShape& theInputs) +{ + GeomShapePtr aResult; + + // Make sure the result will be a compound of the input shapes, if not already + if (theInputs.size() == 1 && theInputs.front().get() && theInputs.front()->isCompound()) + { + aResult = theInputs.front(); + } + else + { + aResult = GeomAlgoAPI_CompoundBuilder::compound(theInputs); + } + + int anIndex = 0; + ResultBodyPtr aResultBody = document()->createBody(data(), anIndex); + aResultBody->store(aResult); + + setResult(aResultBody, anIndex); +} diff --git a/src/FeaturesPlugin/FeaturesPlugin_GlueFaces.h b/src/FeaturesPlugin/FeaturesPlugin_GlueFaces.h new file mode 100644 index 000000000..fd1049be7 --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_GlueFaces.h @@ -0,0 +1,92 @@ +// Copyright (C) 2014-2022 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef FeaturesPlugin_GlueFaces_H_ +#define FeaturesPlugin_GlueFaces_H_ + +#include "FeaturesPlugin.h" + +#include +#include + + +/// \class FeaturesPlugin_GlueFaces +/// \ingroup Plugins +/// \brief Feature to glue duplicated faces. +class FeaturesPlugin_GlueFaces : public ModelAPI_Feature +{ +public: + /// Use plugin manager for features creation + FeaturesPlugin_GlueFaces(); + + /// Feature kind. + inline static const std::string& ID() + { + static const std::string MY_ID("GlueFaces"); + return MY_ID; + } + + /// \return the kind of a feature. + FEATURESPLUGIN_EXPORT virtual const std::string& getKind() + { + static std::string MY_KIND = FeaturesPlugin_GlueFaces::ID(); + return MY_KIND; + } + + /// Attribute name of referenced objects. + inline static const std::string& OBJECTS_LIST_ID() + { + static const std::string MY_OBJECTS_LIST_ID("main_objects"); + return MY_OBJECTS_LIST_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 keeping non-solid shapes. + inline static const std::string& KEEP_NON_SOLIDS_ID() + { + static const std::string MY_KEEP_NON_SOLIDS_ID("keep_non_solids"); + return MY_KEEP_NON_SOLIDS_ID; + } + + /// Request for initialization of data model of the feature: adding all attributes. + FEATURESPLUGIN_EXPORT virtual void initAttributes(); + + /// Executes the faces fusion and stores the modififed shape. + FEATURESPLUGIN_EXPORT virtual void execute(); + +private: + /// Retrieve all shapes from the selection list + void getOriginalShapes(const std::string& theAttributeName, + ListOfShape& theShapes); + + /// Check, whether the result is glued or not + bool isGlued(const ListOfShape& theInputs, + const GeomShapePtr theResult); + + /// Create a compound result object from the unchanged input shapes + void setResultFromInput(const ListOfShape& theInputs); +}; + +#endif // FeaturesPlugin_GlueFaces_H_ diff --git a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp index 56f86af9c..f77e17b61 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -137,6 +138,8 @@ FeaturesPlugin_Plugin::FeaturesPlugin_Plugin() new FeaturesPlugin_ValidatorDefeaturingSelection); aFactory->registerValidator("FeaturesPlugin_ValidatorSewingSelection", new FeaturesPlugin_ValidatorSewingSelection); + aFactory->registerValidator("FeaturesPlugin_ValidatorGlueFacesSelection", + new FeaturesPlugin_ValidatorGlueFacesSelection); // register this plugin ModelAPI_Session::get()->registerPlugin(this); @@ -210,6 +213,8 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(std::string theFeatureID) return FeaturePtr(new FeaturesPlugin_Chamfer); } else if (theFeatureID == FeaturesPlugin_Copy::ID()) { return FeaturePtr(new FeaturesPlugin_Copy); + } else if (theFeatureID == FeaturesPlugin_GlueFaces::ID()) { + return FeaturePtr(new FeaturesPlugin_GlueFaces); } else if (theFeatureID == FeaturesPlugin_ImportResult::ID()) { return FeaturePtr(new FeaturesPlugin_ImportResult); } else if (theFeatureID == FeaturesPlugin_Defeaturing::ID()) { diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp index 71030a080..0d8da03a6 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp @@ -2149,3 +2149,55 @@ bool FeaturesPlugin_ValidatorSewingSelection::isValid(const AttributePtr& theAtt return true; } + +//================================================================================================== +bool FeaturesPlugin_ValidatorGlueFacesSelection::isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + AttributeSelectionListPtr anAttrSelectionList = + std::dynamic_pointer_cast(theAttribute); + if (!anAttrSelectionList.get()) { + theError = "Error: This validator can only work with selection list attributes."; + return false; + } + + // Check selected entities are of valid types + for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) { + AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex); + if (!anAttrSelection.get()) { + theError = "Error: Empty attribute selection."; + return false; + } + ResultPtr aContext = anAttrSelection->context(); + if (!aContext.get()) { + theError = "Error: Empty selection context."; + return false; + } + if (aContext->groupName() != ModelAPI_ResultBody::group()) { + theError = "Error: Not a result body."; + return false; + } + + GeomShapePtr aContextShape = aContext->shape(); + if (!aContextShape.get()) { + theError = "Error: Empty shape."; + return false; + } + + GeomAPI_Shape::ShapeType aShapeType = aContextShape->shapeType(); + std::set anAllowedTypes; + anAllowedTypes.insert(GeomAPI_Shape::FACE); + anAllowedTypes.insert(GeomAPI_Shape::SHELL); + anAllowedTypes.insert(GeomAPI_Shape::SOLID); + anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID); + anAllowedTypes.insert(GeomAPI_Shape::COMPOUND); + if (anAllowedTypes.find(aShapeType) == anAllowedTypes.end()) { + theError = "Error: Selected shape has the wrong type."; + return false; + } + + } + + return true; +} diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.h b/src/FeaturesPlugin/FeaturesPlugin_Validators.h index 4814dc2df..59ac87fed 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.h @@ -482,4 +482,20 @@ public: Events_InfoMessage& theError) const; }; +/// \class FeaturesPlugin_ValidatorGlueFacesSelection +/// \ingroup Validators +/// \brief Validates selection for glue faces operation. +class FeaturesPlugin_ValidatorGlueFacesSelection : public ModelAPI_AttributeValidator +{ +public: + /// \return True if the attribute is valid. It checks whether the selection + /// is acceptable for glue faces operation. + /// \param[in] theAttribute an attribute to check. + /// \param[in] theArguments a filter parameters. + /// \param[out] theError error message. + virtual bool isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const; +}; + #endif diff --git a/src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts b/src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts index 25fa2623d..584156b0e 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts +++ b/src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts @@ -93,6 +93,10 @@ Sewing Couture + + Glue Faces + Recoller les faces + Revolution Révolution @@ -2321,6 +2325,48 @@ + + + GlueFaces + + Perform gluing of connected faces + Effectuer le collage des faces connectées + + + Glue Faces + Recoller les faces + + + No shapes to glue. + Aucune forme à coller. + + + + GlueFaces:main_objects + + Objects + Objets + + + Select shapes to glue. + Sélectionnez les formes à coller. + + + + GlueFaces:tolerance + + Tolerance + Tolérance + + + + GlueFaces:keep_non_solids + + Keep non-solid shapes + Conserver les formes non solides + + + Smash diff --git a/src/FeaturesPlugin/FeaturesPlugin_msg_ru.ts b/src/FeaturesPlugin/FeaturesPlugin_msg_ru.ts index 1b328d613..6448aae02 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_msg_ru.ts +++ b/src/FeaturesPlugin/FeaturesPlugin_msg_ru.ts @@ -350,4 +350,46 @@ + + + GlueFaces + + Perform gluing of connected faces + Выполнить склейку соединенных граней + + + Glue Faces + Склеиваем лица + + + No shapes to glue. + Нет фигур для склеивания. + + + + GlueFaces:main_objects + + Objects + Объекты + + + Select shapes to glue. + Выберите фигуры для склеивания. + + + + GlueFaces:tolerance + + Tolerance + Толерантность + + + + GlueFaces:keep_non_solids + + Keep non-solid shapes + Сохраняйте нетвердые формы + + + diff --git a/src/FeaturesPlugin/Test/TestGlueFaces_Compound.py b/src/FeaturesPlugin/Test/TestGlueFaces_Compound.py new file mode 100644 index 000000000..5202fd31d --- /dev/null +++ b/src/FeaturesPlugin/Test/TestGlueFaces_Compound.py @@ -0,0 +1,129 @@ +# Copyright (C) 2014-2022 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +from salome.shaper import model +from GeomAPI import GeomAPI_Shape + +aShapeTypes = { + GeomAPI_Shape.SOLID: "GeomAPI_Shape.SOLID", + GeomAPI_Shape.FACE: "GeomAPI_Shape.FACE", + GeomAPI_Shape.EDGE: "GeomAPI_Shape.EDGE", + GeomAPI_Shape.VERTEX: "GeomAPI_Shape.VERTEX"} + +def testNbUniqueSubShapes(theFeature, theShapeType, theExpectedNbSubShapes): + """ Tests number of unique feature sub-shapes of passed type for each result. + :param theFeature: feature to test. + :param theShapeType: shape type of sub-shapes to test. + :param theExpectedNbSubShapes: list of sub-shapes numbers. Size of list should be equal to len(theFeature.results()). + """ + aResults = theFeature.feature().results() + aNbResults = len(aResults) + aListSize = len(theExpectedNbSubShapes) + assert (aNbResults == aListSize), "Number of results: {} not equal to list size: {}.".format(aNbResults, aListSize) + for anIndex in range(0, aNbResults): + aNbResultSubShapes = 0 + anExpectedNbSubShapes = theExpectedNbSubShapes[anIndex] + aNbResultSubShapes = aResults[anIndex].shape().subShapes(theShapeType, True).size() + assert (aNbResultSubShapes == anExpectedNbSubShapes), "Number of sub-shapes of type {} for result[{}]: {}. Expected: {}.".format(aShapeTypes[theShapeType], anIndex, aNbResultSubShapes, anExpectedNbSubShapes) + +def testCompound(theFeature,theModel,NbSubRes,NbSolid,NbFace,NbEdge,NbVertex): + """ Tests numbers of unique sub-shapes in compound result + """ + aResults = theFeature.feature().results() + aNbResults = len(aResults) + assert (aNbResults == 1), "Number of results: {} not equal to 1.".format(aNbResults) + assert aResults[0].shape().isCompound(), "Result shape type: {}. Expected: COMPOUND.".format(aResults[0].shape().shapeTypeStr()) + theModel.testNbSubResults(theFeature, NbSubRes) + testNbUniqueSubShapes(theFeature, GeomAPI_Shape.SOLID, NbSolid) + testNbUniqueSubShapes(theFeature, GeomAPI_Shape.FACE, NbFace) + testNbUniqueSubShapes(theFeature, GeomAPI_Shape.EDGE, NbEdge) + testNbUniqueSubShapes(theFeature, GeomAPI_Shape.VERTEX, NbVertex) + +# Create document +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Param_dx = model.addParameter(Part_1_doc, "dx", '10') +Param_alfa = model.addParameter(Part_1_doc, "alfa", '0') + +# ============================================================================= +# Test 1. Glue faces of 2 adjacent boxes in a compound +# ============================================================================= +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +Box_2 = model.addBox(Part_1_doc, 10, 10, 10) +Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_2_1")], axis = model.selection("EDGE", "PartSet/OX"), distance = "dx", keepSubResults = True) +Rotation_1 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Translation_1_1")], axis = model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"), angle = "alfa", keepSubResults = True) +Compound_1_Objects = [model.selection("SOLID", "Box_1_1"), model.selection("SOLID", "Rotation_1_1")] +Compound_1 = model.addCompound(Part_1_doc, Compound_1_Objects) +model.do() + +GlueFaces_1 = model.addGlueFaces(Part_1_doc, [model.selection("COMPOUND", "Compound_1_1")], 1.0e-7, True) +model.end() + +# gluing successful +testCompound(GlueFaces_1, model, [2], [2], [11], [20], [12]) + +# ============================================================================= +# Test 2. Glue faces for 2 solids with 1 common edge only +# ============================================================================= +model.undo() # to reuse Box_1_1, Translation_1_1, and Rotation_1_1 +model.begin() +Param_alfa.setValue(90) +model.do() + +GlueFaces_2 = model.addGlueFaces(Part_1_doc, [model.selection("COMPOUND", "Compound_1_1")], 1.0e-7, True) +model.end() + +# no faces glued +testCompound(GlueFaces_2, model, [2], [2], [12], [24], [16]) + +# ============================================================================= +# Test 3. Glue faces for 2 solids with 2 adjacent faces above default tolerance +# ============================================================================= +model.undo() # to reuse Box_1_1, Translation_1_1, and Rotation_1_1 +model.begin() + +Param_alfa.setValue(0) +Param_dx.setValue(10.0001) +model.do() + +GlueFaces_3 = model.addGlueFaces(Part_1_doc, [model.selection("COMPOUND", "Compound_1_1")], 1.0e-7, True) +model.end() + +# no faces glued +testCompound(GlueFaces_3, model, [2], [2], [12], [24], [16]) + +# ============================================================================= +# Test 4. Glue faces for 2 solids with 2 adjacent faces using different tolerance +# ============================================================================= +model.undo() # to reuse Box_1_1, Translation_1_1, and Rotation_1_1 +model.begin() + +tol = 1.e-4 +GlueFaces_4 = model.addGlueFaces(Part_1_doc, [model.selection("COMPOUND", "Compound_1_1")], tol, True) +model.end() + +# gluing successful +testCompound(GlueFaces_4, model, [2], [2], [11], [20], [12]) + +# ============================================================================= +# Test 5. Check Python dump +# ============================================================================= +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestGlueFaces_Shell.py b/src/FeaturesPlugin/Test/TestGlueFaces_Shell.py new file mode 100644 index 000000000..95f89ab22 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestGlueFaces_Shell.py @@ -0,0 +1,131 @@ +# Copyright (C) 2014-2022 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +from salome.shaper import model +from GeomAPI import GeomAPI_Shape + +aShapeTypes = { + GeomAPI_Shape.SOLID: "GeomAPI_Shape.SOLID", + GeomAPI_Shape.FACE: "GeomAPI_Shape.FACE", + GeomAPI_Shape.EDGE: "GeomAPI_Shape.EDGE", + GeomAPI_Shape.VERTEX: "GeomAPI_Shape.VERTEX"} + +def testNbUniqueSubShapes(theFeature, theShapeType, theExpectedNbSubShapes): + """ Tests number of unique feature sub-shapes of passed type for each result. + :param theFeature: feature to test. + :param theShapeType: shape type of sub-shapes to test. + :param theExpectedNbSubShapes: list of sub-shapes numbers. Size of list should be equal to len(theFeature.results()). + """ + aResults = theFeature.feature().results() + aNbResults = len(aResults) + aListSize = len(theExpectedNbSubShapes) + assert (aNbResults == aListSize), "Number of results: {} not equal to list size: {}.".format(aNbResults, aListSize) + for anIndex in range(0, aNbResults): + aNbResultSubShapes = 0 + anExpectedNbSubShapes = theExpectedNbSubShapes[anIndex] + aNbResultSubShapes = aResults[anIndex].shape().subShapes(theShapeType, True).size() + assert (aNbResultSubShapes == anExpectedNbSubShapes), "Number of sub-shapes of type {} for result[{}]: {}. Expected: {}.".format(aShapeTypes[theShapeType], anIndex, aNbResultSubShapes, anExpectedNbSubShapes) + +def testCompound(theFeature,theModel,NbSubRes,NbSolid,NbFace,NbEdge,NbVertex): + """ Tests numbers of unique sub-shapes in compound result + """ + aResults = theFeature.feature().results() + aNbResults = len(aResults) + assert (aNbResults == 1), "Number of results: {} not equal to 1.".format(aNbResults) + assert aResults[0].shape().isCompound(), "Result shape type: {}. Expected: COMPOUND.".format(aResults[0].shape().shapeTypeStr()) + theModel.testNbSubResults(theFeature, NbSubRes) + testNbUniqueSubShapes(theFeature, GeomAPI_Shape.SOLID, NbSolid) + testNbUniqueSubShapes(theFeature, GeomAPI_Shape.FACE, NbFace) + testNbUniqueSubShapes(theFeature, GeomAPI_Shape.EDGE, NbEdge) + testNbUniqueSubShapes(theFeature, GeomAPI_Shape.VERTEX, NbVertex) + +# Create document +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Param_dx = model.addParameter(Part_1_doc, "dx", '10') +Param_alfa = model.addParameter(Part_1_doc, "alfa", '0') + +# ============================================================================= +# Test 1. Glue faces of 2 adjacent shells +# ============================================================================= +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +Box_2 = model.addBox(Part_1_doc, 10, 10, 10) +Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_2_1")], axis = model.selection("EDGE", "PartSet/OX"), distance = "dx", keepSubResults = True) +Rotation_1 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Translation_1_1")], axis = model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"), angle = "alfa", keepSubResults = True) +Shell_1_Objects = [model.selection("FACE", "Box_1_1/Top"), model.selection("FACE", "Box_1_1/Front")] +Shell_1 = model.addShell(Part_1_doc, Shell_1_Objects) +Shell_2_Objects = [model.selection("FACE", "Rotation_1_1/MF:Rotated&Box_2_1/Top"), model.selection("FACE", "Rotation_1_1/MF:Rotated&Box_2_1/Back")] +Shell_2 = model.addShell(Part_1_doc, Shell_2_Objects) +model.do() + +GlueFaces_1 = model.addGlueFaces(Part_1_doc, [model.selection("SHELL", "Shell_1_1"), model.selection("SHELL", "Shell_2_1")], 1.0e-7, True) +model.end() + +# gluing successful +testCompound(GlueFaces_1, model, [2], [0], [3], [10], [8]) + +# ============================================================================= +# Test 2. Glue faces for 2 shells with 1 common edge only +# ============================================================================= +model.undo() # to reuse the 2 shells +model.begin() +Param_alfa.setValue(90) +model.do() + +GlueFaces_2 = model.addGlueFaces(Part_1_doc, [model.selection("SHELL", "Shell_1_1"), model.selection("SHELL", "Shell_2_1")], 1.0e-7, True) +model.end() + +# no faces glued +testCompound(GlueFaces_2, model, [2], [0], [4], [14], [12]) + +# ============================================================================= +# Test 3. Glue faces for 2 shells with 2 adjacent faces above default tolerance +# ============================================================================= +model.undo() # to reuse the 2 shells +model.begin() + +Param_alfa.setValue(0) +Param_dx.setValue(10.0001) +model.do() + +GlueFaces_3 = model.addGlueFaces(Part_1_doc, [model.selection("SHELL", "Shell_1_1"), model.selection("SHELL", "Shell_2_1")], 1.0e-7, True) +model.end() + +# no faces glued +testCompound(GlueFaces_3, model, [2], [0], [4], [14], [12]) + +# ============================================================================= +# Test 4. Glue faces for 2 solids with 2 adjacent faces using different tolerance +# ============================================================================= +model.undo() # to reuse Box_1_1, Translation_1_1, and Rotation_1_1 +model.begin() + +tol = 1.e-4 +GlueFaces_4 = model.addGlueFaces(Part_1_doc, [model.selection("SHELL", "Shell_1_1"), model.selection("SHELL", "Shell_2_1")], tol, True) +model.end() + +# gluing successful +testCompound(GlueFaces_4, model, [2], [0], [3], [10], [8]) + +# ============================================================================= +# Test 5. Check Python dump +# ============================================================================= +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestGlueFaces_Solids.py b/src/FeaturesPlugin/Test/TestGlueFaces_Solids.py new file mode 100644 index 000000000..7a6284bcb --- /dev/null +++ b/src/FeaturesPlugin/Test/TestGlueFaces_Solids.py @@ -0,0 +1,127 @@ +# Copyright (C) 2014-2022 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +from salome.shaper import model +from GeomAPI import GeomAPI_Shape + +aShapeTypes = { + GeomAPI_Shape.SOLID: "GeomAPI_Shape.SOLID", + GeomAPI_Shape.FACE: "GeomAPI_Shape.FACE", + GeomAPI_Shape.EDGE: "GeomAPI_Shape.EDGE", + GeomAPI_Shape.VERTEX: "GeomAPI_Shape.VERTEX"} + +def testNbUniqueSubShapes(theFeature, theShapeType, theExpectedNbSubShapes): + """ Tests number of unique feature sub-shapes of passed type for each result. + :param theFeature: feature to test. + :param theShapeType: shape type of sub-shapes to test. + :param theExpectedNbSubShapes: list of sub-shapes numbers. Size of list should be equal to len(theFeature.results()). + """ + aResults = theFeature.feature().results() + aNbResults = len(aResults) + aListSize = len(theExpectedNbSubShapes) + assert (aNbResults == aListSize), "Number of results: {} not equal to list size: {}.".format(aNbResults, aListSize) + for anIndex in range(0, aNbResults): + aNbResultSubShapes = 0 + anExpectedNbSubShapes = theExpectedNbSubShapes[anIndex] + aNbResultSubShapes = aResults[anIndex].shape().subShapes(theShapeType, True).size() + assert (aNbResultSubShapes == anExpectedNbSubShapes), "Number of sub-shapes of type {} for result[{}]: {}. Expected: {}.".format(aShapeTypes[theShapeType], anIndex, aNbResultSubShapes, anExpectedNbSubShapes) + +def testCompound(theFeature,theModel,NbSubRes,NbSolid,NbFace,NbEdge,NbVertex): + """ Tests numbers of unique sub-shapes in compound result + """ + aResults = theFeature.feature().results() + aNbResults = len(aResults) + assert (aNbResults == 1), "Number of results: {} not equal to 1.".format(aNbResults) + assert aResults[0].shape().isCompound(), "Result shape type: {}. Expected: COMPOUND.".format(aResults[0].shape().shapeTypeStr()) + theModel.testNbSubResults(theFeature, NbSubRes) + testNbUniqueSubShapes(theFeature, GeomAPI_Shape.SOLID, NbSolid) + testNbUniqueSubShapes(theFeature, GeomAPI_Shape.FACE, NbFace) + testNbUniqueSubShapes(theFeature, GeomAPI_Shape.EDGE, NbEdge) + testNbUniqueSubShapes(theFeature, GeomAPI_Shape.VERTEX, NbVertex) + +# Create document +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Param_dx = model.addParameter(Part_1_doc, "dx", '10') +Param_alfa = model.addParameter(Part_1_doc, "alfa", '0') + +# ============================================================================= +# Test 1. Glue faces of 2 adjacent boxes +# ============================================================================= +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +Box_2 = model.addBox(Part_1_doc, 10, 10, 10) +Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_2_1")], axis = model.selection("EDGE", "PartSet/OX"), distance = "dx", keepSubResults = True) +Rotation_1 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Translation_1_1")], axis = model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"), angle = "alfa", keepSubResults = True) +model.do() + +GlueFaces_1 = model.addGlueFaces(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("SOLID", "Rotation_1_1")], 1.0e-7, True) +model.end() + +# gluing successful +testCompound(GlueFaces_1, model, [2], [2], [11], [20], [12]) + +# ============================================================================= +# Test 2. Glue faces for 2 solids with 1 common edge only +# ============================================================================= +model.undo() # to reuse Box_1_1, Translation_1_1, and Rotation_1_1 +model.begin() +Param_alfa.setValue(90) +model.do() + +GlueFaces_2 = model.addGlueFaces(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("SOLID", "Rotation_1_1")], 1.0e-7, True) +model.end() + +# no faces glued +testCompound(GlueFaces_2, model, [2], [2], [12], [24], [16]) + +# ============================================================================= +# Test 3. Glue faces for 2 solids with 2 adjacent faces above default tolerance +# ============================================================================= +model.undo() # to reuse Box_1_1, Translation_1_1, and Rotation_1_1 +model.begin() + +Param_alfa.setValue(0) +Param_dx.setValue(10.0001) +model.do() + +GlueFaces_3 = model.addGlueFaces(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("SOLID", "Rotation_1_1")], 1.0e-7, True) +model.end() + +# no faces glued +testCompound(GlueFaces_3, model, [2], [2], [12], [24], [16]) + +# ============================================================================= +# Test 4. Glue faces for 2 solids with 2 adjacent faces using different tolerance +# ============================================================================= +model.undo() # to reuse Box_1_1, Translation_1_1, and Rotation_1_1 +model.begin() + +tol = 1.e-4 +GlueFaces_4 = model.addGlueFaces(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("SOLID", "Rotation_1_1")], tol, True) +model.end() + +# gluing successful +testCompound(GlueFaces_4, model, [2], [2], [11], [20], [12]) + +# ============================================================================= +# Test 5. Check Python dump +# ============================================================================= +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/doc/FeaturesPlugin.rst b/src/FeaturesPlugin/doc/FeaturesPlugin.rst index 767922df8..d820d4df8 100644 --- a/src/FeaturesPlugin/doc/FeaturesPlugin.rst +++ b/src/FeaturesPlugin/doc/FeaturesPlugin.rst @@ -23,6 +23,7 @@ Features plug-in provides a set of common topological operations. It implements filletFeature.rst fuseFeatureFaces.rst geometryCalculationFeature.rst + glueFeatureFaces.rst importResultFeature.rst linearCopyFeature.rst loftFeature.rst diff --git a/src/FeaturesPlugin/doc/TUI_glueFeatureFaces.rst b/src/FeaturesPlugin/doc/TUI_glueFeatureFaces.rst new file mode 100644 index 000000000..3be4e87e2 --- /dev/null +++ b/src/FeaturesPlugin/doc/TUI_glueFeatureFaces.rst @@ -0,0 +1,11 @@ + + .. _tui_create_glue_faces: + +Glue Faces +========== + +.. literalinclude:: examples/glue_faces.py + :linenos: + :language: python + +:download:`Download this script ` diff --git a/src/FeaturesPlugin/doc/examples/glue_faces.py b/src/FeaturesPlugin/doc/examples/glue_faces.py new file mode 100644 index 000000000..06a3f0573 --- /dev/null +++ b/src/FeaturesPlugin/doc/examples/glue_faces.py @@ -0,0 +1,13 @@ +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +Box_2 = model.addBox(Part_1_doc, 20, 10, 10) +Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_2_1")], axis = model.selection("EDGE", "PartSet/OX"), distance = 10, keepSubResults = True) +model.do() +GlueFaces_1 = model.addGlueFaces(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("SOLID", "Translation_1_1")], 1.0e-7, True) +model.do() +model.end() diff --git a/src/FeaturesPlugin/doc/glueFeatureFaces.rst b/src/FeaturesPlugin/doc/glueFeatureFaces.rst new file mode 100644 index 000000000..2cfa0907a --- /dev/null +++ b/src/FeaturesPlugin/doc/glueFeatureFaces.rst @@ -0,0 +1,42 @@ +.. |glue_faces.icon| image:: images/glue_faces.png + +Glue Faces +========== + +**Glue Faces** feature glues faces that are coincident with respect to the given tolerance value. + +To perform **Glue Faces** in the active part: + +#. select in the Main Menu *Features - > Glue Faces* item or +#. click |glue_faces.icon| **Glue Faces** button in the toolbar + +The following property panel appears: + +.. figure:: images/GlueFaces.png + :align: center + + **Glue Faces** property panel + +Input fields: + +- **Objects** - contains a list of objects selected in the Object Browser or in the Viewer, on which faces will be glued. +- **Tolerance** - sets the tolerance value to be used for the gluing operation. +- **Keep non-solid shapes** - defines whether to keep non-solid shapes during the gluing operation. + +**TUI Command**: + +.. py:function:: model.addGlueFaces(Part_doc, objects, tolerance, keepNonSolid) + + :param part: The current part object. + :param objects: A list of shapes for which faces should be glued. + :param number: The tolerance value. + :param boolean: *True* to keep non-solid shapes. + :return: Created object. + +Result +"""""" + +The result of the operation will be a compound shape with eliminated faces. +If no faces were glued, the result will be a compound with the original selected shapes. + +**See Also** a sample TUI Script of :ref:`tui_create_glue_faces` operation. diff --git a/src/FeaturesPlugin/doc/images/GlueFaces.png b/src/FeaturesPlugin/doc/images/GlueFaces.png new file mode 100644 index 000000000..8618cc2cf Binary files /dev/null and b/src/FeaturesPlugin/doc/images/GlueFaces.png differ diff --git a/src/FeaturesPlugin/doc/images/glue_faces.png b/src/FeaturesPlugin/doc/images/glue_faces.png new file mode 100644 index 000000000..0d66a119b Binary files /dev/null and b/src/FeaturesPlugin/doc/images/glue_faces.png differ diff --git a/src/FeaturesPlugin/glue_faces_widget.xml b/src/FeaturesPlugin/glue_faces_widget.xml new file mode 100644 index 000000000..768b42260 --- /dev/null +++ b/src/FeaturesPlugin/glue_faces_widget.xml @@ -0,0 +1,18 @@ + + + + + + + + + diff --git a/src/FeaturesPlugin/icons/glue_faces.png b/src/FeaturesPlugin/icons/glue_faces.png new file mode 100644 index 000000000..0d66a119b Binary files /dev/null and b/src/FeaturesPlugin/icons/glue_faces.png differ diff --git a/src/FeaturesPlugin/plugin-Features.xml b/src/FeaturesPlugin/plugin-Features.xml index a77da866c..64b210e9e 100644 --- a/src/FeaturesPlugin/plugin-Features.xml +++ b/src/FeaturesPlugin/plugin-Features.xml @@ -152,6 +152,11 @@ auto_preview="false"> + + + diff --git a/src/FeaturesPlugin/tests.set b/src/FeaturesPlugin/tests.set index 2ca98bd85..b07dec3a0 100644 --- a/src/FeaturesPlugin/tests.set +++ b/src/FeaturesPlugin/tests.set @@ -532,6 +532,9 @@ SET(TEST_NAMES_PARA TestSewing_Manifold.py TestSewing_NonManifold.py TestSewing_Groups.py + TestGlueFaces_Compound.py + TestGlueFaces_Shell.py + TestGlueFaces_Solids.py ) SET(TEST_NAMES_SEQ diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index 640ae3a1f..5263f9cc4 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -97,7 +97,8 @@ SET(PROJECT_HEADERS GeomAlgoAPI_NormalToFace.h GeomAlgoAPI_Tube.h GeomAlgoAPI_ShapeInfo.h - GeomAlgoAPI_CanonicalRecognition.h + GeomAlgoAPI_CanonicalRecognition.h + GeomAlgoAPI_GlueFaces.h ) SET(PROJECT_SOURCES @@ -174,7 +175,8 @@ SET(PROJECT_SOURCES GeomAlgoAPI_NormalToFace.cpp GeomAlgoAPI_Tube.cpp GeomAlgoAPI_ShapeInfo.cpp - GeomAlgoAPI_CanonicalRecognition.cpp + GeomAlgoAPI_CanonicalRecognition.cpp + GeomAlgoAPI_GlueFaces.cpp ) SET(PROJECT_LIBRARIES diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_GlueFaces.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_GlueFaces.cpp new file mode 100644 index 000000000..79223f106 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_GlueFaces.cpp @@ -0,0 +1,165 @@ +// Copyright (C) 2014-2022 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "GeomAlgoAPI_GlueFaces.h" + +#include +#include +#include +#include +#include +#include +#include + +//================================================================================================== +GeomAlgoAPI_GlueFaces::GeomAlgoAPI_GlueFaces(const ListOfShape& theShapes, const double theTolerance/*=1.e-7*/, const bool theKeepNonSolids/*=true*/) +{ + build(theShapes, theTolerance, theKeepNonSolids); +} + +//================================================================================================== +void GeomAlgoAPI_GlueFaces::build(const ListOfShape& theShapes, const double theTolerance, const bool theKeepNonSolids) +{ + if (theShapes.empty()) + { + return; + } + + // Create a compound of all shapes in the list + TopoDS_Shape aBaseShape; + if (theShapes.size() == 1) + { + aBaseShape = theShapes.front()->impl(); + } + else + { + TopoDS_Compound aCompound; + BRep_Builder aBuilder; + aBuilder.MakeCompound(aCompound); + ListOfShape::const_iterator anIt = theShapes.cbegin(); + for (; anIt != theShapes.cend(); ++anIt) + { + const TopoDS_Shape& aShape = (*anIt)->impl(); + if (aShape.IsNull()) break; + aBuilder.Add(aCompound, aShape); + } + if (anIt == theShapes.cend()) + { + aBaseShape = aCompound; + } + else + { + aBaseShape.Nullify(); + } + } + if (aBaseShape.IsNull()) + { + myError = "Shape for gluing is null"; + return; + } + + GEOMAlgo_Gluer2 aGlueAlgo; + + // Initialization + aGlueAlgo.SetArgument(aBaseShape); + aGlueAlgo.SetTolerance(theTolerance); + Standard_Boolean aIsKeepNonSolids = theKeepNonSolids; + aGlueAlgo.SetKeepNonSolids(aIsKeepNonSolids); + + // Detect interfered shapes + aGlueAlgo.Detect(); + Standard_Integer iWrnDetect = aGlueAlgo.WarningStatus(); + if (iWrnDetect == 2) + { + myError = "Glue Error Sticked Shapes"; + return; + } + + Standard_Integer iErr = aGlueAlgo.ErrorStatus(); + if (iErr) + { + switch (iErr) + { + case 11: + myError = "GEOMAlgo_GlueDetector failed"; + break; + case 13: + case 14: + myError = "PerformImagesToWork failed"; + break; + default: + { + // description of all errors see in GEOMAlgo_Gluer2.cxx + myError = "Error in GEOMAlgo_Gluer2 with code "; + myError += std::to_string(iErr); + break; + } + } + return; + } + + // Gluing + aGlueAlgo.Perform(); + iErr = aGlueAlgo.ErrorStatus(); + if (iErr) + { + switch (iErr) + { + case 11: + myError = "GEOMAlgo_GlueDetector failed"; + break; + case 13: + case 14: + myError = "PerformImagesToWork failed"; + break; + default: + { + // description of all errors see in GEOMAlgo_Gluer2.cxx + myError = "Error in GEOMAlgo_Gluer2 with code "; + myError += std::to_string(iErr); + break; + } + } + return; + } + + Standard_Integer iWrn = aGlueAlgo.WarningStatus(); + if (iWrn) + { + switch (iWrn) + { + case 1: + myError = "No shapes to glue"; + break; + default: + // description of all warnings see in GEOMAlgo_Gluer2.cxx + myError = "Warning in GEOMAlgo_Gluer2 with code "; + myError += std::to_string(iWrn); + break; + } + } + + // Result + TopoDS_Shape aResult = aGlueAlgo.Shape(); + + std::shared_ptr aResShape(new GeomAPI_Shape()); + aResShape->setImpl(new TopoDS_Shape(aResult)); + this->setShape(aResShape); + this->setDone(true); +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_GlueFaces.h b/src/GeomAlgoAPI/GeomAlgoAPI_GlueFaces.h new file mode 100644 index 000000000..bff88e9ba --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_GlueFaces.h @@ -0,0 +1,46 @@ +// Copyright (C) 2014-2022 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef GeomAlgoAPI_GlueFaces_H_ +#define GeomAlgoAPI_GlueFaces_H_ + +#include "GeomAlgoAPI.h" +#include "GeomAlgoAPI_MakeShape.h" + +#include + +/// \class GeomAlgoAPI_GlueFaces +/// \ingroup DataAlgo +/// \brief Allows the elimination of coincident (duplicated) faces +/// from a set of separate topological elements. +class GeomAlgoAPI_GlueFaces : public GeomAlgoAPI_MakeShape +{ +public: + /// Constructor with optional arguments + /// \param[in] theShapes list of shapes. + /// \param[in] theTolerance tolerance to be used for gluing operation. + /// \param[in] theKeepNonSolids whether to keep non-solid shapes in the result + GEOMALGOAPI_EXPORT GeomAlgoAPI_GlueFaces(const ListOfShape& theShapes, const double theTolerance = 1.e-7, const bool theKeepNonSolids = true); + +private: + /// Builds resulting shape. + void build(const ListOfShape& theShapes, const double theTolerance, const bool theKeepNonSolids); +}; + +#endif diff --git a/src/GeomAlgoImpl/CMakeLists.txt b/src/GeomAlgoImpl/CMakeLists.txt index db5e6cc54..15d52cfce 100644 --- a/src/GeomAlgoImpl/CMakeLists.txt +++ b/src/GeomAlgoImpl/CMakeLists.txt @@ -21,11 +21,43 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) SET(PROJECT_HEADERS GeomAlgoImpl.h + GEOMAlgo_Algo.hxx + GEOMAlgo_AlgoTools.hxx + GEOMAlgo_BndSphere.hxx + GEOMAlgo_BndSphereTree.hxx + GEOMAlgo_BuilderShape.hxx + GEOMAlgo_CoupleOfShapes.hxx + GEOMAlgo_GlueDetector.hxx + GEOMAlgo_Gluer2.hxx + GEOMAlgo_GluerAlgo.hxx + GEOMAlgo_IndexedDataMapOfIntegerShape.hxx + GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx + GEOMAlgo_IndexedDataMapOfShapeBndSphere.hxx + GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape.hxx + GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx + GEOMAlgo_ListOfCoupleOfShapes.hxx + GEOMAlgo_PassKeyShape.hxx + GEOMAlgo_PassKeyShapeMapHasher.hxx GEOMAlgo_Splitter.hxx GEOMImpl_Fillet1d.hxx ) SET(PROJECT_SOURCES + GEOMAlgo_Algo.cxx + GEOMAlgo_AlgoTools.cxx + GEOMAlgo_AlgoTools_1.cxx + GEOMAlgo_BndSphere.cxx + GEOMAlgo_BndSphereTree.cxx + GEOMAlgo_BuilderShape.cxx + GEOMAlgo_CoupleOfShapes.cxx + GEOMAlgo_GlueDetector.cxx + GEOMAlgo_Gluer2.cxx + GEOMAlgo_Gluer2_1.cxx + GEOMAlgo_Gluer2_2.cxx + GEOMAlgo_Gluer2_3.cxx + GEOMAlgo_GluerAlgo.cxx + GEOMAlgo_PassKeyShape.cxx + GEOMAlgo_PassKeyShapeMapHasher.cxx GEOMAlgo_Splitter.cxx GEOMImpl_Fillet1d.cxx ) diff --git a/src/GeomAlgoImpl/GEOMAlgo_Algo.cxx b/src/GeomAlgoImpl/GEOMAlgo_Algo.cxx new file mode 100644 index 000000000..b93f9c025 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_Algo.cxx @@ -0,0 +1,95 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: GEOMAlgo_Algo.cxx +// Created: Sat Dec 04 12:39:47 2004 +// Author: Peter KURNEV +// +// +#include + + +//======================================================================= +// function: +// purpose: +//======================================================================= +GEOMAlgo_Algo::GEOMAlgo_Algo() + :myErrorStatus(1) + ,myWarningStatus(0) + ,myComputeInternalShapes(Standard_True) +{} + +//======================================================================= +// function: ~ +// purpose: +//======================================================================= +GEOMAlgo_Algo::~GEOMAlgo_Algo() +{ +} + +//======================================================================= +// function: CheckData +// purpose: +//======================================================================= +void GEOMAlgo_Algo::CheckData() +{ + myErrorStatus=0; +} + +//======================================================================= +// function: CheckResult +// purpose: +//======================================================================= +void GEOMAlgo_Algo::CheckResult() +{ + myErrorStatus=0; +} + +//======================================================================= +// function: ErrorStatus +// purpose: +//======================================================================= +Standard_Integer GEOMAlgo_Algo::ErrorStatus()const +{ + return myErrorStatus; +} + +//======================================================================= +// function: WarningStatus +// purpose: +//======================================================================= +Standard_Integer GEOMAlgo_Algo::WarningStatus()const +{ + return myWarningStatus; +} +// myErrorStatus +// +// 1 - object is just initialized + +//======================================================================= +//function : ComputeInternalShapes +//purpose : +//======================================================================= +void GEOMAlgo_Algo::ComputeInternalShapes(const Standard_Boolean theFlag) +{ + myComputeInternalShapes = theFlag; +} diff --git a/src/GeomAlgoImpl/GEOMAlgo_Algo.hxx b/src/GeomAlgoImpl/GEOMAlgo_Algo.hxx new file mode 100644 index 000000000..eaee9dd7f --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_Algo.hxx @@ -0,0 +1,71 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: GEOMAlgo_Algo.hxx +// Created: Sat Dec 04 12:39:47 2004 +// Author: Peter KURNEV +// +// +#ifndef _GEOMAlgo_Algo_HeaderFile +#define _GEOMAlgo_Algo_HeaderFile + +#include + +#include +#include +#include +#include + + +//======================================================================= +//class : GEOMAlgo_Algo +//purpose : +//======================================================================= +class GEOMAlgo_Algo +{ + public: + GEOMALGOIMPL_EXPORT virtual void Perform() = 0; + + GEOMALGOIMPL_EXPORT Standard_Integer ErrorStatus() const; + + GEOMALGOIMPL_EXPORT Standard_Integer WarningStatus() const; + + //! Allows to omit of creation of internal shapes (manifold topology).
+ //! Needed for the SALOME/TRIPOLI module.
+ GEOMALGOIMPL_EXPORT void ComputeInternalShapes(const Standard_Boolean theFlag) ; + +protected: + GEOMALGOIMPL_EXPORT GEOMAlgo_Algo(); + + GEOMALGOIMPL_EXPORT virtual ~GEOMAlgo_Algo(); + + GEOMALGOIMPL_EXPORT virtual void CheckData() ; + + GEOMALGOIMPL_EXPORT virtual void CheckResult() ; + + + Standard_Integer myErrorStatus; + Standard_Integer myWarningStatus; + Standard_Boolean myComputeInternalShapes; +}; + +#endif diff --git a/src/GeomAlgoImpl/GEOMAlgo_AlgoTools.cxx b/src/GeomAlgoImpl/GEOMAlgo_AlgoTools.cxx new file mode 100644 index 000000000..7965b41a5 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_AlgoTools.cxx @@ -0,0 +1,1641 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// 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 +#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); + +static Standard_Boolean comp(const std::pair& theA, + const std::pair& theB); + +static Standard_Boolean IsUiso (const TopoDS_Edge& theEdge, + const TopoDS_Face& theFace); + +static void CorrectShell (const TopoDS_Shape& theShell, + const TopoDS_Face& theFace); + +static gp_Pnt GetMidPnt2d(const TopoDS_Face& theFace, + const Standard_Boolean theIsNaturalRestrictions); + +static void ModifyFacesForGlobalResult(const TopoDS_Face& theInputFace, + const Standard_Real theAverageArea, + const Standard_Boolean theIsToAddFaces, + Standard_Integer& theNbExtremalFaces, + TopTools_MapOfShape& theExtremalFaces, + const std::vector> theFacesAndAreas, + const TopTools_DataMapOfShapeReal& theFaceAreaMap, + const TopTools_IndexedDataMapOfShapeListOfShape& theEFmap, + TopoDS_Shape& theRes, + TopoDS_Shape& theGlobalRes, + TopTools_MapOfShape& theRemovedFaces); + +//======================================================================= +//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; +} + +//======================================================================= +//function : PointCloudInFace +//purpose : +//======================================================================= +Standard_Integer GEOMAlgo_AlgoTools::PointCloudInFace(const TopoDS_Face& theFace, + const int theNbPnts, + TopoDS_Compound& theCompound) +{ +#if OCC_VERSION_LARGE < 0x07050304 + return -1; +#else + ShapeUpgrade_ShapeDivideArea tool (theFace); + tool.SetSplittingByNumber (Standard_True); + tool.NbParts() = theNbPnts; + tool.Perform(); + TopoDS_Shape res = tool.Result(); + + BRep_Builder aBB; + TopoDS_Compound aGlobalRes; + aBB.MakeCompound (aGlobalRes); + + TopTools_IndexedMapOfShape aFaceMap; + TopExp::MapShapes (res, TopAbs_FACE, aFaceMap); + Standard_Integer aNbFaces = aFaceMap.Extent(); + + TopTools_IndexedDataMapOfShapeListOfShape aEFmap; + TopExp::MapShapesAndAncestors (res, TopAbs_EDGE, TopAbs_FACE, aEFmap); + + TopTools_MapOfShape aBiggestFaces, aSmallestFaces; + Standard_Boolean aUseTriangulation = Standard_True; + Standard_Boolean aSkipShared = Standard_False; + if (aNbFaces != theNbPnts) + { + Standard_Real aTotalArea = 0.; + std::vector > aFacesAndAreas (aNbFaces); + for (Standard_Integer ii = 1; ii <= aNbFaces; ii++) + { + GProp_GProps aProps; + BRepGProp::SurfaceProperties (aFaceMap(ii), aProps, aSkipShared, aUseTriangulation); + Standard_Real anArea = aProps.Mass(); + aTotalArea += anArea; + std::pair aFaceWithArea (aFaceMap(ii), anArea); + aFacesAndAreas[ii-1] = aFaceWithArea; + } + std::sort (aFacesAndAreas.begin(), aFacesAndAreas.end(), comp); + + Standard_Real anAverageArea = aTotalArea / theNbPnts; + + TopTools_DataMapOfShapeReal aFaceAreaMap; + for (Standard_Integer ii = 0; ii < aNbFaces; ii++) + aFaceAreaMap.Bind (aFacesAndAreas[ii].first, aFacesAndAreas[ii].second); + + TopTools_MapOfShape aRemovedFaces; + + if (aNbFaces < theNbPnts) + { + Standard_Integer aNbMissingFaces = theNbPnts - aNbFaces; + for (Standard_Integer ii = aNbFaces-1; ii > aNbFaces - aNbMissingFaces - 1; ii--) + aBiggestFaces.Add (aFacesAndAreas[ii].first); + + ModifyFacesForGlobalResult (theFace, anAverageArea, + Standard_True, //to add faces + aNbMissingFaces, aBiggestFaces, + aFacesAndAreas, aFaceAreaMap, aEFmap, + res, aGlobalRes, + aRemovedFaces); + } + else //aNbFaces > theNbPnts + { + Standard_Integer aNbExcessFaces = aNbFaces - theNbPnts; + for (Standard_Integer ii = 0; ii < aNbExcessFaces; ii++) + aSmallestFaces.Add (aFacesAndAreas[ii].first); + + TopTools_IndexedDataMapOfShapeListOfShape aVFmap; + TopExp::MapShapesAndAncestors (res, TopAbs_VERTEX, TopAbs_FACE, aVFmap); + + //Remove smallest faces with free boundaries + for (Standard_Integer ii = 0; ii < aNbExcessFaces; ii++) + { + const TopoDS_Face& aFace = TopoDS::Face (aFacesAndAreas[ii].first); + Standard_Boolean anIsFreeBoundFound = Standard_False; + TopExp_Explorer anExplo (aFace, TopAbs_EDGE); + for (; anExplo.More(); anExplo.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current()); + if (!BRep_Tool::Degenerated (anEdge) && + aEFmap.FindFromKey(anEdge).Extent() < 2) + { + anIsFreeBoundFound = Standard_True; + break; + } + } + if (anIsFreeBoundFound) + { + Standard_Real aMaxArea = 0.; + for (anExplo.Init(aFace, TopAbs_VERTEX); anExplo.More(); anExplo.Next()) + { + const TopoDS_Shape& aVertex = anExplo.Current(); + const TopTools_ListOfShape& aFaceList = aVFmap.FindFromKey (aVertex); + TopTools_ListIteratorOfListOfShape anItl (aFaceList); + for (; anItl.More(); anItl.Next()) + { + Standard_Real anArea = aFaceAreaMap (anItl.Value()); + if (anArea > aMaxArea) + aMaxArea = anArea; + } + } + Standard_Real anArreaOfSmallestFace = aFaceAreaMap (aFace); + if (anArreaOfSmallestFace < aMaxArea / 16) + { + aBB.Remove (res, aFace); + aRemovedFaces.Add (aFace); + } + } + } + + ModifyFacesForGlobalResult (theFace, anAverageArea, + Standard_False, //to decrease number of faces + aNbExcessFaces, aSmallestFaces, + aFacesAndAreas, aFaceAreaMap, aEFmap, + res, aGlobalRes, + aRemovedFaces); + } + } + + aBB.Add (aGlobalRes, res); + + aBB.MakeCompound (theCompound); + for (TopExp_Explorer aGlobalExplo(aGlobalRes, TopAbs_FACE); aGlobalExplo.More(); aGlobalExplo.Next()) + { + const TopoDS_Face& aFace = TopoDS::Face (aGlobalExplo.Current()); + Standard_Boolean anIsNaturalRestrictions = Standard_True; + TopExp_Explorer anExplo (aFace, TopAbs_EDGE); + for (; anExplo.More(); anExplo.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current()); + if (BRep_Tool::Degenerated (anEdge)) + continue; + if (!aEFmap.Contains(anEdge) || + aEFmap.FindFromKey(anEdge).Extent() < 2) + { + anIsNaturalRestrictions = Standard_False; + break; + } + } + + gp_Pnt aPnt = GetMidPnt2d (aFace, anIsNaturalRestrictions); + TopoDS_Vertex aVertex = BRepLib_MakeVertex (aPnt); + aBB.Add (theCompound, aVertex); + } + + return 0; +#endif +} + +Standard_Boolean comp(const std::pair& theA, + const std::pair& theB) +{ + return (theA.second < theB.second); +} + +Standard_Boolean IsUiso (const TopoDS_Edge& theEdge, + const TopoDS_Face& theFace) +{ + BRepAdaptor_Curve2d aBAcurve2d (theEdge, theFace); + gp_Pnt2d aP2d; + gp_Vec2d aVec; + aBAcurve2d.D1 (aBAcurve2d.FirstParameter(), aP2d, aVec); + return (Abs(aVec.Y()) > Abs(aVec.X())); +} + +void CorrectShell (const TopoDS_Shape& theShell, + const TopoDS_Face& theFace) +{ + BRepAdaptor_Surface aBAsurf (theFace, Standard_False); + GeomAbs_SurfaceType aType = aBAsurf.GetType(); + if (aType <= GeomAbs_Torus) //elementary surfaces + return; + + TopLoc_Location anInputLoc; + const Handle(Geom_Surface)& anInputSurf = BRep_Tool::Surface (theFace, anInputLoc); + + BRep_Builder aBB; + + TopoDS_Iterator anIter (theShell); + for (; anIter.More(); anIter.Next()) + { + const TopoDS_Face& aFace = TopoDS::Face (anIter.Value()); + TopLoc_Location aLoc; + const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface (aFace, aLoc); + if (aSurf == anInputSurf) + continue; + + TopExp_Explorer anExplo (aFace, TopAbs_EDGE); + for (; anExplo.More(); anExplo.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current()); + Standard_Real aFirst, aLast; + Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface (anEdge, aFace, aFirst, aLast); + aBB.UpdateEdge (anEdge, aPCurve, anInputSurf, anInputLoc, 0.); + } + Standard_Real aTol = BRep_Tool::Tolerance (aFace); + aBB.UpdateFace (aFace, anInputSurf, anInputLoc, aTol); + } +} + +gp_Pnt GetMidPnt2d(const TopoDS_Face& theFace, + const Standard_Boolean theIsNaturalRestrictions) +{ + gp_Pnt aResPnt; + + if (theIsNaturalRestrictions) + { + BRepAdaptor_Surface aBAsurf (theFace); + Standard_Real aUmin, aUmax, aVmin, aVmax; + aUmin = aBAsurf.FirstUParameter(); + aUmax = aBAsurf.LastUParameter(); + aVmin = aBAsurf.FirstVParameter(); + aVmax = aBAsurf.LastVParameter(); + aResPnt = aBAsurf.Value ((aUmin + aUmax)/2, (aVmin + aVmax)/2); + } + else + { + const Standard_Integer aNbSamples = 4; + TopoDS_Wire aWire = BRepTools::OuterWire (theFace); + TopTools_IndexedMapOfShape aEmap; + TopExp::MapShapes (aWire, TopAbs_EDGE, aEmap); + Standard_Integer aNbPointsOnContour = aNbSamples * aEmap.Extent(); + TColgp_Array1OfPnt anArray (1, aNbPointsOnContour); + + BRepTools_WireExplorer aWexp (aWire, theFace); + Standard_Integer anInd = 0; + for (; aWexp.More(); aWexp.Next()) + { + const TopoDS_Edge& anEdge = aWexp.Current(); + BRepAdaptor_Curve2d aBAcurve2d (anEdge, theFace); + Standard_Real aDelta = (aBAcurve2d.LastParameter() - aBAcurve2d.FirstParameter())/aNbSamples; + for (Standard_Integer ii = 0; ii < aNbSamples; ii++) + { + Standard_Real aParam = aBAcurve2d.FirstParameter() + ii * aDelta; + gp_Pnt2d aP2d = aBAcurve2d.Value (aParam); + gp_Pnt aPnt (aP2d.X(), aP2d.Y(), 0.); + anArray (++anInd) = aPnt; + } + } + + gp_Ax2 anAxis; + Standard_Boolean anIsSingular; + GeomLib::AxeOfInertia (anArray, anAxis, anIsSingular); + gp_Pnt aBaryCentre = anAxis.Location(); + gp_Pnt2d aCentre2d (aBaryCentre.X(), aBaryCentre.Y()); + BRepTopAdaptor_FClass2d aClassifier (theFace, Precision::Confusion()); + BRepAdaptor_Surface aBAsurf (theFace, Standard_False); + + TopAbs_State aStatus = aClassifier.Perform (aCentre2d); + gp_Pnt2d aP2d = aCentre2d; + Standard_Integer anIndVertex = 0; + const Standard_Integer aNbIter = 10; + while (aStatus != TopAbs_IN && anIndVertex < aNbPointsOnContour) + { + gp_Pnt aVertexPnt = anArray (anIndVertex+1); + gp_Pnt2d aVertexP2d (aVertexPnt.X(), aVertexPnt.Y()); + TColgp_SequenceOfPnt2d aPseq; + aPseq.Append (aCentre2d); + aPseq.Append (aVertexP2d); + for (Standard_Integer ii = 1; ii <= aNbIter; ii++) + { + for (Standard_Integer jj = 1; jj < aPseq.Length(); jj++) + { + aP2d.SetXY ((aPseq(jj).XY() + aPseq(jj+1).XY())/2); + aStatus = aClassifier.Perform (aP2d); + if (aStatus == TopAbs_IN) + break; + else + { + aPseq.InsertAfter (jj, aP2d); + jj++; + } + } + if (aStatus == TopAbs_IN) + break; + } + anIndVertex += aNbSamples; + } + aResPnt = aBAsurf.Value (aP2d.X(), aP2d.Y()); + } //case of complex boundaries + + return aResPnt; +} + +void ModifyFacesForGlobalResult(const TopoDS_Face& theInputFace, + const Standard_Real theAverageArea, + const Standard_Boolean theIsToAddFaces, + Standard_Integer& theNbExtremalFaces, + TopTools_MapOfShape& theExtremalFaces, + const std::vector> theFacesAndAreas, + const TopTools_DataMapOfShapeReal& theFaceAreaMap, + const TopTools_IndexedDataMapOfShapeListOfShape& theEFmap, + TopoDS_Shape& theRes, + TopoDS_Shape& theGlobalRes, + TopTools_MapOfShape& theRemovedFaces) +{ + BRep_Builder aBB; + const Standard_Integer aNbFaces = (Standard_Integer) theFacesAndAreas.size(); + + const Standard_Integer aDiff = theNbExtremalFaces - theRemovedFaces.Extent(); + + Standard_Integer aSum = 0; + while (aSum < aDiff) //global loop + { + Standard_Integer aNbFacesDone = 0, aNbFacesInTape = 0; + TopoDS_Face aStartFace; + + Standard_Integer aStartIndex = (theIsToAddFaces)? aNbFaces-1 : 0; + Standard_Integer anEndIndex = (theIsToAddFaces)? 0 : aNbFaces-1; + Standard_Integer aStep = (theIsToAddFaces)? -1 : 1; + + for (Standard_Integer ii = aStartIndex; ii != anEndIndex; ii += aStep) + { + const TopoDS_Face& aFace = TopoDS::Face (theFacesAndAreas[ii].first); + if (!theRemovedFaces.Contains(aFace)) + { + aStartFace = aFace; + break; + } + } + if (aStartFace.IsNull()) + break; + + theRemovedFaces.Add (aStartFace); + + TopoDS_Edge aCommonEdge; + TopoDS_Face aNextFace; + Standard_Real anExtremalArea = (theIsToAddFaces)? 0. : Precision::Infinite(); + for (TopExp_Explorer anExplo(aStartFace, TopAbs_EDGE); anExplo.More(); anExplo.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current()); + const TopTools_ListOfShape& aFaceList = theEFmap.FindFromKey (anEdge); + TopTools_ListIteratorOfListOfShape anItl (aFaceList); + for (; anItl.More(); anItl.Next()) + { + const TopoDS_Face& aFace = TopoDS::Face (anItl.Value()); + if (aFace.IsSame (aStartFace) || + theRemovedFaces.Contains(aFace)) + continue; + Standard_Real anArea = theFaceAreaMap(aFace); + Standard_Boolean anIsToExchange = (theIsToAddFaces)? (anArea > anExtremalArea) : (anArea < anExtremalArea); + if (anIsToExchange) + { + anExtremalArea = anArea; + aCommonEdge = anEdge; + aNextFace = aFace; + } + } + } + if (aCommonEdge.IsNull()) //all adjacent faces are already removed + { + theExtremalFaces.Add (theFacesAndAreas[theNbExtremalFaces].first); + theNbExtremalFaces++; + continue; + } + + //Start filling the shell + aBB.Remove (theRes, aStartFace); + aNbFacesDone++; + TopoDS_Shell aShell; + aBB.MakeShell (aShell); + Standard_Real anAreaOfTape = 0.; + aBB.Add (aShell, aStartFace); + aNbFacesInTape++; + anAreaOfTape += theFaceAreaMap (aStartFace); + + Standard_Boolean anIsUiso = IsUiso (aCommonEdge, aStartFace); + //Find another faces on this level + TopoDS_Face aCurrentFace = aNextFace; + TopoDS_Edge aCurrentEdge = aCommonEdge; + Standard_Boolean anIsFirstDirection = Standard_True; + aBB.Remove (theRes, aCurrentFace); + theRemovedFaces.Add (aCurrentFace); + if (theExtremalFaces.Contains (aCurrentFace)) + { + aNbFacesDone++; + } + aBB.Add (aShell, aCurrentFace); + aNbFacesInTape++; + anAreaOfTape += theFaceAreaMap (aCurrentFace); + Standard_Boolean anIsRound = Standard_False; + for (;;) //local loop + { + TopoDS_Edge aNextEdge; + for (TopExp_Explorer anExplo(aCurrentFace, TopAbs_EDGE); anExplo.More(); anExplo.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current()); + if (anEdge.IsSame (aCurrentEdge)) + continue; + const TopTools_ListOfShape& aFaceList = theEFmap.FindFromKey (anEdge); + TopTools_ListIteratorOfListOfShape anItl (aFaceList); + for (; anItl.More(); anItl.Next()) + { + const TopoDS_Face& aFace = TopoDS::Face (anItl.Value()); + if (aFace.IsSame (aCurrentFace)) + continue; + if (aFace.IsSame (aStartFace)) + { + anIsRound = Standard_True; + break; + } + if (theRemovedFaces.Contains(aFace)) + continue; + if (anIsUiso == IsUiso (anEdge, aFace)) + { + aNextEdge = anEdge; + aNextFace = aFace; + break; + } + } + if (anIsRound || !aNextEdge.IsNull()) + break; + } + if (anIsRound) //round tape: returned to start face + break; + if (aNextEdge.IsNull()) + { + if (anIsFirstDirection) + { + aCurrentFace = aStartFace; + aCurrentEdge = aCommonEdge; + anIsFirstDirection = Standard_False; + continue; + } + else + break; + } + + aBB.Add (aShell, aNextFace); + aNbFacesInTape++; + anAreaOfTape += theFaceAreaMap (aNextFace); + aBB.Remove (theRes, aNextFace); + theRemovedFaces.Add (aNextFace); + if (theExtremalFaces.Contains (aNextFace)) + { + aNbFacesDone++; + } + aCurrentEdge = aNextEdge; + aNextEdge.Nullify(); + aCurrentFace = aNextFace; + } //end of local loop + + //Tape is formed + Standard_Integer aNumberToSplit = (theIsToAddFaces)? aNbFacesInTape + aNbFacesDone : aNbFacesInTape - aNbFacesDone; + if (!theIsToAddFaces && aNbFacesDone > 1) + { + Standard_Integer aRealNumberToSplit = (aNumberToSplit > 0)? aNumberToSplit : 1; + Standard_Real anAverageAreaInTape = anAreaOfTape / aRealNumberToSplit; + if (anAverageAreaInTape > theAverageArea) + { + Standard_Integer aNewNumberToSplit = RealToInt(round(anAreaOfTape / theAverageArea)); + if (aNewNumberToSplit < aNbFacesInTape) + { + Standard_Integer aNumberToIncrease = aNewNumberToSplit - aNumberToSplit; + for (Standard_Integer jj = theNbExtremalFaces; jj < theNbExtremalFaces + aNumberToIncrease; jj++) + theExtremalFaces.Add (theFacesAndAreas[jj].first); + theNbExtremalFaces += aNumberToIncrease; + aNumberToSplit = aNewNumberToSplit; + } + } + } + if (anIsRound && aNumberToSplit <= 1) + { + Standard_Integer aNumberToIncrease = 3 - aNumberToSplit; + for (Standard_Integer jj = theNbExtremalFaces; jj < theNbExtremalFaces + aNumberToIncrease; jj++) + theExtremalFaces.Add (theFacesAndAreas[jj].first); + theNbExtremalFaces += aNumberToIncrease; + aNumberToSplit = 3; + } + CorrectShell (aShell, theInputFace); + ShapeUpgrade_UnifySameDomain aUnifier; + aUnifier.Initialize (aShell, Standard_True, Standard_True); + aUnifier.Build(); + TopoDS_Shape aUnifiedShape = aUnifier.Shape(); + //Splitting + TopoDS_Shape aLocalResult = aUnifiedShape; + Standard_Integer aNbFacesInLocalResult; + if (aNumberToSplit > 1) + { +#if OCC_VERSION_LARGE < 0x07050304 + aNbFacesInLocalResult = 0; +#else + ShapeUpgrade_ShapeDivideArea aLocalTool (aUnifiedShape); + aLocalTool.SetSplittingByNumber (Standard_True); + aLocalTool.MaxArea() = -1; + if (anIsUiso) + aLocalTool.SetNumbersUVSplits (aNumberToSplit, 1); + else + aLocalTool.SetNumbersUVSplits (1, aNumberToSplit); + aLocalTool.Perform(); + aLocalResult = aLocalTool.Result(); + aNbFacesInLocalResult = aNumberToSplit; +#endif + } + else + { + aNbFacesInLocalResult = 1; + if (aNumberToSplit == 0) + { + theExtremalFaces.Add (theFacesAndAreas[theNbExtremalFaces].first); + theNbExtremalFaces++; + } + } + aBB.Add (theGlobalRes, aLocalResult); + + aSum += Abs(aNbFacesInTape - aNbFacesInLocalResult); + } //end of global loop + + //Second global loop + TopoDS_Compound aSecondComp; + aBB.MakeCompound (aSecondComp); + while (aSum < aDiff) + { + TopoDS_Shape aMaxShell; + Standard_Integer aMaxNbFaces = 0; + TopoDS_Iterator anIter (theGlobalRes); + for (; anIter.More(); anIter.Next()) + { + const TopoDS_Shape& aShell = anIter.Value(); + TopTools_IndexedMapOfShape aFaceMap; + TopExp::MapShapes (aShell, TopAbs_FACE, aFaceMap); + if (aFaceMap.Extent() > aMaxNbFaces) + { + aMaxNbFaces = aFaceMap.Extent(); + aMaxShell = aShell; + } + } + + if (aMaxNbFaces == 1) + break; + + aBB.Remove (theGlobalRes, aMaxShell); + //Find iso + Standard_Boolean anIsUiso = Standard_True; + TopTools_IndexedDataMapOfShapeListOfShape aLocalEFmap; + TopExp::MapShapesAndAncestors (aMaxShell, TopAbs_EDGE, TopAbs_FACE, aLocalEFmap); + for (Standard_Integer jj = 1; jj <= aLocalEFmap.Extent(); jj++) + { + const TopoDS_Edge& anEdge = TopoDS::Edge (aLocalEFmap.FindKey(jj)); + const TopTools_ListOfShape& aFaceList = aLocalEFmap(jj); + if (aFaceList.Extent() == 2) + { + const TopoDS_Face& aFace = TopoDS::Face (aFaceList.First()); + anIsUiso = IsUiso (anEdge, aFace); + break; + } + } + CorrectShell (aMaxShell, theInputFace); + ShapeUpgrade_UnifySameDomain aUnifier; + aUnifier.Initialize (aMaxShell, Standard_True, Standard_True); + aUnifier.Build(); + TopoDS_Shape aUnifiedShape = aUnifier.Shape(); + TopoDS_Shape aLocalResult = aUnifiedShape; + + Standard_Integer aNumberToSplit = (theIsToAddFaces)? aMaxNbFaces + (aDiff-aSum) : aMaxNbFaces - (aDiff-aSum); + if (aNumberToSplit > 1) + { +#if OCC_VERSION_LARGE < 0x07050304 + aNumberToSplit = 1; +#else + ShapeUpgrade_ShapeDivideArea aLocalTool (aUnifiedShape); + aLocalTool.SetSplittingByNumber (Standard_True); + aLocalTool.MaxArea() = -1; + if (anIsUiso) + aLocalTool.SetNumbersUVSplits (aNumberToSplit, 1); + else + aLocalTool.SetNumbersUVSplits (1, aNumberToSplit); + aLocalTool.Perform(); + aLocalResult = aLocalTool.Result(); +#endif + } + else + aNumberToSplit = 1; + + aBB.Add (aSecondComp, aLocalResult); + + if (theIsToAddFaces) + break; + aSum += aMaxNbFaces - aNumberToSplit; + } + aBB.Add (theGlobalRes, aSecondComp); +} diff --git a/src/GeomAlgoImpl/GEOMAlgo_AlgoTools.hxx b/src/GeomAlgoImpl/GEOMAlgo_AlgoTools.hxx new file mode 100644 index 000000000..a08f5a167 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_AlgoTools.hxx @@ -0,0 +1,213 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// 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 +#include +#include + + +//! Auxiliary tools for Algorithms
+//======================================================================= +//class : GEOMAlgo_AlgoTools +//purpose : +//======================================================================= +class GEOMAlgo_AlgoTools { + public: + + GEOMALGOIMPL_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.
+ GEOMALGOIMPL_EXPORT + static Standard_Integer PntInFace(const TopoDS_Face& theF, + gp_Pnt& theP, + gp_Pnt2d& theP2D); + + //! Computes a set of points inside the face .
+ //! Returns 0 in case of success.
+ GEOMALGOIMPL_EXPORT + static Standard_Integer PointCloudInFace(const TopoDS_Face& theF, + const int theNbPnts, + TopoDS_Compound& theCompound); + + GEOMALGOIMPL_EXPORT + static Standard_Boolean IsCompositeShape(const TopoDS_Shape& aS); + + + GEOMALGOIMPL_EXPORT + static Standard_Boolean BuildTriangulation(const TopoDS_Shape& aS); + + GEOMALGOIMPL_EXPORT + static Standard_Integer RefineSDShapes(GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape& aMSD, + const Standard_Real aTol, + const Handle(IntTools_Context)& aCtx); + + GEOMALGOIMPL_EXPORT + static Standard_Integer FindSDShapes(const TopTools_ListOfShape& aLE, + const Standard_Real aTol, + TopTools_IndexedDataMapOfShapeListOfShape& aMEE, + const Handle(IntTools_Context)& aCtx); + + GEOMALGOIMPL_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); + + GEOMALGOIMPL_EXPORT + static void PointOnShape(const TopoDS_Shape& aS, + gp_Pnt& aP3D); + + GEOMALGOIMPL_EXPORT + static void PointOnEdge(const TopoDS_Edge& aE, + gp_Pnt& aP3D); + + GEOMALGOIMPL_EXPORT + static void PointOnEdge(const TopoDS_Edge& aE, + const Standard_Real aT,gp_Pnt& aP3D); + + GEOMALGOIMPL_EXPORT + static void PointOnFace(const TopoDS_Face& aF, + gp_Pnt& aP3D); + + GEOMALGOIMPL_EXPORT + static void PointOnFace(const TopoDS_Face& aF, + const Standard_Real aU, + const Standard_Real aV, + gp_Pnt& aP3D); + + GEOMALGOIMPL_EXPORT + static Standard_Boolean ProjectPointOnShape(const gp_Pnt& aP1, + const TopoDS_Shape& aS, + gp_Pnt& aP2, + const Handle(IntTools_Context)& aCtx); + + GEOMALGOIMPL_EXPORT + static void CorrectTolerances(const TopoDS_Shape& aShape, + const Standard_Real aMaxTol=0.0001); + + GEOMALGOIMPL_EXPORT + static void CorrectPointOnCurve(const TopoDS_Shape& S, + const Standard_Real aMaxTol=0.0001); + + GEOMALGOIMPL_EXPORT + static void CorrectCurveOnSurface(const TopoDS_Shape& S, + const Standard_Real aMaxTol=0.0001); + + + GEOMALGOIMPL_EXPORT + static Standard_Boolean IsSplitToReverse1(const TopoDS_Edge& aEF1, + const TopoDS_Edge& aEF2, + const Handle(IntTools_Context)& aCtx); + + GEOMALGOIMPL_EXPORT + static void RefinePCurveForEdgeOnFace(const TopoDS_Edge& aE, + const TopoDS_Face& aF, + const Standard_Real aUMin, + const Standard_Real aUMax); + + GEOMALGOIMPL_EXPORT + static Standard_Boolean IsUPeriodic(const Handle(Geom_Surface) &aS); + + GEOMALGOIMPL_EXPORT + static void MakeContainer(const TopAbs_ShapeEnum theType, + TopoDS_Shape& theC); + + GEOMALGOIMPL_EXPORT + static Standard_Boolean IsSplitToReverse(const TopoDS_Edge& theSplit, + const TopoDS_Edge& theEdge, + const Handle(IntTools_Context)& theCtx); + + GEOMALGOIMPL_EXPORT + static Standard_Boolean IsSplitToReverse(const TopoDS_Face& theFSp, + const TopoDS_Face& theFSr, + const Handle(IntTools_Context)& theCtx); + + GEOMALGOIMPL_EXPORT + static Standard_Boolean IsSplitToReverse(const TopoDS_Shape& theSp, + const TopoDS_Shape& theSr, + const Handle(IntTools_Context)& theCtx); + + GEOMALGOIMPL_EXPORT + static Standard_Integer BuildPCurveForEdgeOnFace(const TopoDS_Edge& aEold, + const TopoDS_Edge& aEnew, + const TopoDS_Face& aF, + const Handle(IntTools_Context)& aCtx); + +// + GEOMALGOIMPL_EXPORT + static void FindChains(const GEOMAlgo_ListOfCoupleOfShapes& aLCS, + GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape& aMapChains); + + GEOMALGOIMPL_EXPORT + static void FindChains(const GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape& aMCV, + GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape& aMapChains); + + GEOMALGOIMPL_EXPORT + static void CopyShape(const TopoDS_Shape& aS, + TopoDS_Shape& aSC); + + GEOMALGOIMPL_EXPORT + static void CopyShape(const TopoDS_Shape& aS, + TopoDS_Shape& aSC, + TopTools_IndexedDataMapOfShapeShape& aMSS); +}; + +#endif diff --git a/src/GeomAlgoImpl/GEOMAlgo_AlgoTools_1.cxx b/src/GeomAlgoImpl/GEOMAlgo_AlgoTools_1.cxx new file mode 100644 index 000000000..7cee3955a --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_AlgoTools_1.cxx @@ -0,0 +1,141 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : GEOMAlgo_AlgoTools_2.cxx +// Created : +// Author : Peter KURNEV + +#include + +#include +#include +#include +#include +#include +#include + + + +static + void ProcessBlock(const TopoDS_Shape& aF, + const GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape& aMCV, + TopTools_IndexedMapOfShape& aProcessed, + TopTools_IndexedMapOfShape& aChain); + +//======================================================================= +// function: FindChains +// purpose : +//======================================================================= +void GEOMAlgo_AlgoTools::FindChains(const GEOMAlgo_ListOfCoupleOfShapes& aLCS, + GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape& aMapChains) +{ + GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS; + GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape aMCV; + // + aItCS.Initialize(aLCS); + for (; aItCS.More(); aItCS.Next()) { + const GEOMAlgo_CoupleOfShapes& aCS=aItCS.Value(); + // + const TopoDS_Shape& aF1=aCS.Shape1(); + const TopoDS_Shape& aF2=aCS.Shape2(); + // + // + if (aMCV.Contains(aF1)) { + TopTools_IndexedMapOfShape& aMV=aMCV.ChangeFromKey(aF1); + aMV.Add(aF1); + aMV.Add(aF2); + } + else { + TopTools_IndexedMapOfShape aMV; + aMV.Add(aF1); + aMV.Add(aF2); + aMCV.Add(aF1, aMV); + } + // + if (aMCV.Contains(aF2)) { + TopTools_IndexedMapOfShape& aMV=aMCV.ChangeFromKey(aF2); + aMV.Add(aF1); + aMV.Add(aF2); + } + else { + TopTools_IndexedMapOfShape aMV; + aMV.Add(aF1); + aMV.Add(aF2); + aMCV.Add(aF2, aMV); + } + } + GEOMAlgo_AlgoTools::FindChains(aMCV, aMapChains); +} +//======================================================================= +// function: FindChains +// purpose : +//======================================================================= +void GEOMAlgo_AlgoTools::FindChains(const GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape& aMCV, + GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape& aMapChains) +{ + Standard_Integer i, j, aNbCV, aNbV; + TopTools_IndexedMapOfShape aProcessed, aChain; + // + aNbCV=aMCV.Extent(); + for (i=1; i<=aNbCV; ++i) { + const TopoDS_Shape& aF=aMCV.FindKey(i); + if (aProcessed.Contains(aF)) { + continue; + } + // + aProcessed.Add(aF); + aChain.Add(aF); + // + const TopTools_IndexedMapOfShape& aMV=aMCV(i); + aNbV=aMV.Extent(); + for (j=1; j<=aNbV; ++j) { + const TopoDS_Shape& aFx=aMV(j); + ProcessBlock(aFx, aMCV, aProcessed, aChain); + } + aMapChains.Add(aF, aChain); + aChain.Clear(); + } +} +//======================================================================= +// function: ProcessBlock +// purpose: +//======================================================================= +void ProcessBlock(const TopoDS_Shape& aF, + const GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape& aMCV, + TopTools_IndexedMapOfShape& aProcessed, + TopTools_IndexedMapOfShape& aChain) +{ + Standard_Integer j, aNbV; + // + if (aProcessed.Contains(aF)) { + return; + } + aProcessed.Add(aF); + aChain.Add(aF); + // + const TopTools_IndexedMapOfShape& aMV=aMCV.FindFromKey(aF); + aNbV=aMV.Extent(); + for (j=1; j<=aNbV; ++j) { + const TopoDS_Shape& aFx=aMV(j); + ProcessBlock(aFx, aMCV, aProcessed, aChain); + } +} + diff --git a/src/GeomAlgoImpl/GEOMAlgo_BndSphere.cxx b/src/GeomAlgoImpl/GEOMAlgo_BndSphere.cxx new file mode 100644 index 000000000..7b8080a01 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_BndSphere.cxx @@ -0,0 +1,57 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: 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/GeomAlgoImpl/GEOMAlgo_BndSphere.hxx b/src/GeomAlgoImpl/GEOMAlgo_BndSphere.hxx new file mode 100644 index 000000000..f016ea297 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_BndSphere.hxx @@ -0,0 +1,76 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: GEOMAlgo_BndSphere.hxx +// Created: +// Author: Peter KURNEV +// + +#ifndef _GEOMAlgo_BndSphere_HeaderFile +#define _GEOMAlgo_BndSphere_HeaderFile + +#include + +#include +#include +#include +#include +#include + + +//======================================================================= +//class : GEOMAlgo_BndSphere +//purpose : +//======================================================================= +class GEOMAlgo_BndSphere { + public: + GEOMALGOIMPL_EXPORT + GEOMAlgo_BndSphere(); + + GEOMALGOIMPL_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); + + GEOMALGOIMPL_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/GeomAlgoImpl/GEOMAlgo_BndSphere.lxx b/src/GeomAlgoImpl/GEOMAlgo_BndSphere.lxx new file mode 100644 index 000000000..56efce47e --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_BndSphere.lxx @@ -0,0 +1,108 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: 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/GeomAlgoImpl/GEOMAlgo_BndSphereTree.cxx b/src/GeomAlgoImpl/GEOMAlgo_BndSphereTree.cxx new file mode 100644 index 000000000..7d19556e0 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_BndSphereTree.cxx @@ -0,0 +1,89 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: 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/GeomAlgoImpl/GEOMAlgo_BndSphereTree.hxx b/src/GeomAlgoImpl/GEOMAlgo_BndSphereTree.hxx new file mode 100644 index 000000000..8be47ad09 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_BndSphereTree.hxx @@ -0,0 +1,56 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: GEOMAlgo_BndSphereTree.hxx +// Created: +// Author: Peter KURNEV +// +// +#ifndef GEOMAlgo_BndSphereTree_HeaderFile +#define GEOMAlgo_BndSphereTree_HeaderFile + +#include + +#include +#include +#include +#include + + +typedef NCollection_UBTree GEOMAlgo_BndSphereTree; + +class GEOMAlgo_BndSphereTreeSelector : public GEOMAlgo_BndSphereTree::Selector +{ +public: + GEOMALGOIMPL_EXPORT GEOMAlgo_BndSphereTreeSelector(); + GEOMALGOIMPL_EXPORT virtual Standard_Boolean Reject(const GEOMAlgo_BndSphere&) const; + GEOMALGOIMPL_EXPORT virtual Standard_Boolean Accept(const Standard_Integer &); + GEOMALGOIMPL_EXPORT virtual ~GEOMAlgo_BndSphereTreeSelector(); + + GEOMALGOIMPL_EXPORT void Clear(); + GEOMALGOIMPL_EXPORT void SetBox(const GEOMAlgo_BndSphere&); + GEOMALGOIMPL_EXPORT const TColStd_ListOfInteger& Indices() const; + +protected: + GEOMAlgo_BndSphere myBox; + TColStd_MapOfInteger myFence; + TColStd_ListOfInteger myIndices; +}; + +#endif diff --git a/src/GeomAlgoImpl/GEOMAlgo_BuilderShape.cxx b/src/GeomAlgoImpl/GEOMAlgo_BuilderShape.cxx new file mode 100644 index 000000000..f59fa82ce --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_BuilderShape.cxx @@ -0,0 +1,130 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: GEOMAlgo_BuilderShape.cxx +// Created: +// Author: Peter KURNEV +// +#include + +//======================================================================= +//function : +//purpose : +//======================================================================= + GEOMAlgo_BuilderShape::GEOMAlgo_BuilderShape() +: + GEOMAlgo_Algo() +{ + myHasDeleted=Standard_False; + myHasGenerated=Standard_False; + myHasModified=Standard_False; +} +//======================================================================= +//function : ~ +//purpose : +//======================================================================= + GEOMAlgo_BuilderShape::~GEOMAlgo_BuilderShape() +{ +} +//======================================================================= +//function : Shape +//purpose : +//======================================================================= + const TopoDS_Shape& GEOMAlgo_BuilderShape::Shape() const +{ + return myShape; +} +// +//======================================================================= +//function : Generated +//purpose : +//======================================================================= + const TopTools_ListOfShape& GEOMAlgo_BuilderShape::Generated(const TopoDS_Shape& ) +{ + myHistShapes.Clear(); + return myHistShapes; +} +//======================================================================= +//function : Modified +//purpose : +//======================================================================= + const TopTools_ListOfShape& GEOMAlgo_BuilderShape::Modified(const TopoDS_Shape& ) +{ + myHistShapes.Clear(); + return myHistShapes; +} +//======================================================================= +//function : IsDeleted +//purpose : +//======================================================================= + Standard_Boolean GEOMAlgo_BuilderShape::IsDeleted(const TopoDS_Shape& theS) +{ + Standard_Boolean bRet; + // + bRet=!myMapShape.Contains(theS); + return bRet; +} +//======================================================================= +//function : HasDeleted +//purpose : +//======================================================================= + Standard_Boolean GEOMAlgo_BuilderShape::HasDeleted()const +{ + return myHasDeleted; +} +//======================================================================= +//function : HasGenerated +//purpose : +//======================================================================= + Standard_Boolean GEOMAlgo_BuilderShape::HasGenerated()const +{ + return myHasGenerated; +} +//======================================================================= +//function : HasModified +//purpose : +//======================================================================= + Standard_Boolean GEOMAlgo_BuilderShape::HasModified()const +{ + return myHasModified; +} +//======================================================================= +//function : PrepareHistory +//purpose : +//======================================================================= + void GEOMAlgo_BuilderShape::PrepareHistory() +{ + myHistShapes.Clear(); + myMapShape.Clear(); + myHasDeleted=Standard_False; + myHasGenerated=Standard_False; + myHasModified=Standard_False; + myImagesResult.Clear(); +} +//======================================================================= +//function : ImagesResult +//purpose : +//======================================================================= + const TopTools_IndexedDataMapOfShapeListOfShape& GEOMAlgo_BuilderShape::ImagesResult()const +{ + return myImagesResult; +} diff --git a/src/GeomAlgoImpl/GEOMAlgo_BuilderShape.hxx b/src/GeomAlgoImpl/GEOMAlgo_BuilderShape.hxx new file mode 100644 index 000000000..2642abec6 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_BuilderShape.hxx @@ -0,0 +1,111 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: GEOMAlgo_BuilderShape.hxx +// Created: +// Author: Peter KURNEV +// +#ifndef _GEOMAlgo_BuilderShape_HeaderFile +#define _GEOMAlgo_BuilderShape_HeaderFile + +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include + + +//! Root class for algorithms that has shape as result
+//======================================================================= +//class : GEOMAlgo_BuilderShape +//purpose : +//======================================================================= +class GEOMAlgo_BuilderShape : public GEOMAlgo_Algo +{ + public: + //! Returns the result of algorithm
+ GEOMALGOIMPL_EXPORT + const TopoDS_Shape& Shape() const; + + //! Returns the list of shapes generated from the
+ //! shape theS.
+ GEOMALGOIMPL_EXPORT + virtual const TopTools_ListOfShape& Generated(const TopoDS_Shape& theS) ; + + //! Returns the list of shapes modified from the
+ //! shape theS.
+ GEOMALGOIMPL_EXPORT + virtual const TopTools_ListOfShape& Modified(const TopoDS_Shape& theS) ; + + //! Returns true if the shape theS has been deleted.
+ GEOMALGOIMPL_EXPORT + virtual Standard_Boolean IsDeleted(const TopoDS_Shape& theS) ; + + //! Returns true if the at least one shape(or sub-shape)
+ //! of arguments has been deleted.
+ GEOMALGOIMPL_EXPORT + Standard_Boolean HasDeleted() const; + + //! Returns true if the at least one shape(or sub-shape)
+ //! of arguments has generated shapes.
+ GEOMALGOIMPL_EXPORT + Standard_Boolean HasGenerated() const; + + //! Returns true if the at least one shape(or sub-shape)
+ //! of arguments has modified shapes.
+ GEOMALGOIMPL_EXPORT + Standard_Boolean HasModified() const; + + GEOMALGOIMPL_EXPORT + const TopTools_IndexedDataMapOfShapeListOfShape& ImagesResult() const; + +protected: + //! Empty constructor
+ GEOMALGOIMPL_EXPORT + GEOMAlgo_BuilderShape(); + + GEOMALGOIMPL_EXPORT + virtual ~GEOMAlgo_BuilderShape(); + + //! Prepare information for history support
+ GEOMALGOIMPL_EXPORT + virtual void PrepareHistory() ; + + + TopoDS_Shape myShape; + TopTools_ListOfShape myHistShapes; + TopTools_MapOfShape myMapShape; + Standard_Boolean myHasDeleted; + Standard_Boolean myHasGenerated; + Standard_Boolean myHasModified; + TopTools_IndexedDataMapOfShapeListOfShape myImagesResult; +}; + +#endif diff --git a/src/GeomAlgoImpl/GEOMAlgo_CoupleOfShapes.cxx b/src/GeomAlgoImpl/GEOMAlgo_CoupleOfShapes.cxx new file mode 100644 index 000000000..60c099a59 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_CoupleOfShapes.cxx @@ -0,0 +1,85 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// 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/GeomAlgoImpl/GEOMAlgo_CoupleOfShapes.hxx b/src/GeomAlgoImpl/GEOMAlgo_CoupleOfShapes.hxx new file mode 100644 index 000000000..95a071e61 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_CoupleOfShapes.hxx @@ -0,0 +1,68 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File: 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 +#include + + +//======================================================================= +//class : GEOMAlgo_CoupleOfShapes +//purpose : +//======================================================================= +class GEOMAlgo_CoupleOfShapes +{ + public: + GEOMALGOIMPL_EXPORT + GEOMAlgo_CoupleOfShapes(); + + GEOMALGOIMPL_EXPORT + void SetShapes(const TopoDS_Shape& aS1,const TopoDS_Shape& aS2) ; + + GEOMALGOIMPL_EXPORT + void SetShape1(const TopoDS_Shape& aS1) ; + + GEOMALGOIMPL_EXPORT + void SetShape2(const TopoDS_Shape& aS2) ; + + GEOMALGOIMPL_EXPORT + void Shapes(TopoDS_Shape& aS1,TopoDS_Shape& aS2) const; + + GEOMALGOIMPL_EXPORT + const TopoDS_Shape& Shape1() const; + + GEOMALGOIMPL_EXPORT + const TopoDS_Shape& Shape2() const; + +protected: + TopoDS_Shape myShape1; + TopoDS_Shape myShape2; +}; + +#endif diff --git a/src/GeomAlgoImpl/GEOMAlgo_GlueDetector.cxx b/src/GeomAlgoImpl/GEOMAlgo_GlueDetector.cxx new file mode 100644 index 000000000..293df4733 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_GlueDetector.cxx @@ -0,0 +1,610 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: GEOMAlgo_GlueDetector.cxx +// 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 + + +// +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 : +//======================================================================= +GEOMAlgo_GlueDetector::GEOMAlgo_GlueDetector() +: + GEOMAlgo_GluerAlgo(), + GEOMAlgo_Algo() +{} + +//======================================================================= +//function : ~ +//purpose : +//======================================================================= +GEOMAlgo_GlueDetector::~GEOMAlgo_GlueDetector() +{} + +//======================================================================= +//function : StickedShapes +//purpose : +//======================================================================= +const TopTools_IndexedDataMapOfShapeListOfShape& + GEOMAlgo_GlueDetector::StickedShapes() +{ + return myStickedShapes; +} + +//======================================================================= +//function : Perform +//purpose : +//======================================================================= +void GEOMAlgo_GlueDetector::Perform() +{ + myErrorStatus=0; + myWarningStatus=0; + myStickedShapes.Clear(); + // + CheckData(); + if (myErrorStatus) { + return; + } + // + // Initialize the context + GEOMAlgo_GluerAlgo::Perform(); + // + DetectVertices(); + if (myErrorStatus) { + return; + } + // + CheckDetected(); + if (myErrorStatus) { + return; + } + // + DetectEdges(); + if (myErrorStatus) { + return; + } + // + DetectFaces(); + if (myErrorStatus) { + return; + } +} + +//======================================================================= +//function : DetectVertices +//purpose : +//======================================================================= +void GEOMAlgo_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 GEOMAlgo_GlueDetector::DetectFaces() +{ + DetectShapes(TopAbs_FACE); +} + +//======================================================================= +//function : DetectEdges +//purpose : +//======================================================================= +void GEOMAlgo_GlueDetector::DetectEdges() +{ + DetectShapes(TopAbs_EDGE); +} + +//======================================================================= +//function : DetectShapes +//purpose : +//======================================================================= +void GEOMAlgo_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 GEOMAlgo_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 GEOMAlgo_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 GEOMAlgo_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 GEOMAlgo_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/GeomAlgoImpl/GEOMAlgo_GlueDetector.hxx b/src/GeomAlgoImpl/GEOMAlgo_GlueDetector.hxx new file mode 100644 index 000000000..1bfc6191f --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_GlueDetector.hxx @@ -0,0 +1,82 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: GEOMAlgo_GlueDetector.hxx +// Author: Peter KURNEV + +#ifndef _GEOMAlgo_GlueDetector_HeaderFile +#define _GEOMAlgo_GlueDetector_HeaderFile + +#include +#include + +#include + +#include +#include + +#include +#include +#include + + +//======================================================================= +//function : GEOMAlgo_GlueDetector +//purpose : +//======================================================================= +class GEOMAlgo_GlueDetector : public GEOMAlgo_GluerAlgo, + public GEOMAlgo_Algo +{ +public: + GEOMALGOIMPL_EXPORT GEOMAlgo_GlueDetector(); + + GEOMALGOIMPL_EXPORT virtual ~GEOMAlgo_GlueDetector(); + + GEOMALGOIMPL_EXPORT virtual void Perform() ; + + GEOMALGOIMPL_EXPORT const TopTools_IndexedDataMapOfShapeListOfShape& StickedShapes(); + +protected: + GEOMALGOIMPL_EXPORT void DetectVertices(); + GEOMALGOIMPL_EXPORT void DetectEdges(); + GEOMALGOIMPL_EXPORT void DetectFaces(); + + GEOMALGOIMPL_EXPORT void DetectShapes(const TopAbs_ShapeEnum aType); + + GEOMALGOIMPL_EXPORT void EdgePassKey(const TopoDS_Edge& aE, + GEOMAlgo_PassKeyShape& aPK); + + GEOMALGOIMPL_EXPORT void FacePassKey(const TopoDS_Face& aF, + GEOMAlgo_PassKeyShape& aPK); + + GEOMALGOIMPL_EXPORT void CheckDetected(); + // + GEOMALGOIMPL_EXPORT void CheckDetected(const TopTools_ListOfShape& aLVSD, + const TopTools_IndexedDataMapOfShapeListOfShape& aMVE, + const TopTools_IndexedDataMapOfShapeListOfShape& aMEV); + + + protected: + TopTools_IndexedDataMapOfShapeListOfShape myStickedShapes; +}; + +#endif diff --git a/src/GeomAlgoImpl/GEOMAlgo_Gluer2.cxx b/src/GeomAlgoImpl/GEOMAlgo_Gluer2.cxx new file mode 100644 index 000000000..3647a66eb --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_Gluer2.cxx @@ -0,0 +1,671 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: GEOMAlgo_Gluer2.cxx +// Author: Peter KURNEV + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + + +//======================================================================= +//function : GEOMAlgo_Gluer2 +//purpose : +//======================================================================= +GEOMAlgo_Gluer2::GEOMAlgo_Gluer2() + :GEOMAlgo_GluerAlgo() + ,GEOMAlgo_BuilderShape() +{ + myTolerance=0.0001; +} + +//======================================================================= +//function : ~GEOMAlgo_Gluer2 +//purpose : +//======================================================================= +GEOMAlgo_Gluer2::~GEOMAlgo_Gluer2() +{ +} + +//======================================================================= +//function : Clear +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::Clear() +{ + myErrorStatus=0; + myWarningStatus=0; + // + GEOMAlgo_GluerAlgo::Clear(); + // + myImagesDetected.Clear(); + myOriginsDetected.Clear(); + myShapesToGlue.Clear(); + myImagesToWork.Clear(); + myOriginsToWork.Clear(); + myKeepNonSolids=Standard_False; + myDetector.Clear(); +} + +//======================================================================= +//function : StickedShapes +//purpose : +//======================================================================= +const TopTools_IndexedDataMapOfShapeListOfShape& GEOMAlgo_Gluer2::StickedShapes() +{ + return myDetector.StickedShapes(); +} + +//======================================================================= +//function : SetShapesToGlue +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::SetShapesToGlue(const TopTools_DataMapOfShapeListOfShape& aM) +{ + myShapesToGlue=aM; +} + +//======================================================================= +//function : ShapesToGlue +//purpose : +//======================================================================= +const TopTools_DataMapOfShapeListOfShape& GEOMAlgo_Gluer2::ShapesToGlue() const +{ + return myShapesToGlue; +} + +//======================================================================= +//function : SetKeepNonSolids +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::SetKeepNonSolids(const Standard_Boolean aFlag) +{ + myKeepNonSolids=aFlag; +} + +//======================================================================= +//function : KeepNonSolids +//purpose : +//======================================================================= +Standard_Boolean GEOMAlgo_Gluer2::KeepNonSolids()const +{ + return myKeepNonSolids; +} + +//======================================================================= +//function : ShapesDetected +//purpose : +//======================================================================= +const TopTools_DataMapOfShapeListOfShape& GEOMAlgo_Gluer2::ShapesDetected() const +{ + return myImagesDetected; +} + +//======================================================================= +//function : ImagesToWork +//purpose : +//======================================================================= +const TopTools_DataMapOfShapeListOfShape& GEOMAlgo_Gluer2::ImagesToWork() const +{ + return myImagesToWork; +} + +//======================================================================= +//function : Perform +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::Perform() +{ + myErrorStatus=0; + myWarningStatus=0; + // + CheckData(); + if (myErrorStatus) { + return; + } + // + // Initialize the context + GEOMAlgo_GluerAlgo::Perform(); + // + PerformShapesToWork(); + if (myErrorStatus) { + return; + } + if (myWarningStatus==1) { + // no shapes to glue + myShape=myArgument; + return; + } + // + FillVertices(); + if (myErrorStatus) { + return; + } + // + FillEdges(); + if (myErrorStatus) { + return; + } + // + FillWires(); + if (myErrorStatus) { + return; + } + // + FillFaces(); + if (myErrorStatus) { + return; + } + // + FillShells(); + if (myErrorStatus) { + return; + } + // + FillSolids(); + if (myErrorStatus) { + return; + } + // + FillCompSolids(); + if (myErrorStatus) { + return; + } + // + FillCompounds(); + if (myErrorStatus) { + return; + } + // + BuildResult(); + if (myErrorStatus) { + return; + } + // + PrepareHistory(); + if (myErrorStatus) { + return; + } + // + BRepLib::SameParameter(myShape, myTolerance, Standard_True); +} + +//======================================================================= +//function : CheckData +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::CheckData() +{ + Standard_Integer aNbSG, i; + TopAbs_ShapeEnum aType, aTypeX; + TopTools_ListIteratorOfListOfShape aItLS; + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS; + // + myErrorStatus=0; + myWarningStatus=0; + // + aNbSG=myShapesToGlue.Extent(); + aType=TopAbs_SHAPE; + if (aNbSG) { + // Check myShapesToGlue + aItDMSLS.Initialize(myShapesToGlue); + for (; aItDMSLS.More(); aItDMSLS.Next()) { + const TopTools_ListOfShape& aLSG=aItDMSLS.Value(); + aItLS.Initialize(aLSG); + for (i=0; aItLS.More(); aItLS.Next(), ++i) { + const TopoDS_Shape& aSG=aItLS.Value(); + aTypeX=aSG.ShapeType(); + if (!i) { + aType=aTypeX; + if (!(aType==TopAbs_VERTEX || + aType==TopAbs_EDGE || + aType==TopAbs_FACE)) { + myErrorStatus=21;// non-brep shapes + return; + } + continue; + } + if (aTypeX!=aType) { + myErrorStatus=20;// non-homogeneous shapes + return; + } + } + } + }// if (aNbSG) { +} + +//======================================================================= +//function : FillEdges +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::FillEdges() +{ + FillBRepShapes(TopAbs_EDGE); +} + +//======================================================================= +//function : FillFaces +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::FillFaces() +{ + FillBRepShapes(TopAbs_FACE); +} + +//======================================================================= +//function : FillWires +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::FillWires() +{ + FillContainers(TopAbs_WIRE); +} + +//======================================================================= +//function : FillShells +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::FillShells() +{ + FillContainers(TopAbs_SHELL); +} + +//======================================================================= +//function : FillSolids +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::FillSolids() +{ + FillContainers(TopAbs_SOLID); +} + +//======================================================================= +//function : FillCompSolids +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::FillCompSolids() +{ + FillContainers(TopAbs_COMPSOLID); +} + +//======================================================================= +//function : FillVertices +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::FillVertices() +{ + TopAbs_ShapeEnum aType; + TopoDS_Vertex aVnew; + TopTools_ListIteratorOfListOfShape aItLS; + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS; + // + myErrorStatus=0; + myWarningStatus=0; + // + aItDMSLS.Initialize(myImagesToWork); + for (; aItDMSLS.More(); aItDMSLS.Next()) { + const TopoDS_Shape& aSkey=aItDMSLS.Key(); + aType=aSkey.ShapeType(); + if (aType!=TopAbs_VERTEX) { + continue; + } + // + const TopTools_ListOfShape& aLSD=aItDMSLS.Value(); + // + GEOMAlgo_Gluer2::MakeVertex(aLSD, aVnew); + // + myImages.Bind(aVnew, aLSD); + // + aItLS.Initialize(aLSD); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aV=aItLS.Value(); + myOrigins.Bind(aV, aVnew); + } + } +} + +//======================================================================= +//function : FillBRepShapes +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::FillBRepShapes(const TopAbs_ShapeEnum theType) +{ + Standard_Boolean bHasImage, bIsToWork; + Standard_Integer i, aNbE; + TopoDS_Iterator aItS; + TopoDS_Shape aEnew; + TopTools_IndexedMapOfShape aME; + TopTools_MapOfShape aMFence; + TopTools_ListIteratorOfListOfShape aItLS; + // + myErrorStatus=0; + myWarningStatus=0; + // + TopExp::MapShapes(myArgument, theType, aME); + // + aNbE=aME.Extent(); + for (i=1; i<=aNbE; ++i) { + const TopoDS_Shape& aE=aME(i); + // + if (!aMFence.Add(aE)) { + continue; + } + // + bIsToWork=myOriginsToWork.IsBound(aE); + bHasImage=HasImage(aE); + if (!bHasImage && !bIsToWork) { + continue; + } + // + MakeBRepShapes(aE, aEnew); + // + //myImages / myOrigins + if (bIsToWork) { + const TopoDS_Shape& aSkey=myOriginsToWork.Find(aE); + const TopTools_ListOfShape& aLSD=myImagesToWork.Find(aSkey); + // + myImages.Bind(aEnew, aLSD); + // + aItLS.Initialize(aLSD); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aEx=aItLS.Value(); + myOrigins.Bind(aEx, aEnew); + // + aMFence.Add(aEx); + } + } + else { + TopTools_ListOfShape aLSD; + // + aLSD.Append(aE); + myImages.Bind(aEnew, aLSD); + myOrigins.Bind(aE, aEnew); + } + }//for (i=1; i<=aNbF; ++i) { +} + +//======================================================================= +//function : FillContainers +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::FillContainers(const TopAbs_ShapeEnum aType) +{ + Standard_Boolean bHasImage, bToReverse; + Standard_Integer i, aNbW; + TopoDS_Shape aWnew, aEnew; + TopoDS_Iterator aItS; + BRep_Builder aBB; + TopTools_IndexedMapOfShape aMW; + TopTools_MapOfShape aMFence; + // + myErrorStatus=0; + myWarningStatus=0; + // + TopExp::MapShapes(myArgument, aType, aMW); + // + aNbW=aMW.Extent(); + for (i=1; i<=aNbW; ++i) { + const TopoDS_Shape& aW=aMW(i); + // + if (!aMFence.Add(aW)) { + continue; + } + // + bHasImage=HasImage(aW); + if (!bHasImage) { + continue; + } + // + GEOMAlgo_AlgoTools::MakeContainer(aType, aWnew); + aWnew.Orientation(aW.Orientation()); + // + aItS.Initialize(aW); + for (; aItS.More(); aItS.Next()) { + const TopoDS_Shape& aE=aItS.Value(); + if (myOrigins.IsBound(aE)) { + aEnew=myOrigins.Find(aE); + // + bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aEnew, aE, myContext); + if (bToReverse) { + aEnew.Reverse(); + } + // + aBB.Add(aWnew, aEnew); + } + else { + aBB.Add(aWnew, aE); + } + } + // + //myImages / myOrigins + TopTools_ListOfShape aLSD; + // + aLSD.Append(aW); + myImages.Bind(aWnew, aLSD); + myOrigins.Bind(aW, aWnew); + // + }//for (i=1; i<=aNbE; ++i) { +} + +//======================================================================= +//function : FillCompounds +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::FillCompounds() +{ + TopAbs_ShapeEnum aType; + TopoDS_Iterator aItC; + // + myErrorStatus=0; + myWarningStatus=0; + // + aItC.Initialize(myArgument); + for (; aItC.More(); aItC.Next()) { + const TopoDS_Shape& aCx=aItC.Value(); + aType=aCx.ShapeType(); + if (aType==TopAbs_COMPOUND) { + FillCompound(aCx); + } + } +} + +//======================================================================= +//function : FillCompound +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::FillCompound(const TopoDS_Shape& aC) +{ + Standard_Boolean bHasImage; + TopAbs_ShapeEnum aType; + TopoDS_Shape aCnew, aCXnew; + TopoDS_Iterator aItC; + BRep_Builder aBB; + // + bHasImage=HasImage(aC); + if (!bHasImage) { + return; + } + // + GEOMAlgo_AlgoTools::MakeContainer(TopAbs_COMPOUND, aCnew); + // + aItC.Initialize(aC); + for (; aItC.More(); aItC.Next()) { + const TopoDS_Shape& aCX=aItC.Value(); + aType=aCX.ShapeType(); + // + if (aType==TopAbs_COMPOUND) { + FillCompound(aCX); + } + // + if (myOrigins.IsBound(aCX)) { + aCXnew=myOrigins.Find(aCX); + aCXnew.Orientation(aCX.Orientation()); + aBB.Add(aCnew, aCXnew); + } + else { + aBB.Add(aCnew, aCX); + } + } + // + //myImages / myOrigins + TopTools_ListOfShape aLSD; + // + aLSD.Append(aC); + myImages.Bind(aCnew, aLSD); + myOrigins.Bind(aC, aCnew); +} + +//======================================================================= +//function : HasImage +//purpose : +//======================================================================= +Standard_Boolean GEOMAlgo_Gluer2::HasImage(const TopoDS_Shape& aC) +{ + Standard_Boolean bRet; + TopAbs_ShapeEnum aType; + TopoDS_Iterator aItC; + // + bRet=Standard_False; + aItC.Initialize(aC); + for (; aItC.More(); aItC.Next()) { + const TopoDS_Shape& aCx=aItC.Value(); + aType=aCx.ShapeType(); + // + if (aType==TopAbs_COMPOUND) { + bRet=HasImage(aCx); + if (bRet) { + return bRet; + } + } + else { + bRet=myOrigins.IsBound(aCx); + if (bRet) { + return bRet; + } + } + } + // + bRet=myOrigins.IsBound(aC); + // + return bRet; +} + +//======================================================================= +//function : BuildResult +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::BuildResult() +{ + Standard_Boolean bHasImage; + TopoDS_Shape aCnew, aCXnew; + TopoDS_Iterator aItC; + BRep_Builder aBB; + // + myErrorStatus=0; + myWarningStatus=0; + // + bHasImage=Standard_False; + aItC.Initialize(myArgument); + for (; aItC.More(); aItC.Next()) { + const TopoDS_Shape& aCx=aItC.Value(); + bHasImage=HasImage(aCx); + if (bHasImage) { + break; + } + } + // + if (!bHasImage) { + myShape=myArgument; + return; + } + // + GEOMAlgo_AlgoTools::MakeContainer(TopAbs_COMPOUND, aCnew); + // + aItC.Initialize(myArgument); + for (; aItC.More(); aItC.Next()) { + const TopoDS_Shape& aCX=aItC.Value(); + if (myOrigins.IsBound(aCX)) { + aCXnew=myOrigins.Find(aCX); + aCXnew.Orientation(aCX.Orientation()); + aBB.Add(aCnew, aCXnew); + } + else { + aBB.Add(aCnew, aCX); + } + } + // + if (!myKeepNonSolids) { + Standard_Integer i, aNb; + TopoDS_Shape aCnew1; + TopTools_IndexedMapOfShape aM; + // + GEOMAlgo_AlgoTools::MakeContainer(TopAbs_COMPOUND, aCnew1); + // + TopExp::MapShapes(aCnew, TopAbs_SOLID, aM); + + aNb=aM.Extent(); + for (i=1; i<=aNb; ++i) { + const TopoDS_Shape& aS=aM(i); + aBB.Add(aCnew1, aS); + } + aCnew=aCnew1; + } + // + myShape=aCnew; +} +//-------------------------------------------------------- +// +// ErrorStatus +// 11 - GEOMAlgo_GlueDetector failed +// 13 - PerformImagesToWork failed +// 14 - PerformImagesToWork failed +// +// WarningStatus +// 1 - no shapes to glue +// 2 - sticked shapes are detected. +// The value of myTolerance is so large that +// subshapes of a shape start to interfere +// (e.g. vertices of an edge). +// In that case, the result can not be obtained diff --git a/src/GeomAlgoImpl/GEOMAlgo_Gluer2.hxx b/src/GeomAlgoImpl/GEOMAlgo_Gluer2.hxx new file mode 100644 index 000000000..c539c365e --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_Gluer2.hxx @@ -0,0 +1,142 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: GEOMAlgo_Gluer2.hxx +// Author: Peter KURNEV + +#ifndef _GEOMAlgo_Gluer2_HeaderFile +#define _GEOMAlgo_Gluer2_HeaderFile + +#include + +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include + +//======================================================================= +//class : GEOMAlgo_Gluer2 +//purpose : +//======================================================================= +class GEOMAlgo_Gluer2 : public GEOMAlgo_GluerAlgo, + public GEOMAlgo_BuilderShape { +public: + + GEOMALGOIMPL_EXPORT GEOMAlgo_Gluer2(); + + GEOMALGOIMPL_EXPORT virtual ~GEOMAlgo_Gluer2(); + + GEOMALGOIMPL_EXPORT void SetShapesToGlue(const TopTools_DataMapOfShapeListOfShape& aM); + + GEOMALGOIMPL_EXPORT const TopTools_DataMapOfShapeListOfShape& ShapesToGlue() const; + + GEOMALGOIMPL_EXPORT void SetKeepNonSolids(const Standard_Boolean theFlag); + + GEOMALGOIMPL_EXPORT Standard_Boolean KeepNonSolids() const; + + GEOMALGOIMPL_EXPORT virtual void Clear(); + + GEOMALGOIMPL_EXPORT virtual void Perform(); + + GEOMALGOIMPL_EXPORT virtual void CheckData(); + + GEOMALGOIMPL_EXPORT void Detect(); + + GEOMALGOIMPL_EXPORT const TopTools_DataMapOfShapeListOfShape& ShapesDetected() const; + + GEOMALGOIMPL_EXPORT const TopTools_DataMapOfShapeListOfShape& ImagesToWork() const; + + GEOMALGOIMPL_EXPORT virtual const TopTools_ListOfShape& Generated(const TopoDS_Shape& theS); + + GEOMALGOIMPL_EXPORT virtual const TopTools_ListOfShape& Modified(const TopoDS_Shape& theS); + + GEOMALGOIMPL_EXPORT virtual Standard_Boolean IsDeleted(const TopoDS_Shape& theS); + + + GEOMALGOIMPL_EXPORT static void MakeVertex(const TopTools_ListOfShape& theLV, + TopoDS_Vertex& theV); + + GEOMALGOIMPL_EXPORT static void MapBRepShapes(const TopoDS_Shape& theS, + TopTools_MapOfShape& theM); + + GEOMALGOIMPL_EXPORT static void MapShapes(const TopoDS_Shape& theS, + TopTools_MapOfShape& theM); + +//modified by NIZNHY-PKV Tue Mar 13 12:23:20 2012f + GEOMALGOIMPL_EXPORT const TopTools_IndexedDataMapOfShapeListOfShape& StickedShapes(); +//modified by NIZNHY-PKV Tue Mar 13 12:23:26 2012t +//------------------------------------------------ +protected: + GEOMALGOIMPL_EXPORT void PerformShapesToWork() ; + + GEOMALGOIMPL_EXPORT void FillVertices(); + GEOMALGOIMPL_EXPORT void FillEdges(); + GEOMALGOIMPL_EXPORT void FillWires(); + GEOMALGOIMPL_EXPORT void FillFaces(); + GEOMALGOIMPL_EXPORT void FillShells(); + GEOMALGOIMPL_EXPORT void FillSolids(); + GEOMALGOIMPL_EXPORT void FillCompSolids(); + GEOMALGOIMPL_EXPORT void FillCompounds(); + + GEOMALGOIMPL_EXPORT void BuildResult(); + + GEOMALGOIMPL_EXPORT void FillBRepShapes(const TopAbs_ShapeEnum theType); + GEOMALGOIMPL_EXPORT void FillContainers(const TopAbs_ShapeEnum theType); + GEOMALGOIMPL_EXPORT void FillCompound(const TopoDS_Shape& theC); + + GEOMALGOIMPL_EXPORT virtual void PrepareHistory(); + + GEOMALGOIMPL_EXPORT Standard_Boolean HasImage(const TopoDS_Shape& theC); + + GEOMALGOIMPL_EXPORT void MakeBRepShapes(const TopoDS_Shape& theS, + TopoDS_Shape& theSnew); + + GEOMALGOIMPL_EXPORT void MakeEdge(const TopoDS_Edge& theE, + TopoDS_Edge& theEnew); + + GEOMALGOIMPL_EXPORT void MakeFace(const TopoDS_Face& theF, + TopoDS_Face& theFnew); + + GEOMALGOIMPL_EXPORT void TreatPair(const GEOMAlgo_CoupleOfShapes& theCS, + GEOMAlgo_ListOfCoupleOfShapes& theLCS); + +protected: + TopTools_DataMapOfShapeListOfShape myShapesToGlue; + TopTools_DataMapOfShapeListOfShape myImagesDetected; + TopTools_DataMapOfShapeShape myOriginsDetected; + TopTools_DataMapOfShapeListOfShape myImagesToWork; + TopTools_DataMapOfShapeShape myOriginsToWork; + Standard_Boolean myKeepNonSolids; + GEOMAlgo_GlueDetector myDetector; +}; + +#endif diff --git a/src/GeomAlgoImpl/GEOMAlgo_Gluer2_1.cxx b/src/GeomAlgoImpl/GEOMAlgo_Gluer2_1.cxx new file mode 100644 index 000000000..cdffa0d15 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_Gluer2_1.cxx @@ -0,0 +1,328 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: GEOMAlgo_Gluer2_1.cxx +// 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 + + +//======================================================================= +//function : MakeBRepShapes +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::MakeBRepShapes(const TopoDS_Shape& theS, + TopoDS_Shape& theSnew) +{ + TopAbs_ShapeEnum aType; + // + aType=theS.ShapeType(); + if (aType==TopAbs_EDGE) { + TopoDS_Edge aEE, aEEnew; + // + aEE=*((TopoDS_Edge*)&theS); + MakeEdge(aEE, aEEnew); + if (myErrorStatus) { + return; + } + // + theSnew=aEEnew; + } + else if (aType==TopAbs_FACE) { + TopoDS_Face aFF, aFFnew; + // + aFF=*((TopoDS_Face*)&theS); + MakeFace(aFF, aFFnew); + if (myErrorStatus) { + return; + } + // + theSnew=aFFnew; + } +} + +//======================================================================= +//function : MakeFace +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::MakeFace(const TopoDS_Face& theF, + TopoDS_Face& theFnew) +{ + Standard_Boolean bIsToReverse, bIsUPeriodic; + Standard_Integer iRet; + Standard_Real aTol, aUMin, aUMax, aVMin, aVMax; + Handle(Geom_Surface) aS; + TopLoc_Location aLoc; + TopoDS_Shape aW, aWr; + TopoDS_Edge aEx; + TopoDS_Face aFF, aFnew; + TopoDS_Iterator aItW, aItE; + BRep_Builder aBB; + TopTools_ListOfShape aLEr; + TopTools_ListIteratorOfListOfShape aItLE; + // + myErrorStatus=0; + // + aFF=theF; + aFF.Orientation(TopAbs_FORWARD); + // + aTol=BRep_Tool::Tolerance(aFF); + aS=BRep_Tool::Surface(aFF, aLoc); + bIsUPeriodic=GEOMAlgo_AlgoTools::IsUPeriodic(aS); + BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax); + // + aBB.MakeFace (aFnew, aS, aLoc, aTol); + // + aItW.Initialize(aFF); + for (; aItW.More(); aItW.Next()) { + const TopoDS_Shape& aW=aItW.Value(); + // + if (!myOrigins.IsBound(aW)) { + aBB.Add(aFnew, aW); + continue; + } + // + aWr=myOrigins.Find(aW); + // + // clear contents of Wr + aLEr.Clear(); + aItE.Initialize(aWr); + for (; aItE.More(); aItE.Next()) { + const TopoDS_Shape& aEr=aItE.Value(); + aLEr.Append(aEr); + } + // + aItLE.Initialize(aLEr); + for (; aItLE.More(); aItLE.Next()) { + const TopoDS_Shape& aEr=aItLE.Value(); + aBB.Remove(aWr, aEr); + } + // + // refill contents of Wr + aItE.Initialize(aW); + for (; aItE.More(); aItE.Next()) { + const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aItE.Value())); + // + aEx=aE; + if (myOrigins.IsBound(aE)) { + aEx=*((TopoDS_Edge*)(&myOrigins.Find(aE))); + } + // + if (!BRep_Tool::Degenerated(aEx)) { + aEx.Orientation(TopAbs_FORWARD); + TopoDS_Edge aE_forward = aE; + aE_forward.Orientation(TopAbs_FORWARD); + if (bIsUPeriodic) { + GEOMAlgo_AlgoTools::RefinePCurveForEdgeOnFace(aEx, aFF, aUMin, aUMax); + } + // + //modified by NIZNHY-PKV Fri Feb 03 11:18:17 2012f + iRet=GEOMAlgo_AlgoTools::BuildPCurveForEdgeOnFace(aE_forward, aEx, aFF, myContext); + if (iRet) { + continue; + } + //modified by NIZNHY-PKV Fri Feb 03 11:18:20 2012t + // + bIsToReverse=GEOMAlgo_AlgoTools::IsSplitToReverse(aEx, aE_forward, myContext); + //bIsToReverse=BOPTools_AlgoTools::IsSplitToReverse(aEx, aE, myContext); + + aEx.Orientation(aE.Orientation()); + + if (bIsToReverse) + aEx.Reverse(); + } + else { + aEx.Orientation(aE.Orientation()); + } + aBB.Add(aWr, aEx); + }// for (; aItE.More(); aItE.Next()) { + // + aBB.Add(aFnew, aWr); + }// for (; aItW.More(); aItW.Next()) { + theFnew=aFnew; +} + +//======================================================================= +//function : MakeEdge +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::MakeEdge(const TopoDS_Edge& aE, + TopoDS_Edge& aNewEdge) +{ + myErrorStatus=0; + // + Standard_Boolean bIsDE; + Standard_Real aT1, aT2; + TopoDS_Vertex aV1, aV2, aVR1, aVR2; + TopoDS_Edge aEx; + // + bIsDE=BRep_Tool::Degenerated(aE); + // + aEx=aE; + aEx.Orientation(TopAbs_FORWARD); + // + TopExp::Vertices(aEx, aV1, aV2); + // + aT1=BRep_Tool::Parameter(aV1, aEx); + aT2=BRep_Tool::Parameter(aV2, aEx); + // + aVR1=aV1; + if (myOrigins.IsBound(aV1)) { + aVR1=*((TopoDS_Vertex*)&myOrigins.Find(aV1)); + } + aVR1.Orientation(TopAbs_FORWARD); + // + aVR2=aV2; + if (myOrigins.IsBound(aV2)) { + aVR2=*((TopoDS_Vertex*)&myOrigins.Find(aV2)); + } + aVR2.Orientation(TopAbs_REVERSED); + // + if (!bIsDE) { + BOPTools_AlgoTools::MakeSplitEdge(aEx, aVR1, aT1, aVR2, aT2, aNewEdge); + } + else { + Standard_Real aTol; + BRep_Builder aBB; + TopoDS_Edge E; + // + aTol=BRep_Tool::Tolerance(aE); + // + E=aEx; + E.EmptyCopy(); + // + aBB.Add (E, aVR1); + aBB.Add (E, aVR2); + aBB.Range(E, aT1, aT2); + aBB.Degenerated(E, Standard_True); + aBB.UpdateEdge(E, aTol); + // + aNewEdge=E; + } +} + +//======================================================================= +//function : MakeVertex +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::MakeVertex(const TopTools_ListOfShape& aLV, + TopoDS_Vertex& aNewVertex) +{ + Standard_Integer aNbV; + Standard_Real aTolV, aD, aDmax; + gp_XYZ aGC; + gp_Pnt aP3D, aPGC; + TopoDS_Vertex aVx; + BRep_Builder aBB; + TopTools_ListIteratorOfListOfShape aIt; + // + aNbV=aLV.Extent(); + if (!aNbV) { + return; + } + // + // center of gravity + aGC.SetCoord(0.,0.,0.); + aIt.Initialize(aLV); + for (; aIt.More(); aIt.Next()) { + aVx=*((TopoDS_Vertex*)(&aIt.Value())); + aP3D=BRep_Tool::Pnt(aVx); + aGC+=aP3D.XYZ(); + } + aGC/=(Standard_Real)aNbV; + aPGC.SetXYZ(aGC); + // + // tolerance value + aDmax=-1.; + aIt.Initialize(aLV); + for (; aIt.More(); aIt.Next()) { + aVx=*((TopoDS_Vertex*)(&aIt.Value())); + aP3D=BRep_Tool::Pnt(aVx); + aTolV=BRep_Tool::Tolerance(aVx); + aD=aPGC.Distance(aP3D)+aTolV; + if (aD>aDmax) { + aDmax=aD; + } + } + // + aBB.MakeVertex (aNewVertex, aPGC, aDmax); +} + +//======================================================================= +//function : MapBRepShapes +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::MapBRepShapes(const TopoDS_Shape& aS, + TopTools_MapOfShape& aM) +{ + TopAbs_ShapeEnum aType; + TopoDS_Iterator aIt; + // + aType=aS.ShapeType(); + if (aType==TopAbs_VERTEX || + aType==TopAbs_EDGE || + aType==TopAbs_FACE) { + aM.Add(aS); + } + // + aIt.Initialize(aS); + for(; aIt.More(); aIt.Next()) { + const TopoDS_Shape& aSx=aIt.Value(); + aType=aSx.ShapeType(); + GEOMAlgo_Gluer2::MapBRepShapes(aSx, aM); + } +} + +// +// ErrorStatus +// +// 40 - GEOMAlgo_GlueDetector has failed diff --git a/src/GeomAlgoImpl/GEOMAlgo_Gluer2_2.cxx b/src/GeomAlgoImpl/GEOMAlgo_Gluer2_2.cxx new file mode 100644 index 000000000..3a3830c68 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_Gluer2_2.cxx @@ -0,0 +1,161 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File: GEOMAlgo_Gluer2_2.cxx +// Created: +// Author: Peter KURNEV +// +// +#include + +#include + +#include +#include + +#include + +#include + + +//======================================================================= +//function : PrepareHistory +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::PrepareHistory() +{ + // + // 1. Clearing + GEOMAlgo_BuilderShape::PrepareHistory(); + // + if(myShape.IsNull()) { + return; + } + // + GEOMAlgo_Gluer2::MapShapes(myShape, myMapShape); + // +} + +//======================================================================= +//function : Generated +//purpose : +//======================================================================= +const TopTools_ListOfShape& GEOMAlgo_Gluer2::Generated(const TopoDS_Shape& ) +{ + myHistShapes.Clear(); + return myHistShapes; +} + +//======================================================================= +//function : Modified +//purpose : +//======================================================================= +const TopTools_ListOfShape& GEOMAlgo_Gluer2::Modified(const TopoDS_Shape& theS) +{ + Standard_Boolean bIsDeleted, bHasImage, bToReverse; + TopAbs_ShapeEnum aType; + TopoDS_Shape aSim; + // + myHistShapes.Clear(); + // + aType=theS.ShapeType(); + if (!(aType==TopAbs_VERTEX || aType==TopAbs_EDGE || + aType==TopAbs_FACE || aType==TopAbs_SOLID)) { + return myHistShapes; + } + // + bIsDeleted=IsDeleted(theS); + if (bIsDeleted) { + return myHistShapes; + } + // + bHasImage=myOrigins.IsBound(theS); + if (!bHasImage) { + return myHistShapes; + } + // + aSim=myOrigins.Find(theS); + if (aSim.IsSame(theS)){ + return myHistShapes; + } + // + if (aType==TopAbs_VERTEX || aType==TopAbs_SOLID) { + aSim.Orientation(theS.Orientation()); + } + else { + bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aSim, theS, myContext); + if (bToReverse) { + aSim.Reverse(); + } + } + // + myHistShapes.Append(aSim); + // + return myHistShapes; +} + +//======================================================================= +//function : IsDeleted +//purpose : +//======================================================================= +Standard_Boolean GEOMAlgo_Gluer2::IsDeleted(const TopoDS_Shape& theS) +{ + Standard_Boolean bRet, bContains, bHasImage; + // + bRet=Standard_False; + // + if (theS.IsNull()) { + return !bRet; //true + } + // + bContains=myMapShape.Contains(theS); + if (bContains) { + return bRet; //false + } + // + bHasImage=myOrigins.IsBound(theS); + if (bHasImage) { + const TopoDS_Shape& aSim=myOrigins.Find(theS); + bContains=myMapShape.Contains(aSim); + if (bContains) { + return bRet; //false + } + } + // + return !bRet; //true +} + +//======================================================================= +//function : MapShapes +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::MapShapes(const TopoDS_Shape& theS, + TopTools_MapOfShape& theM) +{ + TopoDS_Iterator aIt; + // + theM.Add(theS); + aIt.Initialize(theS); + for (; aIt.More(); aIt.Next()) { + const TopoDS_Shape& aSx=aIt.Value(); + GEOMAlgo_Gluer2::MapShapes(aSx, theM); + } +} diff --git a/src/GeomAlgoImpl/GEOMAlgo_Gluer2_3.cxx b/src/GeomAlgoImpl/GEOMAlgo_Gluer2_3.cxx new file mode 100644 index 000000000..2a33953f4 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_Gluer2_3.cxx @@ -0,0 +1,361 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: GEOMAlgo_Gluer2_3.cxx +// Author: Peter KURNEV + +#include + +#include + +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + + +static void MapShapes1(const TopoDS_Shape& aS, + const TopAbs_ShapeEnum aType, + TopTools_IndexedMapOfShape& aM); + + +//======================================================================= +//function : Detect +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::Detect() +{ + Standard_Boolean bCheckGeometry; + Standard_Integer iErr; + TopTools_ListIteratorOfListOfShape aItLS; + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS; + // + myErrorStatus=0; + myWarningStatus=0; + // + myImagesDetected.Clear(); + myOriginsDetected.Clear(); + // + bCheckGeometry=Standard_True; + // + //modified by NIZNHY-PKV Tue Mar 13 13:33:35 2012f + myDetector.Clear(); + myDetector.SetContext(myContext); + //modified by NIZNHY-PKV Tue Mar 13 13:33:38 2012t + myDetector.SetArgument(myArgument); + myDetector.SetTolerance(myTolerance); + myDetector.SetCheckGeometry(bCheckGeometry); + // + myDetector.Perform(); + iErr=myDetector.ErrorStatus(); + if (iErr) { + // Detector is failed + myErrorStatus=11; + return; + } + //modified by NIZNHY-PKV Tue Mar 13 13:40:36 2012f + iErr=myDetector.WarningStatus(); + if (iErr) { + // Sticked shapes are detected + myWarningStatus=2; + } + //modified by NIZNHY-PKV Tue Mar 13 13:40:39 2012t + // + const TopTools_DataMapOfShapeListOfShape& aImages=myDetector.Images(); + aItDMSLS.Initialize(aImages); + for (; aItDMSLS.More(); aItDMSLS.Next()) { + const TopoDS_Shape& aSkey=aItDMSLS.Key(); + const TopTools_ListOfShape& aLSD=aItDMSLS.Value(); + myImagesDetected.Bind(aSkey, aLSD); + } + // + aItDMSLS.Initialize(myImagesDetected); + for (; aItDMSLS.More(); aItDMSLS.Next()) { + const TopoDS_Shape& aSkey=aItDMSLS.Key(); + const TopTools_ListOfShape& aLSD=aItDMSLS.Value(); + aItLS.Initialize(aLSD); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aSx=aItLS.Value(); + myOriginsDetected.Bind(aSx, aSkey); + } + } +} + +//======================================================================= +//function : PerformShapesToWork +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::PerformShapesToWork() +{ + Standard_Integer aNbSG, i, j, k, aNbC, aNb, aNbSD; + TopTools_ListIteratorOfListOfShape aItLS1, aItLS2; + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS; + GEOMAlgo_CoupleOfShapes aCS; + GEOMAlgo_ListOfCoupleOfShapes aLCS; + GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS; + // + myErrorStatus=0; + myWarningStatus=0; + // + myImagesToWork.Clear(); + myOriginsToWork.Clear(); + // + aNbSD=myImagesDetected.Extent(); + if (!aNbSD) {// no shapes to glue detected + myWarningStatus=1; + return; + } + // + aNbSG=myShapesToGlue.Extent(); + if (!aNbSG) { + // glue all possible + myImagesToWork=myImagesDetected; + // + aItDMSLS.Initialize(myImagesToWork); + for (; aItDMSLS.More(); aItDMSLS.Next()) { + const TopoDS_Shape& aSkey=aItDMSLS.Key(); + const TopTools_ListOfShape& aLSD=aItDMSLS.Value(); + aItLS1.Initialize(aLSD); + for (; aItLS1.More(); aItLS1.Next()) { + const TopoDS_Shape& aSx=aItLS1.Value(); + myOriginsToWork.Bind(aSx, aSkey); + } + } + return; + }// if (!aNbSG) { + // + // 1. Make pairs + aItDMSLS.Initialize(myShapesToGlue); + for (k=0; aItDMSLS.More(); aItDMSLS.Next(), ++k) { + //const TopoDS_Shape& aSkey=aItDMSLS.Key(); + const TopTools_ListOfShape& aLSG=aItDMSLS.Value(); + aItLS1.Initialize(aLSG); + for (i=0; aItLS1.More(); aItLS1.Next(), ++i) { + aItLS2.Initialize(aLSG); + for (j=0; aItLS2.More(); aItLS2.Next(), ++j) { + if (j>i) { + const TopoDS_Shape& aSG1=aItLS1.Value(); + const TopoDS_Shape& aSG2=aItLS2.Value(); + aCS.SetShape1(aSG1); + aCS.SetShape2(aSG2); + TreatPair(aCS, aLCS); + } + } + } + } + // + // 2. Find Chains + TopTools_ListOfShape aLSX; + GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape aMC; + // + GEOMAlgo_AlgoTools::FindChains(aLCS, aMC); + // + // 3. myImagesToWork, myOriginsToWork + aNbC=aMC.Extent(); + for (i=1; i<=aNbC; ++i) { + const TopoDS_Shape& aSkey=aMC.FindKey(i); + const TopTools_IndexedMapOfShape& aM=aMC(i); + aLSX.Clear(); + aNb=aM.Extent(); + for (j=1; j<=aNb; ++j) { + const TopoDS_Shape& aS=aM(j); + aLSX.Append(aS); + myOriginsToWork.Bind(aS, aSkey); + } + myImagesToWork.Bind(aSkey, aLSX); + } +} + +//======================================================================= +//function : TreatPair +//purpose : +//======================================================================= +void GEOMAlgo_Gluer2::TreatPair(const GEOMAlgo_CoupleOfShapes& aCS, + GEOMAlgo_ListOfCoupleOfShapes& aLCS) +{ + if (myErrorStatus) { + return; + } + // + Standard_Integer i, aNbS1, aNbS2, aNbS; + TopAbs_ShapeEnum aType, aTypeS; + TopTools_ListIteratorOfListOfShape aItLS; + TopTools_IndexedMapOfShape aMS1, aMS2; + TopTools_DataMapOfShapeListOfShape aDMSLS; + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS; + GEOMAlgo_CoupleOfShapes aCSS; + // + // 1. Checking the pair on whether it can be glued at all + // 1.1 + const TopoDS_Shape& aS1=aCS.Shape1(); + if (!myOriginsDetected.IsBound(aS1)) { + myErrorStatus=30; + return; + } + const TopoDS_Shape& aSkey1=myOriginsDetected.Find(aS1); + // 1.2 + const TopoDS_Shape& aS2=aCS.Shape2(); + if (!myOriginsDetected.IsBound(aS2)) { + myErrorStatus=30; + return; + } + const TopoDS_Shape& aSkey2=myOriginsDetected.Find(aS2); + // 1.3 + if (!aSkey1.IsSame(aSkey2)) { + myErrorStatus=33; + return; + } + // + // 2. Append the pair to the aLCS + aLCS.Append(aCS); + // + // 3. Treatment the sub-shapes of the pair + aType=aS1.ShapeType(); + if (aType==TopAbs_VERTEX) { + return; + } + aTypeS=TopAbs_EDGE; + if (aType==aTypeS) { + aTypeS=TopAbs_VERTEX; + } + // + MapShapes1(aS1, aTypeS, aMS1); + MapShapes1(aS2, aTypeS, aMS2); + // + aNbS1=aMS1.Extent(); + aNbS2=aMS2.Extent(); + if (aNbS1!=aNbS2) { + myErrorStatus=31; + return; + } + // + // 1. + for (i=1; i<=aNbS1; ++i) { + const TopoDS_Shape& aSS1=aMS1(i); + if (aMS2.Contains(aSS1)) { + continue; + } + // + if (!myOriginsDetected.IsBound(aSS1)) { + myErrorStatus=30; + return; + } + // + const TopoDS_Shape& aSkey=myOriginsDetected.Find(aSS1); + if (aDMSLS.IsBound(aSkey)) { + TopTools_ListOfShape& aLS=aDMSLS.ChangeFind(aSkey); + aLS.Append(aSS1); + } + else { + TopTools_ListOfShape aLS; + // + aLS.Append(aSS1); + aDMSLS.Bind(aSkey, aLS); + } + } + // + // 2. + for (i=1; i<=aNbS2; ++i) { + const TopoDS_Shape& aSS2=aMS2(i); + if (aMS1.Contains(aSS2)) { + continue; + } + // + if (!myOriginsDetected.IsBound(aSS2)) { + myErrorStatus=30; + return; + } + // + const TopoDS_Shape& aSkey=myOriginsDetected.Find(aSS2); + if (aDMSLS.IsBound(aSkey)) { + TopTools_ListOfShape& aLS=aDMSLS.ChangeFind(aSkey); + aLS.Append(aSS2); + } + else { + TopTools_ListOfShape aLS; + // + aLS.Append(aSS2); + aDMSLS.Bind(aSkey, aLS); + } + } + // + // 3. + aItDMSLS.Initialize(aDMSLS); + for (; aItDMSLS.More(); aItDMSLS.Next()) { + //const TopoDS_Shape& aSkey=aItDMSLS.Key(); + const TopTools_ListOfShape& aLS=aItDMSLS.Value(); + aNbS=aLS.Extent(); + if (aNbS!=2) { + myErrorStatus=32; + return; + } + // + const TopoDS_Shape& aSS1=aLS.First(); + const TopoDS_Shape& aSS2=aLS.Last(); + aCSS.SetShape1(aSS1); + aCSS.SetShape2(aSS2); + TreatPair(aCSS, aLCS); + } +} + +//======================================================================= +//function : MapShapes1 +//purpose : +//======================================================================= +void MapShapes1(const TopoDS_Shape& aS, + const TopAbs_ShapeEnum aType, + TopTools_IndexedMapOfShape& aM) +{ + TopExp_Explorer aExp; + + aExp.Init (aS, aType); + for ( ;aExp.More(); aExp.Next()) { + const TopoDS_Shape aSx=aExp.Current(); + if (aType==TopAbs_EDGE) { + const TopoDS_Edge& aEx=*((TopoDS_Edge*)&aSx); + if (BRep_Tool::Degenerated(aEx)) { + continue; + } + } + aM.Add(aSx); + } +} diff --git a/src/GeomAlgoImpl/GEOMAlgo_GluerAlgo.cxx b/src/GeomAlgoImpl/GEOMAlgo_GluerAlgo.cxx new file mode 100644 index 000000000..0d9281812 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_GluerAlgo.cxx @@ -0,0 +1,145 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File: GEOMAlgo_GluerAlgo.cxx +// Created: +// Author: Peter KURNEV +// +// +#include +#include + +//======================================================================= +//function : GEOMAlgo_GluerAlgo +//purpose : +//======================================================================= +GEOMAlgo_GluerAlgo::GEOMAlgo_GluerAlgo() +{ + myTolerance=0.0001; + myCheckGeometry=Standard_True; +} +//======================================================================= +//function : ~GEOMAlgo_GluerAlgo +//purpose : +//======================================================================= +GEOMAlgo_GluerAlgo::~GEOMAlgo_GluerAlgo() +{ +} +//======================================================================= +//function : SetArgument +//purpose : +//======================================================================= +void GEOMAlgo_GluerAlgo::SetArgument(const TopoDS_Shape& theShape) +{ + myArgument=theShape; +} +//======================================================================= +//function : Argument +//purpose : +//======================================================================= +const TopoDS_Shape& GEOMAlgo_GluerAlgo::Argument()const +{ + return myArgument; +} +//======================================================================= +//function : SetTolerance +//purpose : +//======================================================================= +void GEOMAlgo_GluerAlgo::SetTolerance(const Standard_Real aT) +{ + myTolerance=aT; +} +//======================================================================= +//function : Tolerance +//purpose : +//======================================================================= +Standard_Real GEOMAlgo_GluerAlgo::Tolerance()const +{ + return myTolerance; +} + +//======================================================================= +//function : SetCheckGeometry +//purpose : +//======================================================================= +void GEOMAlgo_GluerAlgo::SetCheckGeometry(const Standard_Boolean aFlag) +{ + myCheckGeometry=aFlag; +} +//======================================================================= +//function : CheckGeometry +//purpose : +//======================================================================= +Standard_Boolean GEOMAlgo_GluerAlgo::CheckGeometry() const +{ + return myCheckGeometry; +} +//======================================================================= +//function : SetContext +//purpose : +//======================================================================= +void GEOMAlgo_GluerAlgo::SetContext(const Handle(IntTools_Context)& theContext) +{ + myContext=theContext; +} +//======================================================================= +//function : Context +//purpose : +//======================================================================= +const Handle(IntTools_Context)& GEOMAlgo_GluerAlgo::Context() +{ + return myContext; +} +//======================================================================= +//function : Images +//purpose : +//======================================================================= +const TopTools_DataMapOfShapeListOfShape& GEOMAlgo_GluerAlgo::Images()const +{ + return myImages; +} +//======================================================================= +//function : Origins +//purpose : +//======================================================================= +const TopTools_DataMapOfShapeShape& GEOMAlgo_GluerAlgo::Origins()const +{ + return myOrigins; +} +//======================================================================= +//function : Clear +//purpose : +//======================================================================= +void GEOMAlgo_GluerAlgo::Clear() +{ + myImages.Clear(); + myOrigins.Clear(); +} +//======================================================================= +//function : Perform +//purpose : +//======================================================================= +void GEOMAlgo_GluerAlgo::Perform() +{ + if (myContext.IsNull()) { + myContext=new IntTools_Context; + } +} diff --git a/src/GeomAlgoImpl/GEOMAlgo_GluerAlgo.hxx b/src/GeomAlgoImpl/GEOMAlgo_GluerAlgo.hxx new file mode 100644 index 000000000..26f2150d4 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_GluerAlgo.hxx @@ -0,0 +1,99 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File: GEOMAlgo_GluerAlgo.hxx +// Created: +// Author: Peter KURNEV +// +// +#ifndef _GEOMAlgo_GluerAlgo_HeaderFile +#define _GEOMAlgo_GluerAlgo_HeaderFile + +#include + +#include +#include +#include +#include +#include +#include +#include + + +//======================================================================= +//class : GEOMAlgo_GluerAlgo +//purpose : +//======================================================================= +class GEOMAlgo_GluerAlgo { +public: + + GEOMALGOIMPL_EXPORT + GEOMAlgo_GluerAlgo(); + + GEOMALGOIMPL_EXPORT + virtual ~GEOMAlgo_GluerAlgo(); + + GEOMALGOIMPL_EXPORT + virtual void SetArgument(const TopoDS_Shape& theShape) ; + + GEOMALGOIMPL_EXPORT + const TopoDS_Shape& Argument() const; + + GEOMALGOIMPL_EXPORT + void SetTolerance(const Standard_Real aT) ; + + GEOMALGOIMPL_EXPORT + Standard_Real Tolerance() const; + + GEOMALGOIMPL_EXPORT + void SetCheckGeometry(const Standard_Boolean aFlag) ; + + GEOMALGOIMPL_EXPORT + Standard_Boolean CheckGeometry() const; + + GEOMALGOIMPL_EXPORT + virtual void Perform() ; + + GEOMALGOIMPL_EXPORT + virtual void Clear() ; + + GEOMALGOIMPL_EXPORT + void SetContext(const Handle(IntTools_Context)&) ; + + GEOMALGOIMPL_EXPORT + const Handle(IntTools_Context)& Context() ; + + GEOMALGOIMPL_EXPORT + const TopTools_DataMapOfShapeListOfShape& Images() const; + + GEOMALGOIMPL_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; +}; + +#endif diff --git a/src/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfIntegerShape.hxx b/src/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfIntegerShape.hxx new file mode 100644 index 000000000..5da603586 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfIntegerShape.hxx @@ -0,0 +1,44 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File: 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/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx b/src/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx new file mode 100644 index 000000000..7d2c2eb14 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx @@ -0,0 +1,43 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File: 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/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfShapeBndSphere.hxx b/src/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfShapeBndSphere.hxx new file mode 100644 index 000000000..3234c30a1 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfShapeBndSphere.hxx @@ -0,0 +1,45 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: 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/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape.hxx b/src/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape.hxx new file mode 100644 index 000000000..822370d81 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape.hxx @@ -0,0 +1,47 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File: 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/GeomAlgoImpl/GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx b/src/GeomAlgoImpl/GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx new file mode 100644 index 000000000..5574a62c2 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx @@ -0,0 +1,31 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File: GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx +// Created: Wed Feb 22 08:26:34 2012 +// Author: +// + +#ifndef GEOMAlgo_ListIteratorOfListOfCoupleOfShapes_HeaderFile +#define GEOMAlgo_ListIteratorOfListOfCoupleOfShapes_HeaderFile + +#ifndef GEOMAlgo_ListOfCoupleOfShapes_HeaderFile +#include +#endif + +#endif diff --git a/src/GeomAlgoImpl/GEOMAlgo_ListOfCoupleOfShapes.hxx b/src/GeomAlgoImpl/GEOMAlgo_ListOfCoupleOfShapes.hxx new file mode 100644 index 000000000..0134afcf0 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_ListOfCoupleOfShapes.hxx @@ -0,0 +1,34 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: 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/GeomAlgoImpl/GEOMAlgo_PassKeyShape.cxx b/src/GeomAlgoImpl/GEOMAlgo_PassKeyShape.cxx new file mode 100644 index 000000000..57686fd63 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_PassKeyShape.cxx @@ -0,0 +1,229 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// 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/GeomAlgoImpl/GEOMAlgo_PassKeyShape.hxx b/src/GeomAlgoImpl/GEOMAlgo_PassKeyShape.hxx new file mode 100644 index 000000000..2a0f759c6 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_PassKeyShape.hxx @@ -0,0 +1,107 @@ + +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: GEOMAlgo_PassKeyShape.hxx +// Created: +// Author: Peter KURNEV +// +// +#ifndef _GEOMAlgo_PassKeyShape_HeaderFile +#define _GEOMAlgo_PassKeyShape_HeaderFile + +#include + +#include +#include +#include +#include +#include +#include +#include + + +//======================================================================= +//class : GEOMAlgo_PassKeyShape +//purpose : +//======================================================================= +class GEOMAlgo_PassKeyShape { + public: + GEOMALGOIMPL_EXPORT + GEOMAlgo_PassKeyShape(); + + GEOMALGOIMPL_EXPORT + virtual ~GEOMAlgo_PassKeyShape(); + + GEOMALGOIMPL_EXPORT + GEOMAlgo_PassKeyShape(const GEOMAlgo_PassKeyShape& Other); + + GEOMALGOIMPL_EXPORT + GEOMAlgo_PassKeyShape& Assign(const GEOMAlgo_PassKeyShape& Other) ; + + GEOMAlgo_PassKeyShape& operator =(const GEOMAlgo_PassKeyShape& Other) { + return Assign(Other); + } + + GEOMALGOIMPL_EXPORT + void SetShapes(const TopoDS_Shape& aS) ; + + GEOMALGOIMPL_EXPORT + void SetShapes(const TopoDS_Shape& aS1, + const TopoDS_Shape& aS2) ; + + GEOMALGOIMPL_EXPORT + void SetShapes(const TopoDS_Shape& aS1, + const TopoDS_Shape& aS2, + const TopoDS_Shape& aS3) ; + + GEOMALGOIMPL_EXPORT + void SetShapes(const TopoDS_Shape& aS1, + const TopoDS_Shape& aS2, + const TopoDS_Shape& aS3, + const TopoDS_Shape& aS4) ; + + GEOMALGOIMPL_EXPORT + void SetShapes(const TopTools_ListOfShape& aLS) ; + + GEOMALGOIMPL_EXPORT + void Clear() ; + + GEOMALGOIMPL_EXPORT + Standard_Integer NbIds() const; + + GEOMALGOIMPL_EXPORT + Standard_Boolean IsEqual(const GEOMAlgo_PassKeyShape& aOther) const; + + GEOMALGOIMPL_EXPORT + Standard_Integer HashCode(const Standard_Integer Upper) const; + + GEOMALGOIMPL_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/GeomAlgoImpl/GEOMAlgo_PassKeyShapeMapHasher.cxx b/src/GeomAlgoImpl/GEOMAlgo_PassKeyShapeMapHasher.cxx new file mode 100644 index 000000000..d4245cf8c --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_PassKeyShapeMapHasher.cxx @@ -0,0 +1,47 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// 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/GeomAlgoImpl/GEOMAlgo_PassKeyShapeMapHasher.hxx b/src/GeomAlgoImpl/GEOMAlgo_PassKeyShapeMapHasher.hxx new file mode 100644 index 000000000..229e12592 --- /dev/null +++ b/src/GeomAlgoImpl/GEOMAlgo_PassKeyShapeMapHasher.hxx @@ -0,0 +1,54 @@ +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: GEOMAlgo_PassKeyMapHasher.hxx +// Created: +// Author: Peter KURNEV +// +// +#ifndef _GEOMAlgo_PassKeyShapeMapHasher_HeaderFile +#define _GEOMAlgo_PassKeyShapeMapHasher_HeaderFile + +#include + +#include +#include +#include +#include +#include + +//======================================================================= +//class : GEOMAlgo_PassKeyShapeMapHasher +//purpose : +//======================================================================= +class GEOMAlgo_PassKeyShapeMapHasher +{ + public: + GEOMALGOIMPL_EXPORT + static Standard_Integer HashCode(const GEOMAlgo_PassKeyShape& aPKey, + const Standard_Integer Upper) ; + + GEOMALGOIMPL_EXPORT + static Standard_Boolean IsEqual(const GEOMAlgo_PassKeyShape& aPKey1, + const GEOMAlgo_PassKeyShape& aPKey2) ; +}; +#endif diff --git a/src/PythonAPI/model/features/__init__.py b/src/PythonAPI/model/features/__init__.py index a02b05b80..47b8c5771 100644 --- a/src/PythonAPI/model/features/__init__.py +++ b/src/PythonAPI/model/features/__init__.py @@ -37,3 +37,4 @@ from FeaturesAPI import addRemoveResults from FeaturesAPI import addCopy, addImportResult from FeaturesAPI import addDefeaturing from FeaturesAPI import addSewing +from FeaturesAPI import addGlueFaces