Salome HOME
8.3. Intersection feature
authordbv <dbv@opencascade.com>
Tue, 16 Feb 2016 07:34:25 +0000 (10:34 +0300)
committerdbv <dbv@opencascade.com>
Tue, 16 Feb 2016 14:04:48 +0000 (17:04 +0300)
12 files changed:
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_Intersection.h [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp
src/FeaturesPlugin/intersection_widget.xml [new file with mode: 0644]
src/FeaturesPlugin/plugin-Features.xml
src/GeomAlgoAPI/CMakeLists.txt
src/GeomAlgoAPI/GeomAlgoAPI.i
src/GeomAlgoAPI/GeomAlgoAPI_Intersection.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_Intersection.h [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_swig.h
src/GeomValidators/GeomValidators_BooleanSelection.cpp

index a2150fbebed3995f26471d4bcab925da2e96be19..31a4c1c4c9dfd6698518711d32b8f93c00f433ab 100644 (file)
@@ -12,6 +12,7 @@ SET(PROJECT_HEADERS
     FeaturesPlugin_Translation.h
     FeaturesPlugin_Boolean.h
     FeaturesPlugin_Group.h
+    FeaturesPlugin_Intersection.h
     FeaturesPlugin_Partition.h
     FeaturesPlugin_Placement.h
     FeaturesPlugin_CompositeBoolean.h
@@ -35,6 +36,7 @@ SET(PROJECT_SOURCES
     FeaturesPlugin_Translation.cpp
     FeaturesPlugin_Boolean.cpp
     FeaturesPlugin_Group.cpp
+    FeaturesPlugin_Intersection.cpp
     FeaturesPlugin_Partition.cpp
     FeaturesPlugin_Placement.cpp
     FeaturesPlugin_CompositeBoolean.cpp
@@ -66,6 +68,7 @@ SET(XML_RESOURCES
   group_widget.xml
   partition_widget.xml
   placement_widget.xml
+  intersection_widget.xml
 )
 
 INCLUDE_DIRECTORIES(
@@ -77,8 +80,8 @@ INCLUDE_DIRECTORIES(
 
 SET(PROJECT_LIBRARIES
     Events
-    ModelAPI 
-    GeomAPI 
+    ModelAPI
+    GeomAPI
     GeomAlgoAPI
 )
 
diff --git a/src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp b/src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp
new file mode 100644 (file)
index 0000000..39fdb97
--- /dev/null
@@ -0,0 +1,134 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:        FeaturesPlugin_Intersection.cpp
+// Created:     15 Feb 2016
+// Author:      Dmitry Bobylev
+
+#include "FeaturesPlugin_Intersection.h"
+
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Document.h>
+#include <ModelAPI_BodyBuilder.h>
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_AttributeSelectionList.h>
+
+#include <GeomAlgoAPI_Intersection.h>
+
+#include <sstream>
+
+//=================================================================================================
+FeaturesPlugin_Intersection::FeaturesPlugin_Intersection()
+{
+}
+
+//=================================================================================================
+void FeaturesPlugin_Intersection::initAttributes()
+{
+  data()->addAttribute(FeaturesPlugin_Intersection::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId());
+  data()->addAttribute(FeaturesPlugin_Intersection::TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId());
+}
+
+//=================================================================================================
+void FeaturesPlugin_Intersection::execute()
+{
+  ListOfShape anObjects, aTools;
+
+  // Getting objects.
+  AttributeSelectionListPtr anObjectsSelList = selectionList(FeaturesPlugin_Intersection::OBJECT_LIST_ID());
+  for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
+    std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr = anObjectsSelList->value(anObjectsIndex);
+    std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
+    if (!anObject.get()) {
+      return;
+    }
+    anObjects.push_back(anObject);
+  }
+
+  // Getting tools.
+  AttributeSelectionListPtr aToolsSelList = selectionList(FeaturesPlugin_Intersection::TOOL_LIST_ID());
+  for (int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) {
+    std::shared_ptr<ModelAPI_AttributeSelection> aToolAttr = aToolsSelList->value(aToolsIndex);
+    std::shared_ptr<GeomAPI_Shape> aTool = aToolAttr->value();
+    if (!aTool.get()) {
+      return;
+    }
+    aTools.push_back(aTool);
+  }
+
+  if(anObjects.empty() || aTools.empty()) {
+    setError("Error: Objects or tools are empty.");
+    return;
+  }
+
+  int aResultIndex = 0;
+
+  // Create result for each object.
+  for (ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) {
+    std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
+    ListOfShape aListWithObject; aListWithObject.push_back(anObject);
+    GeomAlgoAPI_Intersection anIntersectionAlgo(aListWithObject, aTools);
+
+    // Checking that the algorithm worked properly.
+    if (!anIntersectionAlgo.isDone()) {
+      static const std::string aFeatureError = "Error: Intersection algorithm failed.";
+      setError(aFeatureError);
+      return;
+    }
+    if (anIntersectionAlgo.shape()->isNull()) {
+      static const std::string aShapeError = "Error: Resulting shape is Null.";
+      setError(aShapeError);
+      return;
+    }
+    if (!anIntersectionAlgo.isValid()) {
+      std::string aFeatureError = "Error: resulting shape is not valid";
+      setError(aFeatureError);
+      return;
+    }
+
+    std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
+    loadNamingDS(aResultBody, anObject, aTools, anIntersectionAlgo);
+    setResult(aResultBody, aResultIndex);
+    aResultIndex++;
+  }
+
+  // remove the rest results if there were produced in the previous pass
+  removeResults(aResultIndex);
+}
+
+//=================================================================================================
+void FeaturesPlugin_Intersection::loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+                                               const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+                                               const ListOfShape& theTools,
+                                               GeomAlgoAPI_MakeShape& theMakeShape)
+{
+  //load result
+  std::shared_ptr<GeomAPI_Shape> aResultShape = theMakeShape.shape();
+  std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfShapes = theMakeShape.mapOfSubShapes();
+  const int aDeletedTag = 1;
+  const int aSubsolidsTag = 2; /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids
+  const int aModifyTag = 100000;
+  int aModifyToolsTag = 200000;
+  std::ostringstream aStream;
+
+  theResultBody->storeModified(theBaseShape, aResultShape, aSubsolidsTag);
+
+  std::string aModName = "Modified";
+  theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::VERTEX,
+                                             aModifyTag, aModName, *aMapOfShapes.get(), true);
+  theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::EDGE,
+                                             aModifyTag, aModName, *aMapOfShapes.get(), true);
+  theResultBody->loadDeletedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE, aDeletedTag);
+
+  int anIndex = 1;
+  for(ListOfShape::const_iterator anIter = theTools.begin(); anIter != theTools.end(); anIter++) {
+    aStream.str(std::string());
+    aStream.clear();
+    aStream << aModName << "_" << anIndex++;
+    theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter, GeomAPI_Shape::VERTEX,
+                                               aModifyToolsTag, aStream.str(), *aMapOfShapes.get(), true);
+    theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter, GeomAPI_Shape::EDGE,
+                                               aModifyToolsTag, aStream.str(), *aMapOfShapes.get(), true);
+    theResultBody->loadDeletedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE, aDeletedTag);
+    aModifyToolsTag += 10000;
+  }
+}
diff --git a/src/FeaturesPlugin/FeaturesPlugin_Intersection.h b/src/FeaturesPlugin/FeaturesPlugin_Intersection.h
new file mode 100644 (file)
index 0000000..2c8fff3
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:        FeaturesPlugin_Intersection.h
+// Created:     15 Feb 2016
+// Author:      Dmitry Bobylev
+
+#ifndef FeaturesPlugin_Intersection_H_
+#define FeaturesPlugin_Intersection_H_
+
+#include "FeaturesPlugin.h"
+
+#include <ModelAPI_Feature.h>
+
+#include <GeomAPI_Shape.h>
+
+class GeomAlgoAPI_MakeShape;
+
+/// \class FeaturesPlugin_Intersection
+/// \ingroup Plugins
+/// \brief Intersection feature takes a list of shapes as objects and list of shapes as tools.
+/// The types of objects and tools may be different: whole objects, compsoilds, solids, shells, faces or edges.
+/// The result is less than the minimal dimension from pair of intersection:
+/// for two solids or two faces it is wire, for the edge and face it is vertex, etc.
+class FeaturesPlugin_Intersection : public ModelAPI_Feature
+{
+public:
+  /// Feature kind.
+  inline static const std::string& ID()
+  {
+    static const std::string MY_ID("Intersection");
+    return MY_ID;
+  }
+
+  /// Attribute name of objects.
+  inline static const std::string& OBJECT_LIST_ID()
+  {
+    static const std::string MY_OBJECT_LIST_ID("main_objects");
+    return MY_OBJECT_LIST_ID;
+  }
+
+  /// Attribute name of tools.
+  inline static const std::string& TOOL_LIST_ID()
+  {
+    static const std::string MY_TOOL_LIST_ID("tool_objects");
+    return MY_TOOL_LIST_ID;
+  }
+
+  /// Returns the kind of a feature.
+  FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    static std::string MY_KIND = FeaturesPlugin_Intersection::ID();
+    return MY_KIND;
+  }
+
+  /// Executes feature.
+  FEATURESPLUGIN_EXPORT virtual void execute();
+
+  /// Request for initialization of data model of the feature: adding all attributes.
+  FEATURESPLUGIN_EXPORT virtual void initAttributes();
+
+  /// Use plugin manager for features creation.
+  FeaturesPlugin_Intersection();
+
+private:
+  /// Load Naming data structure of the feature to the document.
+  void loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+                    const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+                    const ListOfShape& theTools,
+                    GeomAlgoAPI_MakeShape& theMakeShape);
+};
+
+#endif
index 26a5b37e6c9f903e42aeb0a326399555abab619f..d40d085baaa2f05bf1cdb0ec0d68ca52608ba243 100644 (file)
@@ -8,6 +8,7 @@
 #include <FeaturesPlugin_ExtrusionCut.h>
 #include <FeaturesPlugin_ExtrusionFuse.h>
 #include <FeaturesPlugin_Group.h>
