Salome HOME
Merge branch 'master' into cgt/devCEA
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Rotation.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        FeaturesPlugin_Rotation.cpp
4 // Created:     12 May 2015
5 // Author:      Dmitry Bobylev
6
7 #include <FeaturesPlugin_Rotation.h>
8
9 #include <ModelAPI_AttributeDouble.h>
10 #include <ModelAPI_AttributeSelectionList.h>
11 #include <ModelAPI_AttributeString.h>
12 #include <ModelAPI_ResultBody.h>
13 #include <ModelAPI_ResultPart.h>
14
15 #include <GeomAlgoAPI_PointBuilder.h>
16
17 #include <GeomAPI_Edge.h>
18 #include <GeomAPI_Lin.h>
19
20 #include <FeaturesPlugin_Tools.h>
21
22 //=================================================================================================
23 FeaturesPlugin_Rotation::FeaturesPlugin_Rotation()
24 {
25 }
26
27 //=================================================================================================
28 void FeaturesPlugin_Rotation::initAttributes()
29 {
30   data()->addAttribute(FeaturesPlugin_Rotation::CREATION_METHOD(),
31                        ModelAPI_AttributeString::typeId());
32
33   AttributeSelectionListPtr aSelection =
34     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
35     FeaturesPlugin_Rotation::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
36
37   data()->addAttribute(FeaturesPlugin_Rotation::AXIS_OBJECT_ID(),
38                        ModelAPI_AttributeSelection::typeId());
39   data()->addAttribute(FeaturesPlugin_Rotation::ANGLE_ID(), ModelAPI_AttributeDouble::typeId());
40
41   data()->addAttribute(FeaturesPlugin_Rotation::CENTER_POINT_ID(),
42                        ModelAPI_AttributeSelection::typeId());
43   data()->addAttribute(FeaturesPlugin_Rotation::START_POINT_ID(),
44                        ModelAPI_AttributeSelection::typeId());
45   data()->addAttribute(FeaturesPlugin_Rotation::END_POINT_ID(),
46                        ModelAPI_AttributeSelection::typeId());
47 }
48
49 //=================================================================================================
50 void FeaturesPlugin_Rotation::execute()
51 {
52   AttributeStringPtr aMethodTypeAttr = string(FeaturesPlugin_Rotation::CREATION_METHOD());
53   std::string aMethodType = aMethodTypeAttr->value();
54
55   if (aMethodType == CREATION_METHOD_BY_ANGLE()) {
56     performTranslationByAxisAndAngle();
57   }
58
59   if (aMethodType == CREATION_METHOD_BY_THREE_POINTS()) {
60     performTranslationByThreePoints();
61   }
62 }
63
64 //=================================================================================================
65 void FeaturesPlugin_Rotation::performTranslationByAxisAndAngle()
66 {
67   // Getting objects.
68   ListOfShape anObjects;
69   std::list<ResultPtr> aContextes;
70   AttributeSelectionListPtr anObjectsSelList =
71     selectionList(FeaturesPlugin_Rotation::OBJECTS_LIST_ID());
72   if (anObjectsSelList->size() == 0) {
73     return;
74   }
75   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
76     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
77       anObjectsSelList->value(anObjectsIndex);
78     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
79     if(!anObject.get()) {
80       return;
81     }
82     anObjects.push_back(anObject);
83     aContextes.push_back(anObjectAttr->context());
84   }
85
86   //Getting axis.
87   std::shared_ptr<GeomAPI_Ax1> anAxis;
88   std::shared_ptr<GeomAPI_Edge> anEdge;
89   std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
90     selection(FeaturesPlugin_Rotation::AXIS_OBJECT_ID());
91   if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
92     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
93   } else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
94              anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
95     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
96   }
97   if(anEdge) {
98     anAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(),
99                                                           anEdge->line()->direction()));
100   }
101
102   // Getting angle.
103   double anAngle = real(FeaturesPlugin_Rotation::ANGLE_ID())->value();
104
105   // Rotating each object.
106   int aResultIndex = 0;
107   std::list<ResultPtr>::iterator aContext = aContextes.begin();
108   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
109         anObjectsIt++, aContext++) {
110     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
111     bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
112
113     // Setting result.
114     if (isPart) {
115       std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
116       aTrsf->setRotation(anAxis, anAngle);
117       ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
118       ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
119       aResultPart->setTrsf(*aContext, aTrsf);
120       setResult(aResultPart, aResultIndex);
121     } else {
122       GeomAlgoAPI_Rotation aRotationAlgo(aBaseShape, anAxis, anAngle);
123
124       if (!aRotationAlgo.check()) {
125         setError(aRotationAlgo.getError());
126         return;
127       }
128
129       aRotationAlgo.build();
130
131       // Checking that the algorithm worked properly.
132       if(!aRotationAlgo.isDone()) {
133         static const std::string aFeatureError = "Error: Rotation algorithm failed.";
134         setError(aFeatureError);
135         break;
136       }
137       if(aRotationAlgo.shape()->isNull()) {
138         static const std::string aShapeError = "Error: Resulting shape is Null.";
139         setError(aShapeError);
140         break;
141       }
142       if(!aRotationAlgo.isValid()) {
143         std::string aFeatureError = "Error: Resulting shape is not valid.";
144         setError(aFeatureError);
145         break;
146       }
147
148       ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
149       loadNamingDS(aRotationAlgo, aResultBody, aBaseShape);
150       setResult(aResultBody, aResultIndex);
151     }
152     aResultIndex++;
153   }
154
155   // Remove the rest results if there were produced in the previous pass.
156   removeResults(aResultIndex);
157 }
158
159 //=================================================================================================
160 void FeaturesPlugin_Rotation::performTranslationByThreePoints()
161 {
162   // Getting objects.
163   ListOfShape anObjects;
164   std::list<ResultPtr> aContextes;
165   AttributeSelectionListPtr anObjectsSelList =
166     selectionList(FeaturesPlugin_Rotation::OBJECTS_LIST_ID());
167   if (anObjectsSelList->size() == 0) {
168     return;
169   }
170   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
171     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
172       anObjectsSelList->value(anObjectsIndex);
173     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
174     if(!anObject.get()) {
175       return;
176     }
177     anObjects.push_back(anObject);
178     aContextes.push_back(anObjectAttr->context());
179   }
180
181   // Getting the center point and two points (start and end)
182   std::shared_ptr<GeomAPI_Pnt> aCenterPoint;
183   std::shared_ptr<GeomAPI_Pnt> aStartPoint;
184   std::shared_ptr<GeomAPI_Pnt> anEndPoint;
185   std::shared_ptr<ModelAPI_AttributeSelection> aCenterRef =
186     selection(FeaturesPlugin_Rotation::CENTER_POINT_ID());
187   std::shared_ptr<ModelAPI_AttributeSelection> aStartPointRef =
188     selection(FeaturesPlugin_Rotation::START_POINT_ID());
189   std::shared_ptr<ModelAPI_AttributeSelection> anEndPointRef =
190     selection(FeaturesPlugin_Rotation::END_POINT_ID());
191   if ((aCenterRef.get() != NULL) && (aStartPointRef.get() != NULL)
192       && (anEndPointRef.get() != NULL)) {
193     GeomShapePtr aCenterShape = aCenterRef->value();
194     if (!aCenterShape.get())
195       aCenterShape = aCenterRef->context()->shape();
196     GeomShapePtr aStartShape = aStartPointRef->value();
197     if (!aStartShape.get())
198       aStartShape = aStartPointRef->context()->shape();
199       GeomShapePtr anEndShape = anEndPointRef->value();
200     if (!anEndShape.get())
201       anEndShape = anEndPointRef->context()->shape();
202     if (aStartShape && anEndShape && aCenterShape) {
203       aCenterPoint = GeomAlgoAPI_PointBuilder::point(aCenterShape);
204       aStartPoint = GeomAlgoAPI_PointBuilder::point(aStartShape);
205       anEndPoint = GeomAlgoAPI_PointBuilder::point(anEndShape);
206     }
207   }
208
209   // Rotating each object.
210   int aResultIndex = 0;
211   std::list<ResultPtr>::iterator aContext = aContextes.begin();
212   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
213         anObjectsIt++, aContext++) {
214     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
215     bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
216
217     // Setting result.
218     if (isPart) {
219        std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
220        aTrsf->setRotation(aCenterPoint, aStartPoint, anEndPoint);
221        ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
222        ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
223        aResultPart->setTrsf(*aContext, aTrsf);
224        setResult(aResultPart, aResultIndex);
225     } else {
226       GeomAlgoAPI_Rotation aRotationAlgo(aBaseShape, aCenterPoint, aStartPoint, anEndPoint);
227
228       if (!aRotationAlgo.check()) {
229         setError(aRotationAlgo.getError());
230         return;
231       }
232
233       aRotationAlgo.build();
234
235       // Checking that the algorithm worked properly.
236       if(!aRotationAlgo.isDone()) {
237         static const std::string aFeatureError = "Error: Rotation algorithm failed.";
238         setError(aFeatureError);
239         break;
240       }
241       if(aRotationAlgo.shape()->isNull()) {
242         static const std::string aShapeError = "Error : Resulting shape is Null.";
243         setError(aShapeError);
244         break;
245       }
246       if(!aRotationAlgo.isValid()) {
247         std::string aFeatureError = "Error: Resulting shape is not valid.";
248         setError(aFeatureError);
249         break;
250       }
251
252       ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
253       loadNamingDS(aRotationAlgo, aResultBody, aBaseShape);
254       setResult(aResultBody, aResultIndex);
255     }
256     aResultIndex++;
257   }
258 }
259
260 //=================================================================================================
261 void FeaturesPlugin_Rotation::loadNamingDS(GeomAlgoAPI_Rotation& theRotaionAlgo,
262                                            std::shared_ptr<ModelAPI_ResultBody> theResultBody,
263                                            std::shared_ptr<GeomAPI_Shape> theBaseShape)
264 {
265   // Store result.
266   theResultBody->storeModified(theBaseShape, theRotaionAlgo.shape());
267
268   std::string aRotatedName = "Rotated";
269   std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theRotaionAlgo.mapOfSubShapes();
270
271   FeaturesPlugin_Tools::storeModifiedShapes(theRotaionAlgo, theResultBody,
272                                             theBaseShape, 1, 2, 3, aRotatedName,
273                                             *aSubShapes.get());
274 }