Salome HOME
Issue #1369: Added "SubShapes" feature.
authordbv <dbv@opencascade.com>
Fri, 29 Apr 2016 17:50:57 +0000 (20:50 +0300)
committerdbv <dbv@opencascade.com>
Thu, 5 May 2016 13:20:21 +0000 (16:20 +0300)
34 files changed:
src/BuildPlugin/BuildPlugin_Plugin.cpp
src/BuildPlugin/BuildPlugin_SubShapes.cpp [new file with mode: 0644]
src/BuildPlugin/BuildPlugin_SubShapes.h [new file with mode: 0644]
src/BuildPlugin/BuildPlugin_Validators.cpp
src/BuildPlugin/BuildPlugin_Validators.h
src/BuildPlugin/CMakeLists.txt
src/BuildPlugin/edge_widget.xml
src/BuildPlugin/face_widget.xml
src/BuildPlugin/plugin-Build.xml
src/BuildPlugin/shell_widget.xml
src/BuildPlugin/subshapes_widget.xml [new file with mode: 0644]
src/BuildPlugin/vertex_widget.xml
src/BuildPlugin/wire_widget.xml
src/GeomAPI/CMakeLists.txt
src/GeomAPI/GeomAPI.i
src/GeomAPI/GeomAPI_DataMapOfShapeMapOfShapes.cpp
src/GeomAPI/GeomAPI_DataMapOfShapeMapOfShapes.h
src/GeomAPI/GeomAPI_Edge.cpp
src/GeomAPI/GeomAPI_Edge.h
src/GeomAPI/GeomAPI_Shape.cpp
src/GeomAPI/GeomAPI_Shape.h
src/GeomAPI/GeomAPI_ShapeIterator.cpp [new file with mode: 0644]
src/GeomAPI/GeomAPI_ShapeIterator.h [new file with mode: 0644]
src/GeomAPI/GeomAPI_Wire.cpp [new file with mode: 0644]
src/GeomAPI/GeomAPI_Wire.h [new file with mode: 0644]
src/GeomAPI/GeomAPI_swig.h
src/GeomAlgoAPI/CMakeLists.txt
src/GeomAlgoAPI/GeomAlgoAPI.i
src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeBuilder.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_ShapeBuilder.h [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h
src/GeomAlgoAPI/GeomAlgoAPI_swig.h

index d834be91f67edda124b4ebed1526762b8f42dd76..4a0097948477332a87348799929f6737a5d9959e 100644 (file)
@@ -14,6 +14,7 @@
 #include <BuildPlugin_Wire.h>
 #include <BuildPlugin_Face.h>
 #include <BuildPlugin_Shell.h>
+#include <BuildPlugin_SubShapes.h>
 #include <BuildPlugin_Validators.h>
 
 // the only created instance of this plugin
@@ -31,6 +32,8 @@ BuildPlugin_Plugin::BuildPlugin_Plugin()
                               new BuildPlugin_ValidatorBaseForWire());
   aFactory->registerValidator("BuildPlugin_ValidatorBaseForFace",
                               new BuildPlugin_ValidatorBaseForFace());
+  aFactory->registerValidator("BuildPlugin_ValidatorSubShapesSelection",
+                              new BuildPlugin_ValidatorSubShapesSelection());
 
   // Register this plugin.
   ModelAPI_Session::get()->registerPlugin(this);
@@ -49,6 +52,8 @@ FeaturePtr BuildPlugin_Plugin::createFeature(std::string theFeatureID)
     return FeaturePtr(new BuildPlugin_Face());
   } else if(theFeatureID == BuildPlugin_Shell::ID()) {
     return FeaturePtr(new BuildPlugin_Shell());
+  } else if(theFeatureID == BuildPlugin_SubShapes::ID()) {
+    return FeaturePtr(new BuildPlugin_SubShapes());
   }
 
   // Feature of such kind is not found.
