From dcd6c43521f88d6cc4808dd0ee96d4eefcb1a019 Mon Sep 17 00:00:00 2001 From: dbv Date: Tue, 16 Feb 2016 10:34:25 +0300 Subject: [PATCH] 8.3. Intersection feature --- src/FeaturesPlugin/CMakeLists.txt | 7 +- .../FeaturesPlugin_Intersection.cpp | 134 ++++++++++++++++++ .../FeaturesPlugin_Intersection.h | 72 ++++++++++ src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp | 3 + src/FeaturesPlugin/intersection_widget.xml | 24 ++++ src/FeaturesPlugin/plugin-Features.xml | 3 + src/GeomAlgoAPI/CMakeLists.txt | 6 +- src/GeomAlgoAPI/GeomAlgoAPI.i | 3 +- src/GeomAlgoAPI/GeomAlgoAPI_Intersection.cpp | 73 ++++++++++ src/GeomAlgoAPI/GeomAlgoAPI_Intersection.h | 33 +++++ src/GeomAlgoAPI/GeomAlgoAPI_swig.h | 1 + .../GeomValidators_BooleanSelection.cpp | 8 +- 12 files changed, 360 insertions(+), 7 deletions(-) create mode 100644 src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp create mode 100644 src/FeaturesPlugin/FeaturesPlugin_Intersection.h create mode 100644 src/FeaturesPlugin/intersection_widget.xml create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_Intersection.cpp create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_Intersection.h diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index a2150fbeb..31a4c1c4c 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -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 index 000000000..39fdb9782 --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp @@ -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 +#include +#include +#include +#include + +#include + +#include + +//================================================================================================= +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 anObjectAttr = anObjectsSelList->value(anObjectsIndex); + std::shared_ptr 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 aToolAttr = aToolsSelList->value(aToolsIndex); + std::shared_ptr 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 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 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 theResultBody, + const std::shared_ptr theBaseShape, + const ListOfShape& theTools, + GeomAlgoAPI_MakeShape& theMakeShape) +{ + //load result + std::shared_ptr aResultShape = theMakeShape.shape(); + std::shared_ptr 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 index 000000000..2c8fff3d5 --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_Intersection.h @@ -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 + +#include + +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 theResultBody, + const std::shared_ptr theBaseShape, + const ListOfShape& theTools, + GeomAlgoAPI_MakeShape& theMakeShape); +}; + +#endif diff --git a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp index 26a5b37e6..d40d085ba 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -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 index 000000000..988f3e07f --- /dev/null +++ b/src/FeaturesPlugin/intersection_widget.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + diff --git a/src/FeaturesPlugin/plugin-Features.xml b/src/FeaturesPlugin/plugin-Features.xml index ba6bf0fb9..afe29e462 100644 --- a/src/FeaturesPlugin/plugin-Features.xml +++ b/src/FeaturesPlugin/plugin-Features.xml @@ -37,6 +37,9 @@ + + + >::value_type & { $result = SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr(*$1)), $descriptor(std::shared_ptr *), SWIG_POINTER_OWN | 0 ); } -%template(ShapeList) std::list >; \ No newline at end of file +%template(ShapeList) std::list >; diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Intersection.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Intersection.cpp new file mode 100644 index 000000000..a1b29f5cb --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Intersection.cpp @@ -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 +#include + +#include +#include +#include + +//================================================================================================= +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(); + 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(); + 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 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 index 000000000..4379feb76 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Intersection.h @@ -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 +#include + +#include + +/// \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 diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_swig.h b/src/GeomAlgoAPI/GeomAlgoAPI_swig.h index 164f8ec61..b93b23850 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_swig.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_swig.h @@ -34,6 +34,7 @@ #include "GeomAlgoAPI_Tools.h" #include "GeomAlgoAPI_Transform.h" #include "GeomAlgoAPI_PaveFiller.h" + #include "GeomAlgoAPI_Intersection.h" #include #include diff --git a/src/GeomValidators/GeomValidators_BooleanSelection.cpp b/src/GeomValidators/GeomValidators_BooleanSelection.cpp index f3f6f248d..c4af6a2e4 100644 --- a/src/GeomValidators/GeomValidators_BooleanSelection.cpp +++ b/src/GeomValidators/GeomValidators_BooleanSelection.cpp @@ -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(); -- 2.39.2