From: dbv Date: Thu, 28 May 2015 18:08:12 +0000 (+0300) Subject: Multiple objects and tools for Boolean operations. X-Git-Tag: V_1.2.0~21 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=5e90be5a37588dd936e6d5f1a6426141bfda7170;p=modules%2Fshaper.git Multiple objects and tools for Boolean operations. --- diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp index 2bf1f1ff0..471e5c7c0 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp @@ -12,43 +12,38 @@ #include #include #include -#include -using namespace std; -// to use multi-selection, please comment the next define and uncomment multi_selector in boolean_widget.xml -#define DEBUG_ONE_OBJECT +#include +#include +#include #define FACE 4 #define _MODIFY_TAG 1 #define _DELETED_TAG 2 + +//================================================================================================= FeaturesPlugin_Boolean::FeaturesPlugin_Boolean() { } +//================================================================================================= void FeaturesPlugin_Boolean::initAttributes() { data()->addAttribute(FeaturesPlugin_Boolean::TYPE_ID(), ModelAPI_AttributeInteger::typeId()); -#ifdef DEBUG_ONE_OBJECT - data()->addAttribute(FeaturesPlugin_Boolean::OBJECT_ID(), ModelAPI_AttributeReference::typeId()); -#else AttributeSelectionListPtr aSelection = std::dynamic_pointer_cast(data()->addAttribute( FeaturesPlugin_Boolean::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId())); // extrusion works with faces always aSelection->setSelectionType("SOLID"); -#endif -#ifdef DEBUG_ONE_OBJECT - data()->addAttribute(FeaturesPlugin_Boolean::TOOL_ID(), ModelAPI_AttributeReference::typeId()); -#else aSelection = std::dynamic_pointer_cast(data()->addAttribute( FeaturesPlugin_Boolean::TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId())); // extrusion works with faces always aSelection->setSelectionType("SOLID"); -#endif } +//================================================================================================= std::shared_ptr FeaturesPlugin_Boolean::getShape(const std::string& theAttrName) { std::shared_ptr aObjRef = std::dynamic_pointer_cast< @@ -62,104 +57,196 @@ std::shared_ptr FeaturesPlugin_Boolean::getShape(const std::strin return std::shared_ptr(); } - +//================================================================================================= void FeaturesPlugin_Boolean::execute() { + // Getting operation type. std::shared_ptr aTypeAttr = std::dynamic_pointer_cast< ModelAPI_AttributeInteger>(data()->attribute(FeaturesPlugin_Boolean::TYPE_ID())); if (!aTypeAttr) return; int aType = aTypeAttr->value(); -#ifdef DEBUG_ONE_OBJECT - std::shared_ptr anObject = this->getShape(FeaturesPlugin_Boolean::OBJECT_ID()); -#else - std::shared_ptr anObject; - { - AttributeSelectionListPtr anObjects = selectionList(FeaturesPlugin_Boolean::OBJECT_LIST_ID()); - if (anObjects->size() == 0) - return; - - // Getting bounding planes. - std::shared_ptr anObjRef = anObjects->value(0); - if (!anObjRef.get()) - return; - anObject = std::dynamic_pointer_cast(anObjRef->value()); - } -#endif - if (!anObject) - return; -#ifdef DEBUG_ONE_OBJECT - std::shared_ptr aTool = this->getShape(FeaturesPlugin_Boolean::TOOL_ID()); -#else - std::shared_ptr aTool; - { - AttributeSelectionListPtr anObjects = selectionList(FeaturesPlugin_Boolean::TOOL_LIST_ID()); - if (anObjects->size() == 0) - return; + ListOfShape anObjects, aTools; - // Getting bounding planes. - std::shared_ptr anObjRef = anObjects->value(0); - if (!anObjRef.get()) + // Getting objects. + AttributeSelectionListPtr anObjectsSelList = selectionList(FeaturesPlugin_Boolean::OBJECT_LIST_ID()); + if (anObjectsSelList->size() == 0) { + return; + } + 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; - aTool = std::dynamic_pointer_cast(anObjRef->value()); + } + anObjects.push_back(anObject); } -#endif - if (!aTool) - return; - - std::shared_ptr aResultBody = document()->createBody(data()); - GeomAlgoAPI_Boolean* aFeature = new GeomAlgoAPI_Boolean(anObject, aTool, aType); - if(aFeature && !aFeature->isDone()) { - static const std::string aFeatureError = "Boolean feature: algorithm failed"; - setError(aFeatureError); - return; - } - // Check if shape is valid - if (aFeature->shape()->isNull()) { - static const std::string aShapeError = "Boolean feature: resulting shape is Null"; - setError(aShapeError); + // Getting tools. + AttributeSelectionListPtr aToolsSelList = selectionList(FeaturesPlugin_Boolean::TOOL_LIST_ID()); + if (aToolsSelList->size() == 0) { return; } - if(!aFeature->isValid()) { - static const std::string aFeatureError = "Boolean feature: resulting shape is not valid"; - setError(aFeatureError); - return; - } - // if result of Boolean operation is same as was before it means that Boolean operation has no sence - // and naming provides no result, so, generate an error in this case - if (anObject->isEqual(aFeature->shape())) { - static const std::string aFeatureError = "Boolean feature: operation was not performed"; - setError(aFeatureError); - return; + 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); } - //LoadNamingDS - LoadNamingDS(aFeature, aResultBody, anObject, aTool, aType); - setResult(aResultBody); + int aResultIndex = 0; + ListOfMakeShape aListOfMakeShape; + std::shared_ptr aResShape; + std::shared_ptr aDataMapOfShapes; + + switch(aType) { + case GeomAlgoAPI_Boolean::BOOL_CUT: { + // Cut each object with all tools + for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) { + std::shared_ptr anObject = *anObjectsIt; + aResShape = anObject; + ListOfShape aSingleObjectList; aSingleObjectList.push_back(anObject); + for(ListOfShape::iterator aToolsIt = aTools.begin(); aToolsIt != aTools.end(); aToolsIt++) { + std::shared_ptr aTool = *aToolsIt; + GeomAlgoAPI_Boolean* aBoolAlgo = new GeomAlgoAPI_Boolean(aResShape, aTool, aType); + if(!aBoolAlgo->isDone() || aBoolAlgo->shape()->isNull() || !aBoolAlgo->isValid()) { + static const std::string aBoolAlgoError = "Boolean feature: algorithm failed"; + setError(aBoolAlgoError); + return; + } + aListOfMakeShape.push_back(aBoolAlgo->makeShape()); + aResShape = aBoolAlgo->shape(); + aBoolAlgo->mapOfShapes(aDataMapOfShapes); + } + + if(GeomAlgoAPI_ShapeProps::volume(aResShape) > 10.e-5) { + std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); + std::shared_ptr aMakeShapeList = std::shared_ptr( + new GeomAlgoAPI_MakeShapeList(aListOfMakeShape)); + + LoadNamingDS(aMakeShapeList, aResultBody, aResShape, aDataMapOfShapes, aSingleObjectList, aTools); + setResult(aResultBody, aResultIndex); + aResultIndex++; + } + } + break; + } + case GeomAlgoAPI_Boolean::BOOL_FUSE: { + // Fuse all objects. + std::shared_ptr aTempRes = anObjects.front(); + for(ListOfShape::iterator anObjectsIt = ++anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) { + std::shared_ptr anObject = *anObjectsIt; + GeomAlgoAPI_Boolean* aBoolAlgo = new GeomAlgoAPI_Boolean(aTempRes, anObject, aType); + if(!aBoolAlgo->isDone() || aBoolAlgo->shape()->isNull() || !aBoolAlgo->isValid()) { + static const std::string aBoolAlgoError = "Boolean feature: algorithm failed"; + setError(aBoolAlgoError); + return; + } + aListOfMakeShape.push_back(aBoolAlgo->makeShape()); + aTempRes = aBoolAlgo->shape(); + } + + // Fuse all tools with result of objects fuse. + for(ListOfShape::iterator aToolsIt = aTools.begin(); aToolsIt != aTools.end(); aToolsIt++) { + std::shared_ptr aTool = *aToolsIt; + GeomAlgoAPI_Boolean* aBoolAlgo = new GeomAlgoAPI_Boolean(aTempRes, aTool, aType); + if(!aBoolAlgo->isDone() || aBoolAlgo->shape()->isNull() || !aBoolAlgo->isValid()) { + static const std::string aBoolAlgoError = "Boolean feature: algorithm failed"; + setError(aBoolAlgoError); + return; + } + aListOfMakeShape.push_back(aBoolAlgo->makeShape()); + aTempRes = aBoolAlgo->shape(); + aBoolAlgo->mapOfShapes(aDataMapOfShapes); + } + aResShape = aTempRes; + + std::shared_ptr aResultBody = document()->createBody(data()); + std::shared_ptr aMakeShapeList = std::shared_ptr( + new GeomAlgoAPI_MakeShapeList(aListOfMakeShape)); + + LoadNamingDS(aMakeShapeList, aResultBody, aResShape, aDataMapOfShapes, anObjects, aTools); + setResult(aResultBody); + aResultIndex++; + break; + } + case GeomAlgoAPI_Boolean::BOOL_COMMON: { + // Search common between object and tool and fuse them. + for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) { + std::shared_ptr anObject = *anObjectsIt; + std::shared_ptr aTempRes; + ListOfShape aSingleObjectList; aSingleObjectList.push_back(anObject); + for(ListOfShape::iterator aToolsIt = aTools.begin(); aToolsIt != aTools.end(); aToolsIt++) { + std::shared_ptr aTool = *aToolsIt; + GeomAlgoAPI_Boolean* aBoolAlgo1 = new GeomAlgoAPI_Boolean(anObject, aTool, aType); + if(!aBoolAlgo1->isDone() || aBoolAlgo1->shape()->isNull() || !aBoolAlgo1->isValid()) { + static const std::string aBoolAlgoError = "Boolean feature: algorithm failed"; + setError(aBoolAlgoError); + return; + } + aListOfMakeShape.push_back(aBoolAlgo1->makeShape()); + + if(!aTempRes) { + aTempRes = aBoolAlgo1->shape(); + aBoolAlgo1->mapOfShapes(aDataMapOfShapes); + } else { + // Fuse common result with previous common results. + GeomAlgoAPI_Boolean* aBoolAlgo2 = new GeomAlgoAPI_Boolean(aTempRes, + aBoolAlgo1->shape(), + GeomAlgoAPI_Boolean::BOOL_FUSE); + if(!aBoolAlgo1->isDone() || aBoolAlgo1->shape()->isNull() || !aBoolAlgo1->isValid()) { + static const std::string aBoolAlgoError = "Boolean feature: algorithm failed"; + setError(aBoolAlgoError); + return; + } + aListOfMakeShape.push_back(aBoolAlgo2->makeShape()); + aTempRes = aBoolAlgo2->shape(); + aBoolAlgo2->mapOfShapes(aDataMapOfShapes); + } + } + aResShape = aTempRes; + + if(GeomAlgoAPI_ShapeProps::volume(aResShape) > 10.e-5) { + std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); + std::shared_ptr aMakeShapeList = std::shared_ptr( + new GeomAlgoAPI_MakeShapeList(aListOfMakeShape)); + + LoadNamingDS(aMakeShapeList, aResultBody, aResShape, aDataMapOfShapes, aSingleObjectList, aTools); + setResult(aResultBody, aResultIndex); + aResultIndex++; + } + } + break; + } + } + // remove the rest results if there were produced in the previous pass + removeResults(aResultIndex); } -//============================================================================ -void FeaturesPlugin_Boolean::LoadNamingDS(GeomAlgoAPI_Boolean* theFeature, - std::shared_ptr theResultBody, - std::shared_ptr theObject, - std::shared_ptr theTool, - int theType) -{ - +//================================================================================================= +void FeaturesPlugin_Boolean::LoadNamingDS(std::shared_ptr theMakeShapeList, + std::shared_ptr theResultBody, + std::shared_ptr theResult, + std::shared_ptr theDataMapOfShapes, + const ListOfShape& theObjects, + const ListOfShape& theTools) +{ //load result - theResultBody->storeModified(theObject, theFeature->shape()); + theResultBody->storeModified(theObjects.front(), theResult); GeomAPI_DataMapOfShapeShape* aSubShapes = new GeomAPI_DataMapOfShapeShape(); - theFeature->mapOfShapes(*aSubShapes); - // Put in DF modified faces std::string aModName = "Modified"; - theResultBody->loadAndOrientModifiedShapes(theFeature->makeShape(), theObject, FACE, _MODIFY_TAG, aModName, *aSubShapes); - theResultBody->loadAndOrientModifiedShapes(theFeature->makeShape(), theTool, FACE, _MODIFY_TAG, aModName, *aSubShapes); + for(ListOfShape::const_iterator anIter = theObjects.begin(); anIter != theObjects.end(); anIter++) { + theResultBody->loadAndOrientModifiedShapes(theMakeShapeList.get(), *anIter, FACE, _MODIFY_TAG, aModName, *theDataMapOfShapes.get()); + theResultBody->loadDeletedShapes(theMakeShapeList.get(), *anIter, FACE, _DELETED_TAG); + } - //Put in DF deleted faces - theResultBody->loadDeletedShapes(theFeature->makeShape(), theObject, FACE, _DELETED_TAG); - theResultBody->loadDeletedShapes(theFeature->makeShape(), theTool, FACE, _DELETED_TAG); + for(ListOfShape::const_iterator anIter = theTools.begin(); anIter != theTools.end(); anIter++) { + theResultBody->loadAndOrientModifiedShapes(theMakeShapeList.get(), *anIter, FACE, _MODIFY_TAG, aModName, *theDataMapOfShapes.get()); + theResultBody->loadDeletedShapes(theMakeShapeList.get(), *anIter, FACE, _DELETED_TAG); + } } diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.h b/src/FeaturesPlugin/FeaturesPlugin_Boolean.h index 53023300a..959d06061 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Boolean.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Boolean.h @@ -12,6 +12,8 @@ #include #include +class GeomAlgoAPI_MakeShapeList; + /**\class FeaturesPlugin_Boolean * \ingroup Plugins * \brief Feature for applying of Boolean operations on Solids. @@ -60,8 +62,8 @@ public: } enum { - BOOL_CUT, - BOOL_FUSE, + BOOL_CUT, + BOOL_FUSE, BOOL_COMMON }; @@ -83,13 +85,14 @@ public: private: std::shared_ptr getShape(const std::string& theAttrName); - + /// Load Naming data structure of the feature to the document - void LoadNamingDS(GeomAlgoAPI_Boolean* theFeature, - std::shared_ptr theResultBody, - std::shared_ptr theObject, - std::shared_ptr theTool, - int theType); + void LoadNamingDS(std::shared_ptr theMakeShapeList, + std::shared_ptr theResultBody, + std::shared_ptr theResult, + std::shared_ptr theDataMapOfShapes, + const ListOfShape& theObjects, + const ListOfShape& theTools); }; #endif diff --git a/src/FeaturesPlugin/boolean_widget.xml b/src/FeaturesPlugin/boolean_widget.xml index f356304b0..76c854b46 100644 --- a/src/FeaturesPlugin/boolean_widget.xml +++ b/src/FeaturesPlugin/boolean_widget.xml @@ -1,22 +1,25 @@ - - + + + GeomAlgoAPI_Boolean::makeCommon( GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(std::shared_ptr theObject, std::shared_ptr theTool, int theType) -: myOperation(theType), myDone(false), myShape(new GeomAPI_Shape()) +: myOperation(theType), myDone(false), myShape(new GeomAPI_Shape()), myMap(new GeomAPI_DataMapOfShapeShape()) { build(theObject, theTool); } @@ -85,9 +85,8 @@ void GeomAlgoAPI_Boolean::build(std::shared_ptr theObject, { BRepAlgoAPI_Fuse* mkFuse = new BRepAlgoAPI_Fuse(anObject, aTool); if (mkFuse && mkFuse->IsDone()) { - setImpl(mkFuse); myDone = mkFuse->IsDone() == Standard_True; - myMkShape = new GeomAlgoAPI_MakeShape (mkFuse); + myMkShape = std::shared_ptr(new GeomAlgoAPI_MakeShape (mkFuse)); aResult = mkFuse->Shape();//GeomAlgoAPI_DFLoader::refineResult(aFuse->Shape()); } break; @@ -96,9 +95,8 @@ void GeomAlgoAPI_Boolean::build(std::shared_ptr theObject, { BRepAlgoAPI_Cut* mkCut = new BRepAlgoAPI_Cut(anObject, aTool); if (mkCut && mkCut->IsDone()) { - setImpl(mkCut); myDone = mkCut->IsDone() == Standard_True; - myMkShape = new GeomAlgoAPI_MakeShape (mkCut); + myMkShape = std::shared_ptr(new GeomAlgoAPI_MakeShape (mkCut)); aResult = mkCut->Shape(); } break; @@ -107,9 +105,8 @@ void GeomAlgoAPI_Boolean::build(std::shared_ptr theObject, { BRepAlgoAPI_Common* mkCom = new BRepAlgoAPI_Common(anObject, aTool); if (mkCom && mkCom->IsDone()) { - setImpl(mkCom); myDone = mkCom->IsDone() == Standard_True; - myMkShape = new GeomAlgoAPI_MakeShape (mkCom); + myMkShape = std::shared_ptr(new GeomAlgoAPI_MakeShape (mkCom)); aResult = mkCom->Shape(); } break; @@ -126,7 +123,7 @@ void GeomAlgoAPI_Boolean::build(std::shared_ptr theObject, for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) { std::shared_ptr aCurrentShape(new GeomAPI_Shape()); aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current())); - myMap.bind(aCurrentShape, aCurrentShape); + myMap->bind(aCurrentShape, aCurrentShape); } } } @@ -150,13 +147,13 @@ const std::shared_ptr& GeomAlgoAPI_Boolean::shape () const } //============================================================================ -void GeomAlgoAPI_Boolean::mapOfShapes (GeomAPI_DataMapOfShapeShape& theMap) const +void GeomAlgoAPI_Boolean::mapOfShapes(std::shared_ptr& theMap) const { theMap = myMap; } //============================================================================ -GeomAlgoAPI_MakeShape * GeomAlgoAPI_Boolean::makeShape() const +const std::shared_ptr& GeomAlgoAPI_Boolean::makeShape() const { return myMkShape; } @@ -164,7 +161,4 @@ GeomAlgoAPI_MakeShape * GeomAlgoAPI_Boolean::makeShape() const //============================================================================ GeomAlgoAPI_Boolean::~GeomAlgoAPI_Boolean() { - if (myImpl) { - myMap.clear(); - } } \ No newline at end of file diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.h b/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.h index 9ca251863..6e92769a9 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.h @@ -70,10 +70,10 @@ class GeomAlgoAPI_Boolean : public GeomAPI_Interface GEOMALGOAPI_EXPORT const std::shared_ptr& shape () const; /// Returns map of sub-shapes of the result. To be used for History keeping - GEOMALGOAPI_EXPORT void mapOfShapes (GeomAPI_DataMapOfShapeShape& theMap) const; + GEOMALGOAPI_EXPORT void mapOfShapes(std::shared_ptr& theMap) const; /// Return interface for for History processing - GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShape* makeShape () const; + GEOMALGOAPI_EXPORT const std::shared_ptr& makeShape () const; ///Destructor GEOMALGOAPI_EXPORT ~GeomAlgoAPI_Boolean(); @@ -86,9 +86,9 @@ class GeomAlgoAPI_Boolean : public GeomAPI_Interface double mySize; bool myDone; int myOperation; - std::shared_ptr myShape; - GeomAPI_DataMapOfShapeShape myMap; - GeomAlgoAPI_MakeShape * myMkShape; + std::shared_ptr myShape; + std::shared_ptr myMap; + std::shared_ptr myMkShape; }; #endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp index 4682f1fb0..b0c7be684 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp @@ -17,10 +17,6 @@ GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape(void* theMkShape) GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape() : GeomAPI_Interface(),myShape(new GeomAPI_Shape()) {} -void GeomAlgoAPI_MakeShape::init(void* theMkShape) -{ - setImpl((void *)implPtr()); -} const std::shared_ptr GeomAlgoAPI_MakeShape::shape() const { diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h index 186b12c67..38519b03f 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h @@ -7,9 +7,11 @@ #define GeomAlgoAPI_MakeShape_H_ #include -#include #include +#include +#include + /**\class GeomAlgoAPI_MakeShape * \ingroup DataAlgo * \brief Interface to the root class of all topological shapes constructions @@ -35,12 +37,12 @@ public: /// Returns whether the shape is an edge GEOMALGOAPI_EXPORT virtual bool isDeleted(const std::shared_ptr theShape); - /// Initializes the algorithm by the builder stored in the interface - GEOMALGOAPI_EXPORT void init(void* theMkShape); protected: /// The resulting shape std::shared_ptr myShape; }; +typedef std::list > ListOfMakeShape; + #endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.cpp new file mode 100644 index 000000000..d5c050caa --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.cpp @@ -0,0 +1,92 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_MakeShapeListList.h +// Created: 27 May 2015 +// Author: Dmitry Bobylev + +#include + +#include +#include +#include +#include + +//================================================================================================= +GeomAlgoAPI_MakeShapeList::GeomAlgoAPI_MakeShapeList() +: GeomAlgoAPI_MakeShape() +{} + +//================================================================================================= +GeomAlgoAPI_MakeShapeList::GeomAlgoAPI_MakeShapeList(const ListOfMakeShape& theMakeShapeList) +: GeomAlgoAPI_MakeShape() +{ + init(theMakeShapeList); +} + +//================================================================================================= +void GeomAlgoAPI_MakeShapeList::init(const ListOfMakeShape& theMakeShapeList) +{ + myMakeShapeList = theMakeShapeList; +} + +//================================================================================================= +const std::shared_ptr GeomAlgoAPI_MakeShapeList::shape() const +{ + if(myMakeShapeList.empty()) { + return std::shared_ptr(); + } else { + return myMakeShapeList.back()->shape(); + } +} + +//================================================================================================= +void GeomAlgoAPI_MakeShapeList::generated(const std::shared_ptr theShape, + ListOfShape& theHistory) +{ + result(theShape, theHistory, GeomAlgoAPI_MakeShapeList::Generated); +} + +//================================================================================================= +void GeomAlgoAPI_MakeShapeList::modified(const std::shared_ptr theShape, + ListOfShape& theHistory) +{ + result(theShape, theHistory, GeomAlgoAPI_MakeShapeList::Modified); +} + +void GeomAlgoAPI_MakeShapeList::result(const std::shared_ptr theShape, + ListOfShape& theHistory, + OperationType theOperationType) +{ + if(myMakeShapeList.empty()) { + return; + } + + NCollection_Map aTempShapes; + NCollection_Map aResultShapes; + aTempShapes.Add(theShape->impl()); + + for(ListOfMakeShape::iterator aBuilderIt = myMakeShapeList.begin(); aBuilderIt != myMakeShapeList.end(); aBuilderIt++) { + BRepBuilderAPI_MakeShape* aBuilder = (*aBuilderIt)->implPtr(); + for(NCollection_Map::Iterator aShapeIt(aTempShapes); aShapeIt.More(); aShapeIt.Next()) { + const TopoDS_Shape& aShape = aShapeIt.Value(); + const TopTools_ListOfShape& aList = theOperationType == GeomAlgoAPI_MakeShapeList::Generated ? + aBuilder->Generated(aShape) : aBuilder->Modified(aShape); + bool prevResRemoved = false; + for(TopTools_ListIteratorOfListOfShape anIt(aList); anIt.More(); anIt.Next()) { + aTempShapes.Add(anIt.Value()); + aResultShapes.Add(anIt.Value()); + if(!prevResRemoved) { + aResultShapes.Remove(aShape); + prevResRemoved = true; + } + } + } + } + + for(NCollection_Map::Iterator aShapeIt(aResultShapes); aShapeIt.More(); aShapeIt.Next()) { + std::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(aShapeIt.Value())); + theHistory.push_back(aShape); + } +} + diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.h b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.h new file mode 100644 index 000000000..8d7975071 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.h @@ -0,0 +1,61 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_MakeShapeList.h +// Created: 27 May 2015 +// Author: Dmitry Bobylev +#ifndef GeomAlgoAPI_MakeShapeList_H_ +#define GeomAlgoAPI_MakeShapeList_H_ + +#include +#include +#include + +#include + +/** \class GeomAlgoAPI_MakeShapeList + * \ingroup DataAlgo + * \brief Interface to the root class of all topological shapes constructions + */ +class GeomAlgoAPI_MakeShapeList : public GeomAlgoAPI_MakeShape +{ + enum OperationType { + Generated, + Modified + }; + +public: + /// Default constructor + GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShapeList(); + + /** \brief Constructor + * \param[in] theMakeShapeList list of algorithms. + */ + GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShapeList(const ListOfMakeShape& theMakeShapeList); + + /** \brief Initializes a class with new list of algorithms. + * \param[in] theMakeShapeList list of algorithms. + */ + GEOMALGOAPI_EXPORT void init(const ListOfMakeShape& theMakeShapeList); + + /// \return a shape built by the shape construction algorithms + GEOMALGOAPI_EXPORT const std::shared_ptr shape() const; + + /// \return the list of shapes generated from the shape \a theShape + GEOMALGOAPI_EXPORT virtual void generated(const std::shared_ptr theShape, + ListOfShape& theHistory); + + /// \return the list of shapes modified from the shape \a theShape + GEOMALGOAPI_EXPORT virtual void modified(const std::shared_ptr theShape, + ListOfShape& theHistory); + +private: + void result(const std::shared_ptr theShape, + ListOfShape& theHistory, + OperationType theOperationType); + + +protected: + ListOfMakeShape myMakeShapeList; +}; + +#endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeProps.h b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeProps.h index abc7faa72..d802840db 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeProps.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeProps.h @@ -22,8 +22,8 @@ public: /// \return the total volume of the solids of the current shape or 0.0 if it can be computed. static double volume(std::shared_ptr theShape); - /// \return the centre of mass of the current shape. The coordinates returned for the center of mass - /// are expressed in the absolute Cartesian coordinate system. + /// \return the centre of mass of the current face. The coordinates returned for the center of mass + /// are expressed in the absolute Cartesian coordinate system. (This function works only for surfaces). static std::shared_ptr centreOfMass(std::shared_ptr theShape); }; diff --git a/src/PartSet/PartSet_Validators.cpp b/src/PartSet/PartSet_Validators.cpp index e31b1b2b5..1e0f79b2f 100644 --- a/src/PartSet/PartSet_Validators.cpp +++ b/src/PartSet/PartSet_Validators.cpp @@ -216,7 +216,7 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute } } } - else if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) { + else if (anAttrType == ModelAPI_AttributeSelection::typeId()) { AttributeSelectionPtr anAttr = std::dynamic_pointer_cast(theAttribute); ResultPtr aContext = anAttr->context(); GeomShapePtr aShape = anAttr->value(); @@ -258,6 +258,32 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute } } } + else if(anAttrType == ModelAPI_AttributeSelectionList::typeId()) { + std::shared_ptr aCurSelList = + std::dynamic_pointer_cast(theAttribute); + anAttrs = aFeature->data()->attributes(ModelAPI_AttributeSelectionList::typeId()); + if(anAttrs.size() > 0) { + std::list>::iterator anAttrItr = anAttrs.begin(); + for(; anAttrItr != anAttrs.end(); anAttrItr++){ + if ((*anAttrItr).get() && (*anAttrItr)->id() != theAttribute->id()){ + std::shared_ptr aRefSelList = + std::dynamic_pointer_cast(*anAttrItr); + for(int i = 0; i < aCurSelList->size(); i++) { + std::shared_ptr aCurSel = aCurSelList->value(i); + for(int j = 0; j < aRefSelList->size(); j++) { + std::shared_ptr aRefSel = aRefSelList->value(j); + if(aCurSel->context() == aRefSel->context()) { + if(aCurSel->value().get() == NULL || aRefSel->value().get() == NULL + || aCurSel->value()->isEqual(aRefSel->value())) { + return false; + } + } + } + } + } + } + } + } return !featureHasReferences(theAttribute); }