1 // Copyright (C) 2014-2016 CEA/DEN, EDF R&D
3 // File: ConstructionPlugin_Axis.cpp
4 // Created: 12 Dec 2014
5 // Author: Vitaly Smetannikov
7 // Modified by CEA (delegation to Alyotech) : 29 Mar 2016
9 #include "ConstructionPlugin_Axis.h"
11 #include <Config_PropManager.h>
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>
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>
36 static const double defaultAxisSize = 100;
38 ConstructionPlugin_Axis::ConstructionPlugin_Axis()
42 void ConstructionPlugin_Axis::initAttributes()
44 data()->addAttribute(ConstructionPlugin_Axis::METHOD(),
45 ModelAPI_AttributeString::typeId());
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());
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());
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());
77 /// Attributes for axis by line.
78 data()->addAttribute(LINE(), ModelAPI_AttributeSelection::typeId());
80 /// Attributes for axis by plane and point.
81 data()->addAttribute(PLANE(), ModelAPI_AttributeSelection::typeId());
82 data()->addAttribute(POINT(), ModelAPI_AttributeSelection::typeId());
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());
95 void ConstructionPlugin_Axis::createAxisByTwoPoints()
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();
102 aShape1 = aRef1->context()->shape();
103 GeomShapePtr aShape2 = aRef2->value();
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);
112 ResultConstructionPtr aConstr = document()->createConstruction(data());
113 aConstr->setInfinite(true);
114 aConstr->setShape(anEdge);
122 void ConstructionPlugin_Axis::createAxisByPointAndDirection()
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();
132 aShape1 = aRef1->context()->shape();
134 std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aXAttr->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);
143 ResultConstructionPtr aConstr = document()->createConstruction(data());
144 aConstr->setInfinite(true);
145 aConstr->setShape(anEdge);
153 void ConstructionPlugin_Axis::createAxisByCylindricalFace()
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);
160 ResultConstructionPtr aConstr = document()->createConstruction(data());
161 aConstr->setInfinite(true);
162 aConstr->setShape(anEdge);
167 void ConstructionPlugin_Axis::createAxisByDimensions()
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();
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);
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);
187 void ConstructionPlugin_Axis::createAxisByLine()
190 AttributeSelectionPtr anEdgeSelection = selection(LINE());
191 GeomShapePtr aLineShape = anEdgeSelection->value();
192 if(!aLineShape.get()) {
193 aLineShape = anEdgeSelection->context()->shape();
195 std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aLineShape));
197 ResultConstructionPtr aConstr = document()->createConstruction(data());
198 aConstr->setInfinite(true);
199 aConstr->setShape(anEdge);
203 void ConstructionPlugin_Axis::createAxisByPlaneAndPoint()
206 AttributeSelectionPtr aFaceSelection = selection(PLANE());
207 GeomShapePtr aFaceShape = aFaceSelection->value();
208 if(!aFaceShape.get()) {
209 aFaceShape = aFaceSelection->context()->shape();
211 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(aFaceShape));
212 std::shared_ptr<GeomAPI_Pln> aPln = aFace->getPlane();
215 AttributeSelectionPtr aPointSelection = selection(POINT());
216 GeomShapePtr aPointShape = aPointSelection->value();
217 if(!aPointShape.get()) {
218 aPointShape = aPointSelection->context()->shape();
220 std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aPointShape));
221 std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
223 std::shared_ptr<GeomAPI_Pnt> aProjPnt = aPln->project(aPnt);
225 if(aProjPnt->isEqual(aPnt)) {
226 aPnt->translate(aPln->direction(), defaultAxisSize);
229 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aPnt, aProjPnt);
231 ResultConstructionPtr aConstr = document()->createConstruction(data());
232 aConstr->setInfinite(true);
233 aConstr->setShape(anEdge);
237 void ConstructionPlugin_Axis::createAxisByTwoPlanes()
240 AttributeSelectionPtr aFaceSelection1 = selection(PLANE1());
241 GeomShapePtr aFaceShape1 = aFaceSelection1->value();
242 if(!aFaceShape1.get()) {
243 aFaceShape1 = aFaceSelection1->context()->shape();
245 std::shared_ptr<GeomAPI_Face> aFace1(new GeomAPI_Face(aFaceShape1));
246 std::shared_ptr<GeomAPI_Pln> aPln1 = aFace1->getPlane();
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();
253 anOffset1 = -anOffset1;
255 aPln1->translate(aPln1->direction(), anOffset1);
259 AttributeSelectionPtr aFaceSelection2 = selection(PLANE2());
260 GeomShapePtr aFaceShape2 = aFaceSelection2->value();
261 if(!aFaceShape2.get()) {
262 aFaceShape2 = aFaceSelection2->context()->shape();
264 std::shared_ptr<GeomAPI_Face> aFace2(new GeomAPI_Face(aFaceShape2));
265 std::shared_ptr<GeomAPI_Pln> aPln2 = aFace2->getPlane();
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();
272 anOffset2 = -anOffset2;
274 aPln2->translate(aPln2->direction(), anOffset2);
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);
282 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aPnt1, aPnt2);
284 ResultConstructionPtr aConstr = document()->createConstruction(data());
285 aConstr->setInfinite(true);
286 aConstr->setShape(anEdge);
290 void ConstructionPlugin_Axis::execute()
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()) {
304 } else if(aMethodType == CREATION_METHOD_BY_PLANE_AND_POINT()) {
305 createAxisByPlaneAndPoint();
306 } else if(aMethodType == CREATION_METHOD_BY_TWO_PLANES()) {
307 createAxisByTwoPlanes();
311 bool ConstructionPlugin_Axis::customisePresentation(ResultPtr theResult, AISObjectPtr thePrs,
312 std::shared_ptr<GeomAPI_ICustomPrs> theDefaultPrs)
314 bool isCustomized = theDefaultPrs.get() != NULL &&
315 theDefaultPrs->customisePresentation(theResult, thePrs, theDefaultPrs);
317 isCustomized = thePrs->setLineStyle(3) || isCustomized;
318 isCustomized = thePrs->setWidth(2) || isCustomized;