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() &&
175 fabs(aDZ) < MINIMAL_LENGTH()) {
176 setError("Axis builder with dimensions :: all dimensions are null", false);
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);
188 void ConstructionPlugin_Axis::createAxisByLine()
191 AttributeSelectionPtr anEdgeSelection = selection(LINE());
192 GeomShapePtr aLineShape = anEdgeSelection->value();
193 if(!aLineShape.get()) {
194 aLineShape = anEdgeSelection->context()->shape();
196 std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aLineShape));
198 ResultConstructionPtr aConstr = document()->createConstruction(data());
199 aConstr->setInfinite(true);
200 aConstr->setShape(anEdge);
204 void ConstructionPlugin_Axis::createAxisByPlaneAndPoint()
207 AttributeSelectionPtr aFaceSelection = selection(PLANE());
208 GeomShapePtr aFaceShape = aFaceSelection->value();
209 if(!aFaceShape.get()) {
210 aFaceShape = aFaceSelection->context()->shape();
212 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(aFaceShape));
213 std::shared_ptr<GeomAPI_Pln> aPln = aFace->getPlane();
216 AttributeSelectionPtr aPointSelection = selection(POINT());
217 GeomShapePtr aPointShape = aPointSelection->value();
218 if(!aPointShape.get()) {
219 aPointShape = aPointSelection->context()->shape();
221 std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aPointShape));
222 std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
224 std::shared_ptr<GeomAPI_Pnt> aProjPnt = aPln->project(aPnt);
226 if(aProjPnt->isEqual(aPnt)) {
227 aPnt->translate(aPln->direction(), defaultAxisSize);
230 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aPnt, aProjPnt);
232 ResultConstructionPtr aConstr = document()->createConstruction(data());
233 aConstr->setInfinite(true);
234 aConstr->setShape(anEdge);
238 void ConstructionPlugin_Axis::createAxisByTwoPlanes()
241 AttributeSelectionPtr aFaceSelection1 = selection(PLANE1());
242 GeomShapePtr aFaceShape1 = aFaceSelection1->value();
243 if(!aFaceShape1.get()) {
244 aFaceShape1 = aFaceSelection1->context()->shape();
246 std::shared_ptr<GeomAPI_Face> aFace1(new GeomAPI_Face(aFaceShape1));
247 std::shared_ptr<GeomAPI_Pln> aPln1 = aFace1->getPlane();
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();
254 anOffset1 = -anOffset1;
256 aPln1->translate(aPln1->direction(), anOffset1);
260 AttributeSelectionPtr aFaceSelection2 = selection(PLANE2());
261 GeomShapePtr aFaceShape2 = aFaceSelection2->value();
262 if(!aFaceShape2.get()) {
263 aFaceShape2 = aFaceSelection2->context()->shape();
265 std::shared_ptr<GeomAPI_Face> aFace2(new GeomAPI_Face(aFaceShape2));
266 std::shared_ptr<GeomAPI_Pln> aPln2 = aFace2->getPlane();
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();
273 anOffset2 = -anOffset2;
275 aPln2->translate(aPln2->direction(), anOffset2);
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);
283 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aPnt1, aPnt2);
285 ResultConstructionPtr aConstr = document()->createConstruction(data());
286 aConstr->setInfinite(true);
287 aConstr->setShape(anEdge);
291 void ConstructionPlugin_Axis::execute()
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()) {
305 } else if(aMethodType == CREATION_METHOD_BY_PLANE_AND_POINT()) {
306 createAxisByPlaneAndPoint();
307 } else if(aMethodType == CREATION_METHOD_BY_TWO_PLANES()) {
308 createAxisByTwoPlanes();
312 bool ConstructionPlugin_Axis::customisePresentation(ResultPtr theResult, AISObjectPtr thePrs,
313 std::shared_ptr<GeomAPI_ICustomPrs> theDefaultPrs)
315 bool isCustomized = theDefaultPrs.get() != NULL &&
316 theDefaultPrs->customisePresentation(theResult, thePrs, theDefaultPrs);
318 isCustomized = thePrs->setLineStyle(3) || isCustomized;
319 isCustomized = thePrs->setWidth(2) || isCustomized;