Salome HOME
Issue #2593: CEA 2018-2 Geometrical Naming
[modules/shaper.git] / src / ConstructionPlugin / ConstructionPlugin_Axis.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
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include "ConstructionPlugin_Axis.h"
22
23 #include <Config_PropManager.h>
24
25 #include <ModelAPI_AttributeBoolean.h>
26 #include <ModelAPI_AttributeSelection.h>
27 #include <ModelAPI_ResultConstruction.h>
28 #include <ModelAPI_AttributeString.h>
29 #include <ModelAPI_AttributeDouble.h>
30 #include <ModelAPI_Session.h>
31 #include <ModelAPI_Validator.h>
32
33 #include <GeomAPI_Edge.h>
34 #include <GeomAPI_Lin.h>
35 #include <GeomAPI_Pln.h>
36 #include <GeomAPI_ShapeIterator.h>
37 #include <GeomAPI_Vertex.h>
38 #include <GeomAlgoAPI_EdgeBuilder.h>
39 #include <GeomAlgoAPI_PointBuilder.h>
40
41 #include <math.h>
42
43 #ifdef _DEBUG
44 #include <iostream>
45 #endif
46
47 static const double defaultAxisSize = 100;
48
49 ConstructionPlugin_Axis::ConstructionPlugin_Axis()
50 {
51 }
52
53 void ConstructionPlugin_Axis::initAttributes()
54 {
55   data()->addAttribute(ConstructionPlugin_Axis::METHOD(),
56                        ModelAPI_AttributeString::typeId());
57
58   // Attributes needed to build the axis using the "two points" method
59   data()->addAttribute(ConstructionPlugin_Axis::POINT_FIRST(),
60                        ModelAPI_AttributeSelection::typeId());
61   data()->addAttribute(ConstructionPlugin_Axis::POINT_SECOND(),
62                        ModelAPI_AttributeSelection::typeId());
63
64   // Attributes needed to build the axis using the "cylindrical face" method"
65   data()->addAttribute(ConstructionPlugin_Axis::CYLINDRICAL_FACE(),
66                        ModelAPI_AttributeSelection::typeId());
67   data()->addAttribute(ConstructionPlugin_Axis::X_DIRECTION(),
68                        ModelAPI_AttributeDouble::typeId());
69   data()->addAttribute(ConstructionPlugin_Axis::Y_DIRECTION(),
70                        ModelAPI_AttributeDouble::typeId());
71   data()->addAttribute(ConstructionPlugin_Axis::Z_DIRECTION(),
72                        ModelAPI_AttributeDouble::typeId());
73   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
74       ConstructionPlugin_Axis::X_DIRECTION());
75   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
76       ConstructionPlugin_Axis::Y_DIRECTION());
77   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
78       ConstructionPlugin_Axis::Z_DIRECTION());
79
80   //Attributes needed to build the axis using the "three dimensions" method
81   data()->addAttribute(ConstructionPlugin_Axis::DX(),
82                        ModelAPI_AttributeDouble::typeId());
83   data()->addAttribute(ConstructionPlugin_Axis::DY(),
84                        ModelAPI_AttributeDouble::typeId());
85   data()->addAttribute(ConstructionPlugin_Axis::DZ(),
86                        ModelAPI_AttributeDouble::typeId());
87
88   /// Attributes for axis by line.
89   data()->addAttribute(LINE(), ModelAPI_AttributeSelection::typeId());
90
91   /// Attributes for axis by plane and point.
92   data()->addAttribute(PLANE(), ModelAPI_AttributeSelection::typeId());
93   data()->addAttribute(POINT(), ModelAPI_AttributeSelection::typeId());
94
95   /// Attributes for axis by two planes.
96   data()->addAttribute(PLANE1(), ModelAPI_AttributeSelection::typeId());
97   data()->addAttribute(USE_OFFSET1(), ModelAPI_AttributeString::typeId());
98   data()->addAttribute(OFFSET1(), ModelAPI_AttributeDouble::typeId());
99   data()->addAttribute(REVERSE_OFFSET1(), ModelAPI_AttributeBoolean::typeId());
100   data()->addAttribute(PLANE2(), ModelAPI_AttributeSelection::typeId());
101   data()->addAttribute(USE_OFFSET2(), ModelAPI_AttributeString::typeId());
102   data()->addAttribute(OFFSET2(), ModelAPI_AttributeDouble::typeId());
103   data()->addAttribute(REVERSE_OFFSET2(), ModelAPI_AttributeBoolean::typeId());
104 }
105
106 void ConstructionPlugin_Axis::createAxisByTwoPoints()
107 {
108   AttributeSelectionPtr aRef1 = data()->selection(ConstructionPlugin_Axis::POINT_FIRST());
109   AttributeSelectionPtr aRef2 = data()->selection(ConstructionPlugin_Axis::POINT_SECOND());
110   if ((aRef1.get() != NULL) && (aRef2.get() != NULL)) {
111     GeomShapePtr aShape1 = aRef1->value();
112     if (!aShape1.get())
113       aShape1 = aRef1->context()->shape();
114     GeomShapePtr aShape2 = aRef2->value();
115     if (!aShape2.get())
116       aShape2 = aRef2->context()->shape();
117     if (aShape1->isVertex() && aShape2->isVertex() && (!aShape1->isEqual(aShape2))) {
118       std::shared_ptr<GeomAPI_Pnt> aStart = GeomAlgoAPI_PointBuilder::point(aShape1);
119       std::shared_ptr<GeomAPI_Pnt> anEnd = GeomAlgoAPI_PointBuilder::point(aShape2);
120       if (aStart->distance(anEnd) > ConstructionPlugin_Axis::MINIMAL_LENGTH()) {
121         std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
122
123         ResultConstructionPtr aConstr = document()->createConstruction(data());
124         aConstr->setInfinite(true);
125         aConstr->setShape(anEdge);
126         setResult(aConstr);
127       }
128     }
129   }
130 }
131
132
133 void ConstructionPlugin_Axis::createAxisByPointAndDirection()
134 {
135   AttributeSelectionPtr aRef1 = data()->selection(ConstructionPlugin_Axis::POINT_FIRST());
136   AttributeDoublePtr aXAttr = data()->real(ConstructionPlugin_Axis::X_DIRECTION());
137   AttributeDoublePtr aYAttr = data()->real(ConstructionPlugin_Axis::Y_DIRECTION());
138   AttributeDoublePtr aZAttr = data()->real(ConstructionPlugin_Axis::Z_DIRECTION());
139   if ((aRef1.get() != NULL) && (aXAttr.get() != NULL) &&
140       (aYAttr.get() != NULL) && (aZAttr.get() != NULL)) {
141     GeomShapePtr aShape1 = aRef1->value();
142     if (!aShape1.get())
143       aShape1 = aRef1->context()->shape();
144
145     std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aXAttr->value(),
146                                                                aYAttr->value(),
147                                                                aZAttr->value()));
148     if (aShape1->isVertex() && (!aShape1->isEqual(aVertex))) {
149       std::shared_ptr<GeomAPI_Pnt> aStart = GeomAlgoAPI_PointBuilder::point(aShape1);
150       std::shared_ptr<GeomAPI_Pnt> anEnd = aVertex->point();
151       if (aStart->distance(anEnd) > ConstructionPlugin_Axis::MINIMAL_LENGTH()) {
152         std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
153
154         ResultConstructionPtr aConstr = document()->createConstruction(data());
155         aConstr->setInfinite(true);
156         aConstr->setShape(anEdge);
157         setResult(aConstr);
158       }
159     }
160   }
161 }
162
163
164 void ConstructionPlugin_Axis::createAxisByCylindricalFace()
165 {
166   std::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(CYLINDRICAL_FACE())->value();
167     // update arguments due to the selection value
168
169   if (!aSelection.get() || aSelection->isNull()) {
170     return;
171   }
172
173   if (aSelection->isCompound()) {
174     GeomAPI_ShapeIterator anIt(aSelection);
175     aSelection = anIt.current();
176   }
177
178   if (aSelection->isFace()) {
179     std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::cylinderAxis(aSelection);
180
181     ResultConstructionPtr aConstr = document()->createConstruction(data());
182     aConstr->setInfinite(true);
183     aConstr->setShape(anEdge);
184     setResult(aConstr);
185   }
186 }
187
188 void ConstructionPlugin_Axis::createAxisByDimensions()
189 {
190   // Start by getting these dimensions
191   double aDX = data()->real(DX())->value();
192   double aDY = data()->real(DY())->value();
193   double aDZ = data()->real(DZ())->value();
194
195   if (fabs(aDX) < MINIMAL_LENGTH()  && fabs(aDY) < MINIMAL_LENGTH() &&
196       fabs(aDZ) < MINIMAL_LENGTH()) {
197     setError("Axis builder with dimensions  :: all dimensions are null", false);
198     return ;
199   }
200
201   // Make the axis, build the ResultConstructionPtr and write it
202   std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aDX, aDY, aDZ);
203   ResultConstructionPtr aConstr = document()->createConstruction(data());
204   aConstr->setInfinite(true);
205   aConstr->setShape(anEdge);
206   setResult(aConstr);
207 }
208
209 void ConstructionPlugin_Axis::createAxisByLine()
210 {
211   // Get edge.
212   AttributeSelectionPtr anEdgeSelection = selection(LINE());
213   GeomShapePtr aLineShape = anEdgeSelection->value();
214   if(!aLineShape.get()) {
215     aLineShape = anEdgeSelection->context()->shape();
216   }
217   GeomEdgePtr anEdge;
218   if (aLineShape->isEdge()) {
219     anEdge = aLineShape->edge();
220   }
221   else if (aLineShape->isCompound()) {
222     GeomAPI_ShapeIterator anIt(aLineShape);
223     anEdge = anIt.current()->edge();
224   }
225
226   ResultConstructionPtr aConstr = document()->createConstruction(data());
227   aConstr->setInfinite(true);
228   aConstr->setShape(anEdge);
229   setResult(aConstr);
230 }
231
232 void ConstructionPlugin_Axis::createAxisByPlaneAndPoint()
233 {
234   // Get face.
235   AttributeSelectionPtr aFaceSelection = selection(PLANE());
236   GeomShapePtr aFaceShape = aFaceSelection->value();
237   if(!aFaceShape.get()) {
238     aFaceShape = aFaceSelection->context()->shape();
239   }
240   GeomFacePtr aFace;
241   if (aFaceShape->isFace()) {
242     aFace = aFaceShape->face();
243   }
244   else if (aFaceShape->isCompound()) {
245     GeomAPI_ShapeIterator anIt(aFaceShape);
246     aFace = anIt.current()->face();
247   }
248   std::shared_ptr<GeomAPI_Pln> aPln = aFace->getPlane();
249
250   // Get point.
251   AttributeSelectionPtr aPointSelection = selection(POINT());
252   GeomShapePtr aPointShape = aPointSelection->value();
253   if(!aPointShape.get()) {
254     aPointShape = aPointSelection->context()->shape();
255   }
256   std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aPointShape));
257   std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
258
259   std::shared_ptr<GeomAPI_Pnt> aProjPnt = aPln->project(aPnt);
260
261   if(aProjPnt->isEqual(aPnt)) {
262     aPnt->translate(aPln->direction(), defaultAxisSize);
263   }
264
265   std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aPnt, aProjPnt);
266
267   ResultConstructionPtr aConstr = document()->createConstruction(data());
268   aConstr->setInfinite(true);
269   aConstr->setShape(anEdge);
270   setResult(aConstr);
271 }
272
273 void ConstructionPlugin_Axis::createAxisByTwoPlanes()
274 {
275   // Get face 1.
276   AttributeSelectionPtr aFaceSelection1 = selection(PLANE1());
277   GeomShapePtr aFaceShape1 = aFaceSelection1->value();
278   if(!aFaceShape1.get()) {
279     aFaceShape1 = aFaceSelection1->context()->shape();
280   }
281   std::shared_ptr<GeomAPI_Face> aFace1;
282   if (aFaceShape1->isFace()) {
283     aFace1 = aFaceShape1->face();
284   }
285   else if (aFaceShape1->isCompound()) {
286     GeomAPI_ShapeIterator anIt(aFaceShape1);
287     aFace1 = anIt.current()->face();
288   }
289   std::shared_ptr<GeomAPI_Pln> aPln1 = aFace1->getPlane();
290
291   std::string useOffset1 = string(USE_OFFSET1())->value();
292   if(!useOffset1.empty()) {
293     double anOffset1 = real(OFFSET1())->value();
294     bool reverseOffset1 = boolean(REVERSE_OFFSET1())->value();
295     if(reverseOffset1) {
296       anOffset1 = -anOffset1;
297     }
298     aPln1->translate(aPln1->direction(), anOffset1);
299   }
300
301   // Get face 2.
302   AttributeSelectionPtr aFaceSelection2 = selection(PLANE2());
303   GeomShapePtr aFaceShape2 = aFaceSelection2->value();
304   if(!aFaceShape2.get()) {
305     aFaceShape2 = aFaceSelection2->context()->shape();
306   }
307   std::shared_ptr<GeomAPI_Face> aFace2;
308   if (aFaceShape2->isFace()) {
309     aFace2 = aFaceShape2->face();
310   }
311   else if (aFaceShape2->isCompound()) {
312     GeomAPI_ShapeIterator anIt(aFaceShape2);
313     aFace2 = anIt.current()->face();
314   }
315   std::shared_ptr<GeomAPI_Pln> aPln2 = aFace2->getPlane();
316
317   std::string useOffset2 = string(USE_OFFSET2())->value();
318   if(!useOffset2.empty()) {
319     double anOffset2 = real(OFFSET2())->value();
320     bool reverseOffset2 = boolean(REVERSE_OFFSET2())->value();
321     if(reverseOffset2) {
322       anOffset2 = -anOffset2;
323     }
324     aPln2->translate(aPln2->direction(), anOffset2);
325   }
326
327   std::shared_ptr<GeomAPI_Lin> aLin = aPln1->intersect(aPln2);
328   std::shared_ptr<GeomAPI_Pnt> aPnt1 = aLin->location();
329   std::shared_ptr<GeomAPI_Pnt> aPnt2 = aLin->location();
330   aPnt2->translate(aLin->direction(), defaultAxisSize);
331
332   std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aPnt1, aPnt2);
333
334   ResultConstructionPtr aConstr = document()->createConstruction(data());
335   aConstr->setInfinite(true);
336   aConstr->setShape(anEdge);
337   setResult(aConstr);
338 }
339
340 void ConstructionPlugin_Axis::execute()
341 {
342   AttributeStringPtr aMethodTypeAttr = string(ConstructionPlugin_Axis::METHOD());
343   std::string aMethodType = aMethodTypeAttr->value();
344   if (aMethodType == CREATION_METHOD_BY_TWO_POINTS()) {
345     createAxisByTwoPoints();
346   } else if (aMethodType == CREATION_METHOD_BY_CYLINDRICAL_FACE()) {
347     createAxisByCylindricalFace();
348   } else if (aMethodType == CREATION_METHOD_BY_POINT_AND_DIRECTION()) {
349     createAxisByPointAndDirection();
350   } else if (aMethodType == CREATION_METHOD_BY_DIMENSIONS()) {
351     createAxisByDimensions();
352   } else if(aMethodType == CREATION_METHOD_BY_LINE()) {
353     createAxisByLine();
354   } else if(aMethodType == CREATION_METHOD_BY_PLANE_AND_POINT()) {
355     createAxisByPlaneAndPoint();
356   } else if(aMethodType == CREATION_METHOD_BY_TWO_PLANES()) {
357     createAxisByTwoPlanes();
358   }
359 }
360
361 bool ConstructionPlugin_Axis::customisePresentation(ResultPtr theResult, AISObjectPtr thePrs,
362   std::shared_ptr<GeomAPI_ICustomPrs> theDefaultPrs)
363 {
364   bool isCustomized = theDefaultPrs.get() != NULL &&
365                       theDefaultPrs->customisePresentation(theResult, thePrs, theDefaultPrs);
366
367   isCustomized = thePrs->setLineStyle(3) || isCustomized;
368   isCustomized = thePrs->setWidth(2) || isCustomized;
369
370   return isCustomized;
371 }