Salome HOME
2bf1f1ff07df017a9894b5ac2ebb73a5bd5a3cfc
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Boolean.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 // File:        FeaturesPlugin_Boolean.cpp
4 // Created:     02 Sept 2014
5 // Author:      Vitaly SMETANNIKOV
6
7 #include "FeaturesPlugin_Boolean.h"
8
9 #include <ModelAPI_Data.h>
10 #include <ModelAPI_Document.h>
11 #include <ModelAPI_AttributeReference.h>
12 #include <ModelAPI_AttributeInteger.h>
13 #include <ModelAPI_ResultBody.h>
14 #include <ModelAPI_AttributeSelectionList.h>
15 #include <GeomAlgoAPI_Boolean.h>
16 using namespace std;
17
18 // to use multi-selection, please comment the next define and uncomment multi_selector in boolean_widget.xml
19 #define DEBUG_ONE_OBJECT
20
21 #define FACE 4
22 #define _MODIFY_TAG 1
23 #define _DELETED_TAG 2
24 FeaturesPlugin_Boolean::FeaturesPlugin_Boolean()
25 {
26 }
27
28 void FeaturesPlugin_Boolean::initAttributes()
29 {
30   data()->addAttribute(FeaturesPlugin_Boolean::TYPE_ID(), ModelAPI_AttributeInteger::typeId());
31
32 #ifdef DEBUG_ONE_OBJECT
33   data()->addAttribute(FeaturesPlugin_Boolean::OBJECT_ID(), ModelAPI_AttributeReference::typeId());
34 #else
35   AttributeSelectionListPtr aSelection = 
36     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
37     FeaturesPlugin_Boolean::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
38   // extrusion works with faces always
39   aSelection->setSelectionType("SOLID");
40 #endif
41
42 #ifdef DEBUG_ONE_OBJECT
43   data()->addAttribute(FeaturesPlugin_Boolean::TOOL_ID(), ModelAPI_AttributeReference::typeId());
44 #else
45   aSelection = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
46     FeaturesPlugin_Boolean::TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
47   // extrusion works with faces always
48   aSelection->setSelectionType("SOLID");
49 #endif
50 }
51
52 std::shared_ptr<GeomAPI_Shape> FeaturesPlugin_Boolean::getShape(const std::string& theAttrName)
53 {
54   std::shared_ptr<ModelAPI_AttributeReference> aObjRef = std::dynamic_pointer_cast<
55       ModelAPI_AttributeReference>(data()->attribute(theAttrName));
56   if (aObjRef) {
57     std::shared_ptr<ModelAPI_ResultBody> aConstr = std::dynamic_pointer_cast<
58         ModelAPI_ResultBody>(aObjRef->value());
59     if (aConstr)
60       return aConstr->shape();
61   }
62   return std::shared_ptr<GeomAPI_Shape>();
63 }
64
65
66 void FeaturesPlugin_Boolean::execute()
67 {
68   std::shared_ptr<ModelAPI_AttributeInteger> aTypeAttr = std::dynamic_pointer_cast<
69       ModelAPI_AttributeInteger>(data()->attribute(FeaturesPlugin_Boolean::TYPE_ID()));
70   if (!aTypeAttr)
71     return;
72   int aType = aTypeAttr->value();
73 #ifdef DEBUG_ONE_OBJECT
74   std::shared_ptr<GeomAPI_Shape> anObject = this->getShape(FeaturesPlugin_Boolean::OBJECT_ID());
75 #else
76   std::shared_ptr<GeomAPI_Shape> anObject;
77   {
78     AttributeSelectionListPtr anObjects = selectionList(FeaturesPlugin_Boolean::OBJECT_LIST_ID());
79     if (anObjects->size() == 0)
80       return;
81
82     // Getting bounding planes.
83     std::shared_ptr<ModelAPI_AttributeSelection> anObjRef = anObjects->value(0);
84     if (!anObjRef.get())
85       return;
86     anObject = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
87   }
88 #endif
89   if (!anObject)
90     return;
91
92 #ifdef DEBUG_ONE_OBJECT
93   std::shared_ptr<GeomAPI_Shape> aTool = this->getShape(FeaturesPlugin_Boolean::TOOL_ID());
94 #else
95   std::shared_ptr<GeomAPI_Shape> aTool;
96   {
97     AttributeSelectionListPtr anObjects = selectionList(FeaturesPlugin_Boolean::TOOL_LIST_ID());
98     if (anObjects->size() == 0)
99       return;
100
101     // Getting bounding planes.
102     std::shared_ptr<ModelAPI_AttributeSelection> anObjRef = anObjects->value(0);
103     if (!anObjRef.get())
104       return;
105     aTool = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
106   }
107 #endif
108   if (!aTool)
109     return;
110
111   std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data());
112
113   GeomAlgoAPI_Boolean* aFeature = new GeomAlgoAPI_Boolean(anObject, aTool, aType);
114   if(aFeature && !aFeature->isDone()) {
115     static const std::string aFeatureError = "Boolean feature: algorithm failed";  
116     setError(aFeatureError);
117     return;
118   }
119    // Check if shape is valid
120   if (aFeature->shape()->isNull()) {
121     static const std::string aShapeError = "Boolean feature: resulting shape is Null";     
122     setError(aShapeError);
123     return;
124   }
125   if(!aFeature->isValid()) {
126     static const std::string aFeatureError = "Boolean feature: resulting shape is not valid";  
127     setError(aFeatureError);
128     return;
129   }  
130   // if result of Boolean operation is same as was before it means that Boolean operation has no sence
131   // and naming provides no result, so, generate an error in this case
132   if (anObject->isEqual(aFeature->shape())) {
133     static const std::string aFeatureError = "Boolean feature: operation was not performed";  
134     setError(aFeatureError);
135     return;
136   }
137   //LoadNamingDS
138   LoadNamingDS(aFeature, aResultBody, anObject, aTool, aType);
139
140   setResult(aResultBody);
141 }
142
143 //============================================================================
144 void FeaturesPlugin_Boolean::LoadNamingDS(GeomAlgoAPI_Boolean* theFeature, 
145                                                 std::shared_ptr<ModelAPI_ResultBody> theResultBody, 
146                                                 std::shared_ptr<GeomAPI_Shape> theObject,
147                                                 std::shared_ptr<GeomAPI_Shape> theTool,
148                                                 int theType)
149 {  
150
151   //load result
152   theResultBody->storeModified(theObject, theFeature->shape()); 
153
154   GeomAPI_DataMapOfShapeShape* aSubShapes = new GeomAPI_DataMapOfShapeShape();
155   theFeature->mapOfShapes(*aSubShapes);
156
157   // Put in DF modified faces
158   std::string aModName = "Modified";
159   theResultBody->loadAndOrientModifiedShapes(theFeature->makeShape(), theObject, FACE, _MODIFY_TAG, aModName, *aSubShapes);
160   theResultBody->loadAndOrientModifiedShapes(theFeature->makeShape(), theTool,   FACE, _MODIFY_TAG, aModName, *aSubShapes);
161
162   //Put in DF deleted faces
163   theResultBody->loadDeletedShapes(theFeature->makeShape(), theObject, FACE, _DELETED_TAG);
164   theResultBody->loadDeletedShapes(theFeature->makeShape(), theTool,   FACE, _DELETED_TAG);  
165 }