Salome HOME
Issue #1650: Added CPP High API for feature Axis;
[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() && fabs(aDZ) < MINIMAL_LENGTH()){
175     setError("Axis builder with dimensions  :: all dimensions are null", false);
176     return ;
177   }
178
179   // Make the axis, build the ResultConstructionPtr and write it
180   std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aDX, aDY, aDZ);
181   ResultConstructionPtr aConstr = document()->createConstruction(data());
182   aConstr->setInfinite(true);
183   aConstr->setShape(anEdge);
184   setResult(aConstr);    
185 }
186
187 void ConstructionPlugin_Axis::createAxisByLine()
188 {
189   // Get edge.
190   AttributeSelectionPtr anEdgeSelection = selection(LINE());
191   GeomShapePtr aLineShape = anEdgeSelection->value();
192   if(!aLineShape.get()) {
193     aLineShape = anEdgeSelection->context()->shape();
194   }
195   std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aLineShape));
196
197   ResultConstructionPtr aConstr = document()->createConstruction(data());
198   aConstr->setInfinite(true);
199   aConstr->setShape(anEdge);
200   setResult(aConstr);
201 }
202
203 void ConstructionPlugin_Axis::createAxisByPlaneAndPoint()
204 {
205   // Get face.
206   AttributeSelectionPtr aFaceSelection = selection(PLANE());
207   GeomShapePtr aFaceShape = aFaceSelection->value();
208   if(!aFaceShape.get()) {
209     aFaceShape = aFaceSelection->context()->shape();
210   }
211   std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(aFaceShape));
212   std::shared_ptr<GeomAPI_Pln> aPln = aFace->getPlane();
213
214   // Get point.
215   AttributeSelectionPtr aPointSelection = selection(POINT());
216   GeomShapePtr aPointShape = aPointSelection->value();
217   if(!aPointShape.get()) {
218     aPointShape = aPointSelection->context()->shape();
219   }
220   std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aPointShape));
221   std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
222
223   std::shared_ptr<GeomAPI_Pnt> aProjPnt = aPln->project(aPnt);
224
225   if(aProjPnt->isEqual(aPnt)) {
226     aPnt->translate(aPln->direction(), defaultAxisSize);
227   }
228
229   std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aPnt, aProjPnt);
230
231   ResultConstructionPtr aConstr = document()->createConstruction(data());
232   aConstr->setInfinite(true);
233   aConstr->setShape(anEdge);
234   setResult(aConstr);
235 }
236
237 void ConstructionPlugin_Axis::createAxisByTwoPlanes()
238 {
239   // Get face 1.
240   AttributeSelectionPtr aFaceSelection1 = selection(PLANE1());
241   GeomShapePtr aFaceShape1 = aFaceSelection1->value();
242   if(!aFaceShape1.get()) {
243     aFaceShape1 = aFaceSelection1->context()->shape();
244   }
245   std::shared_ptr<GeomAPI_Face> aFace1(new GeomAPI_Face(aFaceShape1));
246   std::shared_ptr<GeomAPI_Pln> aPln1 = aFace1->getPlane();
247
248   std::string useOffset1 = string(USE_OFFSET1())->value();
249   if(!useOffset1.empty()) {
250     double anOffset1 = real(OFFSET1())->value();
251     bool reverseOffset1 = boolean(REVERSE_OFFSET1())->value();
252     if(reverseOffset1) {
253       anOffset1 = -anOffset1;
254     }
255     aPln1->translate(aPln1->direction(), anOffset1);
256   }
257
258   // Get face 2.
259   AttributeSelectionPtr aFaceSelection2 = selection(PLANE2());
260   GeomShapePtr aFaceShape2 = aFaceSelection2->value();
261   if(!aFaceShape2.get()) {
262     aFaceShape2 = aFaceSelection2->context()->shape();
263   }
264   std::shared_ptr<GeomAPI_Face> aFace2(new GeomAPI_Face(aFaceShape2));
265   std::shared_ptr<GeomAPI_Pln> aPln2 = aFace2->getPlane();
266
267   std::string useOffset2 = string(USE_OFFSET2())->value();
268   if(!useOffset2.empty()) {
269     double anOffset2 = real(OFFSET2())->value();
270     bool reverseOffset2 = boolean(REVERSE_OFFSET2())->value();
271     if(reverseOffset2) {
272       anOffset2 = -anOffset2;
273     }
274     aPln2->translate(aPln2->direction(), anOffset2);
275   }
276
277   std::shared_ptr<GeomAPI_Lin> aLin = aPln1->intersect(aPln2);
278   std::shared_ptr<GeomAPI_Pnt> aPnt1 = aLin->location();
279   std::shared_ptr<GeomAPI_Pnt> aPnt2 = aLin->location();
280   aPnt2->translate(aLin->direction(), defaultAxisSize);
281
282   std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aPnt1, aPnt2);
283
284   ResultConstructionPtr aConstr = document()->createConstruction(data());
285   aConstr->setInfinite(true);
286   aConstr->setShape(anEdge);
287   setResult(aConstr);
288 }
289
290 void ConstructionPlugin_Axis::execute()
291 {
292   AttributeStringPtr aMethodTypeAttr = string(ConstructionPlugin_Axis::METHOD());
293   std::string aMethodType = aMethodTypeAttr->value();
294   if (aMethodType == CREATION_METHOD_BY_TWO_POINTS()) {
295     createAxisByTwoPoints();
296   } else if (aMethodType == CREATION_METHOD_BY_CYLINDRICAL_FACE()) {
297     createAxisByCylindricalFace();
298   } else if (aMethodType == CREATION_METHOD_BY_POINT_AND_DIRECTION()) {
299     createAxisByPointAndDirection();
300   } else if (aMethodType == CREATION_METHOD_BY_DIMENSIONS()) {
301     createAxisByDimensions();
302   } else if(aMethodType == CREATION_METHOD_BY_LINE()) {
303     createAxisByLine();
304   } else if(aMethodType == CREATION_METHOD_BY_PLANE_AND_POINT()) {
305     createAxisByPlaneAndPoint();
306   } else if(aMethodType == CREATION_METHOD_BY_TWO_PLANES()) {
307     createAxisByTwoPlanes();
308   }
309 }
310
311 bool ConstructionPlugin_Axis::customisePresentation(ResultPtr theResult, AISObjectPtr thePrs,
312   std::shared_ptr<GeomAPI_ICustomPrs> theDefaultPrs)
313 {
314   bool isCustomized = theDefaultPrs.get() != NULL &&
315                       theDefaultPrs->customisePresentation(theResult, thePrs, theDefaultPrs);
316
317   isCustomized = thePrs->setLineStyle(3) || isCustomized;
318   isCustomized = thePrs->setWidth(2) || isCustomized;
319
320   return isCustomized;
321 }