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 = "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);
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 = "Partition algorithm failed";
116 setError(aFeatureError);
119 if (aPartitionAlgo->shape()->isNull()) {
120 static const std::string aShapeError = "Resulting shape is Null";
121 setError(aShapeError);
124 if (!aPartitionAlgo->isValid()) {
125 std::string aFeatureError = "Warning: 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 loadNamingDS(aResultBody, anObjects.front(), aToolsForNaming, aPartitionAlgo->shape(), aMakeShapeList, aMapOfShapes);
135 setResult(aResultBody, aResultIndex);
139 // Create result for each object.
140 for (ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) {
141 std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
142 ListOfShape aListWithObject; aListWithObject.push_back(anObject);
143 std::shared_ptr<GeomAlgoAPI_Partition> aPartitionAlgo(new GeomAlgoAPI_Partition(aListWithObject, aTools));
145 // Checking that the algorithm worked properly.
146 if (!aPartitionAlgo->isDone()) {
147 static const std::string aFeatureError = "Partition algorithm failed";
148 setError(aFeatureError);
151 if (aPartitionAlgo->shape()->isNull()) {
152 static const std::string aShapeError = "Resulting shape is Null";
153 setError(aShapeError);
156 if (!aPartitionAlgo->isValid()) {
157 std::string aFeatureError = "Warning: resulting shape is not valid";
158 setError(aFeatureError);
162 if (GeomAlgoAPI_ShapeTools::volume(aPartitionAlgo->shape()) > 1.e-7) {
163 std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
164 GeomAlgoAPI_MakeShapeList aMakeShapeListCopy = aMakeShapeList;
165 aMakeShapeListCopy.appendAlgo(aPartitionAlgo);
166 GeomAPI_DataMapOfShapeShape aMapOfShapes = *aPartitionAlgo->mapOfSubShapes().get();
167 loadNamingDS(aResultBody, anObject, aToolsForNaming, aPartitionAlgo->shape(), aMakeShapeListCopy, aMapOfShapes);
168 setResult(aResultBody, aResultIndex);
174 // remove the rest results if there were produced in the previous pass
175 removeResults(aResultIndex);
178 //=================================================================================================
179 void FeaturesPlugin_Partition::loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
180 const std::shared_ptr<GeomAPI_Shape> theBaseShape,
181 const ListOfShape& theTools,
182 const std::shared_ptr<GeomAPI_Shape> theResultShape,
183 GeomAlgoAPI_MakeShape& theMakeShape,
184 GeomAPI_DataMapOfShapeShape& theMapOfShapes)
187 if(theBaseShape->isEqual(theResultShape)) {
188 theResultBody->store(theResultShape);
190 const int aDeletedTag = 1;
191 const int aSubsolidsTag = 2; /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids
192 const int aModifyTag = 100000;
193 int aModifyToolsTag = 200000;
194 std::ostringstream aStream;
196 theResultBody->storeModified(theBaseShape, theResultShape, aSubsolidsTag);
198 std::string aModName = "Modified";
199 theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE,
200 aModifyTag, aModName, theMapOfShapes, true);
201 theResultBody->loadDeletedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE, aDeletedTag);
204 for(ListOfShape::const_iterator anIter = theTools.begin(); anIter != theTools.end(); anIter++) {
205 aStream.str(std::string());
207 aStream << aModName << "_" << anIndex++;
208 theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE,
209 aModifyToolsTag, aStream.str(), theMapOfShapes, true);
210 theResultBody->loadDeletedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE, aDeletedTag);
211 aModifyToolsTag += 10000;