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