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