1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 // File: FeaturesPlugin_Partition.cpp
4 // Created: 31 Jul 2015
5 // Author: Natalia ERMOLAEVA
7 #include "FeaturesPlugin_Partition.h"
9 #include <ModelAPI_Data.h>
10 #include <ModelAPI_Document.h>
11 #include <ModelAPI_AttributeBoolean.h>
12 #include <ModelAPI_AttributeReference.h>
13 #include <ModelAPI_AttributeInteger.h>
14 #include <ModelAPI_BodyBuilder.h>
15 #include <ModelAPI_ResultBody.h>
16 #include <ModelAPI_AttributeSelectionList.h>
17 #include <ModelAPI_Session.h>
18 #include <ModelAPI_Validator.h>
20 #include <GeomAlgoAPI_CompoundBuilder.h>
21 #include <GeomAlgoAPI_Partition.h>
22 #include <GeomAlgoAPI_MakeShapeCustom.h>
23 #include <GeomAlgoAPI_MakeShapeList.h>
24 #include <GeomAlgoAPI_ShapeTools.h>
28 //=================================================================================================
29 FeaturesPlugin_Partition::FeaturesPlugin_Partition()
33 //=================================================================================================
34 void FeaturesPlugin_Partition::initAttributes()
36 AttributeSelectionListPtr aSelection =
37 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
38 FeaturesPlugin_Partition::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
39 aSelection->setSelectionType("SOLID");
42 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
43 FeaturesPlugin_Partition::TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
44 aSelection->setSelectionType("SOLID");
46 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TOOL_LIST_ID());
48 data()->addAttribute(COMBINE_ID(), ModelAPI_AttributeBoolean::typeId());
51 //=================================================================================================
52 void FeaturesPlugin_Partition::execute()
54 ListOfShape anObjects, aTools, aToolsForNaming;
57 AttributeSelectionListPtr anObjectsSelList = selectionList(FeaturesPlugin_Partition::OBJECT_LIST_ID());
58 for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
59 std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr = anObjectsSelList->value(anObjectsIndex);
60 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
61 if (!anObject.get()) {
64 anObjects.push_back(anObject);
67 GeomAlgoAPI_MakeShapeList aMakeShapeList;
68 std::list<std::shared_ptr<GeomAPI_Pnt> > aBoundingPoints = GeomAlgoAPI_ShapeTools::getBoundingBox(anObjects, 1.0);
71 AttributeSelectionListPtr aToolsSelList = selectionList(FeaturesPlugin_Partition::TOOL_LIST_ID());
72 for (int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) {
73 std::shared_ptr<ModelAPI_AttributeSelection> aToolAttr = aToolsSelList->value(aToolsIndex);
74 std::shared_ptr<GeomAPI_Shape> aTool = aToolAttr->value();
76 // it could be a construction plane
77 ResultPtr aContext = aToolAttr->context();
79 aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aContext->shape(), aBoundingPoints);
80 std::shared_ptr<GeomAlgoAPI_MakeShapeCustom> aMkShCustom(new GeomAlgoAPI_MakeShapeCustom);
81 aMkShCustom->addModified(aContext->shape(), aTool);
82 aMakeShapeList.appendAlgo(aMkShCustom);
83 aTools.push_back(aTool);
84 aToolsForNaming.push_back(aContext->shape());
87 aTools.push_back(aTool);
88 aToolsForNaming.push_back(aTool);
92 // Getting combine flag.
93 bool isCombine = boolean(COMBINE_ID())->value();
95 if(anObjects.empty()/* || aTools.empty()*/) {
96 std::string aFeatureError = "Error: Not enough objects for partition operation.";
97 setError(aFeatureError);
101 int aResultIndex = 0;
104 // Create single result.
105 //if(!aTools.empty()) {
106 // // This is a workaround for naming. Passing compound of objects as argument instead each object separately.
107 // std::shared_ptr<GeomAPI_Shape> aCompoud = GeomAlgoAPI_CompoundBuilder::compound(anObjects);
108 // anObjects.clear();
109 // anObjects.push_back(aCompoud);
111 std::shared_ptr<GeomAlgoAPI_Partition> aPartitionAlgo(new GeomAlgoAPI_Partition(anObjects, aTools));
113 // Checking that the algorithm worked properly.
114 if (!aPartitionAlgo->isDone()) {
115 static const std::string aFeatureError = "Error: Partition algorithm failed.";
116 setError(aFeatureError);
119 if (aPartitionAlgo->shape()->isNull()) {
120 static const std::string aShapeError = "Error: Resulting shape is Null.";
121 setError(aShapeError);
124 if (!aPartitionAlgo->isValid()) {
125 std::string aFeatureError = "Error: Resulting shape is not valid.";
126 setError(aFeatureError);
130 if (GeomAlgoAPI_ShapeTools::volume(aPartitionAlgo->shape()) > 1.e-7) {
131 std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
132 aMakeShapeList.appendAlgo(aPartitionAlgo);
133 GeomAPI_DataMapOfShapeShape& aMapOfShapes = *aPartitionAlgo->mapOfSubShapes().get();
134 std::shared_ptr<GeomAPI_Shape> aBaseShape = anObjects.front();
135 anObjects.pop_front();
136 aToolsForNaming.insert(aToolsForNaming.end(), anObjects.begin(), anObjects.end());
137 loadNamingDS(aResultBody, aBaseShape, aToolsForNaming, aPartitionAlgo->shape(), aMakeShapeList, aMapOfShapes);
138 setResult(aResultBody, aResultIndex);
142 // Create result for each object.
143 for (ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) {
144 std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
145 ListOfShape aListWithObject; aListWithObject.push_back(anObject);
146 std::shared_ptr<GeomAlgoAPI_Partition> aPartitionAlgo(new GeomAlgoAPI_Partition(aListWithObject, aTools));
148 // Checking that the algorithm worked properly.
149 if (!aPartitionAlgo->isDone()) {
150 static const std::string aFeatureError = "Error: Partition algorithm failed.";
151 setError(aFeatureError);
154 if (aPartitionAlgo->shape()->isNull()) {
155 static const std::string aShapeError = "Error: Resulting shape is Null.";
156 setError(aShapeError);
159 if (!aPartitionAlgo->isValid()) {
160 std::string aFeatureError = "Error: Resulting shape is not valid.";
161 setError(aFeatureError);
165 if (GeomAlgoAPI_ShapeTools::volume(aPartitionAlgo->shape()) > 1.e-7) {
166 std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
167 GeomAlgoAPI_MakeShapeList aMakeShapeListCopy = aMakeShapeList;
168 aMakeShapeListCopy.appendAlgo(aPartitionAlgo);
169 GeomAPI_DataMapOfShapeShape aMapOfShapes = *aPartitionAlgo->mapOfSubShapes().get();
170 loadNamingDS(aResultBody, anObject, aToolsForNaming, aPartitionAlgo->shape(), aMakeShapeListCopy, aMapOfShapes);
171 setResult(aResultBody, aResultIndex);
177 // remove the rest results if there were produced in the previous pass
178 removeResults(aResultIndex);
181 //=================================================================================================
182 void FeaturesPlugin_Partition::loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
183 const std::shared_ptr<GeomAPI_Shape> theBaseShape,
184 const ListOfShape& theTools,
185 const std::shared_ptr<GeomAPI_Shape> theResultShape,
186 GeomAlgoAPI_MakeShape& theMakeShape,
187 GeomAPI_DataMapOfShapeShape& theMapOfShapes)
190 if(theBaseShape->isEqual(theResultShape)) {
191 theResultBody->store(theResultShape);
193 const int aDeletedTag = 1;
194 const int aSubsolidsTag = 2; /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids
195 const int aModifyTag = 100000;
196 int aModifyToolsTag = 200000;
197 std::ostringstream aStream;
199 theResultBody->storeModified(theBaseShape, theResultShape, aSubsolidsTag);
201 std::string aModName = "Modified";
202 theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE,
203 aModifyTag, aModName, theMapOfShapes, true);
204 theResultBody->loadDeletedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE, aDeletedTag);
207 for(ListOfShape::const_iterator anIter = theTools.begin(); anIter != theTools.end(); anIter++) {
208 aStream.str(std::string());
210 aStream << aModName << "_" << anIndex++;
211 theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE,
212 aModifyToolsTag, aStream.str(), theMapOfShapes, true);
213 theResultBody->loadDeletedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE, aDeletedTag);
214 aModifyToolsTag += 10000;