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 Clarisse Genrault (CEA) : 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>
34 static const double defaultAxisSize = 100;
36 ConstructionPlugin_Axis::ConstructionPlugin_Axis()
40 void ConstructionPlugin_Axis::initAttributes()
42 data()->addAttribute(ConstructionPlugin_Axis::METHOD(),
43 ModelAPI_AttributeString::typeId());
45 // Attributes needed to build the axis using the "two points" method
46 data()->addAttribute(ConstructionPlugin_Axis::POINT_FIRST(),
47 ModelAPI_AttributeSelection::typeId());
48 data()->addAttribute(ConstructionPlugin_Axis::POINT_SECOND(),
49 ModelAPI_AttributeSelection::typeId());
51 // Attributes needed to build the axis using the "cylindrical face" method"
52 data()->addAttribute(ConstructionPlugin_Axis::CYLINDRICAL_FACE(),
53 ModelAPI_AttributeSelection::typeId());
54 data()->addAttribute(ConstructionPlugin_Axis::X_DIRECTION(),
55 ModelAPI_AttributeDouble::typeId());
56 data()->addAttribute(ConstructionPlugin_Axis::Y_DIRECTION(),
57 ModelAPI_AttributeDouble::typeId());
58 data()->addAttribute(ConstructionPlugin_Axis::Z_DIRECTION(),
59 ModelAPI_AttributeDouble::typeId());
60 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
61 ConstructionPlugin_Axis::X_DIRECTION());
62 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
63 ConstructionPlugin_Axis::Y_DIRECTION());
64 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
65 ConstructionPlugin_Axis::Z_DIRECTION());
67 //Attributes needed to build the axis using the "three dimensions" method
68 data()->addAttribute(ConstructionPlugin_Axis::DX(),
69 ModelAPI_AttributeDouble::typeId());
70 data()->addAttribute(ConstructionPlugin_Axis::DY(),
71 ModelAPI_AttributeDouble::typeId());
72 data()->addAttribute(ConstructionPlugin_Axis::DZ(),
73 ModelAPI_AttributeDouble::typeId());
75 /// Attributes for axis by line.
76 data()->addAttribute(LINE(), ModelAPI_AttributeSelection::typeId());
78 /// Attributes for axis by plane and point.
79 data()->addAttribute(PLANE(), ModelAPI_AttributeSelection::typeId());
80 data()->addAttribute(POINT(), ModelAPI_AttributeSelection::typeId());
82 /// Attributes for axis by two planes.
83 data()->addAttribute(PLANE1(), ModelAPI_AttributeSelection::typeId());
84 data()->addAttribute(USE_OFFSET1(), ModelAPI_AttributeString::typeId());
85 data()->addAttribute(OFFSET1(), ModelAPI_AttributeDouble::typeId());
86 data()->addAttribute(REVERSE_OFFSET1(), ModelAPI_AttributeBoolean::typeId());
87 data()->addAttribute(PLANE2(), ModelAPI_AttributeSelection::typeId());
88 data()->addAttribute(USE_OFFSET2(), ModelAPI_AttributeString::typeId());
89 data()->addAttribute(OFFSET2(), ModelAPI_AttributeDouble::typeId());
90 data()->addAttribute(REVERSE_OFFSET2(), ModelAPI_AttributeBoolean::typeId());
93 void ConstructionPlugin_Axis::createAxisByTwoPoints()
95 AttributeSelectionPtr aRef1 = data()->selection(ConstructionPlugin_Axis::POINT_FIRST());
96 AttributeSelectionPtr aRef2 = data()->selection(ConstructionPlugin_Axis::POINT_SECOND());
97 if ((aRef1.get() != NULL) && (aRef2.get() != NULL)) {
98 GeomShapePtr aShape1 = aRef1->value();
100 aShape1 = aRef1->context()->shape();
101 GeomShapePtr aShape2 = aRef2->value();
103 aShape2 = aRef2->context()->shape();
104 if (aShape1->isVertex() && aShape2->isVertex() && (!aShape1->isEqual(aShape2))) {
105 std::shared_ptr<GeomAPI_Pnt> aStart = GeomAlgoAPI_PointBuilder::point(aShape1);
106 std::shared_ptr<GeomAPI_Pnt> anEnd = GeomAlgoAPI_PointBuilder::point(aShape2);
107 if (aStart->distance(anEnd) > ConstructionPlugin_Axis::MINIMAL_LENGTH()) {
108 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
110 ResultConstructionPtr aConstr = document()->createConstruction(data());
111 aConstr->setInfinite(true);
112 aConstr->setShape(anEdge);
120 void ConstructionPlugin_Axis::createAxisByPointAndDirection()
122 AttributeSelectionPtr aRef1 = data()->selection(ConstructionPlugin_Axis::POINT_FIRST());
123 AttributeDoublePtr aXAttr = data()->real(ConstructionPlugin_Axis::X_DIRECTION());
124 AttributeDoublePtr aYAttr = data()->real(ConstructionPlugin_Axis::Y_DIRECTION());
125 AttributeDoublePtr aZAttr = data()->real(ConstructionPlugin_Axis::Z_DIRECTION());
126 if ((aRef1.get() != NULL) && (aXAttr.get() != NULL) &&
127 (aYAttr.get() != NULL) && (aZAttr.get() != NULL)) {
128 GeomShapePtr aShape1 = aRef1->value();
130 aShape1 = aRef1->context()->shape();
132 std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aXAttr->value(),
135 if (aShape1->isVertex() && (!aShape1->isEqual(aVertex))) {
136 std::shared_ptr<GeomAPI_Pnt> aStart = GeomAlgoAPI_PointBuilder::point(aShape1);
137 std::shared_ptr<GeomAPI_Pnt> anEnd = aVertex->point();
138 if (aStart->distance(anEnd) > ConstructionPlugin_Axis::MINIMAL_LENGTH()) {
139 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
141 ResultConstructionPtr aConstr = document()->createConstruction(data());
142 aConstr->setInfinite(true);
143 aConstr->setShape(anEdge);
151 void ConstructionPlugin_Axis::createAxisByCylindricalFace()
153 std::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(CYLINDRICAL_FACE())->value();
154 // update arguments due to the selection value
155 if (aSelection && !aSelection->isNull() && aSelection->isFace()) {
156 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::cylinderAxis(aSelection);
158 ResultConstructionPtr aConstr = document()->createConstruction(data());
159 aConstr->setInfinite(true);
160 aConstr->setShape(anEdge);
165 void ConstructionPlugin_Axis::createAxisByDimensions()
167 // Start by getting these dimensions
168 double aDX = data()->real(DX())->value();
169 double aDY = data()->real(DY())->value();
170 double aDZ = data()->real(DZ())->value();
172 if (fabs(aDX) < MINIMAL_LENGTH() && fabs(aDY) < MINIMAL_LENGTH() &&
173 fabs(aDZ) < MINIMAL_LENGTH()) {
174 setError("Axis builder with dimensions :: all dimensions are null", false);
178 // Make the axis, build the ResultConstructionPtr and write it
179 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aDX, aDY, aDZ);
180 ResultConstructionPtr aConstr = document()->createConstruction(data());
181 aConstr->setInfinite(true);
182 aConstr->setShape(anEdge);
186 void ConstructionPlugin_Axis::createAxisByLine()
189 AttributeSelectionPtr anEdgeSelection = selection(LINE());
190 GeomShapePtr aLineShape = anEdgeSelection->value();
191 if(!aLineShape.get()) {
192 aLineShape = anEdgeSelection->context()->shape();
194 std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aLineShape));
196 ResultConstructionPtr aConstr = document()->createConstruction(data());
197 aConstr->setInfinite(true);
198 aConstr->setShape(anEdge);
202 void ConstructionPlugin_Axis::createAxisByPlaneAndPoint()
205 AttributeSelectionPtr aFaceSelection = selection(PLANE());
206 GeomShapePtr aFaceShape = aFaceSelection->value();
207 if(!aFaceShape.get()) {
208 aFaceShape = aFaceSelection->context()->shape();
210 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(aFaceShape));
211 std::shared_ptr<GeomAPI_Pln> aPln = aFace->getPlane();
214 AttributeSelectionPtr aPointSelection = selection(POINT());
215 GeomShapePtr aPointShape = aPointSelection->value();
216 if(!aPointShape.get()) {
217 aPointShape = aPointSelection->context()->shape();
219 std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aPointShape));
220 std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
222 std::shared_ptr<GeomAPI_Pnt> aProjPnt = aPln->project(aPnt);
224 if(aProjPnt->isEqual(aPnt)) {
225 aPnt->translate(aPln->direction(), defaultAxisSize);
228 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aPnt, aProjPnt);
230 ResultConstructionPtr aConstr = document()->createConstruction(data());
231 aConstr->setInfinite(true);
232 aConstr->setShape(anEdge);
236 void ConstructionPlugin_Axis::createAxisByTwoPlanes()
239 AttributeSelectionPtr aFaceSelection1 = selection(PLANE1());
240 GeomShapePtr aFaceShape1 = aFaceSelection1->value();
241 if(!aFaceShape1.get()) {
242 aFaceShape1 = aFaceSelection1->context()->shape();
244 std::shared_ptr<GeomAPI_Face> aFace1(new GeomAPI_Face(aFaceShape1));
245 std::shared_ptr<GeomAPI_Pln> aPln1 = aFace1->getPlane();
247 std::string useOffset1 = string(USE_OFFSET1())->value();
248 if(!useOffset1.empty()) {
249 double anOffset1 = real(OFFSET1())->value();
250 bool reverseOffset1 = boolean(REVERSE_OFFSET1())->value();
252 anOffset1 = -anOffset1;
254 aPln1->translate(aPln1->direction(), anOffset1);
258 AttributeSelectionPtr aFaceSelection2 = selection(PLANE2());
259 GeomShapePtr aFaceShape2 = aFaceSelection2->value();
260 if(!aFaceShape2.get()) {
261 aFaceShape2 = aFaceSelection2->context()->shape();
263 std::shared_ptr<GeomAPI_Face> aFace2(new GeomAPI_Face(aFaceShape2));
264 std::shared_ptr<GeomAPI_Pln> aPln2 = aFace2->getPlane();
266 std::string useOffset2 = string(USE_OFFSET2())->value();
267 if(!useOffset2.empty()) {
268 double anOffset2 = real(OFFSET2())->value();
269 bool reverseOffset2 = boolean(REVERSE_OFFSET2())->value();
271 anOffset2 = -anOffset2;
273 aPln2->translate(aPln2->direction(), anOffset2);
276 std::shared_ptr<GeomAPI_Lin> aLin = aPln1->intersect(aPln2);
277 std::shared_ptr<GeomAPI_Pnt> aPnt1 = aLin->location();
278 std::shared_ptr<GeomAPI_Pnt> aPnt2 = aLin->location();
279 aPnt2->translate(aLin->direction(), defaultAxisSize);
281 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aPnt1, aPnt2);
283 ResultConstructionPtr aConstr = document()->createConstruction(data());
284 aConstr->setInfinite(true);
285 aConstr->setShape(anEdge);
289 void ConstructionPlugin_Axis::execute()
291 AttributeStringPtr aMethodTypeAttr = string(ConstructionPlugin_Axis::METHOD());
292 std::string aMethodType = aMethodTypeAttr->value();
293 if (aMethodType == CREATION_METHOD_BY_TWO_POINTS()) {
294 createAxisByTwoPoints();
295 } else if (aMethodType == CREATION_METHOD_BY_CYLINDRICAL_FACE()) {
296 createAxisByCylindricalFace();
297 } else if (aMethodType == CREATION_METHOD_BY_POINT_AND_DIRECTION()) {
298 createAxisByPointAndDirection();
299 } else if (aMethodType == CREATION_METHOD_BY_DIMENSIONS()) {
300 createAxisByDimensions();
301 } else if(aMethodType == CREATION_METHOD_BY_LINE()) {
303 } else if(aMethodType == CREATION_METHOD_BY_PLANE_AND_POINT()) {
304 createAxisByPlaneAndPoint();
305 } else if(aMethodType == CREATION_METHOD_BY_TWO_PLANES()) {
306 createAxisByTwoPlanes();
310 bool ConstructionPlugin_Axis::customisePresentation(ResultPtr theResult, AISObjectPtr thePrs,
311 std::shared_ptr<GeomAPI_ICustomPrs> theDefaultPrs)
313 bool isCustomized = theDefaultPrs.get() != NULL &&
314 theDefaultPrs->customisePresentation(theResult, thePrs, theDefaultPrs);
316 isCustomized = thePrs->setLineStyle(3) || isCustomized;
317 isCustomized = thePrs->setWidth(2) || isCustomized;