Salome HOME
updated copyright message
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Translation.cpp
1 // Copyright (C) 2014-2023  CEA, EDF
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_Translation.h>
21
22 #include <ModelAPI_AttributeDouble.h>
23 #include <ModelAPI_AttributeSelectionList.h>
24 #include <ModelAPI_AttributeString.h>
25 #include <ModelAPI_BodyBuilder.h>
26 #include <ModelAPI_ResultBody.h>
27 #include <ModelAPI_ResultPart.h>
28 #include <ModelAPI_Session.h>
29 #include <ModelAPI_Tools.h>
30
31 #include <GeomAPI_Ax1.h>
32 #include <GeomAPI_Edge.h>
33 #include <GeomAPI_Lin.h>
34 #include <GeomAPI_ShapeIterator.h>
35 #include <GeomAPI_ShapeHierarchy.h>
36 #include <GeomAPI_Trsf.h>
37
38 #include <GeomAlgoAPI_MakeShapeList.h>
39 #include <GeomAlgoAPI_PointBuilder.h>
40 #include <GeomAlgoAPI_Tools.h>
41 #include <GeomAlgoAPI_Transform.h>
42
43 #include <FeaturesPlugin_Tools.h>
44
45 static const std::string TRANSLATION_VERSION_1("v9.5");
46
47 //=================================================================================================
48 FeaturesPlugin_Translation::FeaturesPlugin_Translation()
49 {
50 }
51
52 //=================================================================================================
53 void FeaturesPlugin_Translation::initAttributes()
54 {
55   data()->addAttribute(FeaturesPlugin_Translation::CREATION_METHOD(),
56                        ModelAPI_AttributeString::typeId());
57
58   AttributeSelectionListPtr aSelection =
59     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
60     FeaturesPlugin_Translation::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
61
62   data()->addAttribute(FeaturesPlugin_Translation::AXIS_OBJECT_ID(),
63                        ModelAPI_AttributeSelection::typeId());
64   data()->addAttribute(FeaturesPlugin_Translation::DISTANCE_ID(),
65                        ModelAPI_AttributeDouble::typeId());
66
67   data()->addAttribute(FeaturesPlugin_Translation::DX_ID(),
68                        ModelAPI_AttributeDouble::typeId());
69   data()->addAttribute(FeaturesPlugin_Translation::DY_ID(),
70                        ModelAPI_AttributeDouble::typeId());
71   data()->addAttribute(FeaturesPlugin_Translation::DZ_ID(),
72                        ModelAPI_AttributeDouble::typeId());
73
74   data()->addAttribute(FeaturesPlugin_Translation::START_POINT_ID(),
75                        ModelAPI_AttributeSelection::typeId());
76   data()->addAttribute(FeaturesPlugin_Translation::END_POINT_ID(),
77                        ModelAPI_AttributeSelection::typeId());
78
79   if (!aSelection->isInitialized()) {
80     // new feature, not read from file
81     data()->setVersion(TRANSLATION_VERSION_1);
82   }
83 }
84
85 //=================================================================================================
86 void FeaturesPlugin_Translation::execute()
87 {
88   AttributeStringPtr aMethodTypeAttr = string(FeaturesPlugin_Translation::CREATION_METHOD());
89   std::string aMethodType = aMethodTypeAttr->value();
90
91   GeomTrsfPtr aTrsf;
92   if (aMethodType == CREATION_METHOD_BY_DISTANCE())
93     aTrsf = translationByAxisAndDistance();
94   else if (aMethodType == CREATION_METHOD_BY_DIMENSIONS())
95     aTrsf = translationByDimensions();
96   else if (aMethodType == CREATION_METHOD_BY_TWO_POINTS())
97     aTrsf = translationByTwoPoints();
98
99   performTranslation(aTrsf);
100 }
101
102 //=================================================================================================
103 GeomTrsfPtr FeaturesPlugin_Translation::translationByAxisAndDistance()
104 {
105   //Getting axis.
106   static const std::string aSelectionError = "Error: The axis shape selection is bad.";
107   AttributeSelectionPtr anObjRef = selection(AXIS_OBJECT_ID());
108   GeomShapePtr aShape = anObjRef->value();
109   if (!aShape.get()) {
110     if (anObjRef->context().get()) {
111       aShape = anObjRef->context()->shape();
112     }
113   }
114   if (!aShape.get()) {
115     setError(aSelectionError);
116     return GeomTrsfPtr();
117   }
118
119   GeomEdgePtr anEdge;
120   if (aShape->isEdge())
121   {
122     anEdge = aShape->edge();
123   }
124   else if (aShape->isCompound())
125   {
126     GeomAPI_ShapeIterator anIt(aShape);
127     anEdge = anIt.current()->edge();
128   }
129
130   if (!anEdge.get())
131   {
132     setError(aSelectionError);
133     return GeomTrsfPtr();
134   }
135
136   std::shared_ptr<GeomAPI_Ax1> anAxis(new GeomAPI_Ax1(anEdge->line()->location(),
137                                                       anEdge->line()->direction()));
138
139   // Getting distance.
140   double aDistance = real(FeaturesPlugin_Translation::DISTANCE_ID())->value();
141
142   GeomTrsfPtr aTrsf(new GeomAPI_Trsf);
143   aTrsf->setTranslation(anAxis, aDistance);
144   return aTrsf;
145 }
146
147 //=================================================================================================
148 GeomTrsfPtr FeaturesPlugin_Translation::translationByDimensions()
149 {
150   // Getting dimensions in X, in Y and in Z
151   double aDX = real(FeaturesPlugin_Translation::DX_ID())->value();
152   double aDY = real(FeaturesPlugin_Translation::DY_ID())->value();
153   double aDZ = real(FeaturesPlugin_Translation::DZ_ID())->value();
154
155   GeomTrsfPtr aTrsf(new GeomAPI_Trsf);
156   aTrsf->setTranslation(aDX, aDY, aDZ);
157   return aTrsf;
158 }
159
160 //=================================================================================================
161 GeomTrsfPtr FeaturesPlugin_Translation::translationByTwoPoints()
162 {
163   // Getting the start point and the end point
164   AttributeSelectionPtr aRef1 = data()->selection(FeaturesPlugin_Translation::START_POINT_ID());
165   AttributeSelectionPtr aRef2 = data()->selection(FeaturesPlugin_Translation::END_POINT_ID());
166   std::shared_ptr<GeomAPI_Pnt> aFirstPoint;
167   std::shared_ptr<GeomAPI_Pnt> aSecondPoint;
168   if ((aRef1.get() != NULL) && (aRef2.get() != NULL)) {
169     GeomShapePtr aShape1 = aRef1->value();
170     if (!aShape1.get()) //If we can't get the points directly, try getting them from the context
171       aShape1 = aRef1->context()->shape();
172     GeomShapePtr aShape2 = aRef2->value();
173     if (!aShape2.get())
174       aShape2 = aRef2->context()->shape();
175     if (aShape1 && aShape2) {
176       aFirstPoint = GeomAlgoAPI_PointBuilder::point(aShape1);
177       aSecondPoint = GeomAlgoAPI_PointBuilder::point(aShape2);
178     }
179   }
180
181   GeomTrsfPtr aTrsf(new GeomAPI_Trsf);
182   if (aFirstPoint && aSecondPoint) {
183     aTrsf->setTranslation(aFirstPoint, aSecondPoint);
184   }
185   return aTrsf;
186 }
187
188 //=================================================================================================
189 void FeaturesPlugin_Translation::performTranslation(const GeomTrsfPtr& theTrsf)
190 {
191   if (!theTrsf) {
192     setError("Invalid transformation.");
193     return;
194   }
195
196   bool isKeepSubShapes = data()->version() == TRANSLATION_VERSION_1;
197
198   // Getting objects.
199   GeomAPI_ShapeHierarchy anObjects;
200   std::list<ResultPtr> aParts;
201   ResultPtr aTextureSource;
202   AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECTS_LIST_ID());
203   if (!FeaturesPlugin_Tools::shapesFromSelectionList
204       (anObjectsSelList, isKeepSubShapes, anObjects, aParts, aTextureSource))
205     return;
206
207   std::string anError;
208   int aResultIndex = 0;
209   // Moving each part.
210   for (std::list<ResultPtr>::iterator aPRes = aParts.begin(); aPRes != aParts.end(); ++aPRes) {
211     ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aPRes);
212     ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
213     aResultPart->setTrsf(anOrigin, theTrsf);
214     setResult(aResultPart, aResultIndex++);
215   }
216
217   // Collect transformations for each object in a part.
218   std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList);
219
220   for (GeomAPI_ShapeHierarchy::iterator anObjectsIt = anObjects.begin();
221     anObjectsIt != anObjects.end(); anObjectsIt++) {
222     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
223     std::shared_ptr<GeomAlgoAPI_Transform> aTransformAlgo(
224         new GeomAlgoAPI_Transform(aBaseShape, theTrsf));
225
226     // Checking that the algorithm worked properly.
227     if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aTransformAlgo, getKind(), anError)) {
228       setError(anError);
229       break;
230     }
231
232     anObjects.markModified(aBaseShape, aTransformAlgo->shape());
233     aMakeShapeList->appendAlgo(aTransformAlgo);
234   }
235
236   // Build results of the operation.
237   const ListOfShape& anOriginalShapes = anObjects.objects();
238   ListOfShape aTopLevel;
239   anObjects.topLevelObjects(aTopLevel);
240   for (ListOfShape::iterator anIt = aTopLevel.begin(); anIt != aTopLevel.end(); ++anIt) {
241     //LoadNamingDS
242     ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
243     ModelAPI_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(),
244                                        aMakeShapeList, *anIt, "Translated");
245     // Copy image data, if any
246     ModelAPI_Tools::copyImageAttribute(aTextureSource, aResultBody);
247     setResult(aResultBody, aResultIndex++);
248   }
249
250   // Remove the rest results if there were produced in the previous pass.
251   removeResults(aResultIndex);
252 }