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