Salome HOME
added new GlueFaces feature
authormbs <martin.bernhard@opencascade.com>
Fri, 9 Dec 2022 19:03:45 +0000 (19:03 +0000)
committerGérald NICOLAS <gerald.nicolas@edf.fr>
Wed, 1 Feb 2023 16:32:07 +0000 (17:32 +0100)
64 files changed:
src/FeaturesAPI/CMakeLists.txt
src/FeaturesAPI/FeaturesAPI.i
src/FeaturesAPI/FeaturesAPI_GlueFaces.cpp [new file with mode: 0644]
src/FeaturesAPI/FeaturesAPI_GlueFaces.h [new file with mode: 0644]
src/FeaturesAPI/FeaturesAPI_swig.h
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_GlueFaces.cpp [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_GlueFaces.h [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp
src/FeaturesPlugin/FeaturesPlugin_Validators.cpp
src/FeaturesPlugin/FeaturesPlugin_Validators.h
src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts
src/FeaturesPlugin/FeaturesPlugin_msg_ru.ts
src/FeaturesPlugin/Test/TestGlueFaces_Compound.py [new file with mode: 0644]
src/FeaturesPlugin/Test/TestGlueFaces_Shell.py [new file with mode: 0644]
src/FeaturesPlugin/Test/TestGlueFaces_Solids.py [new file with mode: 0644]
src/FeaturesPlugin/doc/FeaturesPlugin.rst
src/FeaturesPlugin/doc/TUI_glueFeatureFaces.rst [new file with mode: 0644]
src/FeaturesPlugin/doc/examples/glue_faces.py [new file with mode: 0644]
src/FeaturesPlugin/doc/glueFeatureFaces.rst [new file with mode: 0644]
src/FeaturesPlugin/doc/images/GlueFaces.png [new file with mode: 0644]
src/FeaturesPlugin/doc/images/glue_faces.png [new file with mode: 0644]
src/FeaturesPlugin/glue_faces_widget.xml [new file with mode: 0644]
src/FeaturesPlugin/icons/glue_faces.png [new file with mode: 0644]
src/FeaturesPlugin/plugin-Features.xml
src/FeaturesPlugin/tests.set
src/GeomAlgoAPI/CMakeLists.txt
src/GeomAlgoAPI/GeomAlgoAPI_GlueFaces.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_GlueFaces.h [new file with mode: 0644]
src/GeomAlgoImpl/CMakeLists.txt
src/GeomAlgoImpl/GEOMAlgo_Algo.cxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_Algo.hxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_AlgoTools.cxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_AlgoTools.hxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_AlgoTools_1.cxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_BndSphere.cxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_BndSphere.hxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_BndSphere.lxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_BndSphereTree.cxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_BndSphereTree.hxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_BuilderShape.cxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_BuilderShape.hxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_CoupleOfShapes.cxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_CoupleOfShapes.hxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_GlueDetector.cxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_GlueDetector.hxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_Gluer2.cxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_Gluer2.hxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_Gluer2_1.cxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_Gluer2_2.cxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_Gluer2_3.cxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_GluerAlgo.cxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_GluerAlgo.hxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfIntegerShape.hxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfShapeBndSphere.hxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape.hxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_ListOfCoupleOfShapes.hxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_PassKeyShape.cxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_PassKeyShape.hxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_PassKeyShapeMapHasher.cxx [new file with mode: 0644]
src/GeomAlgoImpl/GEOMAlgo_PassKeyShapeMapHasher.hxx [new file with mode: 0644]
src/PythonAPI/model/features/__init__.py

index 1d929468d5be139e767586abf50c9d08f688f088..985a5c5225c17d569a53f092af64fe9c1a6f4fd8 100644 (file)
@@ -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
index 4a4db824a223f66f3e2297ef4fe0181b3ad6f5dd..57806028df4174fcd7d69af508ab0bae6b006809 100644 (file)
@@ -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)
 %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 (file)
index 0000000..97b7a39
--- /dev/null
@@ -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 <ModelHighAPI_Double.h>
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Tools.h>
+
+//==================================================================================================
+FeaturesAPI_GlueFaces::FeaturesAPI_GlueFaces(const std::shared_ptr<ModelAPI_Feature>& theFeature)
+: ModelHighAPI_Interface(theFeature)
+{
+  initialize();
+}
+
+//==================================================================================================
+FeaturesAPI_GlueFaces::FeaturesAPI_GlueFaces(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                             const std::list<ModelHighAPI_Selection>& 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<ModelHighAPI_Selection>& 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<ModelAPI_Document>& thePart,
+                          const std::list<ModelHighAPI_Selection>& theMainObjects,
+                          const ModelHighAPI_Double& theTolerance,
+                          const bool theKeepNonSolids)
+{
+  std::shared_ptr<ModelAPI_Feature> 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 (file)
index 0000000..04b2ad6
--- /dev/null
@@ -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 <FeaturesPlugin_GlueFaces.h>
+
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
+
+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<ModelAPI_Feature>& theFeature);
+
+  /// Constructor with values.
+  FEATURESAPI_EXPORT
+  explicit FeaturesAPI_GlueFaces(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                 const std::list<ModelHighAPI_Selection>& 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<ModelHighAPI_Selection>& 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<FeaturesAPI_GlueFaces> GlueFacesPtr;
+
+/// \ingroup CPPHighAPI
+/// \brief Create Glue Faces feature.
+FEATURESAPI_EXPORT
+GlueFacesPtr addGlueFaces(const std::shared_ptr<ModelAPI_Document>& thePart,
+                          const std::list<ModelHighAPI_Selection>& theMainObjects,
+                          const ModelHighAPI_Double& theTolerance,
+                          const bool theKeepNonSolids);
+
+#endif // FeatureAPI_GlueFaces_H_
index d46a5c084bc5431f3d6742ae27935c3a2a99c9ba..3dee6e73f89e570782e554d8f4a0c1f590830036 100644 (file)
@@ -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"
index 3f9fb4e533baf7fa99075e9c9944e44b836597c9..6738d6faf75a661a56993989d7ee80f9f6f73d37 100644 (file)
@@ -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 (file)
index 0000000..37d9cbc
--- /dev/null
@@ -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 <ModelAPI_AttributeBoolean.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+#include <ModelAPI_Tools.h>
+
+#include <GeomAPI_ShapeIterator.h>
+#include <GeomAPI_ShapeExplorer.h>
+
+#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAlgoAPI_GlueFaces.h>
+#include <GeomAlgoAPI_Tools.h>
+
+
+//==================================================================================================
+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<GeomAlgoAPI_GlueFaces> 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 (file)
index 0000000..fd1049b
--- /dev/null
@@ -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 <ModelAPI_Feature.h>
+#include <GeomAPI_Shape.h>
+
+
+/// \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_
index 56f86af9ce69a438c8dee916981d24f0c64b4e7d..f77e17b61c52c6023414d2aa81bc4b573c327152 100644 (file)
@@ -33,6 +33,7 @@
 #include <FeaturesPlugin_Fillet.h>
 #include <FeaturesPlugin_Fillet1D.h>
 #include <FeaturesPlugin_GeometryCalculation.h>
+#include <FeaturesPlugin_GlueFaces.h>
 #include <FeaturesPlugin_InspectBoundingBox.h>
 #include <FeaturesPlugin_InspectNormalToFace.h>
 #include <FeaturesPlugin_Intersection.h>
@@ -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()) {
index 71030a080b8f0e46b81a467ce35938b9c8f943f2..0d8da03a687404cb8058b3819ffeabdbe9f6edcc 100644 (file)
@@ -2149,3 +2149,55 @@ bool FeaturesPlugin_ValidatorSewingSelection::isValid(const AttributePtr& theAtt
 
   return true;
 }
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorGlueFacesSelection::isValid(const AttributePtr& theAttribute,
+                                                         const std::list<std::string>& theArguments,
+                                                         Events_InfoMessage& theError) const
+{
+  AttributeSelectionListPtr anAttrSelectionList =
+      std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(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<GeomAPI_Shape::ShapeType> 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;
+}
index 4814dc2df2ff51df6f5282d4e1c85b8c23919f0c..59ac87fede464b79ecdfb60ca280f93be6c15de7 100644 (file)
@@ -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<std::string>& theArguments,
+                       Events_InfoMessage& theError) const;
+};
+
 #endif
index 25fa2623df112fe4a5839444cfed51d1e666dc74..584156b0e5461e5fa7535618547afb048fa70869 100644 (file)
       <source>Sewing</source>
       <translation>Couture</translation>
     </message>
+    <message>
+      <source>Glue Faces</source>
+      <translation>Recoller les faces</translation>
+    </message>
     <message>
       <source>Revolution</source>
       <translation>Révolution</translation>
     </message>
   </context>
 
+  <!-- GlueFaces -->
+  <context>
+    <name>GlueFaces</name>
+    <message>
+      <source>Perform gluing of connected faces</source>
+      <translation>Effectuer le collage des faces connectées</translation>
+    </message>
+    <message>
+      <source>Glue Faces</source>
+      <translation>Recoller les faces</translation>
+    </message>
+    <message>
+      <source>No shapes to glue.</source>
+      <translation>Aucune forme à coller.</translation>
+    </message>
+  </context>
+  <context>
+    <name>GlueFaces:main_objects</name>
+    <message>
+      <source>Objects</source>
+      <translation>Objets</translation>
+    </message>
+    <message>
+      <source>Select shapes to glue.</source>
+      <translation>Sélectionnez les formes à coller.</translation>
+    </message>
+  </context>
+  <context>
+    <name>GlueFaces:tolerance</name>
+    <message>
+      <source>Tolerance</source>
+      <translation>Tolérance</translation>
+    </message>
+  </context>
+  <context>
+    <name>GlueFaces:keep_non_solids</name>
+    <message>
+      <source>Keep non-solid shapes</source>
+      <translation>Conserver les formes non solides</translation>
+    </message>
+  </context>
+
   <!-- Smash -->
   <context>
     <name>Smash</name>
index 1b328d613edf7757cb8427954311f9f47e0bfe0e..6448aae0206549fd0fc31a49e06a2d4e93e5c861 100644 (file)
     </message>
   </context>
 
+  <!-- GlueFaces -->
+  <context>
+    <name>GlueFaces</name>
+    <message>
+      <source>Perform gluing of connected faces</source>
+      <translation>Выполнить склейку соединенных граней</translation>
+    </message>
+    <message>
+      <source>Glue Faces</source>
+      <translation>Склеиваем лица</translation>
+    </message>
+    <message>
+      <source>No shapes to glue.</source>
+      <translation>Нет фигур для склеивания.</translation>
+    </message>
+  </context>
+  <context>
+    <name>GlueFaces:main_objects</name>
+    <message>
+      <source>Objects</source>
+      <translation>Объекты</translation>
+    </message>
+    <message>
+      <source>Select shapes to glue.</source>
+      <translation>Выберите фигуры для склеивания.</translation>
+    </message>
+  </context>
+  <context>
+    <name>GlueFaces:tolerance</name>
+    <message>
+      <source>Tolerance</source>
+      <translation>Толерантность</translation>
+    </message>
+  </context>
+  <context>
+    <name>GlueFaces:keep_non_solids</name>
+    <message>
+      <source>Keep non-solid shapes</source>
+      <translation>Сохраняйте нетвердые формы</translation>
+    </message>
+  </context>
+
 </TS>
diff --git a/src/FeaturesPlugin/Test/TestGlueFaces_Compound.py b/src/FeaturesPlugin/Test/TestGlueFaces_Compound.py
new file mode 100644 (file)
index 0000000..5202fd3
--- /dev/null
@@ -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 (file)
index 0000000..95f89ab
--- /dev/null
@@ -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 (file)
index 0000000..7a6284b
--- /dev/null
@@ -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())
index 767922df8a1d7c6c9ff1cfd390a8b2dc6d2432b3..d820d4df86c07d433777a17e0ae33a0c2bc9a5bb 100644 (file)
@@ -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 (file)
index 0000000..3be4e87
--- /dev/null
@@ -0,0 +1,11 @@
+
+  .. _tui_create_glue_faces:
+
+Glue Faces
+==========
+
+.. literalinclude:: examples/glue_faces.py 
+    :linenos:
+    :language: python
+
+:download:`Download this script <examples/glue_faces.py>`
diff --git a/src/FeaturesPlugin/doc/examples/glue_faces.py b/src/FeaturesPlugin/doc/examples/glue_faces.py
new file mode 100644 (file)
index 0000000..06a3f05
--- /dev/null
@@ -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 (file)
index 0000000..2cfa090
--- /dev/null
@@ -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 (file)
index 0000000..8618cc2
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 (file)
index 0000000..0d66a11
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 (file)
index 0000000..768b422
--- /dev/null
@@ -0,0 +1,18 @@
+<source>
+  <multi_selector id="main_objects"
+    label="Objects"
+    icon=""
+    tooltip="Select shapes to glue."
+    concealment="true">
+    <validator id="FeaturesPlugin_ValidatorGlueFacesSelection"/>
+  </multi_selector>
+  <groupbox>
+    <doublevalue id="tolerance"
+                  label="Tolerance"
+                  min="1.0e-7"
+                  step="1.0e-7"
+                  default="1.0e-7"
+                  tooltip="Tolerance"/>
+  </groupbox>
+  <boolvalue id="keep_non_solids" label="Keep non-solid shapes" default="true" tooltip="Keep non-solid shapes"/>
+</source>
diff --git a/src/FeaturesPlugin/icons/glue_faces.png b/src/FeaturesPlugin/icons/glue_faces.png
new file mode 100644 (file)
index 0000000..0d66a11
Binary files /dev/null and b/src/FeaturesPlugin/icons/glue_faces.png differ
index a77da866c293c05f23f945e02b61db4d6c0204e1..64b210e9e5340a8f7a699dc0af818ef6f0cb5639 100644 (file)
                 auto_preview="false">
           <source path="sewing_widget.xml"/>
       </feature>
