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 email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
20 #include "FeaturesPlugin_Boolean.h"
22 #include <ModelAPI_Data.h>
23 #include <ModelAPI_Document.h>
24 #include <ModelAPI_AttributeReference.h>
25 #include <ModelAPI_AttributeInteger.h>
26 #include <ModelAPI_ResultCompSolid.h>
27 #include <ModelAPI_ResultBody.h>
28 #include <ModelAPI_AttributeSelectionList.h>
29 #include <ModelAPI_Session.h>
30 #include <ModelAPI_Validator.h>
31 #include <ModelAPI_Tools.h>
33 #include <GeomAlgoAPI_Boolean.h>
34 #include <GeomAlgoAPI_MakeShapeList.h>
35 #include <GeomAlgoAPI_Partition.h>
36 #include <GeomAlgoAPI_PaveFiller.h>
37 #include <GeomAlgoAPI_ShapeTools.h>
38 #include <GeomAPI_ShapeExplorer.h>
39 #include <GeomAPI_ShapeIterator.h>
44 //=================================================================================================
45 FeaturesPlugin_Boolean::FeaturesPlugin_Boolean()
49 //=================================================================================================
50 void FeaturesPlugin_Boolean::initAttributes()
52 data()->addAttribute(FeaturesPlugin_Boolean::TYPE_ID(), ModelAPI_AttributeInteger::typeId());
54 AttributeSelectionListPtr aSelection =
55 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
56 FeaturesPlugin_Boolean::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
58 aSelection = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
59 FeaturesPlugin_Boolean::TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
61 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), OBJECT_LIST_ID());
62 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TOOL_LIST_ID());
65 //=================================================================================================
66 std::shared_ptr<GeomAPI_Shape> FeaturesPlugin_Boolean::getShape(const std::string& theAttrName)
68 std::shared_ptr<ModelAPI_AttributeReference> aObjRef = std::dynamic_pointer_cast<
69 ModelAPI_AttributeReference>(data()->attribute(theAttrName));
71 std::shared_ptr<ModelAPI_ResultBody> aConstr = std::dynamic_pointer_cast<
72 ModelAPI_ResultBody>(aObjRef->value());
74 return aConstr->shape();
76 return std::shared_ptr<GeomAPI_Shape>();
79 //=================================================================================================
80 void FeaturesPlugin_Boolean::execute()
82 // Getting operation type.
83 std::shared_ptr<ModelAPI_AttributeInteger> aTypeAttr = std::dynamic_pointer_cast<
84 ModelAPI_AttributeInteger>(data()->attribute(FeaturesPlugin_Boolean::TYPE_ID()));
87 OperationType aType = (FeaturesPlugin_Boolean::OperationType)aTypeAttr->value();
89 ListOfShape anObjects, aTools, anEdgesAndFaces;
90 std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape> aCompSolidsObjects;
93 AttributeSelectionListPtr anObjectsSelList =
94 selectionList(FeaturesPlugin_Boolean::OBJECT_LIST_ID());
95 for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
96 AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex);
97 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
101 ResultPtr aContext = anObjectAttr->context();
102 ResultCompSolidPtr aResCompSolidPtr = ModelAPI_Tools::compSolidOwner(aContext);
103 if(aResCompSolidPtr.get()) {
104 std::shared_ptr<GeomAPI_Shape> aContextShape = aResCompSolidPtr->shape();
105 std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
106 anIt = aCompSolidsObjects.begin();
107 for(; anIt != aCompSolidsObjects.end(); anIt++) {
108 if(anIt->first->isEqual(aContextShape)) {
109 aCompSolidsObjects[anIt->first].push_back(anObject);
113 if(anIt == aCompSolidsObjects.end()) {
114 aCompSolidsObjects[aContextShape].push_back(anObject);
117 if(anObject->shapeType() == GeomAPI_Shape::EDGE ||
118 anObject->shapeType() == GeomAPI_Shape::FACE) {
119 anEdgesAndFaces.push_back(anObject);
121 anObjects.push_back(anObject);
127 AttributeSelectionListPtr aToolsSelList = selectionList(FeaturesPlugin_Boolean::TOOL_LIST_ID());
128 for(int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) {
129 AttributeSelectionPtr aToolAttr = aToolsSelList->value(aToolsIndex);
130 std::shared_ptr<GeomAPI_Shape> aTool = aToolAttr->value();
134 if(aTool->shapeType() == GeomAPI_Shape::EDGE ||
135 aTool->shapeType() == GeomAPI_Shape::FACE) {
136 anEdgesAndFaces.push_back(aTool);
138 aTools.push_back(aTool);
142 int aResultIndex = 0;
148 if((anObjects.empty() && aCompSolidsObjects.empty()) || aTools.empty()) {
149 std::string aFeatureError = "Error: Not enough objects for boolean operation.";
150 setError(aFeatureError);
154 // For solids cut each object with all tools.
155 for(ListOfShape::iterator
156 anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) {
157 std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
158 ListOfShape aListWithObject;
159 aListWithObject.push_back(anObject);
160 GeomAlgoAPI_MakeShape aBoolAlgo;
161 GeomShapePtr aResShape;
166 GeomAlgoAPI_Boolean(aListWithObject, aTools, GeomAlgoAPI_Boolean::BOOL_CUT);
167 aResShape = aBoolAlgo.shape();
172 GeomAlgoAPI_Boolean(aListWithObject, aTools, GeomAlgoAPI_Boolean::BOOL_COMMON);
173 aResShape = aBoolAlgo.shape();
177 aBoolAlgo = GeomAlgoAPI_Partition(aListWithObject, aTools);
178 aResShape = aBoolAlgo.shape();
179 if(aResShape->shapeType() == GeomAPI_Shape::COMPOUND) {
180 int aSubResultsNb = 0;
181 GeomAPI_ShapeIterator anIt(aResShape);
182 for(; anIt.more(); anIt.next()) {
185 if(aSubResultsNb == 1) {
186 anIt.init(aResShape);
188 aResShape = anIt.current();
196 // Checking that the algorithm worked properly.
197 if(!aBoolAlgo.isDone()) {
198 static const std::string aFeatureError = "Error: Boolean algorithm failed.";
199 setError(aFeatureError);
202 if(aResShape->isNull()) {
203 static const std::string aShapeError = "Error: Resulting shape is Null.";
204 setError(aShapeError);
207 if(!aBoolAlgo.isValid()) {
208 std::string aFeatureError = "Error: Resulting shape is not valid.";
209 setError(aFeatureError);
213 if(GeomAlgoAPI_ShapeTools::volume(aResShape) > 1.e-27) {
214 std::shared_ptr<ModelAPI_ResultBody> aResultBody =
215 document()->createBody(data(), aResultIndex);
216 loadNamingDS(aResultBody, anObject, aTools, aResShape,
217 aBoolAlgo, *aBoolAlgo.mapOfSubShapes().get());
218 setResult(aResultBody, aResultIndex);
223 // Compsolids handling
224 for(std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
225 anIt = aCompSolidsObjects.begin();
226 anIt != aCompSolidsObjects.end(); anIt++) {
227 std::shared_ptr<GeomAPI_Shape> aCompSolid = anIt->first;
228 ListOfShape& aUsedInOperationSolids = anIt->second;
230 // Collecting solids from compsolids which will not be modified in boolean operation.
231 ListOfShape aNotUsedSolids;
232 for(GeomAPI_ShapeExplorer
233 anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
234 std::shared_ptr<GeomAPI_Shape> aSolidInCompSolid = anExp.current();
235 ListOfShape::iterator anIt = aUsedInOperationSolids.begin();
236 for(; anIt != aUsedInOperationSolids.end(); anIt++) {
237 if(aSolidInCompSolid->isEqual(*anIt)) {
241 if(anIt == aUsedInOperationSolids.end()) {
242 aNotUsedSolids.push_back(aSolidInCompSolid);
246 std::shared_ptr<GeomAlgoAPI_MakeShape> aBoolAlgo;
250 aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aUsedInOperationSolids,
252 GeomAlgoAPI_Boolean::BOOL_CUT));
256 aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aUsedInOperationSolids,
258 GeomAlgoAPI_Boolean::BOOL_COMMON));
262 aBoolAlgo.reset(new GeomAlgoAPI_Partition(aUsedInOperationSolids, aTools));
267 // Checking that the algorithm worked properly.
268 if(!aBoolAlgo->isDone()) {
269 static const std::string aFeatureError = "Error: Boolean algorithm failed.";
270 setError(aFeatureError);
273 if(aBoolAlgo->shape()->isNull()) {
274 static const std::string aShapeError = "Error: Resulting shape is Null.";
275 setError(aShapeError);
278 if(!aBoolAlgo->isValid()) {
279 std::string aFeatureError = "Error: Resulting shape is not valid.";
280 setError(aFeatureError);
284 GeomAlgoAPI_MakeShapeList aMakeShapeList;
285 aMakeShapeList.appendAlgo(aBoolAlgo);
286 GeomAPI_DataMapOfShapeShape aMapOfShapes;
287 aMapOfShapes.merge(aBoolAlgo->mapOfSubShapes());
288 GeomShapePtr aResultShape = aBoolAlgo->shape();
290 // Add result to not used solids from compsolid.
291 if(!aNotUsedSolids.empty()) {
292 ListOfShape aShapesToAdd = aNotUsedSolids;
293 aShapesToAdd.push_back(aBoolAlgo->shape());
294 std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(
295 new GeomAlgoAPI_PaveFiller(aShapesToAdd, true));
296 if(!aFillerAlgo->isDone()) {
297 std::string aFeatureError = "Error: PaveFiller algorithm failed.";
298 setError(aFeatureError);
302 aMakeShapeList.appendAlgo(aFillerAlgo);
303 aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes());
304 aResultShape = aFillerAlgo->shape();
307 if(GeomAlgoAPI_ShapeTools::volume(aResultShape) > 1.e-27) {
308 std::shared_ptr<ModelAPI_ResultBody> aResultBody =
309 document()->createBody(data(), aResultIndex);
310 loadNamingDS(aResultBody, aCompSolid, aTools, aResultShape, aMakeShapeList, aMapOfShapes);
311 setResult(aResultBody, aResultIndex);
318 if((anObjects.size() + aTools.size() +
319 aCompSolidsObjects.size() + anEdgesAndFaces.size()) < 2) {
320 std::string aFeatureError = "Error: Not enough objects for boolean operation.";
321 setError(aFeatureError);
325 // Collecting all solids which will be fused.
326 ListOfShape aSolidsToFuse;
327 aSolidsToFuse.insert(aSolidsToFuse.end(), anObjects.begin(), anObjects.end());
328 aSolidsToFuse.insert(aSolidsToFuse.end(), aTools.begin(), aTools.end());
330 // Collecting solids from compsolids which will not be modified
331 // in boolean operation and will be added to result.
332 ListOfShape aShapesToAdd;
333 for(std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
334 anIt = aCompSolidsObjects.begin();
335 anIt != aCompSolidsObjects.end(); anIt++) {
336 std::shared_ptr<GeomAPI_Shape> aCompSolid = anIt->first;
337 ListOfShape& aUsedInOperationSolids = anIt->second;
338 aSolidsToFuse.insert(aSolidsToFuse.end(), aUsedInOperationSolids.begin(),
339 aUsedInOperationSolids.end());
341 // Collect solids from compsolid which will not be modified in boolean operation.
342 for(GeomAPI_ShapeExplorer
343 anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
344 std::shared_ptr<GeomAPI_Shape> aSolidInCompSolid = anExp.current();
345 ListOfShape::iterator anIt = aUsedInOperationSolids.begin();
346 for(; anIt != aUsedInOperationSolids.end(); anIt++) {
347 if(aSolidInCompSolid->isEqual(*anIt)) {
351 if(anIt == aUsedInOperationSolids.end()) {
352 aShapesToAdd.push_back(aSolidInCompSolid);
357 ListOfShape anOriginalShapes = aSolidsToFuse;
358 anOriginalShapes.insert(anOriginalShapes.end(), aShapesToAdd.begin(), aShapesToAdd.end());
360 // Cut edges and faces(if we have any) with solids.
361 GeomAlgoAPI_MakeShapeList aMakeShapeList;
362 GeomAPI_DataMapOfShapeShape aMapOfShapes;
363 std::shared_ptr<GeomAPI_Shape> aCuttedEdgesAndFaces;
364 if(!anEdgesAndFaces.empty()) {
365 std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(new GeomAlgoAPI_Boolean(anEdgesAndFaces,
366 anOriginalShapes, GeomAlgoAPI_Boolean::BOOL_CUT));
367 if(aCutAlgo->isDone()) {
368 aCuttedEdgesAndFaces = aCutAlgo->shape();
369 aMakeShapeList.appendAlgo(aCutAlgo);
370 aMapOfShapes.merge(aCutAlgo->mapOfSubShapes());
373 anOriginalShapes.insert(anOriginalShapes.end(), anEdgesAndFaces.begin(),
374 anEdgesAndFaces.end());
376 // If we have compsolids then cut with not used solids all others.
377 if(!aShapesToAdd.empty()) {
378 aSolidsToFuse.clear();
379 for(ListOfShape::iterator
380 anIt = anOriginalShapes.begin(); anIt != anOriginalShapes.end(); anIt++) {
381 ListOfShape aOneObjectList;
382 aOneObjectList.push_back(*anIt);
383 std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(
384 new GeomAlgoAPI_Boolean(aOneObjectList, aShapesToAdd, GeomAlgoAPI_Boolean::BOOL_CUT));
386 if(GeomAlgoAPI_ShapeTools::volume(aCutAlgo->shape()) > 1.e-27) {
387 aSolidsToFuse.push_back(aCutAlgo->shape());
388 aMakeShapeList.appendAlgo(aCutAlgo);
389 aMapOfShapes.merge(aCutAlgo->mapOfSubShapes());
394 if(!aSolidsToFuse.empty()) {
396 anObjects.push_back(aSolidsToFuse.back());
397 aSolidsToFuse.pop_back();
398 aTools = aSolidsToFuse;
401 // Fuse all objects and all tools.
402 std::shared_ptr<GeomAPI_Shape> aShape;
403 if(anObjects.size() == 1 && aTools.empty()) {
404 aShape = anObjects.front();
405 } else if(anObjects.empty() && aTools.size() == 1) {
406 aShape = aTools.front();
407 } else if((anObjects.size() + aTools.size()) > 1){
408 std::shared_ptr<GeomAlgoAPI_Boolean> aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects,
410 GeomAlgoAPI_Boolean::BOOL_FUSE));
412 // Checking that the algorithm worked properly.
413 if(!aFuseAlgo->isDone()) {
414 static const std::string aFeatureError = "Error: Boolean algorithm failed.";
415 setError(aFeatureError);
418 if(aFuseAlgo->shape()->isNull()) {
419 static const std::string aShapeError = "Error: Resulting shape is Null.";
420 setError(aShapeError);
423 if(!aFuseAlgo->isValid()) {
424 std::string aFeatureError = "Error: Resulting shape is not valid.";
425 setError(aFeatureError);
429 aShape = aFuseAlgo->shape();
430 aMakeShapeList.appendAlgo(aFuseAlgo);
431 aMapOfShapes.merge(aFuseAlgo->mapOfSubShapes());
434 // Combine result with not used solids from compsolid and edges and faces (if we have any).
435 if(aCuttedEdgesAndFaces.get() && !aCuttedEdgesAndFaces->isNull()) {
436 aShapesToAdd.push_back(aCuttedEdgesAndFaces);
438 aShapesToAdd.insert(aShapesToAdd.end(), anEdgesAndFaces.begin(), anEdgesAndFaces.end());
440 if(!aShapesToAdd.empty()) {
442 aShapesToAdd.push_back(aShape);
444 std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(
445 new GeomAlgoAPI_PaveFiller(aShapesToAdd, true));
446 if(!aFillerAlgo->isDone()) {
447 std::string aFeatureError = "Error: PaveFiller algorithm failed.";
448 setError(aFeatureError);
451 if(aFillerAlgo->shape()->isNull()) {
452 static const std::string aShapeError = "Error: Resulting shape is Null.";
453 setError(aShapeError);
456 if(!aFillerAlgo->isValid()) {
457 std::string aFeatureError = "Error: Resulting shape is not valid.";
458 setError(aFeatureError);
462 aShape = aFillerAlgo->shape();
463 aMakeShapeList.appendAlgo(aFillerAlgo);
464 aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes());
467 std::shared_ptr<GeomAPI_Shape> aBackShape = anOriginalShapes.back();
468 anOriginalShapes.pop_back();
469 std::shared_ptr<ModelAPI_ResultBody> aResultBody =
470 document()->createBody(data(), aResultIndex);
471 loadNamingDS(aResultBody, aBackShape, anOriginalShapes,
472 aShape, aMakeShapeList, aMapOfShapes);
473 setResult(aResultBody, aResultIndex);
478 if((anObjects.empty() && aCompSolidsObjects.empty()) || aTools.empty()) {
479 std::string aFeatureError = "Error: Not enough objects for boolean operation.";
480 setError(aFeatureError);
484 // List of original solids for naming.
485 ListOfShape anOriginalShapes;
486 anOriginalShapes.insert(anOriginalShapes.end(), anObjects.begin(), anObjects.end());
487 anOriginalShapes.insert(anOriginalShapes.end(), aTools.begin(), aTools.end());
489 // Collecting all solids which will be smashed.
490 ListOfShape aShapesToSmash;
491 aShapesToSmash.insert(aShapesToSmash.end(), anObjects.begin(), anObjects.end());
493 // Collecting solids from compsolids which will not be modified in
494 // boolean operation and will be added to result.
495 ListOfShape aShapesToAdd;
496 for(std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
497 anIt = aCompSolidsObjects.begin();
498 anIt != aCompSolidsObjects.end(); anIt++) {
499 std::shared_ptr<GeomAPI_Shape> aCompSolid = anIt->first;
500 ListOfShape& aUsedInOperationSolids = anIt->second;
501 anOriginalShapes.push_back(aCompSolid);
502 aShapesToSmash.insert(aShapesToSmash.end(), aUsedInOperationSolids.begin(),
503 aUsedInOperationSolids.end());
505 // Collect solids from compsolid which will not be modified in boolean operation.
506 for(GeomAPI_ShapeExplorer
507 anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
508 std::shared_ptr<GeomAPI_Shape> aSolidInCompSolid = anExp.current();
509 ListOfShape::iterator anIt = aUsedInOperationSolids.begin();
510 for(; anIt != aUsedInOperationSolids.end(); anIt++) {
511 if(aSolidInCompSolid->isEqual(*anIt)) {
515 if(anIt == aUsedInOperationSolids.end()) {
516 aShapesToAdd.push_back(aSolidInCompSolid);
521 GeomAlgoAPI_MakeShapeList aMakeShapeList;
522 GeomAPI_DataMapOfShapeShape aMapOfShapes;
523 if(!aShapesToAdd.empty()) {
524 // Cut objects with not used solids.
525 std::shared_ptr<GeomAlgoAPI_Boolean> anObjectsCutAlgo(new GeomAlgoAPI_Boolean(
528 GeomAlgoAPI_Boolean::BOOL_CUT));
530 if(GeomAlgoAPI_ShapeTools::volume(anObjectsCutAlgo->shape()) > 1.e-27) {
531 aShapesToSmash.clear();
532 aShapesToSmash.push_back(anObjectsCutAlgo->shape());
533 aMakeShapeList.appendAlgo(anObjectsCutAlgo);
534 aMapOfShapes.merge(anObjectsCutAlgo->mapOfSubShapes());
537 // Cut tools with not used solids.
538 std::shared_ptr<GeomAlgoAPI_Boolean> aToolsCutAlgo(new GeomAlgoAPI_Boolean(aTools,
540 GeomAlgoAPI_Boolean::BOOL_CUT));
542 if(GeomAlgoAPI_ShapeTools::volume(aToolsCutAlgo->shape()) > 1.e-27) {
544 aTools.push_back(aToolsCutAlgo->shape());
545 aMakeShapeList.appendAlgo(aToolsCutAlgo);
546 aMapOfShapes.merge(aToolsCutAlgo->mapOfSubShapes());
550 // Cut objects with tools.
551 std::shared_ptr<GeomAlgoAPI_Boolean> aBoolAlgo(new GeomAlgoAPI_Boolean(aShapesToSmash,
553 GeomAlgoAPI_Boolean::BOOL_CUT));
555 // Checking that the algorithm worked properly.
556 if(!aBoolAlgo->isDone()) {
557 static const std::string aFeatureError = "Error: Boolean algorithm failed.";
558 setError(aFeatureError);
561 if(aBoolAlgo->shape()->isNull()) {
562 static const std::string aShapeError = "Error: Resulting shape is Null.";
563 setError(aShapeError);
566 if(!aBoolAlgo->isValid()) {
567 std::string aFeatureError = "Error: Resulting shape is not valid.";
568 setError(aFeatureError);
571 aMakeShapeList.appendAlgo(aBoolAlgo);
572 aMapOfShapes.merge(aBoolAlgo->mapOfSubShapes());
574 // Put all (cut result, tools and not used solids) to PaveFiller.
575 aShapesToAdd.push_back(aBoolAlgo->shape());
576 aShapesToAdd.insert(aShapesToAdd.end(), aTools.begin(), aTools.end());
578 std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(new GeomAlgoAPI_PaveFiller(aShapesToAdd,
580 if(!aFillerAlgo->isDone()) {
581 std::string aFeatureError = "Error: PaveFiller algorithm failed.";
582 setError(aFeatureError);
585 if(aFillerAlgo->shape()->isNull()) {
586 static const std::string aShapeError = "Error: Resulting shape is Null.";
587 setError(aShapeError);
590 if(!aFillerAlgo->isValid()) {
591 std::string aFeatureError = "Error: Resulting shape is not valid.";
592 setError(aFeatureError);
596 std::shared_ptr<GeomAPI_Shape> aShape = aFillerAlgo->shape();
597 aMakeShapeList.appendAlgo(aFillerAlgo);
598 aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes());
600 std::shared_ptr<GeomAPI_Shape> aFrontShape = anOriginalShapes.front();
601 anOriginalShapes.pop_front();
602 std::shared_ptr<ModelAPI_ResultBody> aResultBody =
603 document()->createBody(data(), aResultIndex);
604 loadNamingDS(aResultBody, aFrontShape, anOriginalShapes,
605 aShape, aMakeShapeList, aMapOfShapes);
606 setResult(aResultBody, aResultIndex);
612 std::string anOperationError = "Error: Wrong type of operation";
613 setError(anOperationError);
617 // remove the rest results if there were produced in the previous pass
618 removeResults(aResultIndex);
621 //=================================================================================================
622 void FeaturesPlugin_Boolean::loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
623 const std::shared_ptr<GeomAPI_Shape> theBaseShape,
624 const ListOfShape& theTools,
625 const std::shared_ptr<GeomAPI_Shape> theResultShape,
626 GeomAlgoAPI_MakeShape& theMakeShape,
627 GeomAPI_DataMapOfShapeShape& theMapOfShapes)
630 if(theBaseShape->isEqual(theResultShape)) {
631 theResultBody->store(theResultShape);
633 const int aModifyTag = 1;
634 const int aDeletedTag = 2;
635 /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids
636 const int aSubsolidsTag = 3;
637 const int anEdgesAndFacesTag = 10000;
639 theResultBody->storeModified(theBaseShape, theResultShape, aSubsolidsTag);
641 const std::string aModName = "Modified";
642 const std::string aModEName = "Modified_Edge";
643 const std::string aModFName = "Modified_Face";
645 theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE,
646 aModifyTag, aModName, theMapOfShapes);
647 theResultBody->loadDeletedShapes(&theMakeShape, theBaseShape,
648 GeomAPI_Shape::FACE, aDeletedTag);
652 for(ListOfShape::const_iterator
653 anIter = theTools.begin(); anIter != theTools.end(); anIter++) {
654 if((*anIter)->shapeType() == GeomAPI_Shape::EDGE) {
655 aTag = anEdgesAndFacesTag;
658 else if((*anIter)->shapeType() == GeomAPI_Shape::FACE) {
659 aTag = anEdgesAndFacesTag;
665 theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter,
666 aName == aModEName ? GeomAPI_Shape::EDGE : GeomAPI_Shape::FACE,
667 aTag, aName, theMapOfShapes);
668 theResultBody->loadDeletedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE, aDeletedTag);