Salome HOME
Remove French translations
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_MultiTranslation.cpp
1 // Copyright (C) 2014-2019  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
18 //
19
20 #include <FeaturesPlugin_MultiTranslation.h>
21 #include <FeaturesPlugin_Tools.h>
22
23 #include <GeomAlgoAPI_CompoundBuilder.h>
24 #include <GeomAlgoAPI_MakeShapeList.h>
25 #include <GeomAlgoAPI_Tools.h>
26
27 #include <GeomAPI_Ax1.h>
28 #include <GeomAPI_Edge.h>
29 #include <GeomAPI_Lin.h>
30 #include <GeomAPI_ShapeIterator.h>
31 #include <GeomAPI_Trsf.h>
32
33 #include <ModelAPI_AttributeDouble.h>
34 #include <ModelAPI_AttributeInteger.h>
35 #include <ModelAPI_AttributeSelectionList.h>
36 #include <ModelAPI_AttributeString.h>
37 #include <ModelAPI_ResultBody.h>
38 #include <ModelAPI_ResultPart.h>
39
40 #include <math.h>
41
42 //=================================================================================================
43 FeaturesPlugin_MultiTranslation::FeaturesPlugin_MultiTranslation()
44 {
45 }
46
47 //=================================================================================================
48 void FeaturesPlugin_MultiTranslation::initAttributes()
49 {
50   AttributeSelectionListPtr aSelection =
51     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
52     FeaturesPlugin_MultiTranslation::OBJECTS_LIST_ID(),
53     ModelAPI_AttributeSelectionList::typeId()));
54
55   data()->addAttribute(FeaturesPlugin_MultiTranslation::AXIS_FIRST_DIR_ID(),
56                        ModelAPI_AttributeSelection::typeId());
57   data()->addAttribute(FeaturesPlugin_MultiTranslation::STEP_FIRST_DIR_ID(),
58                        ModelAPI_AttributeDouble::typeId());
59   data()->addAttribute(FeaturesPlugin_MultiTranslation::NB_COPIES_FIRST_DIR_ID(),
60                        ModelAPI_AttributeInteger::typeId());
61
62   data()->addAttribute(FeaturesPlugin_MultiTranslation::USE_SECOND_DIR_ID(),
63                        ModelAPI_AttributeString::typeId());
64   data()->addAttribute(FeaturesPlugin_MultiTranslation::AXIS_SECOND_DIR_ID(),
65                        ModelAPI_AttributeSelection::typeId());
66   data()->addAttribute(FeaturesPlugin_MultiTranslation::STEP_SECOND_DIR_ID(),
67                        ModelAPI_AttributeDouble::typeId());
68   data()->addAttribute(FeaturesPlugin_MultiTranslation::NB_COPIES_SECOND_DIR_ID(),
69                        ModelAPI_AttributeInteger::typeId());
70 }
71
72 //=================================================================================================
73 void FeaturesPlugin_MultiTranslation::execute()
74 {
75   std::string useSecondDir = string(FeaturesPlugin_MultiTranslation::USE_SECOND_DIR_ID())->value();
76   if(!useSecondDir.empty()) {
77     performTwoDirection();
78   } else {
79     performOneDirection();
80   }
81 }
82
83 //=================================================================================================
84 void FeaturesPlugin_MultiTranslation::performOneDirection()
85 {
86   // Getting objects.
87   ListOfShape anObjects;
88   std::list<ResultPtr> aContextes;
89   AttributeSelectionListPtr anObjectsSelList =
90     selectionList(FeaturesPlugin_MultiTranslation::OBJECTS_LIST_ID());
91   if (anObjectsSelList->size() == 0) {
92     setError("Error: empty selection list");
93     return;
94   }
95   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
96     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
97       anObjectsSelList->value(anObjectsIndex);
98     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
99     if(!anObject.get()) { // may be for not-activated parts
100       return;
101     }
102     anObjects.push_back(anObject);
103     aContextes.push_back(anObjectAttr->context());
104   }
105
106   //Getting axis.
107   static const std::string aSelectionError = "Error: The axis shape selection is bad.";
108   AttributeSelectionPtr anObjRef = selection(AXIS_FIRST_DIR_ID());
109   GeomShapePtr aShape = anObjRef->value();
110   if (!aShape.get()) {
111     if (anObjRef->context().get()) {
112       aShape = anObjRef->context()->shape();
113     }
114   }
115   if (!aShape.get()) {
116     setError(aSelectionError);
117     return;
118   }
119
120   GeomEdgePtr anEdge;
121   if (aShape->isEdge())
122   {
123     anEdge = aShape->edge();
124   }
125   else if (aShape->isCompound())
126   {
127     GeomAPI_ShapeIterator anIt(aShape);
128     anEdge = anIt.current()->edge();
129   }
130
131   if (!anEdge.get())
132   {
133     setError(aSelectionError);
134     return;
135   }
136
137   std::shared_ptr<GeomAPI_Ax1> anAxis (new GeomAPI_Ax1(anEdge->line()->location(),
138                                                        anEdge->line()->direction()));
139
140   // Getting step.
141   double aStep = real(FeaturesPlugin_MultiTranslation::STEP_FIRST_DIR_ID())->value();
142
143   // Getting number of copies.
144   int nbCopies =
145     integer(FeaturesPlugin_MultiTranslation::NB_COPIES_FIRST_DIR_ID())->value();
146
147   if (nbCopies <=0) {
148     std::string aFeatureError = "Multitranslation builder ";
149     aFeatureError+=":: the number of copies for the first direction is null or negative.";
150     setError(aFeatureError);
151     return;
152   }
153
154   // Moving each object.
155   int aResultIndex = 0;
156   std::list<ResultPtr>::iterator aContext = aContextes.begin();
157   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
158         anObjectsIt++, aContext++) {
159     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
160     bool isPart = aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group();
161
162     // Setting result.
163     if (isPart) {
164       ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
165       std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
166       for (int i=0; i<nbCopies; i++) {
167         aTrsf->setTranslation(anAxis, i*aStep);
168         ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
169         aResultPart->setTrsf(*aContext, aTrsf);
170         setResult(aResultPart, aResultIndex);
171         aResultIndex++;
172       }
173     } else {
174       std::string anError;
175       ListOfShape aListOfShape;
176       ListOfMakeShape aMakeShapeList;
177
178       for (int i=0; i<nbCopies; i++) {
179         std::shared_ptr<GeomAlgoAPI_Translation> aTranslationAlgo(
180           new GeomAlgoAPI_Translation(aBaseShape, anAxis, i*aStep));
181
182         if (!aTranslationAlgo->check()) {
183           setError(aTranslationAlgo->getError());
184           break;
185         }
186
187         aTranslationAlgo->build();
188
189         // Checking that the algorithm worked properly.
190         if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(
191             aTranslationAlgo, getKind(), anError)) {
192           setError(anError);
193           break;
194         }
195         aListOfShape.push_back(aTranslationAlgo->shape());
196         aMakeShapeList.push_back(aTranslationAlgo);
197       }
198
199       std::shared_ptr<GeomAlgoAPI_MakeShapeList>
200           aListOfTranslationAlgo(new GeomAlgoAPI_MakeShapeList(aMakeShapeList));
201
202       std::shared_ptr<GeomAPI_Shape> aCompound =
203         GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
204       ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
205
206       ListOfShape aBaseShapes;
207       aBaseShapes.push_back(aBaseShape);
208       FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShapes, ListOfShape(),
209                                                aListOfTranslationAlgo, aCompound, "Translated");
210
211       setResult(aResultBody, aResultIndex);
212     }
213     aResultIndex++;
214   }
215
216   // Remove the rest results if there were produced in the previous pass.
217   removeResults(aResultIndex);
218 }
219
220 //=================================================================================================
221 void FeaturesPlugin_MultiTranslation::performTwoDirection()
222 {
223   // Getting objects.
224   ListOfShape anObjects;
225   std::list<ResultPtr> aContextes;
226   AttributeSelectionListPtr anObjectsSelList =
227     selectionList(FeaturesPlugin_MultiTranslation::OBJECTS_LIST_ID());
228   if (anObjectsSelList->size() == 0) {
229     setError("Error: empty selection list");
230     return;
231   }
232   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
233     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
234       anObjectsSelList->value(anObjectsIndex);
235     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
236     if(!anObject.get()) { // may be for not-activated parts
237       return;
238     }
239     anObjects.push_back(anObject);
240     aContextes.push_back(anObjectAttr->context());
241   }
242
243   //Getting axis.
244   static const std::string aSelectionError = "Error: The axis shape selection is bad.";
245   AttributeSelectionPtr anObjRef = selection(AXIS_FIRST_DIR_ID());
246   GeomShapePtr aShape = anObjRef->value();
247   if (!aShape.get()) {
248     if (anObjRef->context().get()) {
249       aShape = anObjRef->context()->shape();
250     }
251   }
252   if (!aShape.get()) {
253     setError(aSelectionError);
254     return;
255   }
256
257   GeomEdgePtr anEdge;
258   if (aShape->isEdge())
259   {
260     anEdge = aShape->edge();
261   }
262   else if (aShape->isCompound())
263   {
264     GeomAPI_ShapeIterator anIt(aShape);
265     anEdge = anIt.current()->edge();
266   }
267
268   if (!anEdge.get())
269   {
270     setError(aSelectionError);
271     return;
272   }
273
274   std::shared_ptr<GeomAPI_Ax1> aFirstAxis(new GeomAPI_Ax1(anEdge->line()->location(),
275                                                           anEdge->line()->direction()));
276
277   //Getting axis.
278   anObjRef = selection(AXIS_SECOND_DIR_ID());
279   aShape = anObjRef->value();
280   if (!aShape.get()) {
281     if (anObjRef->context().get()) {
282       aShape = anObjRef->context()->shape();
283     }
284   }
285   if (!aShape.get()) {
286     setError(aSelectionError);
287     return;
288   }
289
290   if (aShape->isEdge())
291   {
292     anEdge = aShape->edge();
293   }
294   else if (aShape->isCompound())
295   {
296     GeomAPI_ShapeIterator anIt(aShape);
297     anEdge = anIt.current()->edge();
298   }
299
300   if (!anEdge.get())
301   {
302     setError(aSelectionError);
303     return;
304   }
305
306   std::shared_ptr<GeomAPI_Ax1> aSecondAxis(new GeomAPI_Ax1(anEdge->line()->location(),
307                                                            anEdge->line()->direction()));
308
309   // Getting step.
310   double aFirstStep = real(FeaturesPlugin_MultiTranslation::STEP_FIRST_DIR_ID())->value();
311   double aSecondStep = real(FeaturesPlugin_MultiTranslation::STEP_SECOND_DIR_ID())->value();
312
313   // Getting number of copies.
314   int aFirstNbCopies =
315     integer(FeaturesPlugin_MultiTranslation::NB_COPIES_FIRST_DIR_ID())->value();
316   int aSecondNbCopies =
317     integer(FeaturesPlugin_MultiTranslation::NB_COPIES_SECOND_DIR_ID())->value();
318
319   if (aFirstNbCopies <=0) {
320     std::string aFeatureError = "Multitranslation builder ";
321     aFeatureError+=":: the number of copies for the first direction is null or negative.";
322     setError(aFeatureError);
323     return;
324   }
325
326   if (aSecondNbCopies <=0) {
327     std::string aFeatureError = "Multitranslation builder ";
328     aFeatureError+=":: the number of copies for the second direction is null or negative.";
329     setError(aFeatureError);
330     return;
331   }
332
333   // Coord aFirstAxis
334   double x1 = aFirstAxis->dir()->x();
335   double y1 = aFirstAxis->dir()->y();
336   double z1 = aFirstAxis->dir()->z();
337   double norm1 = sqrt(x1*x1 + y1*y1 + z1*z1);
338
339   // Coord aSecondAxis
340   double x2 = aSecondAxis->dir()->x();
341   double y2 = aSecondAxis->dir()->y();
342   double z2 = aSecondAxis->dir()->z();
343   double norm2 = sqrt(x2*x2 + y2*y2 + z2*z2);
344
345   // Moving each object.
346   int aResultIndex = 0;
347   std::list<ResultPtr>::iterator aContext = aContextes.begin();
348   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
349         anObjectsIt++, aContext++) {
350     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
351     bool isPart = aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group();
352
353     // Setting result.
354     if (isPart) {
355       ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
356       std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
357       for (int j=0; j<aSecondNbCopies; j++) {
358         for (int i=0; i<aFirstNbCopies; i++) {
359           double dx = i*aFirstStep*x1/norm1+j*aSecondStep*x2/norm2;
360           double dy = i*aFirstStep*y1/norm1+j*aSecondStep*y2/norm2;
361           double dz = i*aFirstStep*z1/norm1+j*aSecondStep*z2/norm2;
362           aTrsf->setTranslation(dx, dy, dz);
363           ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
364           aResultPart->setTrsf(*aContext, aTrsf);
365           setResult(aResultPart, aResultIndex);
366           aResultIndex++;
367         }
368       }
369     } else {
370       std::string anError;
371       ListOfShape aListOfShape;
372       ListOfMakeShape aMakeShapeList;
373
374       for (int j=0; j<aSecondNbCopies; j++) {
375         for (int i=0; i<aFirstNbCopies; i++) {
376           double dx = i*aFirstStep*x1/norm1+j*aSecondStep*x2/norm2;
377           double dy = i*aFirstStep*y1/norm1+j*aSecondStep*y2/norm2;
378           double dz = i*aFirstStep*z1/norm1+j*aSecondStep*z2/norm2;
379           std::shared_ptr<GeomAlgoAPI_Translation> aTranslationAlgo(
380             new GeomAlgoAPI_Translation(aBaseShape, dx, dy, dz));
381
382           if (!aTranslationAlgo->check()) {
383             setError(aTranslationAlgo->getError());
384             break;
385           }
386
387           aTranslationAlgo->build();
388
389           // Checking that the algorithm worked properly.
390           if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(
391               aTranslationAlgo, getKind(), anError)) {
392             setError(anError);
393             break;
394           }
395           aListOfShape.push_back(aTranslationAlgo->shape());
396           aMakeShapeList.push_back(aTranslationAlgo);
397         }
398       }
399
400       std::shared_ptr<GeomAlgoAPI_MakeShapeList>
401           aListOfTranslationAlgo(new GeomAlgoAPI_MakeShapeList(aMakeShapeList));
402
403       std::shared_ptr<GeomAPI_Shape> aCompound =
404         GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
405       ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
406
407       ListOfShape aBaseShapes;
408       aBaseShapes.push_back(aBaseShape);
409       FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShapes, ListOfShape(),
410                                                aListOfTranslationAlgo, aCompound, "Translated");
411
412       setResult(aResultBody, aResultIndex);
413     }
414     aResultIndex++;
415   }
416
417   // Remove the rest results if there were produced in the previous pass.
418   removeResults(aResultIndex);
419 }