diff --git a/src/BuildPlugin/BuildPlugin_SubShapes.cpp b/src/BuildPlugin/BuildPlugin_SubShapes.cpp
new file mode 100644 (file)
index 0000000..d0e1af5
--- /dev/null
@@ -0,0 +1,122 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        BuildPlugin_SubShapes.cpp
+// Created:     14 April 2016
+// Author:      Dmitry Bobylev
+
+#include "BuildPlugin_SubShapes.h"
+
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+
+#include <GeomAPI_Edge.h>
+#include <GeomAPI_ShapeIterator.h>
+#include <GeomAPI_Wire.h>
+
+#include <GeomAlgoAPI_ShapeBuilder.h>
+
+//==================================================================================================
+BuildPlugin_SubShapes::BuildPlugin_SubShapes()
+{
+}
+
+//==================================================================================================
+void BuildPlugin_SubShapes::initAttributes()
+{
+  data()->addAttribute(BASE_SHAPE_ID(), ModelAPI_AttributeSelection::typeId());
+
+  data()->addAttribute(SUB_SHAPES_ID(), ModelAPI_AttributeSelectionList::typeId());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SUB_SHAPES_ID());
+}
+
+void BuildPlugin_SubShapes::attributeChanged(const std::string& theID)
+{
+  ModelAPI_Feature::attributeChanged(theID);
+
+  if(theID == BASE_SHAPE_ID()) {
+    AttributeSelectionPtr aShapeAttrSelection = selection(BASE_SHAPE_ID());
+    AttributeSelectionListPtr aSubShapesAttrList = selectionList(SUB_SHAPES_ID());
+    if(!aShapeAttrSelection.get() || !aSubShapesAttrList.get()) {
+      return;
+    }
+    ResultPtr aContext = aShapeAttrSelection->context();
+
+    aSubShapesAttrList->clear();
+
+    GeomShapePtr aBaseShape = aShapeAttrSelection->value();
+    if(!aBaseShape.get()) {
+      return;
+    }
+    GeomAPI_Shape::ShapeType aBaseShapeType = aBaseShape->shapeType();
+    for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
+      GeomShapePtr aSubShape = anIt.current();
+      if(aBaseShapeType == GeomAPI_Shape::WIRE) {
+        for(GeomAPI_ShapeIterator aSubIt(aSubShape); aSubIt.more(); aSubIt.next()) {
+          GeomShapePtr aSubOfSubShape = aSubIt.current();
+          if(aSubOfSubShape->orientation() == GeomAPI_Shape::INTERNAL) {
+            aSubShapesAttrList->append(aContext, aSubOfSubShape);
+          }
+        }
+      } else if(aBaseShapeType == GeomAPI_Shape::FACE) {
+        if(aSubShape->shapeType() != GeomAPI_Shape::WIRE) {
+          aSubShapesAttrList->append(aContext, aSubShape);
+        } else if(aSubShape->orientation() == GeomAPI_Shape::INTERNAL) {
+          if(aSubShape->shapeType() == GeomAPI_Shape::WIRE) {
+            for(GeomAPI_ShapeIterator aWireIt(aSubShape); aWireIt.more(); aWireIt.next()) {
+              aSubShapesAttrList->append(aContext, aWireIt.current());
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+//==================================================================================================
+void BuildPlugin_SubShapes::execute()
+{
+  // Get base shape and sub-shapes list.
+  AttributeSelectionPtr aShapeAttrSelection = selection(BASE_SHAPE_ID());
+  AttributeSelectionListPtr aSubShapesAttrList = selectionList(SUB_SHAPES_ID());
+  if(!aShapeAttrSelection.get() || !aSubShapesAttrList.get()) {
+    return;
+  }
+
+  // Get base shape without internal shapes.
+  GeomShapePtr aBaseShape = aShapeAttrSelection->value();
+  if(!aBaseShape.get()) {
+    return;
+  }
+  GeomAlgoAPI_ShapeBuilder aBuilder;
+  aBuilder.removeInternal(aBaseShape);
+  GeomShapePtr aResultShape = aBuilder.shape();
+
+  // Get list of shapes.
+  ListOfShape aShapesToAdd;
+  for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
+    AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
+    aShapesToAdd.push_back(anAttrSelectionInList->value());
+  }
+
+  // Copy sub-shapes from list to new shape.
+  if(!aShapesToAdd.empty()) {
+    aBuilder.add(aResultShape, aShapesToAdd);
+    aResultShape = aBuilder.shape();
+  }
+
+  // Store result.
+  ResultBodyPtr aResultBody = document()->createBody(data());
+  aResultBody->storeModified(aBaseShape, aResultShape);
+  aResultBody->loadAndOrientModifiedShapes(&aBuilder, aBaseShape, GeomAPI_Shape::EDGE, 1,
+                                          "Modified_Edge", *aBuilder.mapOfSubShapes().get());
+  for(ListOfShape::const_iterator anIt = aShapesToAdd.cbegin(); anIt != aShapesToAdd.cend(); ++anIt) {
+    GeomAPI_Shape::ShapeType aShType = (*anIt)->shapeType();
+    aResultBody->loadAndOrientModifiedShapes(&aBuilder, *anIt, aShType, 1,
+                                             aShType == GeomAPI_Shape::VERTEX ? "Modified_Vertex" : "Modified_Edge",
+                                             *aBuilder.mapOfSubShapes().get());
+  }
+  setResult(aResultBody);
+}
diff --git a/src/BuildPlugin/BuildPlugin_SubShapes.h b/src/BuildPlugin/BuildPlugin_SubShapes.h
new file mode 100644 (file)
index 0000000..8910f0c
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        BuildPlugin_SubShapes.h
+// Created:     14 April 2016
+// Author:      Dmitry Bobylev
+
+#ifndef BuildPlugin_SubShapes_H_
+#define BuildPlugin_SubShapes_H_
+
+#include "BuildPlugin.h"
+
+#include <ModelAPI_Feature.h>
+
+/// \class BuildPlugin_SubShapes
+/// \ingroup Plugins
+/// \brief Feature for adding or removing sub-shapes from shape.
+class BuildPlugin_SubShapes: public ModelAPI_Feature
+{
+public:
+  /// Use plugin manager for features creation
+  BuildPlugin_SubShapes();
+
+  /// Feature kind.
+  inline static const std::string& ID()
+  {
+    static const std::string MY_ID("SubShapes");
+    return MY_ID;
+  }
+
+  /// Attribute name of base shape.
+  inline static const std::string& BASE_SHAPE_ID()
+  {
+    static const std::string MY_BASE_SHAPE_ID("base_shape");
+    return MY_BASE_SHAPE_ID;
+  }
+
+  /// Attribute name of sub-shapes.
+  inline static const std::string& SUB_SHAPES_ID()
+  {
+    static const std::string MY_SUB_SHAPES_ID("sub_shapes");
+    return MY_SUB_SHAPES_ID;
+  }
+
+  /// \return the kind of a feature.
+  BUILDPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    static std::string MY_KIND = BuildPlugin_SubShapes::ID();
+    return MY_KIND;
+  }
+
+  /// Request for initialization of data model of the feature: adding all attributes.
+  BUILDPLUGIN_EXPORT virtual void initAttributes();
+
+  /// Called on change of any argument-attribute of this object.
+  /// \param[in] theID identifier of changed attribute.
+  BUILDPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
+
+  /// Creates a new part document if needed.
+  BUILDPLUGIN_EXPORT virtual void execute();
+};
+
+#endif
index dfdd20d3990afd28b0e77fdaf2af31db0ab9d11d..cde7cf95bc11cf81c3d5cb97dcaac299f5781cc2 100644 (file)
@@ -19,6 +19,7 @@
 #include <GeomAlgoAPI_SketchBuilder.h>
 #include <GeomAlgoAPI_WireBuilder.h>
 
+#include <GeomValidators_FeatureKind.h>
 #include <GeomValidators_ShapeType.h>
 
 #include <Events_Error.h>
@@ -30,11 +31,13 @@ bool BuildPlugin_ValidatorBaseForBuild::isValid(const AttributePtr& theAttribute
 {
   // Get base objects list.
   if(theAttribute->attributeType() != ModelAPI_AttributeSelectionList::typeId()) {
-    Events_Error::send("Error: BuildPlugin_ValidatorBaseForBuild does not support attribute type \"" + theAttribute->attributeType()
-      + "\"\n Only \"" + ModelAPI_AttributeSelectionList::typeId() + "\" supported.");
+    Events_Error::send("Error: BuildPlugin_ValidatorBaseForBuild does not support attribute type \""
+      + theAttribute->attributeType() + "\"\n Only \"" + ModelAPI_AttributeSelectionList::typeId()
+      + "\" supported.");
     return false;
   }
-  AttributeSelectionListPtr aSelectionList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+  AttributeSelectionListPtr aSelectionList =
+    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
   if(!aSelectionList.get()) {
     theError = "Could not get selection list.";
     return false;
@@ -109,7 +112,8 @@ bool BuildPlugin_ValidatorBaseForWire::isValid(const std::shared_ptr<ModelAPI_Fe
 {
   // Get attribute.
   if(theArguments.size() != 1) {
-    Events_Error::send("Error: BuildPlugin_ValidatorBaseForWire should be used only with 1 parameter (ID of base objects list).");
+    Events_Error::send("Error: BuildPlugin_ValidatorBaseForWire should be used only with "
+      "1 parameter (ID of base objects list).");
     return false;
   }
   AttributeSelectionListPtr aSelectionList = theFeature->selectionList(theArguments.front());
@@ -153,7 +157,8 @@ bool BuildPlugin_ValidatorBaseForFace::isValid(const std::shared_ptr<ModelAPI_Fe
 {
   // Get attribute.
   if(theArguments.size() != 1) {
-    Events_Error::send("Error: BuildPlugin_ValidatorBaseForFace should be used only with 1 parameter (ID of base objects list).");
+    Events_Error::send("Error: BuildPlugin_ValidatorBaseForFace should be used only with "
+      "1 parameter (ID of base objects list).");
     return false;
   }
   AttributeSelectionListPtr aSelectionList = theFeature->selectionList(theArguments.front());
@@ -218,3 +223,90 @@ bool BuildPlugin_ValidatorBaseForFace::isNotObligatory(std::string theFeature, s
 {
   return false;
 }
+
+//=================================================================================================
+bool BuildPlugin_ValidatorSubShapesSelection::isValid(const AttributePtr& theAttribute,
+                                                      const std::list<std::string>& theArguments,
+                                                      std::string& theError) const
+{
+  if(theArguments.size() != 2) {
+    Events_Error::send("Error: BuildPlugin_ValidatorSubShapesSelection should be used only with "
+      "2 parameters (ID of base shape; Sketch feature id).");
+    return false;
+  }
+
+  // Get base objects list.
+  if(theAttribute->attributeType() != ModelAPI_AttributeSelectionList::typeId()) {
+    Events_Error::send("Error: BuildPlugin_ValidatorSubShapesSelection does not support attribute type \""
+      + theAttribute->attributeType() + "\"\n Only \"" + ModelAPI_AttributeSelectionList::typeId()
+      + "\" supported.");
+    return false;
+  }
+  AttributeSelectionListPtr aSelectionList =
+    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+  if(!aSelectionList.get()) {
+    theError = "Could not get selection list.";
+    return false;
+  }
+
+  // Get base shape.
+  FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
+  AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(theArguments.front());
+
+  if(!aShapeAttrSelection.get()) {
+    theError = "Base shape is empty.";
+    return false;
+  }
+
+  ResultPtr aBaseContext = aShapeAttrSelection->context();
+
+  GeomShapePtr aBaseShape  = aShapeAttrSelection->value();
+  if(!aBaseShape.get()) {
+    theError = "Base shape is empty.";
+    return false;
+  }
+
+  // If selected shape is wire allow to select only vertices. If face - allow vertices and edges.
+  std::set<GeomAPI_Shape::ShapeType> anAllowedTypes;
+  switch(aBaseShape->shapeType()) {
+    case GeomAPI_Shape::FACE: anAllowedTypes.insert(GeomAPI_Shape::EDGE);
+    case GeomAPI_Shape::WIRE: anAllowedTypes.insert(GeomAPI_Shape::VERTEX);
+    default: break;
+  }
+
+  // Check selected shapes.
+  GeomValidators_FeatureKind aFeatureKindValidator;
+  std::list<std::string> anArguments;
+  anArguments.push_back(theArguments.back());
+  for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
+    AttributeSelectionPtr aSelectionAttrInList = aSelectionList->value(anIndex);
+    if(!aSelectionAttrInList.get()) {
+      theError = "Empty attribute in list.";
+      return false;
+    }
+    // If context not same check that it is a selection on Sketch.
+    if(aBaseContext != aSelectionAttrInList->context()) {
+      if(!aFeatureKindValidator.isValid(aSelectionAttrInList, anArguments, theError)) {
+        return false;
+      }
+    }
+
+    // Check shape type.
+    GeomShapePtr aShapeInList = aSelectionAttrInList->value();
+    if(!aShapeInList.get()) {
+      aShapeInList = aSelectionAttrInList->context()->shape();
+    }
+    if(anAllowedTypes.find(aShapeInList->shapeType()) == anAllowedTypes.cend()) {
+      theError = "Selected shape has unacceptable type.";
+      return false;
+    }
+
+    // Check that shape inside wire or face.
+    if(!GeomAlgoAPI_ShapeTools::isSubShapeInShape(aShapeInList, aBaseShape)) {
+      theError = "Selected shape is not inside base face.";
+      return false;
+    }
+  }
+
+  return true;
+}
index 1f2091efe0e45347047c9eb7399cc7b3677d5a31..2bd253f9ddbc3736d4eeab108b6854fb5e0bb9c7 100644 (file)
@@ -64,4 +64,19 @@ public:
   virtual bool isNotObligatory(std::string theFeature, std::string theAttribute);
 };
 
+/// \class BuildPlugin_ValidatorSubShapesSelection
+/// \ingroup Validators
+/// \brief A validator for selection sub-shapes for SubShape feature.
+class BuildPlugin_ValidatorSubShapesSelection: public ModelAPI_AttributeValidator
+{
+public:
+  //! Returns true if attribute is ok.
+  //! \param[in] theAttribute the checked attribute.
+  //! \param[in] theArguments arguments of the attribute.
+  //! \param[out] theError error message.
+   virtual bool isValid(const AttributePtr& theAttribute,
+                        const std::list<std::string>& theArguments,
+                        std::string& theError) const;
+};
+
 #endif
index 0a7cda8f9ce71e5c656ee8d3bc85564a6b4f84ad..8c3b62d88b8676c16215faa9bac3bd987b465ea5 100644 (file)
@@ -19,6 +19,7 @@ SET(PROJECT_HEADERS
     BuildPlugin_Wire.h
     BuildPlugin_Face.h
     BuildPlugin_Shell.h
+    BuildPlugin_SubShapes.h
     BuildPlugin_Validators.h
 )
 
@@ -29,6 +30,7 @@ SET(PROJECT_SOURCES
     BuildPlugin_Wire.cpp
     BuildPlugin_Face.cpp
     BuildPlugin_Shell.cpp
+    BuildPlugin_SubShapes.cpp
     BuildPlugin_Validators.cpp
 )
 
@@ -39,6 +41,7 @@ SET(XML_RESOURCES
     wire_widget.xml
     face_widget.xml
     shell_widget.xml
+    subshapes_widget.xml
 )
 
 SET(PROJECT_LIBRARIES
index bacb83e55b7f74d17745f549b707ee5be8b44a1b..6890eae4d997a92a84193053942847becf84209c 100644 (file)
@@ -4,7 +4,8 @@
   <multi_selector id="base_objects"
                   label="Edges:"
                   tooltip="Select edges on sketch or edges objects."
-                  type_choice="edges objects">
+                  type_choice="edges objects"
+                  concealment="true">
     <validator id="BuildPlugin_ValidatorBaseForBuild" parameters="edge"/>
   </multi_selector>
 </source>
index a019054bd4a06e3934dac47fe70485a221b3b3e6..49ea6b4cc95c58810c33ca571e1fdbb2461c5885 100644 (file)
@@ -4,7 +4,8 @@
   <multi_selector id="base_objects"
                   label="Segments and wires:"
                   tooltip="Select edges on sketch, edges or wires objects."
-                  type_choice="edges objects">
+                  type_choice="edges objects"
+                  concealment="true">
     <validator id="BuildPlugin_ValidatorBaseForBuild" parameters="edge,wire"/>
   </multi_selector>
   <validator id="BuildPlugin_ValidatorBaseForFace" parameters="base_objects"/>
index 362eb118f65b4abb7751616895db16cfff69087c..f66be99e8800982c781fd58d454af921efd57c93 100644 (file)
@@ -2,7 +2,7 @@
 
 <plugin>
   <workbench id="Build" document="Part">
-    <group id="Shape">
+    <group id="Generate">
       <feature id="Vertex" title="Vertex" tooltip ="Create a vertex from sketch vertex and vertex objects" icon="icons/Build/feature_vertex.png">
         <source path="vertex_widget.xml"/>
       </feature>
         <source path="shell_widget.xml"/>
       </feature>
     </group>
+    <group id="Modify">
+      <feature id="SubShapes" title="Sub-Shapes" tooltip ="Allows to add or to remove sub-shapes of the selected shape" icon="icons/Build/feature_subshapes.png">
+        <source path="subshapes_widget.xml"/>
+      </feature>
+    </group>
    </workbench>
 </plugin>
index 00defb939a0415f95b232a96bc4ea4017dd10fc8..45e2a716ededca3098ba3071e0fc441590dd0770 100644 (file)
@@ -4,7 +4,8 @@
   <multi_selector id="base_objects"
                   label="Faces and shells:"
                   tooltip="Select faces or shells objects."
-                  type_choice="objects">
+                  type_choice="objects"
+                  concealment="true">
     <validator id="GeomValidators_ShapeType" parameters="face,shell"/>
   </multi_selector>
 </source>
diff --git a/src/BuildPlugin/subshapes_widget.xml b/src/BuildPlugin/subshapes_widget.xml
new file mode 100644 (file)
index 0000000..767d015
--- /dev/null
@@ -0,0 +1,18 @@
+<!-- Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+<source>
+  <shape_selector id="base_shape"
+                  label="Shape:"
+                  tooltip="Select a shape to modify."
+                  shape_types="objects"
+                  concealment="true">
+    <validator id="GeomValidators_ShapeType" parameters="wire,face"/>
+  </shape_selector>
+  <multi_selector id="sub_shapes"
+                  label="Sub-Shapes:"
+                  tooltip="Select shapes on sketch to add."
+                  type_choice="vertices edges"
+                  concealment="true">
+    <validator id="BuildPlugin_ValidatorSubShapesSelection" parameters="base_shape,Sketch"/>
+  </multi_selector>
+</source>
index cbf5ae8e49215a37391ca1276a1d24b0fbe49bbf..372da411cc36515925ddf563bcf283e39726ce74 100644 (file)
@@ -4,7 +4,8 @@
   <multi_selector id="base_objects"
                   label="Vertices:"
                   tooltip="Select vertices on sketch or vertex objects."
-                  type_choice="vertices objects">
+                  type_choice="vertices objects"
+                  concealment="true">
     <validator id="BuildPlugin_ValidatorBaseForBuild" parameters="vertex"/>
   </multi_selector>
 </source>
index cae74e9a36f49ecc49d9482f0d654eb6c128e205..e2c99d561ef73e312319c6a688486903a257082c 100644 (file)
@@ -4,7 +4,8 @@
   <multi_selector id="base_objects"
                   label="Segments and wires:"
                   tooltip="Select edges on sketch, edges or wires objects."
-                  type_choice="edges objects">
+                  type_choice="edges objects"
+                  concealment="true">
     <validator id="BuildPlugin_ValidatorBaseForBuild" parameters="edge,wire"/>
   </multi_selector>
   <action id="add_contour"
index 9f5ba706f2e813c5b92542a292709efdadefa0f1..c440f5e4dc4afe65adb2deabde9067714001428c 100644 (file)
@@ -21,6 +21,7 @@ SET(PROJECT_HEADERS
     GeomAPI_Pln.h
     GeomAPI_Shape.h
     GeomAPI_ShapeExplorer.h
+    GeomAPI_ShapeIterator.h
     GeomAPI_Edge.h
     GeomAPI_Face.h
     GeomAPI_PlanarEdges.h
@@ -37,6 +38,7 @@ SET(PROJECT_HEADERS
     GeomAPI_Trsf.h
     GeomAPI_Angle.h
     GeomAPI_Angle2d.h
+    GeomAPI_Wire.h
 )
 
 SET(PROJECT_SOURCES
@@ -54,6 +56,7 @@ SET(PROJECT_SOURCES
     GeomAPI_Pln.cpp
     GeomAPI_Shape.cpp
     GeomAPI_ShapeExplorer.cpp
+    GeomAPI_ShapeIterator.cpp
     GeomAPI_Edge.cpp
     GeomAPI_Face.cpp
     GeomAPI_PlanarEdges.cpp
@@ -70,6 +73,7 @@ SET(PROJECT_SOURCES
     GeomAPI_Trsf.cpp
     GeomAPI_Angle.cpp
     GeomAPI_Angle2d.cpp
+    GeomAPI_Wire.cpp
 )
 
 SET(PROJECT_LIBRARIES
index b367e4333d258c2969672548e737c84816791ed7..02687c2590dfec87e98ca7870e7897f241a77dec 100644 (file)
 %shared_ptr(GeomAPI_Pnt2d)
 %shared_ptr(GeomAPI_Shape)
 %shared_ptr(GeomAPI_ShapeExplorer)
+%shared_ptr(GeomAPI_ShapeIterator)
 %shared_ptr(GeomAPI_Vertex)
 %shared_ptr(GeomAPI_XY)
 %shared_ptr(GeomAPI_XYZ)
 %shared_ptr(GeomAPI_Trsf)
+%shared_ptr(GeomAPI_Wire)
 
 
 // all supported interfaces
@@ -68,7 +70,9 @@
 %include "GeomAPI_Pnt.h"
 %include "GeomAPI_Pnt2d.h"
 %include "GeomAPI_ShapeExplorer.h"
+%include "GeomAPI_ShapeIterator.h"
 %include "GeomAPI_Vertex.h"
 %include "GeomAPI_XY.h"
 %include "GeomAPI_XYZ.h"
 %include "GeomAPI_Trsf.h"
+%include "GeomAPI_Wire.h"
index 9e076e6f9c838140ce1129adb3af7f80bdaaf0a3..350289e897451c836eb25fc6f294782f2237dfb4 100644 (file)
@@ -22,6 +22,9 @@ bool GeomAPI_DataMapOfShapeMapOfShapes::bind(const std::shared_ptr<GeomAPI_Shape
                                              const ListOfShape& theItems)
 {
   const TopoDS_Shape& aKey = theKey->impl<TopoDS_Shape>();
+  if(MY_MAP->IsBound(aKey)) {
+    MY_MAP->ChangeFind(aKey).Clear();
+  }
   for(ListOfShape::const_iterator anIt = theItems.cbegin(); anIt != theItems.cend(); anIt++) {
     const TopoDS_Shape& anItem = (*anIt)->impl<TopoDS_Shape>();
     if(MY_MAP->IsBound(aKey)) {
@@ -85,6 +88,12 @@ bool GeomAPI_DataMapOfShapeMapOfShapes::unBind(const std::shared_ptr<GeomAPI_Sha
   return MY_MAP->UnBind(aKey) == Standard_True;
 }
 
+//=================================================================================================
+void GeomAPI_DataMapOfShapeMapOfShapes::clear()
+{
+  return MY_MAP->Clear();
+}
+
 //=================================================================================================
 int GeomAPI_DataMapOfShapeMapOfShapes::size() const
 {
index 5dd4dbd4d67fc3cb9c487841a7b98ef6bc5ab6fc..1d2c55911c524851fdf2697bbd0499a51b5d92b8 100644 (file)
@@ -7,33 +7,30 @@
 #ifndef GeomAPI_DataMapOfShapeMapOfShapes_H_
 #define GeomAPI_DataMapOfShapeMapOfShapes_H_
 
-#include <GeomAPI_Interface.h>
+#include "GeomAPI_Interface.h"
 
-#include <GeomAPI_Shape.h>
+#include "GeomAPI_Shape.h"
 
-/**\class GeomAPI_DataMapOfShapeMapOfShapes
- * \ingroup DataModel
- * \brief DataMap of Shape - Map of Shapes defined by TopoDS_Shapes
- */
+/// \class GeomAPI_DataMapOfShapeMapOfShapes
+/// \ingroup DataModel
+/// \brief DataMap of Shape - Map of Shapes defined by TopoDS_Shapes
 class GeomAPI_DataMapOfShapeMapOfShapes : public GeomAPI_Interface
 {
 public:
   /// Constructor.Creates empty map.
   GEOMAPI_EXPORT GeomAPI_DataMapOfShapeMapOfShapes();
 
-  /** \brief Binds list of shapes to the key shape.
-      \param[in] theKey key shape.
-      \param[in] theItems list of shapes. If shapes have duplications in list only one will be stored.
-      \returns true if items bound successfully.
-   */
+  /// \brief Binds list of shapes to the key shape.
+  /// \param[in] theKey key shape.
+  /// \param[in] theItems list of shapes. If shapes have duplications in list only one will be stored.
+  /// \returns true if items bound successfully.
   GEOMAPI_EXPORT bool bind(const std::shared_ptr<GeomAPI_Shape> theKey,
                            const ListOfShape& theItems);
 
-  /** \brief Adds item to the map bounded to the key.
-      \param[in] theKey key shape.
-      \param[in] theItem item shape.
-      \returns true if item bounded successfully. False if it is already bound.
-   */
+  /// \brief Adds item to the map bounded to the key.
+  /// \param[in] theKey key shape.
+  /// \param[in] theItem item shape.
+  /// \returns true if item bounded successfully. False if it is already bound.
   GEOMAPI_EXPORT bool add(const std::shared_ptr<GeomAPI_Shape> theKey,
                           const std::shared_ptr<GeomAPI_Shape> theItem);
 
@@ -47,6 +44,9 @@ public:
   /// Undinds shapes from theKey.
   GEOMAPI_EXPORT bool unBind(const std::shared_ptr<GeomAPI_Shape> theKey);
 
+  /// Clears map.
+  GEOMAPI_EXPORT void clear();
+
   /// \return size of map.
   GEOMAPI_EXPORT int size() const;
 };
index 63761a0317b65c5a040d45132a313753115df0ba..594829f8cbb90c0af9422be90d989aa6770f2e18 100644 (file)
@@ -14,6 +14,7 @@
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS.hxx>
+#include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
 #include <Geom_Curve.hxx>
 #include <Geom_Line.hxx>
 #include <gp_Pln.hxx>
 
 GeomAPI_Edge::GeomAPI_Edge()
-  : GeomAPI_Shape()
 {
+  TopoDS_Edge* anEdge = new TopoDS_Edge;
+
+  BRep_Builder aBuilder;
+  aBuilder.MakeEdge(*anEdge);
+
+  setImpl(anEdge);
 }
 
 GeomAPI_Edge::GeomAPI_Edge(const std::shared_ptr<GeomAPI_Shape>& theShape)
index d0d5ca2e81c4b9ba70cbbe8e7877c2add5c5fd4c..e4dfcf2a8201208ab78b576f073c0d57b3ddbed6 100644 (file)
@@ -22,7 +22,7 @@ class GeomAPI_Lin;
 class GeomAPI_Edge : public GeomAPI_Shape
 {
 public:
-   /// Creation of empty (null) shape
+   /// Makes an undefined Edge (no geometry).
   GEOMAPI_EXPORT 
    GeomAPI_Edge();
 
index 3b85b2dcf421425fa6f81f2220498bc4fa623321..0ee2a087c67a17b2d790f8e8b4df1b12d5a89255 100644 (file)
@@ -36,6 +36,13 @@ GeomAPI_Shape::GeomAPI_Shape()
 {
 }
 
+std::shared_ptr<GeomAPI_Shape> GeomAPI_Shape::emptyCopied() const
+{
+  GeomShapePtr aShape(new GeomAPI_Shape());
+  aShape->setImpl(new TopoDS_Shape(MY_SHAPE->EmptyCopied()));
+  return aShape;
+}
+
 bool GeomAPI_Shape::isNull() const
 {
   return MY_SHAPE->IsNull() == Standard_True;
@@ -314,6 +321,31 @@ std::string GeomAPI_Shape::shapeTypeStr() const
   return aShapeTypeStr;
 }
 
+GeomAPI_Shape::Orientation GeomAPI_Shape::orientation() const
+{
+  TopAbs_Orientation anOrientation = MY_SHAPE->Orientation();
+
+  switch(anOrientation) {
+    case TopAbs_FORWARD:  return FORWARD;
+    case TopAbs_REVERSED: return REVERSED;
+    case TopAbs_INTERNAL: return INTERNAL;
+    case TopAbs_EXTERNAL: return EXTERNAL;
+    default:              return FORWARD;
+  }
+}
+
+void GeomAPI_Shape::setOrientation(const GeomAPI_Shape::Orientation theOrientation)
+{
+  TopAbs_Orientation anOrientation = MY_SHAPE->Orientation();
+
+  switch(theOrientation) {
+    case FORWARD:  MY_SHAPE->Orientation(TopAbs_FORWARD);  break;
+    case REVERSED: MY_SHAPE->Orientation(TopAbs_REVERSED); break;
+    case INTERNAL: MY_SHAPE->Orientation(TopAbs_INTERNAL); break;
+    case EXTERNAL: MY_SHAPE->Orientation(TopAbs_EXTERNAL); break;
+  }
+}
+
 bool GeomAPI_Shape::isSubShape(const std::shared_ptr<GeomAPI_Shape> theShape) const
 {
   if(!theShape.get()) {
index 098245119c13aa28dc5775ad90170410d5ab714b..9d2b8b278292dbfd435b1528846960c6f0d8b926 100644 (file)
@@ -25,11 +25,23 @@ public:
     SHAPE
   };
 
+  /// Shape orientation
+  enum Orientation {
+    FORWARD,
+    REVERSED,
+    INTERNAL,
+    EXTERNAL
+  };
+
  public:
   /// Creation of empty (null) shape
   GEOMAPI_EXPORT 
   GeomAPI_Shape();
 
+  /// \return a new Shape with the same Orientation and Location and a new TShape with the same
+  ///         geometry and no sub-shapes.
+  GEOMAPI_EXPORT std::shared_ptr<GeomAPI_Shape> emptyCopied() const;
+
   /// Returns true if the underlied shape is null
   GEOMAPI_EXPORT 
   bool isNull() const;
@@ -82,11 +94,16 @@ public:
   GEOMAPI_EXPORT
   virtual std::string shapeTypeStr() const;
 
+  /// \return the shape orientation.
+  GEOMAPI_EXPORT virtual Orientation orientation() const;
+
+  /// Sets the shape orientation.
+  GEOMAPI_EXPORT virtual void setOrientation(const Orientation theOrientation);
+
   /// \return true if passed shape is a sub-shape of this shape.
   /// \param theShape shape to search.
   GEOMAPI_EXPORT virtual bool isSubShape(const std::shared_ptr<GeomAPI_Shape> theShape) const;
 
-
   /// Computes boundary dimensions of the shape
   /// Returns False if it is not possible
   GEOMAPI_EXPORT 
diff --git a/src/GeomAPI/GeomAPI_ShapeIterator.cpp b/src/GeomAPI/GeomAPI_ShapeIterator.cpp
new file mode 100644 (file)
index 0000000..6b63f20
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAPI_ShapeIterator.cpp
+// Created:     27 April 2016
+// Author:      Dmitry Bobylev
+
+#include "GeomAPI_ShapeIterator.h"
+
+#include <Standard_NoMoreObject.hxx>
+#include <TopoDS_Iterator.hxx>
+
+#define MY_ITERATOR implPtr<TopoDS_Iterator>()
+
+//==================================================================================================
+GeomAPI_ShapeIterator::GeomAPI_ShapeIterator()
+: GeomAPI_Interface(new TopoDS_Iterator())
+{
+}
+
+//==================================================================================================
+GeomAPI_ShapeIterator::GeomAPI_ShapeIterator(const std::shared_ptr<GeomAPI_Shape> theShape)
+: GeomAPI_Interface(new TopoDS_Iterator())
+{
+  init(theShape);
+}
+
+//==================================================================================================
+void GeomAPI_ShapeIterator::init(const std::shared_ptr<GeomAPI_Shape> theShape)
+{
+  if(!theShape.get()) {
+    return;
+  }
+  MY_ITERATOR->Initialize(theShape->impl<TopoDS_Shape>());
+}
+
+//==================================================================================================
+bool GeomAPI_ShapeIterator::more() const
+{
+  return MY_ITERATOR->More() == Standard_True;
+}
+
+//==================================================================================================
+void GeomAPI_ShapeIterator::next()
+{
+  try {
+    MY_ITERATOR->Next();
+  } catch (Standard_NoMoreObject) {
+  }
+}
+
+//==================================================================================================
+std::shared_ptr<GeomAPI_Shape> GeomAPI_ShapeIterator::current()
+{
+  try {
+    const TopoDS_Shape& aShape = MY_ITERATOR->Value();
+    std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape());
+    aGeomShape->setImpl(new TopoDS_Shape(aShape));
+    return aGeomShape;
+  } catch (Standard_NoMoreObject) {
+    return std::shared_ptr<GeomAPI_Shape>();
+  }
+}
diff --git a/src/GeomAPI/GeomAPI_ShapeIterator.h b/src/GeomAPI/GeomAPI_ShapeIterator.h
new file mode 100644 (file)
index 0000000..098f171
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAPI_ShapeIterator.h
+// Created:     27 April 2016
+// Author:      Dmitry Bobylev
+
+#ifndef GeomAPI_ShapeIterator_H_
+#define GeomAPI_ShapeIterator_H_
+
+#include "GeomAPI.h"
+#include "GeomAPI_Shape.h"
+
+/// \class GeomAPI_ShapeIterator
+/// \ingroup DataModel
+/// \brief Iterates on the underlying shape underlying a given GeomAPI_Shape object, providing access
+///        to its component sub-shapes. Each component shape is returned as a GeomAPI_Shape with
+///        an orientation, and a compound of the original values and the relative values.
+class GeomAPI_ShapeIterator : public GeomAPI_Interface
+{
+public:
+  /// Default constructor. Creates an empty iterator, becomes usefull after Init.
+  GEOMAPI_EXPORT GeomAPI_ShapeIterator();
+
+  /// \brief Creates an iterator on theShape sub-shapes.
+  /// \param[in] theShape shape to iterate.
+  GEOMAPI_EXPORT GeomAPI_ShapeIterator(const std::shared_ptr<GeomAPI_Shape> theShape);
+
+  /// \brief Initializes this iterator with theShape.
+  /// \param[in] theShape shape to iterate.
+  GEOMAPI_EXPORT void init(const std::shared_ptr<GeomAPI_Shape> theShape);
+
+  /// \return  true if there is another sub-shape in the shape which this iterator is scanning.
+  GEOMAPI_EXPORT bool more() const;
+
+  /// Moves on to the next sub-shape in the shape which this iterator is scanning.
+  GEOMAPI_EXPORT void next();
+
+  /// \return the current sub-shape in the shape which this iterator is scanning.
+  GEOMAPI_EXPORT std::shared_ptr<GeomAPI_Shape> current();
+};
+
+#endif
\ No newline at end of file
diff --git a/src/GeomAPI/GeomAPI_Wire.cpp b/src/GeomAPI/GeomAPI_Wire.cpp
new file mode 100644 (file)
index 0000000..e5eb9d4
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAPI_Wire.cpp
+// Created:     28 April 2016
+// Author:      Dmitry Bobylev
+
+#include "GeomAPI_Wire.h"
+
+#include <BRep_Builder.hxx>
+#include <TopoDS_Wire.hxx>
+
+//==================================================================================================
+GeomAPI_Wire::GeomAPI_Wire()
+{
+  TopoDS_Wire* aWire = new TopoDS_Wire();
+
+  BRep_Builder aBuilder;
+  aBuilder.MakeWire(*aWire);
+
+  this->setImpl(aWire);
+}
diff --git a/src/GeomAPI/GeomAPI_Wire.h b/src/GeomAPI/GeomAPI_Wire.h
new file mode 100644 (file)
index 0000000..2c11608
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAPI_Wire.h
+// Created:     28 April 2016
+// Author:      Dmitry Bobylev
+
+#ifndef GeomAPI_Wire_H_
+#define GeomAPI_Wire_H_
+
+#include "GeomAPI_Shape.h"
+
+/// \class GeomAPI_Wire
+/// \ingroup DataModel
+/// \brief Interface to the wire object
+class GeomAPI_Wire: public GeomAPI_Shape
+{
+public:
+  /// Makes an undefined Wire.
+  GEOMAPI_EXPORT GeomAPI_Wire();
+};
+
+#endif
+
index 0dd57e6cd5b8a2341cd7d083ba84e8d85c9de976..2c8e0e44983019a6a853a0394736670d04c12837 100644 (file)
   #include "GeomAPI_Pnt2d.h"
   #include "GeomAPI_Shape.h"
   #include "GeomAPI_ShapeExplorer.h"
+  #include "GeomAPI_ShapeIterator.h"
   #include "GeomAPI_Vertex.h"
   #include "GeomAPI_XY.h"
   #include "GeomAPI_XYZ.h"
   #include "GeomAPI_Trsf.h"
+  #include "GeomAPI_Wire.h"
 
   #include <memory>
   #include <string>
index e765913a8bb46a71c9617c52f3501e09690287af..bdc7a8d58f32052a355c1f992b846b59a406f019 100644 (file)
@@ -38,6 +38,7 @@ SET(PROJECT_HEADERS
     GeomAlgoAPI_Pipe.h
     GeomAlgoAPI_WireBuilder.h
     GeomAlgoAPI_Sewing.h
+    GeomAlgoAPI_ShapeBuilder.h
 )
 
 SET(PROJECT_SOURCES
@@ -72,6 +73,7 @@ SET(PROJECT_SOURCES
     GeomAlgoAPI_Pipe.cpp
     GeomAlgoAPI_WireBuilder.cpp
     GeomAlgoAPI_Sewing.cpp
+    GeomAlgoAPI_ShapeBuilder.cpp
 )
 
 SET(PROJECT_LIBRARIES
index e4efaa2ba357688ebfd5c3e9dc4086aba5c0213f..cd79ade66626b8d1923c62f036fce8d89b465bdd 100644 (file)
@@ -44,6 +44,7 @@
 %include "GeomAlgoAPI_Pipe.h"
 %include "GeomAlgoAPI_WireBuilder.h"
 %include "GeomAlgoAPI_Sewing.h"
+%include "GeomAlgoAPI_ShapeBuilder.h"
 
 %typemap(out) std::list< std::shared_ptr< GeomAPI_Shape > >::value_type & {
   $result = SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr<GeomAPI_Shape>(*$1)), $descriptor(std::shared_ptr<GeomAPI_Shape> *), SWIG_POINTER_OWN | 0 );
index e7d5165ce194d85bd478b8cefadc035be7fd08bd..2397dafbf472d1300a96edc933f6575dc5a46f01 100644 (file)
@@ -91,7 +91,10 @@ void GeomAlgoAPI_MakeShape::modified(const std::shared_ptr<GeomAPI_Shape> theSha
   TopTools_ListOfShape aList;
   if(myBuilderType == OCCT_BRepBuilderAPI_MakeShape) {
     BRepBuilderAPI_MakeShape* aMakeShape = implPtr<BRepBuilderAPI_MakeShape>();
-    aList = aMakeShape->Modified(theShape->impl<TopoDS_Shape>());
+    try {
+      aList = aMakeShape->Modified(theShape->impl<TopoDS_Shape>());
+    } catch(Standard_NoSuchObject) {
+    }
   } else if(myBuilderType == OCCT_BOPAlgo_Builder) {
     BOPAlgo_Builder* aBOPBuilder = implPtr<BOPAlgo_Builder>();
     aList = aBOPBuilder->Modified(theShape->impl<TopoDS_Shape>());
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeBuilder.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeBuilder.cpp
new file mode 100644 (file)
index 0000000..eea9ae9
--- /dev/null
@@ -0,0 +1,175 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_ShapeBuilder.cpp
+// Created:     27 April 2016
+// Author:      Dmitry Bobylev
+
+#include "GeomAlgoAPI_ShapeBuilder.h"
+
+#include "GeomAlgoAPI_MakeShapeCustom.h"
+
+#include <GeomAPI_ShapeIterator.h>
+
+#include <BRep_Builder.hxx>
+#include <BRepBuilderAPI_Copy.hxx>
+#include <BRepExtrema_DistShapeShape.hxx>
+#include <BRepTools_ReShape.hxx>
+#include <Precision.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shape.hxx>
+
+//==================================================================================================
+void GeomAlgoAPI_ShapeBuilder::add(std::shared_ptr<GeomAPI_Shape> theShape,
+                                   const std::shared_ptr<GeomAPI_Shape> theShapeToAdd)
+{
+  if(!theShape.get() || !theShapeToAdd.get()) {
+    return;
+  }
+
+  TopoDS_Shape* aShape = theShape->implPtr<TopoDS_Shape>();
+  const TopoDS_Shape& aShapeToAdd = theShapeToAdd->impl<TopoDS_Shape>();
+
+  BRep_Builder aBuilder;
+  aBuilder.Add(*aShape, aShapeToAdd);
+}
+
+
+//==================================================================================================
+void GeomAlgoAPI_ShapeBuilder::remove(std::shared_ptr<GeomAPI_Shape> theShape,
+                                      const std::shared_ptr<GeomAPI_Shape> theShapeToRemove)
+{
+  if(!theShape.get() || !theShapeToRemove.get()) {
+    return;
+  }
+
+  TopoDS_Shape* aShape = theShape->implPtr<TopoDS_Shape>();
+  const TopoDS_Shape& aShapeToRemove = theShapeToRemove->impl<TopoDS_Shape>();
+
+  BRep_Builder aBuilder;
+  aBuilder.Remove(*aShape, aShapeToRemove);
+}
+
+//==================================================================================================
+GeomAlgoAPI_ShapeBuilder::GeomAlgoAPI_ShapeBuilder()
+{
+}
+
+//==================================================================================================
+void GeomAlgoAPI_ShapeBuilder::removeInternal(const std::shared_ptr<GeomAPI_Shape> theShape)
+{
+  GeomShapePtr aResultShape = theShape->emptyCopied();
+  GeomAPI_Shape::ShapeType aBaseShapeType = theShape->shapeType();
+  std::shared_ptr<GeomAlgoAPI_MakeShapeCustom> aMakeShapeCustom(new GeomAlgoAPI_MakeShapeCustom());
+  for(GeomAPI_ShapeIterator anIter(theShape); anIter.more(); anIter.next()) {
+    GeomShapePtr aSubShape = anIter.current();
+    if(aBaseShapeType == GeomAPI_Shape::WIRE) {
+      GeomShapePtr aSubShapeCopy = aSubShape->emptyCopied();
+      aMakeShapeCustom->addModified(aSubShape, aSubShapeCopy);
+      for(GeomAPI_ShapeIterator aSubIter(aSubShape); aSubIter.more(); aSubIter.next()) {
+        GeomShapePtr aSubOfSubShape = aSubIter.current();
+        if(aSubOfSubShape->orientation() != GeomAPI_Shape::INTERNAL) {
+          GeomAlgoAPI_ShapeBuilder::add(aSubShapeCopy, aSubOfSubShape);
+        }
+      }
+      GeomAlgoAPI_ShapeBuilder::add(aResultShape, aSubShapeCopy);
+    } else if(aBaseShapeType == GeomAPI_Shape::FACE) {
+      if(aSubShape->shapeType() == GeomAPI_Shape::WIRE
+          && aSubShape->orientation() != GeomAPI_Shape::INTERNAL) {
+        GeomAlgoAPI_ShapeBuilder::add(aResultShape, aSubShape);
+      }
+    }
+  }
+
+  this->appendAlgo(aMakeShapeCustom);
+
+  setShape(aResultShape);
+  setDone(true);
+}
+
+//==================================================================================================
+void GeomAlgoAPI_ShapeBuilder::add(const std::shared_ptr<GeomAPI_Shape> theShape,
+                                   const ListOfShape& theShapesToAdd)
+{
+  // Get base shape.
+  if(!theShape.get()) {
+    return;
+  }
+  const TopoDS_Shape& aBaseShape = theShape->impl<TopoDS_Shape>();
+  TopAbs_ShapeEnum aBaseShapeType = aBaseShape.ShapeType();
+
+  // Copy base shape.
+  BRepBuilderAPI_Copy* aCopyBuilder = new BRepBuilderAPI_Copy(aBaseShape, Standard_False);
+  this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aCopyBuilder)));
+  if(!aCopyBuilder->IsDone()) {
+    return;
+  }
+  TopoDS_Shape aResultShape = aCopyBuilder->Shape();
+
+  // Copy sub-shapes from list to new shape.
+  BRep_Builder aBuilder;
+  std::shared_ptr<GeomAlgoAPI_MakeShapeCustom> aMakeShapeCustom(new GeomAlgoAPI_MakeShapeCustom());
+  for(ListOfShape::const_iterator anIt = theShapesToAdd.cbegin(); anIt != theShapesToAdd.cend(); ++anIt) {
+    TopoDS_Shape aShapeToAdd = (*anIt)->impl<TopoDS_Shape>();
+    for(TopExp_Explorer aResExp(aResultShape, TopAbs_VERTEX); aResExp.More(); aResExp.Next()) {
+      const TopoDS_Vertex& aVertexInRes = TopoDS::Vertex(aResExp.Current());
+      const gp_Pnt aPntInRes = BRep_Tool::Pnt(aVertexInRes);
+      for(TopExp_Explorer anAddExp(aShapeToAdd, TopAbs_VERTEX); anAddExp.More(); anAddExp.Next()) {
+        const TopoDS_Vertex& aVertexInAdd = TopoDS::Vertex(anAddExp.Current());
+        const gp_Pnt aPntInAdd = BRep_Tool::Pnt(aVertexInAdd);
+        if(aPntInRes.Distance(aPntInAdd) < Precision::Confusion()) {
+          BRepTools_ReShape aReShape;
+          TopoDS_Shape aVertexInResMod = aVertexInRes;
+          aVertexInResMod.Orientation(aVertexInAdd.Orientation());
+          aReShape.Replace(aVertexInAdd, aVertexInResMod);
+          TopoDS_Shape aModShape = aReShape.Apply(aShapeToAdd);
+
+          GeomShapePtr aGeomBaseShape(new GeomAPI_Shape());
+          GeomShapePtr aGeomModShape(new GeomAPI_Shape());
+          aGeomBaseShape->setImpl(new TopoDS_Shape(aShapeToAdd));
+          aGeomModShape->setImpl(new TopoDS_Shape(aModShape));
+          aMakeShapeCustom->addModified(aGeomBaseShape, aGeomModShape);
+          aShapeToAdd = aModShape;
+        }
+      }
+    }
+    TopAbs_ShapeEnum aShapeToAddType = aShapeToAdd.ShapeType();
+    if(aBaseShapeType == TopAbs_WIRE) {
+      if(aShapeToAddType == TopAbs_VERTEX) {
+        // Find on which edge vertex is lie and add to this edge.
+        for(TopExp_Explorer aResultExp(aResultShape, TopAbs_EDGE); aResultExp.More(); aResultExp.Next()) {
+          TopoDS_Shape anEdge = aResultExp.Current();
+          BRepExtrema_DistShapeShape aDist(anEdge, aShapeToAdd);
+          aDist.Perform();
+          if(aDist.IsDone() && aDist.Value() <= Precision::Confusion()) {
+            aShapeToAdd.Orientation(TopAbs_INTERNAL);
+            Standard_Boolean aFreeFlag = anEdge.Free();
+            anEdge.Free(Standard_True);
+            aBuilder.Add(anEdge, aShapeToAdd);
+            anEdge.Free(aFreeFlag);
+            break;
+          }
+        }
+      }
+    } else if(aBaseShapeType == GeomAPI_Shape::FACE) {
+      if(aShapeToAddType == GeomAPI_Shape::EDGE) {
+        aShapeToAdd.Orientation(TopAbs_INTERNAL);
+        TopoDS_Wire aWire;
+        aBuilder.MakeWire(aWire);
+        aBuilder.Add(aWire, aShapeToAdd);
+        aShapeToAdd = aWire;
+        aShapeToAdd.Orientation(TopAbs_INTERNAL);
+      }
+      aBuilder.Add(aResultShape, aShapeToAdd);
+    }
+  }
+  this->appendAlgo(aMakeShapeCustom);
+
+  // Set result.
+  std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+  aShape->setImpl(new TopoDS_Shape(aResultShape));
+  setShape(aShape);
+  setDone(true);
+}
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeBuilder.h b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeBuilder.h
new file mode 100644 (file)
index 0000000..55ecaa3
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_ShapeBuilder.h
+// Created:     27 April 2016
+// Author:      Dmitry Bobylev
+
+#ifndef GeomAlgoAPI_ShapeBuilder_H_
+#define GeomAlgoAPI_ShapeBuilder_H_
+
+#include "GeomAlgoAPI.h"
+#include "GeomAlgoAPI_MakeShapeList.h"
+
+#include <GeomAPI_Shape.h>
+
+/// \class GeomAlgoAPI_ShapeBuilder
+/// \ingroup DataAlgo
+/// \brief Allows to add or remove subshapes from a shape.
+class GeomAlgoAPI_ShapeBuilder: public GeomAlgoAPI_MakeShapeList
+{
+ public:
+   /// \brief Adds theShapeToAdd in theShape.
+   /// \param[in] theShape shape to modify.
+   /// \param[in] theShapeToAdd shape which will be added.
+   GEOMALGOAPI_EXPORT static void add(std::shared_ptr<GeomAPI_Shape> theShape,
+                                      const std::shared_ptr<GeomAPI_Shape> theShapeToAdd);
+
+   /// \brief Removes theShapeToRemove in theShape.
+   /// \param[in] theShape shape to modify.
+   /// \param[in] theShapeToRemove shape which will be removed.
+   GEOMALGOAPI_EXPORT static void remove(std::shared_ptr<GeomAPI_Shape> theShape,
+                                         const std::shared_ptr<GeomAPI_Shape> theShapeToRemove);
+
+   /// Creates empty builder.
+   GEOMALGOAPI_EXPORT GeomAlgoAPI_ShapeBuilder();
+
+   /// \brief Store new shape as result of removing internal shapes from theShape.
+   /// \param[in] theShape base shape.
+   GEOMALGOAPI_EXPORT void removeInternal(const std::shared_ptr<GeomAPI_Shape> theShape);
+
+   /// \brief Store new shape as result of adding theShapesToAdd to theShape.
+   /// \param[in] theShape base shape.
+   /// \param[in] theShapesToAdd shapes which will be added.
+   GEOMALGOAPI_EXPORT void add(const std::shared_ptr<GeomAPI_Shape> theShape,
+                               const ListOfShape& theShapesToAdd);
+};
+
+#endif
index 47d05e566058953cd77ab69d04fc1f59493010e6..4ce4640ef188df4daa0740fcecfa1471f4d9d053 100644 (file)
 #include <Bnd_Box.hxx>
 #include <BOPTools.hxx>
 #include <BRep_Builder.hxx>
+#include <BRepAdaptor_Curve.hxx>
 #include <BRepAlgo_FaceRestrictor.hxx>
 #include <BRepBndLib.hxx>
 #include <BRepBuilderAPI_FindPlane.hxx>
+#include <BRepBuilderAPI_MakeEdge.hxx>
 #include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepExtrema_DistShapeShape.hxx>
 #include <BRepGProp.hxx>
+#include <BRepTopAdaptor_FClass2d.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom2d_Curve.hxx>
+#include <BRepLib_CheckCurveOnSurface.hxx>
 #include <BRep_Tool.hxx>
 #include <Geom_Plane.hxx>
 #include <GeomLib_IsPlanarSurface.hxx>
 #include <GeomLib_Tool.hxx>
+#include <GeomProjLib.hxx>
 #include <gp_Pln.hxx>
 #include <GProp_GProps.hxx>
 #include <IntAna_IntConicQuad.hxx>
 #include <IntAna_Quadric.hxx>
 #include <NCollection_Vector.hxx>
 #include <ShapeAnalysis.hxx>
+#include <ShapeAnalysis_Surface.hxx>
 #include <TopoDS_Builder.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Face.hxx>
@@ -398,3 +407,74 @@ std::shared_ptr<GeomAPI_Pln> GeomAlgoAPI_ShapeTools::findPlane(const ListOfShape
 
   return aPln;
 }
+
+//=================================================================================================
+bool GeomAlgoAPI_ShapeTools::isSubShapeInShape(const std::shared_ptr<GeomAPI_Shape> theSubShape,
+                                               const std::shared_ptr<GeomAPI_Shape> theBaseShape)
+{
+  if(!theSubShape.get() || !theBaseShape.get()) {
+    return false;
+  }
+
+  const TopoDS_Shape& aSubShape = theSubShape->impl<TopoDS_Shape>();
+  const TopoDS_Shape& aBaseShape = theBaseShape->impl<TopoDS_Shape>();
+
+  if(aSubShape.ShapeType() == TopAbs_VERTEX) {
+    // If sub-shape is a vertex check distance to shape. If it is <= Precision::Confusion() then OK.
+    BRepExtrema_DistShapeShape aDist(aBaseShape, aSubShape);
+    aDist.Perform();
+    if(!aDist.IsDone() || aDist.Value() > Precision::Confusion()) {
+      return false;
+    }
+  } else if (aSubShape.ShapeType() == TopAbs_EDGE) {
+    if(aBaseShape.ShapeType() == TopAbs_FACE) {
+      // Check that edge is on face surface.
+      TopoDS_Face aFace = TopoDS::Face(aBaseShape);
+      TopoDS_Edge anEdge = TopoDS::Edge(aSubShape);
+      BRepLib_CheckCurveOnSurface aCheck(anEdge, aFace);
+      aCheck.Perform();
+      if(!aCheck.IsDone() || aCheck.MaxDistance() > Precision::Confusion()) {
+        return false;
+      }
+
+      // Check intersections.
+      TopoDS_Vertex aV1, aV2;
+      ShapeAnalysis::FindBounds(anEdge, aV1, aV2);
+      gp_Pnt aPnt1 = BRep_Tool::Pnt(aV1);
+      gp_Pnt aPnt2 = BRep_Tool::Pnt(aV2);
+      for(TopExp_Explorer anExp(aBaseShape, TopAbs_EDGE); anExp.More(); anExp.Next()) {
+        const TopoDS_Shape& anEdgeOnFace = anExp.Current();
+        BRepExtrema_DistShapeShape aDist(anEdgeOnFace, anEdge);
+        aDist.Perform();
+        if(aDist.IsDone() && aDist.Value() <= Precision::Confusion()) {
+          // Edge intersect face bound. Check that it is not on edge begin or end.
+          for(Standard_Integer anIndex = 1; anIndex <= aDist.NbSolution(); ++anIndex) {
+            gp_Pnt aPntOnSubShape = aDist.PointOnShape2(anIndex);
+            if(aPntOnSubShape.Distance(aPnt1) > Precision::Confusion()
+                && aPntOnSubShape.Distance(aPnt2) > Precision::Confusion()) {
+              return false;
+            }
+          }
+        }
+      }
+
+      // No intersections found. Edge is inside or outside face. Check it.
+      BRepAdaptor_Curve aCurveAdaptor(anEdge);
+      gp_Pnt aPointToCheck = aCurveAdaptor.Value((aCurveAdaptor.FirstParameter() + aCurveAdaptor.LastParameter()) / 2.0);
+      Handle(Geom_Surface) aSurface = BRep_Tool::Surface(aFace);
+      ShapeAnalysis_Surface aSAS(aSurface);
+      gp_Pnt2d aPointOnFace = aSAS.ValueOfUV(aPointToCheck, Precision::Confusion());
+      BRepTopAdaptor_FClass2d aFClass2d(aFace, Precision::Confusion());
+      if(aFClass2d.Perform(aPointOnFace) == TopAbs_OUT) {
+        return false;
+      }
+
+    } else {
+      return false;
+    }
+  } else {
+    return false;
+  }
+
+  return true;
+}
index 07d6704ab861d8cc4d0dfc2de5ec64d040d05677..3fdee67c5d9380bee37f4938ab7f2e6a6099f326 100644 (file)
@@ -78,6 +78,13 @@ public:
   /// \param[in] theShapes shapes to find plane.
   /// \return plane where all shapes lie or empty ptr if they not planar.
   static std::shared_ptr<GeomAPI_Pln> findPlane(const ListOfShape& theShapes);
+
+  /// \brief Checks that vertex/edge is inside face or vertext inside wire.
+  /// \param[in] theSubShape shape that should be inside.
+  /// \param[in] theBaseShape base shape.
+  /// \return true if edge inside the face.
+  static bool isSubShapeInShape(const std::shared_ptr<GeomAPI_Shape> theSubShape,
+                                const std::shared_ptr<GeomAPI_Shape> theBaseShape);
 };
 
 #endif
index 3cf49122dbd9ab254e62aa0a7e1aa8c8bb825d8c..2eb6c3f913ca0bdad60b38977f3dfd865c3b82f2 100644 (file)
@@ -38,7 +38,8 @@
   #include "GeomAlgoAPI_Pipe.h"
   #include "GeomAlgoAPI_WireBuilder.h"
   #include "GeomAlgoAPI_Sewing.h"
-  
+  #include "GeomAlgoAPI_ShapeBuilder.h"
+
   #include <memory>
   #include <string>
   #include <list>