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 std::shared_ptr<GeomAPI_Shape> aContextShape = aResCompSolidPtr->shape();
106 std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
107 anIt = aCompSolidsObjects.begin();
108 for(; anIt != aCompSolidsObjects.end(); anIt++) {
109 if(anIt->first->isEqual(aContextShape)) {
110 aCompSolidsObjects[anIt->first].push_back(anObject);
114 if(anIt == aCompSolidsObjects.end()) {
115 aCompSolidsObjects[aContextShape].push_back(anObject);
118 if(anObject->shapeType() == GeomAPI_Shape::EDGE ||
119 anObject->shapeType() == GeomAPI_Shape::FACE) {
120 anEdgesAndFaces.push_back(anObject);
122 anObjects.push_back(anObject);
128 AttributeSelectionListPtr aToolsSelList = selectionList(FeaturesPlugin_Boolean::TOOL_LIST_ID());
129 for(int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) {
130 AttributeSelectionPtr aToolAttr = aToolsSelList->value(aToolsIndex);
131 std::shared_ptr<GeomAPI_Shape> aTool = aToolAttr->value();
135 if(aTool->shapeType() == GeomAPI_Shape::EDGE ||
136 aTool->shapeType() == GeomAPI_Shape::FACE) {
137 anEdgesAndFaces.push_back(aTool);
139 aTools.push_back(aTool);
143 int aResultIndex = 0;
149 if((anObjects.empty() && aCompSolidsObjects.empty()) || aTools.empty()) {
150 std::string aFeatureError = "Error: Not enough objects for boolean operation.";
151 setError(aFeatureError);
155 // For solids cut each object with all tools.
156 for(ListOfShape::iterator
157 anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) {
158 std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
159 ListOfShape aListWithObject;
160 aListWithObject.push_back(anObject);
161 GeomAlgoAPI_MakeShape aBoolAlgo;
162 GeomShapePtr aResShape;
167 GeomAlgoAPI_Boolean(aListWithObject, aTools, GeomAlgoAPI_Boolean::BOOL_CUT);
168 aResShape = aBoolAlgo.shape();
173 GeomAlgoAPI_Boolean(aListWithObject, aTools, GeomAlgoAPI_Boolean::BOOL_COMMON);
174 aResShape = aBoolAlgo.shape();
178 aBoolAlgo = GeomAlgoAPI_Partition(aListWithObject, aTools);
179 aResShape = aBoolAlgo.shape();
180 if(aResShape->shapeType() == GeomAPI_Shape::COMPOUND) {
181 int aSubResultsNb = 0;
182 GeomAPI_ShapeIterator anIt(aResShape);
183 for(; anIt.more(); anIt.next()) {
186 if(aSubResultsNb == 1) {
187 anIt.init(aResShape);
189 aResShape = anIt.current();
197 // Checking that the algorithm worked properly.
198 if(!aBoolAlgo.isDone()) {
199 static const std::string aFeatureError = "Error: Boolean algorithm failed.";
200 setError(aFeatureError);
203 if(aResShape->isNull()) {
204 static const std::string aShapeError = "Error: Resulting shape is Null.";
205 setError(aShapeError);
208 if(!aBoolAlgo.isValid()) {
209 std::string aFeatureError = "Error: Resulting shape is not valid.";
210 setError(aFeatureError);
214 if(GeomAlgoAPI_ShapeTools::volume(aResShape) > 1.e-27) {
215 std::shared_ptr<ModelAPI_ResultBody> aResultBody =
216 document()->createBody(data(), aResultIndex);
217 loadNamingDS(aResultBody, anObject, aTools, aResShape,
218 aBoolAlgo, *aBoolAlgo.mapOfSubShapes().get());
219 setResult(aResultBody, aResultIndex);
224 // Compsolids handling
225 for(std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
226 anIt = aCompSolidsObjects.begin();
227 anIt != aCompSolidsObjects.end(); anIt++) {
228 std::shared_ptr<GeomAPI_Shape> aCompSolid = anIt->first;
229 ListOfShape& aUsedInOperationSolids = anIt->second;
231 // Collecting solids from compsolids which will not be modified in boolean operation.
232 ListOfShape aNotUsedSolids;
233 for(GeomAPI_ShapeExplorer
234 anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
235 std::shared_ptr<GeomAPI_Shape> aSolidInCompSolid = anExp.current();
236 ListOfShape::iterator anIt = aUsedInOperationSolids.begin();
237 for(; anIt != aUsedInOperationSolids.end(); anIt++) {
238 if(aSolidInCompSolid->isEqual(*anIt)) {
242 if(anIt == aUsedInOperationSolids.end()) {
243 aNotUsedSolids.push_back(aSolidInCompSolid);
247 std::shared_ptr<GeomAlgoAPI_MakeShape> aBoolAlgo;
251 aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aUsedInOperationSolids,
253 GeomAlgoAPI_Boolean::BOOL_CUT));
257 aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aUsedInOperationSolids,
259 GeomAlgoAPI_Boolean::BOOL_COMMON));
263 aBoolAlgo.reset(new GeomAlgoAPI_Partition(aUsedInOperationSolids, aTools));
268 // Checking that the algorithm worked properly.
269 if(!aBoolAlgo->isDone()) {
270 static const std::string aFeatureError = "Error: Boolean algorithm failed.";
271 setError(aFeatureError);
274 if(aBoolAlgo->shape()->isNull()) {
275 static const std::string aShapeError = "Error: Resulting shape is Null.";
276 setError(aShapeError);
279 if(!aBoolAlgo->isValid()) {
280 std::string aFeatureError = "Error: Resulting shape is not valid.";
281 setError(aFeatureError);
285 GeomAlgoAPI_MakeShapeList aMakeShapeList;
286 aMakeShapeList.appendAlgo(aBoolAlgo);
287 GeomAPI_DataMapOfShapeShape aMapOfShapes;
288 aMapOfShapes.merge(aBoolAlgo->mapOfSubShapes());
289 GeomShapePtr aResultShape = aBoolAlgo->shape();
291 // Add result to not used solids from compsolid.
292 if(!aNotUsedSolids.empty()) {
293 ListOfShape aShapesToAdd = aNotUsedSolids;
294 aShapesToAdd.push_back(aBoolAlgo->shape());
295 std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(
296 new GeomAlgoAPI_PaveFiller(aShapesToAdd, true));
297 if(!aFillerAlgo->isDone()) {
298 std::string aFeatureError = "Error: PaveFiller algorithm failed.";
299 setError(aFeatureError);
303 aMakeShapeList.appendAlgo(aFillerAlgo);
304 aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes());
305 aResultShape = aFillerAlgo->shape();
308 if(GeomAlgoAPI_ShapeTools::volume(aResultShape) > 1.e-27) {
309 std::shared_ptr<ModelAPI_ResultBody> aResultBody =
310 document()->createBody(data(), aResultIndex);
311 loadNamingDS(aResultBody, aCompSolid, aTools, aResultShape, aMakeShapeList, aMapOfShapes);
312 setResult(aResultBody, aResultIndex);
319 if((anObjects.size() + aTools.size() +
320 aCompSolidsObjects.size() + anEdgesAndFaces.size()) < 2) {
321 std::string aFeatureError = "Error: Not enough objects for boolean operation.";
322 setError(aFeatureError);
326 // Collecting all solids which will be fused.
327 ListOfShape aSolidsToFuse;
328 aSolidsToFuse.insert(aSolidsToFuse.end(), anObjects.begin(), anObjects.end());
329 aSolidsToFuse.insert(aSolidsToFuse.end(), aTools.begin(), aTools.end());
331 // Collecting solids from compsolids which will not be modified
332 // in boolean operation and will be added to result.
333 ListOfShape aShapesToAdd;
334 for(std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
335 anIt = aCompSolidsObjects.begin();
336 anIt != aCompSolidsObjects.end(); anIt++) {
337 std::shared_ptr<GeomAPI_Shape> aCompSolid = anIt->first;
338 ListOfShape& aUsedInOperationSolids = anIt->second;
339 aSolidsToFuse.insert(aSolidsToFuse.end(), aUsedInOperationSolids.begin(),
340 aUsedInOperationSolids.end());
342 // Collect solids from compsolid which will not be modified in boolean operation.
343 for(GeomAPI_ShapeExplorer
344 anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
345 std::shared_ptr<GeomAPI_Shape> aSolidInCompSolid = anExp.current();
346 ListOfShape::iterator anIt = aUsedInOperationSolids.begin();
347 for(; anIt != aUsedInOperationSolids.end(); anIt++) {
348 if(aSolidInCompSolid->isEqual(*anIt)) {
352 if(anIt == aUsedInOperationSolids.end()) {
353 aShapesToAdd.push_back(aSolidInCompSolid);
358 ListOfShape anOriginalShapes = aSolidsToFuse;
359 anOriginalShapes.insert(anOriginalShapes.end(), aShapesToAdd.begin(), aShapesToAdd.end());
361 // Cut edges and faces(if we have any) with solids.
362 GeomAlgoAPI_MakeShapeList aMakeShapeList;
363 GeomAPI_DataMapOfShapeShape aMapOfShapes;
364 std::shared_ptr<GeomAPI_Shape> aCuttedEdgesAndFaces;
365 if(!anEdgesAndFaces.empty()) {
366 std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(new GeomAlgoAPI_Boolean(anEdgesAndFaces,
367 anOriginalShapes, GeomAlgoAPI_Boolean::BOOL_CUT));
368 if(aCutAlgo->isDone()) {
369 aCuttedEdgesAndFaces = aCutAlgo->shape();
370 aMakeShapeList.appendAlgo(aCutAlgo);
371 aMapOfShapes.merge(aCutAlgo->mapOfSubShapes());
374 anOriginalShapes.insert(anOriginalShapes.end(), anEdgesAndFaces.begin(),
375 anEdgesAndFaces.end());
377 // If we have compsolids then cut with not used solids all others.
378 if(!aShapesToAdd.empty()) {
379 aSolidsToFuse.clear();
380 for(ListOfShape::iterator
381 anIt = anOriginalShapes.begin(); anIt != anOriginalShapes.end(); anIt++) {
382 ListOfShape aOneObjectList;
383 aOneObjectList.push_back(*anIt);
384 std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(
385 new GeomAlgoAPI_Boolean(aOneObjectList, aShapesToAdd, GeomAlgoAPI_Boolean::BOOL_CUT));
387 if(GeomAlgoAPI_ShapeTools::volume(aCutAlgo->shape()) > 1.e-27) {
388 aSolidsToFuse.push_back(aCutAlgo->shape());
389 aMakeShapeList.appendAlgo(aCutAlgo);
390 aMapOfShapes.merge(aCutAlgo->mapOfSubShapes());
395 if(!aSolidsToFuse.empty()) {
397 anObjects.push_back(aSolidsToFuse.back());
398 aSolidsToFuse.pop_back();
399 aTools = aSolidsToFuse;
402 // Fuse all objects and all tools.
403 std::shared_ptr<GeomAPI_Shape> aShape;
404 if(anObjects.size() == 1 && aTools.empty()) {
405 aShape = anObjects.front();
406 } else if(anObjects.empty() && aTools.size() == 1) {
407 aShape = aTools.front();
408 } else if((anObjects.size() + aTools.size()) > 1){
409 std::shared_ptr<GeomAlgoAPI_Boolean> aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects,
411 GeomAlgoAPI_Boolean::BOOL_FUSE));
413 // Checking that the algorithm worked properly.
414 if(!aFuseAlgo->isDone()) {
415 static const std::string aFeatureError = "Error: Boolean algorithm failed.";
416 setError(aFeatureError);
419 if(aFuseAlgo->shape()->isNull()) {
420 static const std::string aShapeError = "Error: Resulting shape is Null.";
421 setError(aShapeError);
424 if(!aFuseAlgo->isValid()) {
425 std::string aFeatureError = "Error: Resulting shape is not valid.";
426 setError(aFeatureError);
430 aShape = aFuseAlgo->shape();
431 aMakeShapeList.appendAlgo(aFuseAlgo);
432 aMapOfShapes.merge(aFuseAlgo->mapOfSubShapes());
435 // Combine result with not used solids from compsolid and edges and faces (if we have any).
436 if(aCuttedEdgesAndFaces.get() && !aCuttedEdgesAndFaces->isNull()) {
437 aShapesToAdd.push_back(aCuttedEdgesAndFaces);
439 aShapesToAdd.insert(aShapesToAdd.end(), anEdgesAndFaces.begin(), anEdgesAndFaces.end());
441 if(!aShapesToAdd.empty()) {
443 aShapesToAdd.push_back(aShape);
445 std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(
446 new GeomAlgoAPI_PaveFiller(aShapesToAdd, true));
447 if(!aFillerAlgo->isDone()) {
448 std::string aFeatureError = "Error: PaveFiller algorithm failed.";
449 setError(aFeatureError);
452 if(aFillerAlgo->shape()->isNull()) {
453 static const std::string aShapeError = "Error: Resulting shape is Null.";
454 setError(aShapeError);
457 if(!aFillerAlgo->isValid()) {
458 std::string aFeatureError = "Error: Resulting shape is not valid.";
459 setError(aFeatureError);
463 aShape = aFillerAlgo->shape();
464 aMakeShapeList.appendAlgo(aFillerAlgo);
465 aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes());
468 std::shared_ptr<GeomAPI_Shape> aBackShape = anOriginalShapes.back();
469 anOriginalShapes.pop_back();
470 std::shared_ptr<ModelAPI_ResultBody> aResultBody =
471 document()->createBody(data(), aResultIndex);
472 loadNamingDS(aResultBody, aBackShape, anOriginalShapes,
473 aShape, aMakeShapeList, aMapOfShapes);
474 setResult(aResultBody, aResultIndex);
479 if((anObjects.empty() && aCompSolidsObjects.empty()) || aTools.empty()) {
480 std::string aFeatureError = "Error: Not enough objects for boolean operation.";
481 setError(aFeatureError);
485 // List of original solids for naming.
486 ListOfShape anOriginalShapes;
487 anOriginalShapes.insert(anOriginalShapes.end(), anObjects.begin(), anObjects.end());
488 anOriginalShapes.insert(anOriginalShapes.end(), aTools.begin(), aTools.end());
490 // Collecting all solids which will be smashed.
491 ListOfShape aShapesToSmash;
492 aShapesToSmash.insert(aShapesToSmash.end(), anObjects.begin(), anObjects.end());
494 // Collecting solids from compsolids which will not be modified in
495 // boolean operation and will be added to result.
496 ListOfShape aShapesToAdd;
497 for(std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
498 anIt = aCompSolidsObjects.begin();
499 anIt != aCompSolidsObjects.end(); anIt++) {
500 std::shared_ptr<GeomAPI_Shape> aCompSolid = anIt->first;
501 ListOfShape& aUsedInOperationSolids = anIt->second;
502 anOriginalShapes.push_back(aCompSolid);
503 aShapesToSmash.insert(aShapesToSmash.end(), aUsedInOperationSolids.begin(),
504 aUsedInOperationSolids.end());
506 // Collect solids from compsolid which will not be modified in boolean operation.
507 for(GeomAPI_ShapeExplorer
508 anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
509 std::shared_ptr<GeomAPI_Shape> aSolidInCompSolid = anExp.current();
510 ListOfShape::iterator anIt = aUsedInOperationSolids.begin();
511 for(; anIt != aUsedInOperationSolids.end(); anIt++) {
512 if(aSolidInCompSolid->isEqual(*anIt)) {
516 if(anIt == aUsedInOperationSolids.end()) {
517 aShapesToAdd.push_back(aSolidInCompSolid);
522 GeomAlgoAPI_MakeShapeList aMakeShapeList;
523 GeomAPI_DataMapOfShapeShape aMapOfShapes;
524 if(!aShapesToAdd.empty()) {
525 // Cut objects with not used solids.
526 std::shared_ptr<GeomAlgoAPI_Boolean> anObjectsCutAlgo(new GeomAlgoAPI_Boolean(
529 GeomAlgoAPI_Boolean::BOOL_CUT));
531 if(GeomAlgoAPI_ShapeTools::volume(anObjectsCutAlgo->shape()) > 1.e-27) {
532 aShapesToSmash.clear();
533 aShapesToSmash.push_back(anObjectsCutAlgo->shape());
534 aMakeShapeList.appendAlgo(anObjectsCutAlgo);
535 aMapOfShapes.merge(anObjectsCutAlgo->mapOfSubShapes());
538 // Cut tools with not used solids.
539 std::shared_ptr<GeomAlgoAPI_Boolean> aToolsCutAlgo(new GeomAlgoAPI_Boolean(aTools,
541 GeomAlgoAPI_Boolean::BOOL_CUT));
543 if(GeomAlgoAPI_ShapeTools::volume(aToolsCutAlgo->shape()) > 1.e-27) {
545 aTools.push_back(aToolsCutAlgo->shape());
546 aMakeShapeList.appendAlgo(aToolsCutAlgo);
547 aMapOfShapes.merge(aToolsCutAlgo->mapOfSubShapes());
551 // Cut objects with tools.
552 std::shared_ptr<GeomAlgoAPI_Boolean> aBoolAlgo(new GeomAlgoAPI_Boolean(aShapesToSmash,
554 GeomAlgoAPI_Boolean::BOOL_CUT));
556 // Checking that the algorithm worked properly.
557 if(!aBoolAlgo->isDone()) {
558 static const std::string aFeatureError = "Error: Boolean algorithm failed.";
559 setError(aFeatureError);
562 if(aBoolAlgo->shape()->isNull()) {
563 static const std::string aShapeError = "Error: Resulting shape is Null.";
564 setError(aShapeError);
567 if(!aBoolAlgo->isValid()) {
568 std::string aFeatureError = "Error: Resulting shape is not valid.";
569 setError(aFeatureError);
572 aMakeShapeList.appendAlgo(aBoolAlgo);
573 aMapOfShapes.merge(aBoolAlgo->mapOfSubShapes());
575 // Put all (cut result, tools and not used solids) to PaveFiller.
576 aShapesToAdd.push_back(aBoolAlgo->shape());
577 aShapesToAdd.insert(aShapesToAdd.end(), aTools.begin(), aTools.end());
579 std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(new GeomAlgoAPI_PaveFiller(aShapesToAdd,
581 if(!aFillerAlgo->isDone()) {
582 std::string aFeatureError = "Error: PaveFiller algorithm failed.";
583 setError(aFeatureError);
586 if(aFillerAlgo->shape()->isNull()) {
587 static const std::string aShapeError = "Error: Resulting shape is Null.";
588 setError(aShapeError);
591 if(!aFillerAlgo->isValid()) {
592 std::string aFeatureError = "Error: Resulting shape is not valid.";
593 setError(aFeatureError);
597 std::shared_ptr<GeomAPI_Shape> aShape = aFillerAlgo->shape();
598 aMakeShapeList.appendAlgo(aFillerAlgo);
599 aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes());
601 std::shared_ptr<GeomAPI_Shape> aFrontShape = anOriginalShapes.front();
602 anOriginalShapes.pop_front();
603 std::shared_ptr<ModelAPI_ResultBody> aResultBody =
604 document()->createBody(data(), aResultIndex);
605 loadNamingDS(aResultBody, aFrontShape, anOriginalShapes,
606 aShape, aMakeShapeList, aMapOfShapes);
607 setResult(aResultBody, aResultIndex);
613 std::string anOperationError = "Error: Wrong type of operation";
614 setError(anOperationError);
618 // remove the rest results if there were produced in the previous pass
619 removeResults(aResultIndex);
622 //=================================================================================================
623 void FeaturesPlugin_Boolean::loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
624 const std::shared_ptr<GeomAPI_Shape> theBaseShape,
625 const ListOfShape& theTools,
626 const std::shared_ptr<GeomAPI_Shape> theResultShape,
627 GeomAlgoAPI_MakeShape& theMakeShape,
628 GeomAPI_DataMapOfShapeShape& theMapOfShapes)
631 if(theBaseShape->isEqual(theResultShape)) {
632 theResultBody->store(theResultShape);
634 const int aModifyTag = 1;
635 const int aDeletedTag = 2;
636 /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids
637 const int aSubsolidsTag = 3;
638 const int anEdgesAndFacesTag = 10000;
640 theResultBody->storeModified(theBaseShape, theResultShape, aSubsolidsTag);
642 const std::string aModName = "Modified";
643 const std::string aModEName = "Modified_Edge";
644 const std::string aModFName = "Modified_Face";
646 theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE,
647 aModifyTag, aModName, theMapOfShapes);
648 theResultBody->loadDeletedShapes(&theMakeShape, theBaseShape,
649 GeomAPI_Shape::FACE, aDeletedTag);
653 for(ListOfShape::const_iterator
654 anIter = theTools.begin(); anIter != theTools.end(); anIter++) {
655 if((*anIter)->shapeType() == GeomAPI_Shape::EDGE) {
656 aTag = anEdgesAndFacesTag;
659 else if((*anIter)->shapeType() == GeomAPI_Shape::FACE) {
660 aTag = anEdgesAndFacesTag;
666 theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter,
667 aName == aModEName ? GeomAPI_Shape::EDGE : GeomAPI_Shape::FACE,
668 aTag, aName, theMapOfShapes);
669 theResultBody->loadDeletedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE, aDeletedTag);