+#include <FeaturesPlugin_Intersection.h>
 #include <FeaturesPlugin_Translation.h>
 #include <FeaturesPlugin_Partition.h>
 #include <FeaturesPlugin_Placement.h>
@@ -54,6 +55,8 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(string theFeatureID)
     return FeaturePtr(new FeaturesPlugin_Boolean);
   } else if (theFeatureID == FeaturesPlugin_Group::ID()) {
     return FeaturePtr(new FeaturesPlugin_Group);
+  } else if (theFeatureID == FeaturesPlugin_Intersection::ID()) {
+    return FeaturePtr(new FeaturesPlugin_Intersection);
   } else if (theFeatureID == FeaturesPlugin_Partition::ID()) {
     return FeaturePtr(new FeaturesPlugin_Partition);
   } else if (theFeatureID == FeaturesPlugin_Placement::ID()) {
diff --git a/src/FeaturesPlugin/intersection_widget.xml b/src/FeaturesPlugin/intersection_widget.xml
new file mode 100644 (file)
index 0000000..988f3e0
--- /dev/null
@@ -0,0 +1,24 @@
+<!-- Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+<source>
+  <multi_selector id="main_objects"
+    label="Main objects"
+    icon=":icons/cut_shape.png"
+    tooltip="Select objects(objects, compsoilds, solids, shells, faces or edges)"
+    type_choice="Solids Objects"
+    use_choice="false"
+    concealment="true">
+    <validator id="PartSet_DifferentObjects"/>
+    <validator id="GeomValidators_ShapeType" parameters="edge,face,solid"/>
+  </multi_selector>
+  <multi_selector id="tool_objects"
+    label="Tool objects"
+    icon=":icons/cut_tool.png"
+    tooltip="Select tools(objects, compsoilds, solids, shells, faces or edges)"
+    type_choice="Solids Objects"
+    use_choice="false"
+    concealment="true">
+    <validator id="PartSet_DifferentObjects"/>
+    <validator id="GeomValidators_ShapeType" parameters="edge,face,solid"/>
+  </multi_selector>
+</source>
index ba6bf0fb98e2b61941512fbcb2675651950ed783..afe29e4620127105acf345f4ed452f8cd8dd972f 100644 (file)
@@ -37,6 +37,9 @@
       <feature id="Partition" title="Partition" tooltip="Perform partition operations with solids" icon=":icons/partition.png">
           <source path="partition_widget.xml"/>
       </feature>
+      <feature id="Intersection" title="Intersection" tooltip="Intersect objects with tools" icon=":icons/intersection.png">
+          <source path="intersection_widget.xml"/>
+      </feature>
     </group>
     <group id="Collections">
       <feature id="Group"
index 24c17e62d685f5b36d7defc685334f5afc6feb1f..5ad6028f1c56d174033996174186e4431e37d967 100644 (file)
@@ -34,6 +34,7 @@ SET(PROJECT_HEADERS
     GeomAlgoAPI_ShapeTools.h
     GeomAlgoAPI_Partition.h
     GeomAlgoAPI_PaveFiller.h
+    GeomAlgoAPI_Intersection.h
 )
 
 SET(PROJECT_SOURCES
@@ -64,6 +65,7 @@ SET(PROJECT_SOURCES
     GeomAlgoAPI_ShapeTools.cpp
     GeomAlgoAPI_Partition.cpp
     GeomAlgoAPI_PaveFiller.cpp
+    GeomAlgoAPI_Intersection.cpp
 )
 
 SET(PROJECT_LIBRARIES
@@ -72,8 +74,8 @@ SET(PROJECT_LIBRARIES
     ModelAPI
     ${CAS_OCAF}
     ${CAS_SHAPE}
-    ${CAS_TKBO} 
-    ${CAS_TKBool} 
+    ${CAS_TKBO}
+    ${CAS_TKBool}
     ${CAS_TKBRep}
     ${CAS_TKCAF}
     ${CAS_TKCAF}
index 86addb6d2af1f326c52ddfe8b62f2872cb07303a..df680e9df416c165e44136df3c73ac846d1e97b8 100644 (file)
@@ -40,8 +40,9 @@
 %include "GeomAlgoAPI_Tools.h"
 %include "GeomAlgoAPI_Transform.h"
 %include "GeomAlgoAPI_PaveFiller.h"
+%include "GeomAlgoAPI_Intersection.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 );
 }
-%template(ShapeList) std::list<std::shared_ptr<GeomAPI_Shape> >;
\ No newline at end of file
+%template(ShapeList) std::list<std::shared_ptr<GeomAPI_Shape> >;
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Intersection.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Intersection.cpp
new file mode 100644 (file)
index 0000000..a1b29f5
--- /dev/null
@@ -0,0 +1,73 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_Intersection.cpp
+// Created:     16 Feb 2016
+// Author:      Dmitry Bobylev
+
+#include "GeomAlgoAPI_Intersection.h"
+
+#include <GeomAlgoAPI_DFLoader.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+
+#include <BRepAlgoAPI_Section.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS_Builder.hxx>
+
+//=================================================================================================
+GeomAlgoAPI_Intersection::GeomAlgoAPI_Intersection(const ListOfShape& theObjects,
+                                                   const ListOfShape& theTools)
+{
+  build(theObjects, theTools);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_Intersection::build(const ListOfShape& theObjects,
+                                     const ListOfShape& theTools)
+{
+  if (theObjects.empty() || theTools.empty()) {
+    return;
+  }
+
+  // Creating partition operation.
+  BRepAlgoAPI_Section* anOperation = new BRepAlgoAPI_Section;
+  this->setImpl(anOperation);
+  this->setBuilderType(OCCT_BRepBuilderAPI_MakeShape);
+
+  TopAbs_ShapeEnum aShapeType = TopAbs_COMPOUND;
+
+  // Getting objects.
+  TopTools_ListOfShape anObjects;
+  for (ListOfShape::const_iterator anObjectsIt = theObjects.begin(); anObjectsIt != theObjects.end(); anObjectsIt++) {
+    const TopoDS_Shape& aShape = (*anObjectsIt)->impl<TopoDS_Shape>();
+    if(!aShape.IsNull()) {
+      anObjects.Append(aShape);
+    }
+  }
+  anOperation->SetArguments(anObjects);
+
+  // Getting tools.
+  TopTools_ListOfShape aTools;
+  for (ListOfShape::const_iterator aToolsIt = theTools.begin(); aToolsIt != theTools.end(); aToolsIt++) {
+    const TopoDS_Shape& aShape = (*aToolsIt)->impl<TopoDS_Shape>();
+    if(!aShape.IsNull()) {
+      aTools.Append(aShape);
+    }
+  }
+  anOperation->SetTools(aTools);
+
+  // Building and getting result.
+  anOperation->Build();
+  if(!anOperation->IsDone()) {
+    return;
+  }
+  TopoDS_Shape aResult = anOperation->Shape();
+
+  if(aResult.ShapeType() == TopAbs_COMPOUND) {
+    aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
+  }
+
+  std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+  aShape->setImpl(new TopoDS_Shape(aResult));
+  this->setShape(aShape);
+  this->setDone(true);
+}
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Intersection.h b/src/GeomAlgoAPI/GeomAlgoAPI_Intersection.h
new file mode 100644 (file)
index 0000000..4379feb
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_Intersection.h
+// Created:     16 Feb 2016
+// Author:      Dmitry Bobylev
+
+#ifndef GeomAlgoAPI_Intersection_H_
+#define GeomAlgoAPI_Intersection_H_
+
+#include <GeomAlgoAPI.h>
+#include <GeomAlgoAPI_MakeShape.h>
+
+#include <GeomAPI_Shape.h>
+
+/// \class GeomAlgoAPI_Intersection
+/// \ingroup DataAlgo
+/// \brief Performs the intersection operations.
+class GeomAlgoAPI_Intersection : public GeomAlgoAPI_MakeShape
+{
+public:
+  /// \brief Constructor.
+  /// \param[in] theObjects list of objects.
+  /// \param[in] theTools list of tools.
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_Intersection(const ListOfShape& theObjects,
+                                              const ListOfShape& theTools);
+
+private:
+  /// Builds resulting shape.
+  void build(const ListOfShape& theObjects,
+             const ListOfShape& theTools);
+};
+
+#endif
index 164f8ec61783d4325a54ecaa18549daa68f056b6..b93b23850c9c1b4369bc3b99765bf4c5e42a5af3 100644 (file)
@@ -34,6 +34,7 @@
   #include "GeomAlgoAPI_Tools.h"
   #include "GeomAlgoAPI_Transform.h"
   #include "GeomAlgoAPI_PaveFiller.h"
+  #include "GeomAlgoAPI_Intersection.h"
 
   #include <memory>
   #include <string>
index f3f6f248d37f2ff5d6eb6162dab1226f46bf6cec..c4af6a2e4b3e2a3075a4d8f22527fcc1302cc7fb 100644 (file)
@@ -40,8 +40,12 @@ bool GeomValidators_BooleanSelection::isValid(const AttributePtr& theAttribute,
         return false;
       }
       std::string aFeatureKind = aFeature->getKind();
-      if(aFeatureKind == "Sketch") {
-        theError = "Error: sketch shape is selected, but only objects are acceptable.";
+      if(aFeatureKind == "Sketch" || 
+         aFeatureKind == "Plane" ||
+         aFeatureKind == "Axis") {
+        theError = "Error: ";
+        theError += aFeatureKind;
+        theError += " shape is not allowed for selection.";
         return false;
       }
       aShape = aContext->shape();