+      <feature id="GlueFaces" title="Glue Faces" tooltip="Perform gluing of connected faces"
+                icon="icons/Features/glue_faces.png" helpfile="glueFeatureFaces.html"
+                auto_preview="false">
+          <source path="glue_faces_widget.xml"/>
+      </feature>
     </group>
   </workbench>
   <workbench id="Part">
index 2ca98bd85dc84fc5471a52f6dd6d06e6ab899552..b07dec3a08fc17ebd3d670e68504a55d0d59bf80 100644 (file)
@@ -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
index 640ae3a1f4cca5dc119c2bc86aa65a930cbbaf9c..5263f9cc43ad1b85a3bf5807f30b240bd449f25a 100644 (file)
@@ -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 (file)
index 0000000..79223f1
--- /dev/null
@@ -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 <GeomAPI_ShapeIterator.h>
+#include <GEOMAlgo_Gluer2.hxx>
+#include <BRep_Builder.hxx>
+#include <BRepBuilderAPI_MakeShape.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shape.hxx>
+
+//==================================================================================================
+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<TopoDS_Shape>();
+  }
+  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<TopoDS_Shape>();
+      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<GeomAPI_Shape> 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 (file)
index 0000000..bff88e9
--- /dev/null
@@ -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 <GeomAPI_Shape.h>
+
+/// \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
index db5e6cc549e54b3945b3dd884ac18a58c2cefba6..15d52cfce8cf913658f837859f9742db5176e332 100644 (file)
@@ -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 (file)
index 0000000..b93f9c0
--- /dev/null
@@ -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
+//              <peter@PREFEX>
+//
+#include <GEOMAlgo_Algo.hxx>
+
+
+//=======================================================================
+// 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 (file)
index 0000000..eaee9dd
--- /dev/null
@@ -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
+//              <peter@PREFEX>
+//
+#ifndef _GEOMAlgo_Algo_HeaderFile
+#define _GEOMAlgo_Algo_HeaderFile
+
+#include <GeomAlgoImpl.h>
+
+#include <Standard.hxx>
+#include <Standard_Macro.hxx>
+#include <Standard_Integer.hxx>
+#include <Standard_Boolean.hxx>
+
+
+//=======================================================================
+//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). <br>
+  //!          Needed for the SALOME/TRIPOLI module. <br>
+  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 (file)
index 0000000..7965b41
--- /dev/null
@@ -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 <GEOMAlgo_AlgoTools.hxx>
+
+#include <Basics_OCCTVersion.hxx>
+
+#include <gp_Pnt.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_Dir2d.hxx>
+#include <gp_Ax2.hxx>
+#include <Bnd_Box.hxx>
+
+#include <BRepAdaptor_Curve2d.hxx>
+#include <BRepTopAdaptor_FClass2d.hxx>
+
+#include <Geom2d_Curve.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
+#include <Geom2d_Line.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
+
+#include <Geom2dHatch_Intersector.hxx>
+#include <Geom2dHatch_Hatcher.hxx>
+
+#include <Geom2dAdaptor_Curve.hxx>
+#include <HatchGen_Domain.hxx>
+
+#include <GeomLib.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_Surface.hxx>
+
+#include <GeomAdaptor_Surface.hxx>
+
+#include <GeomAPI_ProjectPointOnSurf.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
+
+#include <GProp_GProps.hxx>
+
+#include <Poly_Triangulation.hxx>
+
+#include <TopAbs_Orientation.hxx>
+
+#include <TopLoc_Location.hxx>
+
+#include <TopoDS.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Compound.hxx>
+
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+
+#include <BRep_Tool.hxx>
+#include <BRep_Builder.hxx>
+#include <BRepLib_MakeVertex.hxx>
+
+#include <BRepTools.hxx>
+#include <BRepTools_WireExplorer.hxx>
+#include <BRepBndLib.hxx>
+#include <BRepMesh_IncrementalMesh.hxx>
+#include <BRepGProp.hxx>
+
+#include <IntTools_Tools.hxx>
+
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopTools_DataMapOfShapeReal.hxx>
+#include <TColgp_SequenceOfPnt2d.hxx>
+
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopAbs_ShapeEnum.hxx>
+
+#include <IntTools_Tools.hxx>
+
+#include <BOPTools_AlgoTools3D.hxx>
+#include <BOPTools_AlgoTools2D.hxx>
+
+#include <ShapeUpgrade_ShapeDivideArea.hxx>
+#include <ShapeUpgrade_UnifySameDomain.hxx>
+
+#include <GEOMAlgo_PassKeyShape.hxx>
+
+#include <algorithm>
+
+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<TopoDS_Shape, Standard_Real>& theA,
+                             const std::pair<TopoDS_Shape, Standard_Real>& 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<std::pair<TopoDS_Shape, Standard_Real>> 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)<aTol) {
+      aV2DT.Reverse();
+    }
+  }
+  else {   // U Closed
+    if (fabs(aU-aUS2)<aTol) {
+      aV2DT.Reverse();
+    }
+  }
+  //
+  aC2DTnew->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(aD2<aTol2) {
+        aLESD.Append(aE2);
+      }
+    }
+  }
+  return 0;
+}
+
+//=======================================================================
+//function : FindSDShapes
+//purpose  :
+//=======================================================================
+Standard_Integer GEOMAlgo_AlgoTools::FindSDShapes
+  (const TopTools_ListOfShape& aLE,
+   const Standard_Real aTol,
+   TopTools_IndexedDataMapOfShapeListOfShape& aMEE,
+   const Handle(IntTools_Context)& aCtx)
+{
+  Standard_Integer aNbE, aNbEProcessed, aNbESD, iErr;
+  TopTools_ListOfShape aLESD;
+  TopTools_ListIteratorOfListOfShape aIt, aIt1;
+  TopTools_IndexedMapOfShape aMProcessed;
+  TopAbs_ShapeEnum aType;
+  //
+  aNbE=aLE.Extent();
+  if (!aNbE) {
+    return 3; // Err
+  }
+  if (aNbE==1) {
+    return 0; // Nothing to do
+  }
+  //
+  for(;;) {
+    aNbEProcessed=aMProcessed.Extent();
+    if (aNbEProcessed==aNbE) {
+      break;
+    }
+    //
+    aIt.Initialize(aLE);
+    for (; aIt.More(); aIt.Next()) {
+      const TopoDS_Shape& aS=aIt.Value();
+      //
+      if (aMProcessed.Contains(aS)) {
+        continue;
+      }
+      //
+      aType=aS.ShapeType();
+      if (aType==TopAbs_EDGE) {
+        const TopoDS_Edge& aE=TopoDS::Edge(aS);
+        if (BRep_Tool::Degenerated(aE)) {
+          aMProcessed.Add(aE);
+          continue;
+        }
+      }
+      //
+      aLESD.Clear();
+      iErr=GEOMAlgo_AlgoTools::FindSDShapes(aS, aLE, aTol, aLESD, aCtx);
+      if (iErr) {
+        return 2; // Err
+      }
+      //
+      aNbESD=aLESD.Extent();
+      if (!aNbESD) {
+        return 1; // Err
+      }
+      //
+      aMEE.Add(aS, aLESD);
+      //
+      aIt1.Initialize(aLESD);
+      for (; aIt1.More(); aIt1.Next()) {
+        const TopoDS_Shape& aE1=aIt1.Value();
+        aMProcessed.Add(aE1);
+      }
+    }
+  }
+  return 0;
+}
+//=======================================================================
+//function : RefineSDShapes
+//purpose  :
+//=======================================================================
+Standard_Integer GEOMAlgo_AlgoTools::RefineSDShapes
+  (GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape& aMPKLE,
+   const Standard_Real aTol,
+   const Handle(IntTools_Context)& aCtx)
+{
+  Standard_Integer i, aNbE, iErr, j, aNbEE, aNbToAdd;
+  TopTools_IndexedDataMapOfShapeListOfShape aMEE, aMSDE, aMEToAdd;
+  //
+  iErr=1;
+  //
+  aNbE=aMPKLE.Extent();
+  for (i=1; i<=aNbE; ++i) {
+    TopTools_ListOfShape& aLSDE=aMPKLE.ChangeFromIndex(i);
+    //
+    aMEE.Clear();
+    iErr=GEOMAlgo_AlgoTools::FindSDShapes(aLSDE, aTol, aMEE, aCtx);
+    if (iErr) {
+      return iErr;
+    }
+    //
+    aNbEE=aMEE.Extent();
+    if (aNbEE==1) {
+      continue;  // nothing to do
+    }
+    //
+    for (j=1; j<=aNbEE; ++j) {
+      TopTools_ListOfShape& aLEE=aMEE.ChangeFromIndex(j);
+      //
+      if (j==1) {
+        aLSDE.Clear();
+        aLSDE.Append(aLEE);
+      }
+      else {
+        const TopoDS_Shape& aE1=aLEE.First();
+        aMEToAdd.Add(aE1, aLEE);
+      }
+    }
+  }
+  //
+  aNbToAdd=aMEToAdd.Extent();
+  if (!aNbToAdd) {
+    return aNbToAdd;
+  }
+  //
+  for (i=1; i<=aNbToAdd; ++i) {
+    GEOMAlgo_PassKeyShape aPKE1;
+    //
+    const TopoDS_Shape& aE1=aMEToAdd.FindKey(i);
+    const TopTools_ListOfShape& aLE=aMEToAdd(i);
+    //
+    aPKE1.SetShapes(aE1);
+    aMPKLE.Add(aPKE1, aLE);
+  }
+  //
+  return 0;
+}
+//=======================================================================
+//function : BuildTriangulation
+//purpose  :
+//=======================================================================
+Standard_Boolean 
+  GEOMAlgo_AlgoTools::BuildTriangulation (const TopoDS_Shape& theShape)
+{
+  // calculate deflection
+  Standard_Real aDeviationCoefficient = 0.001;
+
+  Bnd_Box B;
+  BRepBndLib::Add(theShape, B);
+  Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
+  B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
+
+  Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
+  Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
+  Standard_Real aHLRAngle = 0.349066;
+
+  // build triangulation
+  BRepMesh_IncrementalMesh Inc (theShape, aDeflection, Standard_False, aHLRAngle);
+
+  // check triangulation
+  bool isTriangulation = true;
+
+  TopExp_Explorer exp (theShape, TopAbs_FACE);
+  if (exp.More())
+  {
+    TopLoc_Location aTopLoc;
+    Handle(Poly_Triangulation) aTRF;
+    aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
+    if (aTRF.IsNull()) {
+      isTriangulation = false;
+    }
+  }
+  else // no faces, try edges
+  {
+    TopExp_Explorer expe (theShape, TopAbs_EDGE);
+    if (!expe.More()) {
+      isTriangulation = false;
+    }
+    else {
+      TopLoc_Location aLoc;
+      Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
+      if (aPE.IsNull()) {
+        isTriangulation = false;
+      }
+    }
+  }
+  return isTriangulation;
+}
+
+//=======================================================================
+//function : IsCompositeShape
+//purpose  :
+//=======================================================================
+Standard_Boolean GEOMAlgo_AlgoTools::IsCompositeShape(const TopoDS_Shape& aS)
+{
+  Standard_Boolean bRet;
+  Standard_Integer iCnt;
+  TopoDS_Iterator aIt;
+  //
+  iCnt=0;
+  GetCount(aS, iCnt);
+  bRet=(iCnt>1);
+  //
+  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<std::pair<TopoDS_Shape, Standard_Real> > 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<TopoDS_Shape, Standard_Real> 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<TopoDS_Shape, Standard_Real>& theA,
+                      const std::pair<TopoDS_Shape, Standard_Real>& 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<std::pair<TopoDS_Shape, Standard_Real>> 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 (file)
index 0000000..a08f5a1
--- /dev/null
@@ -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 <GeomAlgoImpl.h>
+
+#include <Standard.hxx>
+#include <Standard_Macro.hxx>
+#include <Standard_Boolean.hxx>
+#include <IntTools_Context.hxx>
+#include <Standard_Integer.hxx>
+
+#include <gp_Pnt.hxx>
+#include <gp_Pnt2d.hxx>
+
+#include <Geom_Surface.hxx>
+
+#include <TopAbs_ShapeEnum.hxx>
+
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Compound.hxx>
+
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_IndexedDataMapOfShapeShape.hxx>
+
+#include <GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx>
+#include <GEOMAlgo_ListOfCoupleOfShapes.hxx>
+#include <GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape.hxx>
+
+
+//!  Auxiliary tools for Algorithms <br>
+//=======================================================================
+//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 <theP> inside the face <theF>. <br>
+  //!          <theP2D> - 2D representation of <theP> <br>
+  //!          on the surface of <theF> <br>
+  //!          Returns 0 in case of success. <br>
+  GEOMALGOIMPL_EXPORT
+    static Standard_Integer PntInFace(const TopoDS_Face& theF,
+                                      gp_Pnt& theP,
+                                      gp_Pnt2d& theP2D);
+
+  //! Computes a set of points inside the face <theF>. <br>
+  //!          Returns 0 in case of success. <br>
+  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 (file)
index 0000000..7cee395
--- /dev/null
@@ -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 <GEOMAlgo_AlgoTools.hxx>
+
+#include <GEOMAlgo_ListOfCoupleOfShapes.hxx>
+#include <GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <GEOMAlgo_CoupleOfShapes.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+
+
+
+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 (file)
index 0000000..7b8080a
--- /dev/null
@@ -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
+//             <pkv@irinox>
+//
+#include <GEOMAlgo_BndSphere.hxx>
+
+//=======================================================================
+//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 (file)
index 0000000..f016ea2
--- /dev/null
@@ -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
+//             <pkv@irinox>
+
+#ifndef _GEOMAlgo_BndSphere_HeaderFile
+#define _GEOMAlgo_BndSphere_HeaderFile
+
+#include <GeomAlgoImpl.h>
+
+#include <Standard.hxx>
+#include <Standard_Macro.hxx>
+#include <gp_Pnt.hxx>
+#include <Standard_Real.hxx>
+#include <Standard_Boolean.hxx>
+
+
+//=======================================================================
+//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 <GEOMAlgo_BndSphere.lxx>
+
+#endif
diff --git a/src/GeomAlgoImpl/GEOMAlgo_BndSphere.lxx b/src/GeomAlgoImpl/GEOMAlgo_BndSphere.lxx
new file mode 100644 (file)
index 0000000..56efce4
--- /dev/null
@@ -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
+//             <pkv@irinox>
+//=======================================================================
+//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 (file)
index 0000000..7d19556
--- /dev/null
@@ -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
+//             <pkv@irinox>
+//
+#include <GEOMAlgo_BndSphereTree.hxx>
+//=======================================================================
+//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 (file)
index 0000000..8be47ad
--- /dev/null
@@ -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
+//             <pkv@irinox>
+//
+#ifndef GEOMAlgo_BndSphereTree_HeaderFile
+#define GEOMAlgo_BndSphereTree_HeaderFile
+
+#include <GeomAlgoImpl.h>
+
+#include <NCollection_UBTree.hxx>
+#include <GEOMAlgo_BndSphere.hxx>
+#include <TColStd_MapOfInteger.hxx>
+#include <TColStd_ListOfInteger.hxx>
+
+
+typedef NCollection_UBTree <Standard_Integer , GEOMAlgo_BndSphere> 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 (file)
index 0000000..f59fa82
--- /dev/null
@@ -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 <GEOMAlgo_BuilderShape.hxx>
+
+//=======================================================================
+//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 (file)
index 0000000..2642abe
--- /dev/null
@@ -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 <GeomAlgoImpl.h>
+
+#include <Standard.hxx>
+#include <Standard_Macro.hxx>
+#include <Standard_Boolean.hxx>
+
+#include <TopoDS_Shape.hxx>
+
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+
+#include <GEOMAlgo_Algo.hxx>
+
+
+//! Root class for algorithms that has shape as result <br>
+//=======================================================================
+//class    : GEOMAlgo_BuilderShape
+//purpose  :
+//=======================================================================
+class GEOMAlgo_BuilderShape  : public GEOMAlgo_Algo
+{
+ public:
+  //!  Returns the result of algorithm <br>
+  GEOMALGOIMPL_EXPORT
+    const TopoDS_Shape& Shape() const;
+
+  //! Returns the list of shapes generated from the <br>
+  //!          shape theS. <br>
+  GEOMALGOIMPL_EXPORT
+    virtual const TopTools_ListOfShape& Generated(const TopoDS_Shape& theS) ;
+
+  //! Returns the list of shapes modified from the <br>
+  //!          shape theS. <br>
+  GEOMALGOIMPL_EXPORT
+    virtual const TopTools_ListOfShape& Modified(const TopoDS_Shape& theS) ;
+
+  //! Returns true if the shape theS has been deleted. <br>
+  GEOMALGOIMPL_EXPORT
+    virtual  Standard_Boolean IsDeleted(const TopoDS_Shape& theS) ;
+
+  //! Returns true if the at least one shape(or sub-shape) <br>
+  //!          of arguments has been deleted. <br>
+  GEOMALGOIMPL_EXPORT
+    Standard_Boolean HasDeleted() const;
+
+  //! Returns true if the at least one shape(or sub-shape) <br>
+  //!          of arguments has generated shapes. <br>
+  GEOMALGOIMPL_EXPORT
+    Standard_Boolean HasGenerated() const;
+
+  //! Returns true if the at least one shape(or sub-shape) <br>
+  //!          of arguments has modified shapes. <br>
+  GEOMALGOIMPL_EXPORT
+    Standard_Boolean HasModified() const;
+
+  GEOMALGOIMPL_EXPORT
+    const TopTools_IndexedDataMapOfShapeListOfShape& ImagesResult() const;
+
+protected:
+  //! Empty constructor <br>
+  GEOMALGOIMPL_EXPORT
+    GEOMAlgo_BuilderShape();
+
+  GEOMALGOIMPL_EXPORT
+    virtual ~GEOMAlgo_BuilderShape();
+
+  //!  Prepare information for history support <br>
+  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 (file)
index 0000000..60c099a
--- /dev/null
@@ -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
+//              <pkv@irinox>
+//
+#include <GEOMAlgo_CoupleOfShapes.hxx>
+//=======================================================================
+//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 (file)
index 0000000..95a071e
--- /dev/null
@@ -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
+//              <pkv@irinox>
+//
+
+#ifndef _GEOMAlgo_CoupleOfShapes_HeaderFile
+#define _GEOMAlgo_CoupleOfShapes_HeaderFile
+
+#include <GeomAlgoImpl.h>
+
+#include <Standard.hxx>
+#include <Standard_Macro.hxx>
+#include <TopoDS_Shape.hxx>
+
+
+//=======================================================================
+//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 (file)
index 0000000..293df47
--- /dev/null
@@ -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 <GEOMAlgo_GlueDetector.hxx>
+
+#include <Bnd_Box.hxx>
+#include <NCollection_UBTreeFiller.hxx>
+
+#include <TColStd_ListOfInteger.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
+#include <TColStd_MapIteratorOfMapOfInteger.hxx>
+
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Compound.hxx>
+
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopTools_MapIteratorOfMapOfShape.hxx>
+
+#include <TopExp.hxx>
+#include <BRep_Tool.hxx>
+#include <BRep_Builder.hxx>
+#include <BRepBndLib.hxx>
+
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopTools_MapOfShape.hxx>
+
+#include <GEOMAlgo_BndSphereTree.hxx>
+#include <GEOMAlgo_BndSphere.hxx>
+#include <GEOMAlgo_IndexedDataMapOfShapeBndSphere.hxx>
+
+#include <GEOMAlgo_IndexedDataMapOfIntegerShape.hxx>
+#include <GEOMAlgo_PassKeyShape.hxx>
+#include <GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx>
+#include <GEOMAlgo_AlgoTools.hxx>
+
+
+//
+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 <Standard_Integer, GEOMAlgo_BndSphere> 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<TopTools_IndexedDataMapOfShapeListOfShape&>(aMVE).ChangeSeek(aVSD);
+  if (!pLE) {
+    return iRet;
+  }
+  aItLE.Initialize(*pLE);
+  for (; aItLE.More(); aItLE.Next()) {
+    const TopoDS_Shape& aE=aItLE.Value();
+    //
+    pLV=const_cast<TopTools_IndexedDataMapOfShapeListOfShape&>(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 (file)
index 0000000..1bfc619
--- /dev/null
@@ -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 <Standard.hxx>
+#include <Standard_Macro.hxx>
+
+#include <TopAbs_ShapeEnum.hxx>
+
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+
+#include <GEOMAlgo_GluerAlgo.hxx>
+#include <GEOMAlgo_Algo.hxx>
+#include <GEOMAlgo_PassKeyShape.hxx>
+
+
+//=======================================================================
+//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 (file)
index 0000000..3647a66
--- /dev/null
@@ -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 <GEOMAlgo_Gluer2.hxx>
+
+#include <TopAbs_ShapeEnum.hxx>
+
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Vertex.hxx>
+
+#include <BRep_Builder.hxx>
+#include <TopExp.hxx>
+#include <BRepLib.hxx>
+
+#include <TopTools_MapOfShape.hxx>
+#include <TopTools_MapIteratorOfMapOfShape.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+
+#include <BOPTools_AlgoTools.hxx>
+
+#include <GEOMAlgo_GlueDetector.hxx>
+#include <GEOMAlgo_AlgoTools.hxx>
+
+
+//=======================================================================
+//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 (file)
index 0000000..c539c36
--- /dev/null
@@ -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 <GeomAlgoImpl.h>
+
+#include <Standard.hxx>
+#include <Standard_Macro.hxx>
+#include <Standard_Boolean.hxx>
+
+#include <TopAbs_ShapeEnum.hxx>
+
+#include <TopTools_DataMapOfShapeListOfShape.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
+
+#include <GEOMAlgo_GluerAlgo.hxx>
+#include <GEOMAlgo_BuilderShape.hxx>
+#include <GEOMAlgo_GlueDetector.hxx>
+#include <GEOMAlgo_CoupleOfShapes.hxx>
+#include <GEOMAlgo_ListOfCoupleOfShapes.hxx>
+
+//=======================================================================
+//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 (file)
index 0000000..cdffa0d
--- /dev/null
@@ -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 <GEOMAlgo_Gluer2.hxx>
+
+#include <gp_XYZ.hxx>
+#include <gp_Pnt.hxx>
+
+#include <TopLoc_Location.hxx>
+
+#include <Geom_Surface.hxx>
+
+#include <TopAbs_ShapeEnum.hxx>
+
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Iterator.hxx>
+
+#include <BRep_Tool.hxx>
+#include <BRep_Builder.hxx>
+
+#include <BRepTools.hxx>
+#include <TopExp.hxx>
+
+#include <TopTools_MapOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+
+#include <BOPTools_AlgoTools.hxx>
+#include <GEOMAlgo_AlgoTools.hxx>
+#include <BOPTools_AlgoTools2D.hxx>
+
+
+//=======================================================================
+//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 (file)
index 0000000..3a3830c
--- /dev/null
@@ -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
+//              <peter@PREFEX>
+//
+#include <GEOMAlgo_Gluer2.hxx>
+
+#include <TopAbs_ShapeEnum.hxx>
+
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shape.hxx>
+
+#include <BOPTools_AlgoTools.hxx>
+
+#include <GEOMAlgo_BuilderShape.hxx>
+
+
+//=======================================================================
+//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 (file)
index 0000000..2a33953
--- /dev/null
@@ -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 <GEOMAlgo_Gluer2.hxx>
+
+#include <TopAbs_ShapeEnum.hxx>
+
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Edge.hxx>
+
+#include <BRep_Tool.hxx>
+
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+
+#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
+#include <TopTools_DataMapOfShapeListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopTools_MapIteratorOfMapOfShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+
+#include <GEOMAlgo_CoupleOfShapes.hxx>
+#include <GEOMAlgo_ListOfCoupleOfShapes.hxx>
+#include <GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx>
+
+#include <GEOMAlgo_AlgoTools.hxx>
+#include <GEOMAlgo_GlueDetector.hxx>
+#include <GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape.hxx>
+
+
+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 (file)
index 0000000..0d92818
--- /dev/null
@@ -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
+//              <peter@PREFEX>
+//
+#include <GEOMAlgo_GluerAlgo.hxx>
+#include <IntTools_Context.hxx>
+
+//=======================================================================
+//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 (file)
index 0000000..26f2150
--- /dev/null
@@ -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
+//              <pkv@irinox>
+//
+#ifndef _GEOMAlgo_GluerAlgo_HeaderFile
+#define _GEOMAlgo_GluerAlgo_HeaderFile
+
+#include <GeomAlgoImpl.h>
+
+#include <Standard_Macro.hxx>
+#include <TopoDS_Shape.hxx>
+#include <Standard_Real.hxx>
+#include <Standard_Boolean.hxx>
+#include <IntTools_Context.hxx>
+#include <TopTools_DataMapOfShapeListOfShape.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
+
+
+//=======================================================================
+//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 (file)
index 0000000..5da6035
--- /dev/null
@@ -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:
+//              <pkv@BDEURI37616>
+
+
+#ifndef GEOMAlgo_IndexedDataMapOfIntegerShape_HeaderFile
+#define GEOMAlgo_IndexedDataMapOfIntegerShape_HeaderFile
+
+
+
+#include <TopoDS_Shape.hxx>
+#include <Standard_Integer.hxx>
+#include <TColStd_MapIntegerHasher.hxx>
+
+#define _NCollection_MapHasher
+#include <NCollection_IndexedDataMap.hxx>
+
+
+typedef NCollection_IndexedDataMap<Standard_Integer, TopoDS_Shape, TColStd_MapIntegerHasher> GEOMAlgo_IndexedDataMapOfIntegerShape;
+
+#undef _NCollection_MapHasher
+
+
+
+#endif
diff --git a/src/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx b/src/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx
new file mode 100644 (file)
index 0000000..7d2c2eb
--- /dev/null
@@ -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:
+//              <pkv@BDEURI37616>
+
+
+#ifndef GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape_HeaderFile
+#define GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape_HeaderFile
+
+#include <GEOMAlgo_PassKeyShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <GEOMAlgo_PassKeyShapeMapHasher.hxx>
+
+
+#define _NCollection_MapHasher
+#include <NCollection_IndexedDataMap.hxx>
+
+
+typedef NCollection_IndexedDataMap<GEOMAlgo_PassKeyShape, TopTools_ListOfShape, GEOMAlgo_PassKeyShapeMapHasher> GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape;
+
+#undef _NCollection_MapHasher
+
+
+
+#endif
diff --git a/src/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfShapeBndSphere.hxx b/src/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfShapeBndSphere.hxx
new file mode 100644 (file)
index 0000000..3234c30
--- /dev/null
@@ -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:     
+//             <pkv@BDEURI37616>
+
+
+#ifndef GEOMAlgo_IndexedDataMapOfShapeBndSphere_HeaderFile
+#define GEOMAlgo_IndexedDataMapOfShapeBndSphere_HeaderFile
+
+#include <TopoDS_Shape.hxx>  
+#include <TopTools_ShapeMapHasher.hxx>
+#include <GEOMAlgo_BndSphere.hxx>
+
+#define _NCollection_MapHasher
+#include <NCollection_IndexedDataMap.hxx>
+
+
+
+typedef NCollection_IndexedDataMap<TopoDS_Shape, GEOMAlgo_BndSphere, TopTools_ShapeMapHasher> GEOMAlgo_IndexedDataMapOfShapeBndSphere; 
+#undef _NCollection_MapHasher
+
+
+
+
+#endif
diff --git a/src/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape.hxx b/src/GeomAlgoImpl/GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape.hxx
new file mode 100644 (file)
index 0000000..822370d
--- /dev/null
@@ -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:
+//             <pkv@BDEURI37616>
+// File:       GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape.hxx
+// Created:    Mon Feb 20 11:59:23 2012
+// Author:
+//             <pkv@BDEURI37616>
+
+
+#ifndef GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape_HeaderFile
+#define GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape_HeaderFile
+
+
+#include <TopoDS_Shape.hxx>
+#include <TopTools_ShapeMapHasher.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+
+#define _NCollection_MapHasher
+#include <NCollection_IndexedDataMap.hxx>
+
+
+typedef NCollection_IndexedDataMap <TopoDS_Shape, TopTools_IndexedMapOfShape, TopTools_ShapeMapHasher> GEOMAlgo_IndexedDataMapOfShapeIndexedMapOfShape;
+
+#undef _NCollection_MapHasher
+
+
+#endif
+
diff --git a/src/GeomAlgoImpl/GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx b/src/GeomAlgoImpl/GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx
new file mode 100644 (file)
index 0000000..5574a62
--- /dev/null
@@ -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:
+//              <pkv@BDEURI37616>
+
+#ifndef GEOMAlgo_ListIteratorOfListOfCoupleOfShapes_HeaderFile
+#define GEOMAlgo_ListIteratorOfListOfCoupleOfShapes_HeaderFile
+
+#ifndef GEOMAlgo_ListOfCoupleOfShapes_HeaderFile
+#include <GEOMAlgo_ListOfCoupleOfShapes.hxx>
+#endif
+
+#endif
diff --git a/src/GeomAlgoImpl/GEOMAlgo_ListOfCoupleOfShapes.hxx b/src/GeomAlgoImpl/GEOMAlgo_ListOfCoupleOfShapes.hxx
new file mode 100644 (file)
index 0000000..0134afc
--- /dev/null
@@ -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:
+//              <pkv@BDEURI37616>
+
+#ifndef GEOMAlgo_ListOfCoupleOfShapes_HeaderFile
+#define GEOMAlgo_ListOfCoupleOfShapes_HeaderFile
+
+#include <NCollection_List.hxx>
+#include <GEOMAlgo_CoupleOfShapes.hxx>
+
+typedef NCollection_List<GEOMAlgo_CoupleOfShapes> 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 (file)
index 0000000..57686fd
--- /dev/null
@@ -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
+//              <pkv@irinox>
+//
+#include <GEOMAlgo_PassKeyShape.hxx>
+
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+
+
+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 (file)
index 0000000..2a0f759
--- /dev/null
@@ -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
+//              <pkv@irinox>
+//
+#ifndef _GEOMAlgo_PassKeyShape_HeaderFile
+#define _GEOMAlgo_PassKeyShape_HeaderFile
+
+#include <GeomAlgoImpl.h>
+
+#include <Standard.hxx>
+#include <Standard_Macro.hxx>
+#include <Standard_Integer.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <Standard_Boolean.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopTools_ListOfShape.hxx>
+
+
+//=======================================================================
+//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 (file)
index 0000000..d4245cf
--- /dev/null
@@ -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
+//              <pkv@irinox>
+//
+#include <GEOMAlgo_PassKeyShapeMapHasher.hxx>
+
+//=======================================================================
+//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 (file)
index 0000000..229e125
--- /dev/null
@@ -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
+//              <pkv@irinox>
+//
+#ifndef _GEOMAlgo_PassKeyShapeMapHasher_HeaderFile
+#define _GEOMAlgo_PassKeyShapeMapHasher_HeaderFile
+
+#include <GeomAlgoImpl.h>
+
+#include <Standard.hxx>
+#include <Standard_Macro.hxx>
+#include <Standard_Integer.hxx>
+#include <Standard_Boolean.hxx>
+#include <GEOMAlgo_PassKeyShape.hxx>
+
+//=======================================================================
+//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
index a02b05b80a6c6299b1833856d7bc473751f9b56c..47b8c5771b6f65b18027f258dd1e4d3840c2fa06 100644 (file)
@@ -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