Salome HOME
Meet the coding style (line length <= 100)
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Scale.cpp
1 // Copyright (C) 2014-201x CEA/DEN, EDF R&D
2
3 // File:        FeaturesPlugin_Scale.cpp
4 // Created:     13 Jan 2017
5 // Author:      Clarisse Genrault (CEA)
6
7 #include <FeaturesPlugin_Scale.h>
8
9 #include <GeomAlgoAPI_PointBuilder.h>
10
11 #include <ModelAPI_AttributeDouble.h>
12 #include <ModelAPI_AttributeSelectionList.h>
13 #include <ModelAPI_AttributeString.h>
14 #include <ModelAPI_ResultBody.h>
15 #include <ModelAPI_ResultPart.h>
16
17 #include <iostream>
18
19 //=================================================================================================
20 FeaturesPlugin_Scale::FeaturesPlugin_Scale()
21 {
22 }
23
24 //=================================================================================================
25 void FeaturesPlugin_Scale::initAttributes()
26 {
27   data()->addAttribute(FeaturesPlugin_Scale::CREATION_METHOD(),
28                        ModelAPI_AttributeString::typeId());
29
30   AttributeSelectionListPtr aSelection =
31     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
32     FeaturesPlugin_Scale::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
33
34   data()->addAttribute(FeaturesPlugin_Scale::CENTER_POINT_ID(),
35                        ModelAPI_AttributeSelection::typeId());
36
37   data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_ID(),
38                        ModelAPI_AttributeDouble::typeId());
39
40   data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_X_ID(),
41                        ModelAPI_AttributeDouble::typeId());
42   data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_Y_ID(),
43                        ModelAPI_AttributeDouble::typeId());
44   data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_Z_ID(),
45                        ModelAPI_AttributeDouble::typeId());
46 }
47
48 //=================================================================================================
49 void FeaturesPlugin_Scale::execute()
50 {
51   AttributeStringPtr aMethodTypeAttr = string(FeaturesPlugin_Scale::CREATION_METHOD());
52   std::string aMethodType = aMethodTypeAttr->value();
53
54   if (aMethodType == FeaturesPlugin_Scale::CREATION_METHOD_BY_FACTOR()) {
55     performScaleByFactor();
56   }
57
58   if (aMethodType == FeaturesPlugin_Scale::CREATION_METHOD_BY_DIMENSIONS()) {
59     performScaleByDimensions();
60   }
61 }
62
63 //=================================================================================================
64 void FeaturesPlugin_Scale::performScaleByFactor()
65 {
66   // Getting objects.
67   ListOfShape anObjects;
68   std::list<ResultPtr> aContextes;
69   AttributeSelectionListPtr anObjectsSelList =
70     selectionList(FeaturesPlugin_Scale::OBJECTS_LIST_ID());
71   if (anObjectsSelList->size() == 0) {
72     return;
73   }
74   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
75     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
76       anObjectsSelList->value(anObjectsIndex);
77     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
78     if(!anObject.get()) { // may be for not-activated parts
79       eraseResults();
80       return;
81     }
82     anObjects.push_back(anObject);
83     aContextes.push_back(anObjectAttr->context());
84   }
85
86   // Getting the center point
87   std::shared_ptr<GeomAPI_Pnt> aCenterPoint;
88   std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
89     selection(FeaturesPlugin_Scale::CENTER_POINT_ID());
90   if (anObjRef.get() != NULL) {
91     GeomShapePtr aShape = anObjRef->value();
92     if (!aShape.get()) {
93       aShape = anObjRef->context()->shape();
94     }
95     if (aShape) {
96       aCenterPoint = GeomAlgoAPI_PointBuilder::point(aShape);
97     }
98   }
99
100   // Getting scale factor
101   double aScaleFactor = real(FeaturesPlugin_Scale::SCALE_FACTOR_ID())->value();
102
103   // Moving each object.
104   int aResultIndex = 0;
105   std::list<ResultPtr>::iterator aContext = aContextes.begin();
106   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
107         anObjectsIt++, aContext++) {
108     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
109     GeomAlgoAPI_Scale aScaleAlgo(aBaseShape, aCenterPoint, aScaleFactor);
110
111     if (!aScaleAlgo.check()) {
112       setError(aScaleAlgo.getError());
113       return;
114     }
115
116     aScaleAlgo.build();
117
118     // Checking that the algorithm worked properly.
119     if(!aScaleAlgo.isDone()) {
120       static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
121       setError(aFeatureError);
122       break;
123     }
124     if(aScaleAlgo.shape()->isNull()) {
125       static const std::string aShapeError = "Error: Resulting shape is Null.";
126       setError(aShapeError);
127       break;
128     }
129     if(!aScaleAlgo.isValid()) {
130       std::string aFeatureError = "Error: Resulting shape is not valid.";
131       setError(aFeatureError);
132       break;
133     }
134
135     ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
136     loadNamingDS(aScaleAlgo, aResultBody, aBaseShape);
137     setResult(aResultBody, aResultIndex);
138     aResultIndex++;
139   }
140
141   // Remove the rest results if there were produced in the previous pass.
142   removeResults(aResultIndex);
143 }
144
145 //=================================================================================================
146 void FeaturesPlugin_Scale::performScaleByDimensions()
147 {
148   // Getting objects.
149   ListOfShape anObjects;
150   std::list<ResultPtr> aContextes;
151   AttributeSelectionListPtr anObjectsSelList =
152     selectionList(FeaturesPlugin_Scale::OBJECTS_LIST_ID());
153   if (anObjectsSelList->size() == 0) {
154     return;
155   }
156   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
157     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
158       anObjectsSelList->value(anObjectsIndex);
159     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
160     if(!anObject.get()) { // may be for not-activated parts
161       eraseResults();
162       return;
163     }
164     anObjects.push_back(anObject);
165     aContextes.push_back(anObjectAttr->context());
166   }
167
168   // Getting the center point
169   std::shared_ptr<GeomAPI_Pnt> aCenterPoint;
170   std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
171     selection(FeaturesPlugin_Scale::CENTER_POINT_ID());
172   if (anObjRef.get() != NULL) {
173     GeomShapePtr aShape = anObjRef->value();
174     if (!aShape.get()) {
175       aShape = anObjRef->context()->shape();
176     }
177     if (aShape) {
178       aCenterPoint = GeomAlgoAPI_PointBuilder::point(aShape);
179     }
180   }
181
182   // Getting dimensions
183   double aScaleFactorX = real(FeaturesPlugin_Scale::SCALE_FACTOR_X_ID())->value();
184   double aScaleFactorY = real(FeaturesPlugin_Scale::SCALE_FACTOR_Y_ID())->value();
185   double aScaleFactorZ = real(FeaturesPlugin_Scale::SCALE_FACTOR_Z_ID())->value();
186
187   // Moving each object.
188   int aResultIndex = 0;
189   std::list<ResultPtr>::iterator aContext = aContextes.begin();
190   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
191         anObjectsIt++, aContext++) {
192     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
193     GeomAlgoAPI_Scale aScaleAlgo(aBaseShape, aCenterPoint,
194                                  aScaleFactorX, aScaleFactorY, aScaleFactorZ);
195
196     if (!aScaleAlgo.check()) {
197       setError(aScaleAlgo.getError());
198       return;
199     }
200
201     aScaleAlgo.build();
202
203     // Checking that the algorithm worked properly.
204     if(!aScaleAlgo.isDone()) {
205       static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
206       setError(aFeatureError);
207       break;
208     }
209     if(aScaleAlgo.shape()->isNull()) {
210       static const std::string aShapeError = "Error: Resulting shape is Null.";
211       setError(aShapeError);
212       break;
213     }
214     if(!aScaleAlgo.isValid()) {
215       std::string aFeatureError = "Error: Resulting shape is not valid.";
216       setError(aFeatureError);
217       break;
218     }
219
220     ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
221     loadNamingDS(aScaleAlgo, aResultBody, aBaseShape);
222     setResult(aResultBody, aResultIndex);
223     aResultIndex++;
224   }
225
226   // Remove the rest results if there were produced in the previous pass.
227   removeResults(aResultIndex);
228 }
229
230 //=================================================================================================
231 void FeaturesPlugin_Scale::loadNamingDS(GeomAlgoAPI_Scale& theScaleAlgo,
232                                         std::shared_ptr<ModelAPI_ResultBody> theResultBody,
233                                         std::shared_ptr<GeomAPI_Shape> theBaseShape)
234 {
235   // Store and name the result.
236   theResultBody->storeModified(theBaseShape, theScaleAlgo.shape());
237
238   // Name the faces
239   std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theScaleAlgo.mapOfSubShapes();
240   int aReflectedTag = 1;
241   std::string aReflectedName = "Scaled";
242   theResultBody->loadAndOrientModifiedShapes(&theScaleAlgo,
243                                               theBaseShape, GeomAPI_Shape::FACE,
244                                               aReflectedTag, aReflectedName, *aSubShapes.get());
245 }