]> SALOME platform Git repositories - modules/shaper.git/blob - src/FeaturesPlugin/FeaturesPlugin_Scale.cpp
Salome HOME
Add copyright header according to request of CEA from 06.06.2017
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Scale.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
18 //
19
20 #include <FeaturesPlugin_Scale.h>
21
22 #include <GeomAlgoAPI_PointBuilder.h>
23
24 #include <ModelAPI_AttributeDouble.h>
25 #include <ModelAPI_AttributeSelectionList.h>
26 #include <ModelAPI_AttributeString.h>
27 #include <ModelAPI_ResultBody.h>
28 #include <ModelAPI_ResultPart.h>
29
30 #include <iostream>
31
32 //=================================================================================================
33 FeaturesPlugin_Scale::FeaturesPlugin_Scale()
34 {
35 }
36
37 //=================================================================================================
38 void FeaturesPlugin_Scale::initAttributes()
39 {
40   data()->addAttribute(FeaturesPlugin_Scale::CREATION_METHOD(),
41                        ModelAPI_AttributeString::typeId());
42
43   AttributeSelectionListPtr aSelection =
44     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
45     FeaturesPlugin_Scale::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
46
47   data()->addAttribute(FeaturesPlugin_Scale::CENTER_POINT_ID(),
48                        ModelAPI_AttributeSelection::typeId());
49
50   data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_ID(),
51                        ModelAPI_AttributeDouble::typeId());
52
53   data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_X_ID(),
54                        ModelAPI_AttributeDouble::typeId());
55   data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_Y_ID(),
56                        ModelAPI_AttributeDouble::typeId());
57   data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_Z_ID(),
58                        ModelAPI_AttributeDouble::typeId());
59 }
60
61 //=================================================================================================
62 void FeaturesPlugin_Scale::execute()
63 {
64   AttributeStringPtr aMethodTypeAttr = string(FeaturesPlugin_Scale::CREATION_METHOD());
65   std::string aMethodType = aMethodTypeAttr->value();
66
67   if (aMethodType == FeaturesPlugin_Scale::CREATION_METHOD_BY_FACTOR()) {
68     performScaleByFactor();
69   }
70
71   if (aMethodType == FeaturesPlugin_Scale::CREATION_METHOD_BY_DIMENSIONS()) {
72     performScaleByDimensions();
73   }
74 }
75
76 //=================================================================================================
77 void FeaturesPlugin_Scale::performScaleByFactor()
78 {
79   // Getting objects.
80   ListOfShape anObjects;
81   std::list<ResultPtr> aContextes;
82   AttributeSelectionListPtr anObjectsSelList =
83     selectionList(FeaturesPlugin_Scale::OBJECTS_LIST_ID());
84   if (anObjectsSelList->size() == 0) {
85     return;
86   }
87   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
88     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
89       anObjectsSelList->value(anObjectsIndex);
90     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
91     if(!anObject.get()) { // may be for not-activated parts
92       eraseResults();
93       return;
94     }
95     anObjects.push_back(anObject);
96     aContextes.push_back(anObjectAttr->context());
97   }
98
99   // Getting the center point
100   std::shared_ptr<GeomAPI_Pnt> aCenterPoint;
101   std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
102     selection(FeaturesPlugin_Scale::CENTER_POINT_ID());
103   if (anObjRef.get() != NULL) {
104     GeomShapePtr aShape = anObjRef->value();
105     if (!aShape.get()) {
106       aShape = anObjRef->context()->shape();
107     }
108     if (aShape) {
109       aCenterPoint = GeomAlgoAPI_PointBuilder::point(aShape);
110     }
111   }
112
113   // Getting scale factor
114   double aScaleFactor = real(FeaturesPlugin_Scale::SCALE_FACTOR_ID())->value();
115
116   // Moving each object.
117   int aResultIndex = 0;
118   std::list<ResultPtr>::iterator aContext = aContextes.begin();
119   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
120         anObjectsIt++, aContext++) {
121     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
122     GeomAlgoAPI_Scale aScaleAlgo(aBaseShape, aCenterPoint, aScaleFactor);
123
124     if (!aScaleAlgo.check()) {
125       setError(aScaleAlgo.getError());
126       return;
127     }
128
129     aScaleAlgo.build();
130
131     // Checking that the algorithm worked properly.
132     if(!aScaleAlgo.isDone()) {
133       static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
134       setError(aFeatureError);
135       break;
136     }
137     if(aScaleAlgo.shape()->isNull()) {
138       static const std::string aShapeError = "Error: Resulting shape is Null.";
139       setError(aShapeError);
140       break;
141     }
142     if(!aScaleAlgo.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(aScaleAlgo, aResultBody, aBaseShape);
150     setResult(aResultBody, aResultIndex);
151     aResultIndex++;
152   }
153
154   // Remove the rest results if there were produced in the previous pass.
155   removeResults(aResultIndex);
156 }
157
158 //=================================================================================================
159 void FeaturesPlugin_Scale::performScaleByDimensions()
160 {
161   // Getting objects.
162   ListOfShape anObjects;
163   std::list<ResultPtr> aContextes;
164   AttributeSelectionListPtr anObjectsSelList =
165     selectionList(FeaturesPlugin_Scale::OBJECTS_LIST_ID());
166   if (anObjectsSelList->size() == 0) {
167     return;
168   }
169   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
170     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
171       anObjectsSelList->value(anObjectsIndex);
172     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
173     if(!anObject.get()) { // may be for not-activated parts
174       eraseResults();
175       return;
176     }
177     anObjects.push_back(anObject);
178     aContextes.push_back(anObjectAttr->context());
179   }
180
181   // Getting the center point
182   std::shared_ptr<GeomAPI_Pnt> aCenterPoint;
183   std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
184     selection(FeaturesPlugin_Scale::CENTER_POINT_ID());
185   if (anObjRef.get() != NULL) {
186     GeomShapePtr aShape = anObjRef->value();
187     if (!aShape.get()) {
188       aShape = anObjRef->context()->shape();
189     }
190     if (aShape) {
191       aCenterPoint = GeomAlgoAPI_PointBuilder::point(aShape);
192     }
193   }
194
195   // Getting dimensions
196   double aScaleFactorX = real(FeaturesPlugin_Scale::SCALE_FACTOR_X_ID())->value();
197   double aScaleFactorY = real(FeaturesPlugin_Scale::SCALE_FACTOR_Y_ID())->value();
198   double aScaleFactorZ = real(FeaturesPlugin_Scale::SCALE_FACTOR_Z_ID())->value();
199
200   // Moving each object.
201   int aResultIndex = 0;
202   std::list<ResultPtr>::iterator aContext = aContextes.begin();
203   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
204         anObjectsIt++, aContext++) {
205     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
206     GeomAlgoAPI_Scale aScaleAlgo(aBaseShape, aCenterPoint,
207                                  aScaleFactorX, aScaleFactorY, aScaleFactorZ);
208
209     if (!aScaleAlgo.check()) {
210       setError(aScaleAlgo.getError());
211       return;
212     }
213
214     aScaleAlgo.build();
215
216     // Checking that the algorithm worked properly.
217     if(!aScaleAlgo.isDone()) {
218       static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
219       setError(aFeatureError);
220       break;
221     }
222     if(aScaleAlgo.shape()->isNull()) {
223       static const std::string aShapeError = "Error: Resulting shape is Null.";
224       setError(aShapeError);
225       break;
226     }
227     if(!aScaleAlgo.isValid()) {
228       std::string aFeatureError = "Error: Resulting shape is not valid.";
229       setError(aFeatureError);
230       break;
231     }
232
233     ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
234     loadNamingDS(aScaleAlgo, aResultBody, aBaseShape);
235     setResult(aResultBody, aResultIndex);
236     aResultIndex++;
237   }
238
239   // Remove the rest results if there were produced in the previous pass.
240   removeResults(aResultIndex);
241 }
242
243 //=================================================================================================
244 void FeaturesPlugin_Scale::loadNamingDS(GeomAlgoAPI_Scale& theScaleAlgo,
245                                         std::shared_ptr<ModelAPI_ResultBody> theResultBody,
246                                         std::shared_ptr<GeomAPI_Shape> theBaseShape)
247 {
248   // Store and name the result.
249   theResultBody->storeModified(theBaseShape, theScaleAlgo.shape());
250
251   // Name the faces
252   std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theScaleAlgo.mapOfSubShapes();
253   int aReflectedTag = 1;
254   std::string aReflectedName = "Scaled";
255   theResultBody->loadAndOrientModifiedShapes(&theScaleAlgo,
256                                               theBaseShape, GeomAPI_Shape::FACE,
257                                               aReflectedTag, aReflectedName, *aSubShapes.get());
258 }