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