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