Salome HOME
Merge branch 'Dev_1.2.0' of newgeom:newgeom.git into Dev_1.2.0
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Extrusion.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 // File:        FeaturesPlugin_Extrusion.cpp
4 // Created:     30 May 2014
5 // Author:      Vitaly SMETANNIKOV
6
7 #include "FeaturesPlugin_Extrusion.h"
8 #include <ModelAPI_Session.h>
9 #include <ModelAPI_Document.h>
10 #include <ModelAPI_Data.h>
11 #include <ModelAPI_ResultConstruction.h>
12 #include <ModelAPI_ResultBody.h>
13 #include <ModelAPI_AttributeDouble.h>
14 #include <ModelAPI_AttributeSelection.h>
15 #include <ModelAPI_AttributeSelectionList.h>
16 #include <ModelAPI_AttributeBoolean.h>
17 #include <ModelAPI_AttributeString.h>
18 #include <ModelAPI_AttributeReference.h>
19 #include <GeomAlgoAPI_Extrusion.h>
20
21 using namespace std;
22 #define _LATERAL_TAG 1
23 #define _FIRST_TAG 2
24 #define _LAST_TAG 3
25 #define EDGE 6
26
27 FeaturesPlugin_Extrusion::FeaturesPlugin_Extrusion()
28 {
29 }
30
31 void FeaturesPlugin_Extrusion::initAttributes()
32 {
33   AttributeSelectionListPtr aSelection = 
34     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
35     FeaturesPlugin_Extrusion::LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
36   // extrusion works with faces always
37   aSelection->setSelectionType("FACE");
38
39   data()->addAttribute(FeaturesPlugin_Extrusion::REVERSE_ID(), ModelAPI_AttributeBoolean::typeId());
40   data()->addAttribute(FeaturesPlugin_Extrusion::TO_SIZE_ID(), ModelAPI_AttributeDouble::typeId());
41   //data()->addAttribute(FeaturesPlugin_Extrusion::FROM_SIZE_ID(), ModelAPI_AttributeDouble::typeId());
42
43   //data()->addAttribute(FeaturesPlugin_Extrusion::AXIS_OBJECT_ID(), ModelAPI_AttributeReference::typeId());
44
45   //data()->addAttribute(FeaturesPlugin_Extrusion::FROM_OBJECT_ID(), ModelAPI_AttributeReference::typeId());
46   //data()->addAttribute(FeaturesPlugin_Extrusion::TO_OBJECT_ID(), ModelAPI_AttributeReference::typeId());
47 }
48
49 void FeaturesPlugin_Extrusion::execute()
50 {
51   AttributeSelectionListPtr aFaceRefs = selectionList(FeaturesPlugin_Extrusion::LIST_ID());
52
53   // for each selected face generate a result
54   int anIndex = 0, aResultIndex = 0;
55   for(; anIndex < aFaceRefs->size(); anIndex++) {
56     std::shared_ptr<ModelAPI_AttributeSelection> aFaceRef = aFaceRefs->value(anIndex);
57     ResultPtr aContextRes = aFaceRef->context();
58     std::shared_ptr<GeomAPI_Shape> aContext = aContextRes->shape();
59     if (!aContext.get()) {
60       static const std::string aContextError = "The selection context is bad";
61       setError(aContextError);
62       break;
63     }
64     double aSize = real(FeaturesPlugin_Extrusion::TO_SIZE_ID())->value();
65     if (boolean(FeaturesPlugin_Extrusion::REVERSE_ID())->value())
66       aSize = -aSize;
67
68     std::shared_ptr<GeomAPI_Shape> aValueFace = aFaceRef->value();
69     int aFacesNum = -1; // this mean that "aFace" is used
70     ResultConstructionPtr aConstruction =
71       std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContextRes);
72     if (!aValueFace.get()) { // this may be the whole sketch result selected, check and get faces
73       if (aConstruction.get()) {
74         aFacesNum = aConstruction->facesNum();
75       } else {
76         static const std::string aFaceError = "Can not find basis for extrusion";
77         setError(aFaceError);
78         break;
79       }
80     }
81
82     for(int aFaceIndex = 0; aFaceIndex < aFacesNum || aFacesNum == -1; aFaceIndex++) {
83       ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
84       std::shared_ptr<GeomAPI_Shape> aFace;
85       if (aFacesNum == -1) {
86         aFace = aValueFace;
87       } else {
88         aFace = std::dynamic_pointer_cast<GeomAPI_Shape>(aConstruction->face(aFaceIndex));
89       }
90       GeomAlgoAPI_Extrusion aFeature(aFace, aSize);
91       if(!aFeature.isDone()) {
92         static const std::string aFeatureError = "Extrusion algorithm failed";  
93         setError(aFeatureError);
94         break;
95       }
96
97       // Check if shape is valid
98       if (aFeature.shape()->isNull()) {
99         static const std::string aShapeError = "Resulting shape is Null";     
100         setError(aShapeError);
101         break;
102       }
103       if(!aFeature.isValid()) {
104         std::string aFeatureError = "Warning: resulting shape is not valid";  
105         setError(aFeatureError);
106         break;
107       }  
108       //LoadNamingDS
109       LoadNamingDS(aFeature, aResultBody, aFace, aContext);
110
111       setResult(aResultBody, aResultIndex);
112       aResultIndex++;
113
114       if (aFacesNum == -1)
115         break;
116     }
117   }
118   // remove the rest results if there were produced in the previous pass
119   removeResults(aResultIndex);
120 }
121
122 //============================================================================
123 void FeaturesPlugin_Extrusion::LoadNamingDS(GeomAlgoAPI_Extrusion& theFeature, 
124   std::shared_ptr<ModelAPI_ResultBody> theResultBody, 
125   std::shared_ptr<GeomAPI_Shape> theBasis,
126   std::shared_ptr<GeomAPI_Shape> theContext)
127 {  
128
129
130   //load result
131   if(theBasis->isEqual(theContext))
132     theResultBody->store(theFeature.shape());
133   else
134     theResultBody->storeGenerated(theContext, theFeature.shape()); 
135
136   GeomAPI_DataMapOfShapeShape* aSubShapes = new GeomAPI_DataMapOfShapeShape();
137   theFeature.mapOfShapes(*aSubShapes);
138
139   //Insert lateral face : Face from Edge
140   std::string aLatName = "LateralFace";
141   theResultBody->loadAndOrientGeneratedShapes(theFeature.makeShape(), theBasis, EDGE,_LATERAL_TAG, aLatName, *aSubShapes);
142
143   //Insert bottom face
144   std::string aBotName = "BottomFace";
145   std::shared_ptr<GeomAPI_Shape> aBottomFace = theFeature.firstShape();  
146   if (!aBottomFace->isNull()) {
147         if (aSubShapes->isBound(aBottomFace)) {  
148                 aBottomFace = aSubShapes->find(aBottomFace);            
149     }     
150     theResultBody->generated(aBottomFace, aBotName, _FIRST_TAG);
151   }
152
153
154
155   //Insert top face
156   std::string aTopName = "TopFace";
157   std::shared_ptr<GeomAPI_Shape> aTopFace = theFeature.lastShape();
158   if (!aTopFace->isNull()) {
159     if (aSubShapes->isBound(aTopFace)) {         
160       aTopFace = aSubShapes->find(aTopFace);    
161     }
162     theResultBody->generated(aTopFace, aTopName, _LAST_TAG);
163   }
164   
165 }
166
167 //============================================================================
168 void FeaturesPlugin_Extrusion::clearResult()
169 {
170   std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data());
171   std::shared_ptr<GeomAPI_Shape> anEmptyShape(new GeomAPI_Shape);
172   aResultBody->store(anEmptyShape);
173   setResult(aResultBody);
174 }