Salome HOME
Issue #308: Do not select same object for boolean operation
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Extrusion.cpp
1 // File:        FeaturesPlugin_Extrusion.cpp
2 // Created:     30 May 2014
3 // Author:      Vitaly SMETANNIKOV
4
5 #include "FeaturesPlugin_Extrusion.h"
6 #include <ModelAPI_Session.h>
7 #include <ModelAPI_Document.h>
8 #include <ModelAPI_Data.h>
9 #include <ModelAPI_ResultConstruction.h>
10 #include <ModelAPI_ResultBody.h>
11 #include <ModelAPI_AttributeDouble.h>
12 #include <ModelAPI_AttributeSelection.h>
13 #include <ModelAPI_AttributeBoolean.h>
14 #include <GeomAlgoAPI_Extrusion.h>
15
16 using namespace std;
17 #define _LATERAL_TAG 1
18 #define _FIRST_TAG 2
19 #define _LAST_TAG 3
20 #define EDGE 6
21
22 FeaturesPlugin_Extrusion::FeaturesPlugin_Extrusion()
23 {
24 }
25
26 void FeaturesPlugin_Extrusion::initAttributes()
27 {
28   data()->addAttribute(FeaturesPlugin_Extrusion::FACE_ID(), ModelAPI_AttributeSelection::type());
29   data()->addAttribute(FeaturesPlugin_Extrusion::SIZE_ID(), ModelAPI_AttributeDouble::type());
30   data()->addAttribute(FeaturesPlugin_Extrusion::REVERSE_ID(), ModelAPI_AttributeBoolean::type());
31 }
32
33 void FeaturesPlugin_Extrusion::execute()
34 {
35   std::shared_ptr<ModelAPI_AttributeSelection> aFaceRef = std::dynamic_pointer_cast<
36     ModelAPI_AttributeSelection>(data()->attribute(FeaturesPlugin_Extrusion::FACE_ID()));
37   if (!aFaceRef)
38     return;
39
40   std::shared_ptr<GeomAPI_Shape> aFace = 
41     std::dynamic_pointer_cast<GeomAPI_Shape>(aFaceRef->value());
42   if (!aFace)
43     return;
44
45   std::shared_ptr<GeomAPI_Shape> aContext;
46   ResultPtr aContextRes = aFaceRef->context();
47   if (aContextRes) {
48     if (aContextRes->groupName() == ModelAPI_ResultBody::group())
49       aContext = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContextRes)->shape();
50     else if (aContextRes->groupName() == ModelAPI_ResultConstruction::group())
51       aContext = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContextRes)->shape();
52   }
53   if (!aContext) {
54     static const std::string aContextError = "The selection context is bad";
55     setError(aContextError);
56     return;
57   }
58
59   double aSize = data()->real(FeaturesPlugin_Extrusion::SIZE_ID())->value();
60   if (data()->boolean(FeaturesPlugin_Extrusion::REVERSE_ID())->value())
61     aSize = -aSize;
62
63   std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data());
64   GeomAlgoAPI_Extrusion aFeature(aFace, aSize);
65   if(!aFeature.isDone()) {
66     static const std::string aFeatureError = "Extrusion algorithm failed";  
67     setError(aFeatureError);
68     return;
69   }
70
71   // Check if shape is valid
72   if (aFeature.shape()->isNull()) {
73     static const std::string aShapeError = "Resulting shape is Null";     
74     setError(aShapeError);
75     return;
76   }
77   if(!aFeature.isValid()) {
78     std::string aFeatureError = "Warning: resulting shape is not valid";  
79     setError(aFeatureError);
80     return;
81   }  
82   //LoadNamingDS
83   LoadNamingDS(aFeature, aResultBody, aFace, aContext);
84
85   setResult(aResultBody);
86 }
87
88 //============================================================================
89 void FeaturesPlugin_Extrusion::LoadNamingDS(GeomAlgoAPI_Extrusion& theFeature, 
90   std::shared_ptr<ModelAPI_ResultBody> theResultBody, 
91   std::shared_ptr<GeomAPI_Shape> theBasis,
92   std::shared_ptr<GeomAPI_Shape> theContext)
93 {  
94
95
96   //load result
97   if(theBasis->isEqual(theContext))
98     theResultBody->store(theFeature.shape());
99   else
100     theResultBody->storeGenerated(theContext, theFeature.shape()); 
101
102   GeomAPI_DataMapOfShapeShape* aSubShapes = new GeomAPI_DataMapOfShapeShape();
103   theFeature.mapOfShapes(*aSubShapes);
104
105     //Insert lateral face : Face from Edge
106   theResultBody->loadAndOrientGeneratedShapes(theFeature.makeShape(), theBasis, EDGE,_LATERAL_TAG, *aSubShapes);
107
108   //Insert bottom face
109   std::shared_ptr<GeomAPI_Shape> aBottomFace = theFeature.firstShape();  
110   if (!aBottomFace->isNull()) {
111         if (aSubShapes->isBound(aBottomFace)) {  
112                 aBottomFace = aSubShapes->find(aBottomFace);            
113     }    
114     theResultBody->generated(aBottomFace, _FIRST_TAG);
115   }
116
117
118
119   //Insert top face
120   std::shared_ptr<GeomAPI_Shape> aTopFace = theFeature.lastShape();
121   if (!aTopFace->isNull()) {
122     if (aSubShapes->isBound(aTopFace)) {         
123       aTopFace = aSubShapes->find(aTopFace);    
124     }
125     theResultBody->generated(aTopFace, _LAST_TAG);
126   }
127
128   
129 }