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