1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include "FeaturesPlugin_Boolean.h"
23 #include <ModelAPI_Data.h>
24 #include <ModelAPI_Document.h>
25 #include <ModelAPI_AttributeReference.h>
26 #include <ModelAPI_AttributeInteger.h>
27 #include <ModelAPI_ResultCompSolid.h>
28 #include <ModelAPI_ResultBody.h>
29 #include <ModelAPI_AttributeSelectionList.h>
30 #include <ModelAPI_Session.h>
31 #include <ModelAPI_Validator.h>
32 #include <ModelAPI_Tools.h>
34 #include <GeomAlgoAPI_Boolean.h>
35 #include <GeomAlgoAPI_MakeShapeList.h>
36 #include <GeomAlgoAPI_Partition.h>
37 #include <GeomAlgoAPI_PaveFiller.h>
38 #include <GeomAlgoAPI_ShapeTools.h>
39 #include <GeomAPI_ShapeExplorer.h>
40 #include <GeomAPI_ShapeIterator.h>
45 //=================================================================================================
46 FeaturesPlugin_Boolean::FeaturesPlugin_Boolean()
50 //=================================================================================================
51 void FeaturesPlugin_Boolean::initAttributes()
53 data()->addAttribute(FeaturesPlugin_Boolean::TYPE_ID(), ModelAPI_AttributeInteger::typeId());
55 AttributeSelectionListPtr aSelection =
56 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
57 FeaturesPlugin_Boolean::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
59 aSelection = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
60 FeaturesPlugin_Boolean::TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
62 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), OBJECT_LIST_ID());
63 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TOOL_LIST_ID());
66 //=================================================================================================
67 std::shared_ptr<GeomAPI_Shape> FeaturesPlugin_Boolean::getShape(const std::string& theAttrName)
69 std::shared_ptr<ModelAPI_AttributeReference> aObjRef = std::dynamic_pointer_cast<
70 ModelAPI_AttributeReference>(data()->attribute(theAttrName));
72 std::shared_ptr<ModelAPI_ResultBody> aConstr = std::dynamic_pointer_cast<
73 ModelAPI_ResultBody>(aObjRef->value());
75 return aConstr->shape();
77 return std::shared_ptr<GeomAPI_Shape>();
80 //=================================================================================================
81 void FeaturesPlugin_Boolean::execute()
83 // Getting operation type.
84 std::shared_ptr<ModelAPI_AttributeInteger> aTypeAttr = std::dynamic_pointer_cast<
85 ModelAPI_AttributeInteger>(data()->attribute(FeaturesPlugin_Boolean::TYPE_ID()));
88 OperationType aType = (FeaturesPlugin_Boolean::OperationType)aTypeAttr->value();
90 ListOfShape anObjects, aTools, anEdgesAndFaces;
91 std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape> aCompSolidsObjects;
94 AttributeSelectionListPtr anObjectsSelList =
95 selectionList(FeaturesPlugin_Boolean::OBJECT_LIST_ID());
96 for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
97 AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex);
98 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
102 ResultPtr aContext = anObjectAttr->context();
103 ResultCompSolidPtr aResCompSolidPtr = ModelAPI_Tools::compSolidOwner(aContext);
104 if(aResCompSolidPtr.get()
105 && aResCompSolidPtr->shape()->shapeType() == GeomAPI_Shape::COMPSOLID) {
106 std::shared_ptr<GeomAPI_Shape> aContextShape = aResCompSolidPtr->shape();
107 std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
108 anIt = aCompSolidsObjects.begin();
109 for(; anIt != aCompSolidsObjects.end(); anIt++) {
110 if(anIt->first->isEqual(aContextShape)) {
111 aCompSolidsObjects[anIt->first].push_back(anObject);
115 if(anIt == aCompSolidsObjects.end()) {
116 aCompSolidsObjects[aContextShape].push_back(anObject);
119 if(anObject->shapeType() == GeomAPI_Shape::EDGE ||
120 anObject->shapeType() == GeomAPI_Shape::FACE) {
121 anEdgesAndFaces.push_back(anObject);
123 anObjects.push_back(anObject);
129 AttributeSelectionListPtr aToolsSelList = selectionList(FeaturesPlugin_Boolean::TOOL_LIST_ID());
130 for(int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) {
131 AttributeSelectionPtr aToolAttr = aToolsSelList->value(aToolsIndex);
132 std::shared_ptr<GeomAPI_Shape> aTool = aToolAttr->value();
136 if(aTool->shapeType() == GeomAPI_Shape::EDGE ||
137 aTool->shapeType() == GeomAPI_Shape::FACE) {
138 anEdgesAndFaces.push_back(aTool);
140 aTools.push_back(aTool);
144 int aResultIndex = 0;
150 if((anObjects.empty() && aCompSolidsObjects.empty()) || aTools.empty()) {
151 std::string aFeatureError = "Error: Not enough objects for boolean operation.";
152 setError(aFeatureError);
156 // For solids cut each object with all tools.
157 for(ListOfShape::iterator
158 anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) {
159 std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
160 ListOfShape aListWithObject;
161 aListWithObject.push_back(anObject);
162 GeomAlgoAPI_MakeShape aBoolAlgo;
163 GeomShapePtr aResShape;
168 GeomAlgoAPI_Boolean(aListWithObject, aTools, GeomAlgoAPI_Boolean::BOOL_CUT);
169 aResShape = aBoolAlgo.shape();
174 GeomAlgoAPI_Boolean(aListWithObject, aTools, GeomAlgoAPI_Boolean::BOOL_COMMON);
175 aResShape = aBoolAlgo.shape();
179 aBoolAlgo = GeomAlgoAPI_Partition(aListWithObject, aTools);
180 aResShape = aBoolAlgo.shape();
181 if(aResShape->shapeType() == GeomAPI_Shape::COMPOUND) {
182 int aSubResultsNb = 0;
183 GeomAPI_ShapeIterator anIt(aResShape);
184 for(; anIt.more(); anIt.next()) {
187 if(aSubResultsNb == 1) {
188 anIt.init(aResShape);
190 aResShape = anIt.current();
198 // Checking that the algorithm worked properly.
199 if(!aBoolAlgo.isDone()) {
200 static const std::string aFeatureError = "Error: Boolean algorithm failed.";
201 setError(aFeatureError);
204 if(aResShape->isNull()) {
205 static const std::string aShapeError = "Error: Resulting shape is Null.";
206 setError(aShapeError);
209 if(!aBoolAlgo.isValid()) {
210 std::string aFeatureError = "Error: Resulting shape is not valid.";
211 setError(aFeatureError);
215 if(GeomAlgoAPI_ShapeTools::volume(aResShape) > 1.e-27) {
216 std::shared_ptr<ModelAPI_ResultBody> aResultBody =
217 document()->createBody(data(), aResultIndex);
218 loadNamingDS(aResultBody, anObject, aTools, aResShape,
219 aBoolAlgo, *aBoolAlgo.mapOfSubShapes().get());
220 setResult(aResultBody, aResultIndex);
225 // Compsolids handling
226 for(std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
227 anIt = aCompSolidsObjects.begin();
228 anIt != aCompSolidsObjects.end(); anIt++) {
229 std::shared_ptr<GeomAPI_Shape> aCompSolid = anIt->first;
230 ListOfShape& aUsedInOperationSolids = anIt->second;
232 // Collecting solids from compsolids which will not be modified in boolean operation.
233 ListOfShape aNotUsedSolids;
234 for(GeomAPI_ShapeExplorer
235 anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
236 std::shared_ptr<GeomAPI_Shape> aSolidInCompSolid = anExp.current();
237 ListOfShape::iterator anIt = aUsedInOperationSolids.begin();
238 for(; anIt != aUsedInOperationSolids.end(); anIt++) {
239 if(aSolidInCompSolid->isEqual(*anIt)) {
243 if(anIt == aUsedInOperationSolids.end()) {
244 aNotUsedSolids.push_back(aSolidInCompSolid);
248 std::shared_ptr<GeomAlgoAPI_MakeShape> aBoolAlgo;
252 aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aUsedInOperationSolids,
254 GeomAlgoAPI_Boolean::BOOL_CUT));
258 aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aUsedInOperationSolids,
260 GeomAlgoAPI_Boolean::BOOL_COMMON));
264 aBoolAlgo.reset(new GeomAlgoAPI_Partition(aUsedInOperationSolids, aTools));
269 // Checking that the algorithm worked properly.
270 if(!aBoolAlgo->isDone()) {
271 static const std::string aFeatureError = "Error: Boolean algorithm failed.";
272 setError(aFeatureError);
275 if(aBoolAlgo->shape()->isNull()) {
276 static const std::string aShapeError = "Error: Resulting shape is Null.";
277 setError(aShapeError);
280 if(!aBoolAlgo->isValid()) {
281 std::string aFeatureError = "Error: Resulting shape is not valid.";
282 setError(aFeatureError);
286 GeomAlgoAPI_MakeShapeList aMakeShapeList;
287 aMakeShapeList.appendAlgo(aBoolAlgo);
288 GeomAPI_DataMapOfShapeShape aMapOfShapes;
289 aMapOfShapes.merge(aBoolAlgo->mapOfSubShapes());
290 GeomShapePtr aResultShape = aBoolAlgo->shape();
292 // Add result to not used solids from compsolid.
293 if(!aNotUsedSolids.empty()) {
294 ListOfShape aShapesToAdd = aNotUsedSolids;
295 aShapesToAdd.push_back(aBoolAlgo->shape());
296 std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(
297 new GeomAlgoAPI_PaveFiller(aShapesToAdd, true));
298 if(!aFillerAlgo->isDone()) {
299 std::string aFeatureError = "Error: PaveFiller algorithm failed.";
300 setError(aFeatureError);
304 aMakeShapeList.appendAlgo(aFillerAlgo);
305 aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes());
306 aResultShape = aFillerAlgo->shape();
309 if(GeomAlgoAPI_ShapeTools::volume(aResultShape) > 1.e-27) {
310 std::shared_ptr<ModelAPI_ResultBody> aResultBody =
311 document()->createBody(data(), aResultIndex);
312 loadNamingDS(aResultBody, aCompSolid, aTools, aResultShape, aMakeShapeList, aMapOfShapes);
313 setResult(aResultBody, aResultIndex);
320 if((anObjects.size() + aTools.size() +
321 aCompSolidsObjects.size() + anEdgesAndFaces.size()) < 2) {
322 std::string aFeatureError = "Error: Not enough objects for boolean operation.";
323 setError(aFeatureError);
327 // Collecting all solids which will be fused.
328 ListOfShape aSolidsToFuse;
329 aSolidsToFuse.insert(aSolidsToFuse.end(), anObjects.begin(), anObjects.end());
330 aSolidsToFuse.insert(aSolidsToFuse.end(), aTools.begin(), aTools.end());
332 // Collecting solids from compsolids which will not be modified
333 // in boolean operation and will be added to result.
334 ListOfShape aShapesToAdd;
335 for(std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
336 anIt = aCompSolidsObjects.begin();
337 anIt != aCompSolidsObjects.end(); anIt++) {
338 std::shared_ptr<GeomAPI_Shape> aCompSolid = anIt->first;
339 ListOfShape& aUsedInOperationSolids = anIt->second;
340 aSolidsToFuse.insert(aSolidsToFuse.end(), aUsedInOperationSolids.begin(),
341 aUsedInOperationSolids.end());
343 // Collect solids from compsolid which will not be modified in boolean operation.
344 for(GeomAPI_ShapeExplorer
345 anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
346 std::shared_ptr<GeomAPI_Shape> aSolidInCompSolid = anExp.current();
347 ListOfShape::iterator anIt = aUsedInOperationSolids.begin();
348 for(; anIt != aUsedInOperationSolids.end(); anIt++) {
349 if(aSolidInCompSolid->isEqual(*anIt)) {
353 if(anIt == aUsedInOperationSolids.end()) {
354 aShapesToAdd.push_back(aSolidInCompSolid);
359 ListOfShape anOriginalShapes = aSolidsToFuse;
360 anOriginalShapes.insert(anOriginalShapes.end(), aShapesToAdd.begin(), aShapesToAdd.end());
362 // Cut edges and faces(if we have any) with solids.
363 GeomAlgoAPI_MakeShapeList aMakeShapeList;
364 GeomAPI_DataMapOfShapeShape aMapOfShapes;
365 std::shared_ptr<GeomAPI_Shape> aCuttedEdgesAndFaces;
366 if(!anEdgesAndFaces.empty()) {
367 std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(new GeomAlgoAPI_Boolean(anEdgesAndFaces,
368 anOriginalShapes, GeomAlgoAPI_Boolean::BOOL_CUT));
369 if(aCutAlgo->isDone()) {
370 aCuttedEdgesAndFaces = aCutAlgo->shape();
371 aMakeShapeList.appendAlgo(aCutAlgo);
372 aMapOfShapes.merge(aCutAlgo->mapOfSubShapes());
375 anOriginalShapes.insert(anOriginalShapes.end(), anEdgesAndFaces.begin(),
376 anEdgesAndFaces.end());
378 // If we have compsolids then cut with not used solids all others.
379 if(!aShapesToAdd.empty()) {
380 aSolidsToFuse.clear();
381 for(ListOfShape::iterator
382 anIt = anOriginalShapes.begin(); anIt != anOriginalShapes.end(); anIt++) {
383 ListOfShape aOneObjectList;
384 aOneObjectList.push_back(*anIt);
385 std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(
386 new GeomAlgoAPI_Boolean(aOneObjectList, aShapesToAdd, GeomAlgoAPI_Boolean::BOOL_CUT));
388 if(GeomAlgoAPI_ShapeTools::volume(aCutAlgo->shape()) > 1.e-27) {
389 aSolidsToFuse.push_back(aCutAlgo->shape());
390 aMakeShapeList.appendAlgo(aCutAlgo);
391 aMapOfShapes.merge(aCutAlgo->mapOfSubShapes());
396 if(!aSolidsToFuse.empty()) {
398 anObjects.push_back(aSolidsToFuse.back());
399 aSolidsToFuse.pop_back();
400 aTools = aSolidsToFuse;
403 // Fuse all objects and all tools.
404 std::shared_ptr<GeomAPI_Shape> aShape;
405 if(anObjects.size() == 1 && aTools.empty()) {
406 aShape = anObjects.front();
407 } else if(anObjects.empty() && aTools.size() == 1) {
408 aShape = aTools.front();
409 } else if((anObjects.size() + aTools.size()) > 1){
410 std::shared_ptr<GeomAlgoAPI_Boolean> aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects,
412 GeomAlgoAPI_Boolean::BOOL_FUSE));
414 // Checking that the algorithm worked properly.
415 if(!aFuseAlgo->isDone()) {
416 static const std::string aFeatureError = "Error: Boolean algorithm failed.";
417 setError(aFeatureError);
420 if(aFuseAlgo->shape()->isNull()) {
421 static const std::string aShapeError = "Error: Resulting shape is Null.";
422 setError(aShapeError);
425 if(!aFuseAlgo->isValid()) {
426 std::string aFeatureError = "Error: Resulting shape is not valid.";
427 setError(aFeatureError);
431 aShape = aFuseAlgo->shape();
432 aMakeShapeList.appendAlgo(aFuseAlgo);
433 aMapOfShapes.merge(aFuseAlgo->mapOfSubShapes());
436 // Combine result with not used solids from compsolid and edges and faces (if we have any).
437 if(aCuttedEdgesAndFaces.get() && !aCuttedEdgesAndFaces->isNull()) {
438 aShapesToAdd.push_back(aCuttedEdgesAndFaces);
440 aShapesToAdd.insert(aShapesToAdd.end(), anEdgesAndFaces.begin(), anEdgesAndFaces.end());
442 if(!aShapesToAdd.empty()) {
444 aShapesToAdd.push_back(aShape);
446 std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(
447 new GeomAlgoAPI_PaveFiller(aShapesToAdd, true));
448 if(!aFillerAlgo->isDone()) {
449 std::string aFeatureError = "Error: PaveFiller algorithm failed.";
450 setError(aFeatureError);
453 if(aFillerAlgo->shape()->isNull()) {
454 static const std::string aShapeError = "Error: Resulting shape is Null.";
455 setError(aShapeError);
458 if(!aFillerAlgo->isValid()) {
459 std::string aFeatureError = "Error: Resulting shape is not valid.";
460 setError(aFeatureError);
464 aShape = aFillerAlgo->shape();
465 aMakeShapeList.appendAlgo(aFillerAlgo);
466 aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes());
469 std::shared_ptr<GeomAPI_Shape> aBackShape = anOriginalShapes.back();
470 anOriginalShapes.pop_back();
471 std::shared_ptr<ModelAPI_ResultBody> aResultBody =
472 document()->createBody(data(), aResultIndex);
473 loadNamingDS(aResultBody, aBackShape, anOriginalShapes,
474 aShape, aMakeShapeList, aMapOfShapes);
475 setResult(aResultBody, aResultIndex);
480 if((anObjects.empty() && aCompSolidsObjects.empty()) || aTools.empty()) {
481 std::string aFeatureError = "Error: Not enough objects for boolean operation.";
482 setError(aFeatureError);
486 // List of original solids for naming.
487 ListOfShape anOriginalShapes;
488 anOriginalShapes.insert(anOriginalShapes.end(), anObjects.begin(), anObjects.end());
489 anOriginalShapes.insert(anOriginalShapes.end(), aTools.begin(), aTools.end());
491 // Collecting all solids which will be smashed.
492 ListOfShape aShapesToSmash;
493 aShapesToSmash.insert(aShapesToSmash.end(), anObjects.begin(), anObjects.end());
495 // Collecting solids from compsolids which will not be modified in
496 // boolean operation and will be added to result.
497 ListOfShape aShapesToAdd;
498 for(std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
499 anIt = aCompSolidsObjects.begin();
500 anIt != aCompSolidsObjects.end(); anIt++) {
501 std::shared_ptr<GeomAPI_Shape> aCompSolid = anIt->first;
502 ListOfShape& aUsedInOperationSolids = anIt->second;
503 anOriginalShapes.push_back(aCompSolid);
504 aShapesToSmash.insert(aShapesToSmash.end(), aUsedInOperationSolids.begin(),
505 aUsedInOperationSolids.end());
507 // Collect solids from compsolid which will not be modified in boolean operation.
508 for(GeomAPI_ShapeExplorer
509 anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
510 std::shared_ptr<GeomAPI_Shape> aSolidInCompSolid = anExp.current();
511 ListOfShape::iterator anIt = aUsedInOperationSolids.begin();
512 for(; anIt != aUsedInOperationSolids.end(); anIt++) {
513 if(aSolidInCompSolid->isEqual(*anIt)) {
517 if(anIt == aUsedInOperationSolids.end()) {
518 aShapesToAdd.push_back(aSolidInCompSolid);
523 GeomAlgoAPI_MakeShapeList aMakeShapeList;
524 GeomAPI_DataMapOfShapeShape aMapOfShapes;
525 if(!aShapesToAdd.empty()) {
526 // Cut objects with not used solids.
527 std::shared_ptr<GeomAlgoAPI_Boolean> anObjectsCutAlgo(new GeomAlgoAPI_Boolean(
530 GeomAlgoAPI_Boolean::BOOL_CUT));
532 if(GeomAlgoAPI_ShapeTools::volume(anObjectsCutAlgo->shape()) > 1.e-27) {
533 aShapesToSmash.clear();
534 aShapesToSmash.push_back(anObjectsCutAlgo->shape());
535 aMakeShapeList.appendAlgo(anObjectsCutAlgo);
536 aMapOfShapes.merge(anObjectsCutAlgo->mapOfSubShapes());
539 // Cut tools with not used solids.
540 std::shared_ptr<GeomAlgoAPI_Boolean> aToolsCutAlgo(new GeomAlgoAPI_Boolean(aTools,
542 GeomAlgoAPI_Boolean::BOOL_CUT));
544 if(GeomAlgoAPI_ShapeTools::volume(aToolsCutAlgo->shape()) > 1.e-27) {
546 aTools.push_back(aToolsCutAlgo->shape());
547 aMakeShapeList.appendAlgo(aToolsCutAlgo);
548 aMapOfShapes.merge(aToolsCutAlgo->mapOfSubShapes());
552 // Cut objects with tools.
553 std::shared_ptr<GeomAlgoAPI_Boolean> aBoolAlgo(new GeomAlgoAPI_Boolean(aShapesToSmash,
555 GeomAlgoAPI_Boolean::BOOL_CUT));
557 // Checking that the algorithm worked properly.
558 if(!aBoolAlgo->isDone()) {
559 static const std::string aFeatureError = "Error: Boolean algorithm failed.";
560 setError(aFeatureError);
563 if(aBoolAlgo->shape()->isNull()) {
564 static const std::string aShapeError = "Error: Resulting shape is Null.";
565 setError(aShapeError);
568 if(!aBoolAlgo->isValid()) {
569 std::string aFeatureError = "Error: Resulting shape is not valid.";
570 setError(aFeatureError);
573 aMakeShapeList.appendAlgo(aBoolAlgo);
574 aMapOfShapes.merge(aBoolAlgo->mapOfSubShapes());
576 // Put all (cut result, tools and not used solids) to PaveFiller.
577 aShapesToAdd.push_back(aBoolAlgo->shape());
578 aShapesToAdd.insert(aShapesToAdd.end(), aTools.begin(), aTools.end());
580 std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(new GeomAlgoAPI_PaveFiller(aShapesToAdd,
582 if(!aFillerAlgo->isDone()) {
583 std::string aFeatureError = "Error: PaveFiller algorithm failed.";
584 setError(aFeatureError);
587 if(aFillerAlgo->shape()->isNull()) {
588 static const std::string aShapeError = "Error: Resulting shape is Null.";
589 setError(aShapeError);
592 if(!aFillerAlgo->isValid()) {
593 std::string aFeatureError = "Error: Resulting shape is not valid.";
594 setError(aFeatureError);
598 std::shared_ptr<GeomAPI_Shape> aShape = aFillerAlgo->shape();
599 aMakeShapeList.appendAlgo(aFillerAlgo);
600 aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes());
602 std::shared_ptr<GeomAPI_Shape> aFrontShape = anOriginalShapes.front();
603 anOriginalShapes.pop_front();
604 std::shared_ptr<ModelAPI_ResultBody> aResultBody =
605 document()->createBody(data(), aResultIndex);
606 loadNamingDS(aResultBody, aFrontShape, anOriginalShapes,
607 aShape, aMakeShapeList, aMapOfShapes);
608 setResult(aResultBody, aResultIndex);
614 std::string anOperationError = "Error: Wrong type of operation";
615 setError(anOperationError);
619 // remove the rest results if there were produced in the previous pass
620 removeResults(aResultIndex);
623 //=================================================================================================
624 void FeaturesPlugin_Boolean::loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
625 const std::shared_ptr<GeomAPI_Shape> theBaseShape,
626 const ListOfShape& theTools,
627 const std::shared_ptr<GeomAPI_Shape> theResultShape,
628 GeomAlgoAPI_MakeShape& theMakeShape,
629 GeomAPI_DataMapOfShapeShape& theMapOfShapes)
632 if(theBaseShape->isEqual(theResultShape)) {
633 theResultBody->store(theResultShape, false);
635 const int aModifyTag = 1;
636 const int aDeletedTag = 2;
637 /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids
638 const int aSubsolidsTag = 3;
639 const int anEdgesAndFacesTag = 10000;
641 theResultBody->storeModified(theBaseShape, theResultShape, aSubsolidsTag);
643 const std::string aModName = "Modified";
644 const std::string aModEName = "Modified_Edge";
645 const std::string aModFName = "Modified_Face";
647 theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE,
648 aModifyTag, aModName, theMapOfShapes, false, false, true);
649 theResultBody->loadDeletedShapes(&theMakeShape, theBaseShape,
650 GeomAPI_Shape::FACE, aDeletedTag);
654 for(ListOfShape::const_iterator
655 anIter = theTools.begin(); anIter != theTools.end(); anIter++) {
656 if((*anIter)->shapeType() == GeomAPI_Shape::EDGE) {
657 aTag = anEdgesAndFacesTag;
660 else if((*anIter)->shapeType() == GeomAPI_Shape::FACE) {
661 aTag = anEdgesAndFacesTag;
667 theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter,
668 aName == aModEName ? GeomAPI_Shape::EDGE : GeomAPI_Shape::FACE,
669 aTag, aName, theMapOfShapes, false, false, true);
670 theResultBody->loadDeletedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE, aDeletedTag);