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_AttributeSelection.h>
14 #include <ModelAPI_ResultConstruction.h>
15 #include <ModelAPI_AttributeString.h>
16 #include <ModelAPI_AttributeDouble.h>
17 #include <ModelAPI_Session.h>
18 #include <ModelAPI_Validator.h>
20 #include <GeomAPI_Edge.h>
21 #include <GeomAPI_Pln.h>
22 #include <GeomAPI_Vertex.h>
23 #include <GeomAlgoAPI_EdgeBuilder.h>
24 #include <GeomAlgoAPI_PointBuilder.h>
34 ConstructionPlugin_Axis::ConstructionPlugin_Axis()
38 void ConstructionPlugin_Axis::initAttributes()
40 data()->addAttribute(ConstructionPlugin_Axis::METHOD(),
41 ModelAPI_AttributeString::typeId());
43 // Attributes needed to build the axis using the "two points" method
44 data()->addAttribute(ConstructionPlugin_Axis::POINT_FIRST(),
45 ModelAPI_AttributeSelection::typeId());
46 data()->addAttribute(ConstructionPlugin_Axis::POINT_SECOND(),
47 ModelAPI_AttributeSelection::typeId());
49 // Attributes needed to build the axis using the "cylindrical face" method"
50 data()->addAttribute(ConstructionPlugin_Axis::CYLINDRICAL_FACE(),
51 ModelAPI_AttributeSelection::typeId());
52 data()->addAttribute(ConstructionPlugin_Axis::X_DIRECTION(),
53 ModelAPI_AttributeDouble::typeId());
54 data()->addAttribute(ConstructionPlugin_Axis::Y_DIRECTION(),
55 ModelAPI_AttributeDouble::typeId());
56 data()->addAttribute(ConstructionPlugin_Axis::Z_DIRECTION(),
57 ModelAPI_AttributeDouble::typeId());
58 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
59 ConstructionPlugin_Axis::X_DIRECTION());
60 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
61 ConstructionPlugin_Axis::Y_DIRECTION());
62 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
63 ConstructionPlugin_Axis::Z_DIRECTION());
65 //Attributes needed to build the axis using the "three dimensions" method
66 data()->addAttribute(ConstructionPlugin_Axis::DX(),
67 ModelAPI_AttributeDouble::typeId());
68 data()->addAttribute(ConstructionPlugin_Axis::DY(),
69 ModelAPI_AttributeDouble::typeId());
70 data()->addAttribute(ConstructionPlugin_Axis::DZ(),
71 ModelAPI_AttributeDouble::typeId());
73 /// Attributes for axis by line.
74 data()->addAttribute(LINE(), ModelAPI_AttributeSelection::typeId());
76 /// Attributes for axis by plane and point.
77 data()->addAttribute(PLANE(), ModelAPI_AttributeSelection::typeId());
78 data()->addAttribute(POINT(), ModelAPI_AttributeSelection::typeId());
81 void ConstructionPlugin_Axis::createAxisByTwoPoints()
83 AttributeSelectionPtr aRef1 = data()->selection(ConstructionPlugin_Axis::POINT_FIRST());
84 AttributeSelectionPtr aRef2 = data()->selection(ConstructionPlugin_Axis::POINT_SECOND());
85 if ((aRef1.get() != NULL) && (aRef2.get() != NULL)) {
86 GeomShapePtr aShape1 = aRef1->value();
88 aShape1 = aRef1->context()->shape();
89 GeomShapePtr aShape2 = aRef2->value();
91 aShape2 = aRef2->context()->shape();
92 if (aShape1->isVertex() && aShape2->isVertex() && (!aShape1->isEqual(aShape2))) {
93 std::shared_ptr<GeomAPI_Pnt> aStart = GeomAlgoAPI_PointBuilder::point(aShape1);
94 std::shared_ptr<GeomAPI_Pnt> anEnd = GeomAlgoAPI_PointBuilder::point(aShape2);
95 if (aStart->distance(anEnd) > ConstructionPlugin_Axis::MINIMAL_LENGTH()) {
96 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
98 ResultConstructionPtr aConstr = document()->createConstruction(data());
99 aConstr->setInfinite(true);
100 aConstr->setShape(anEdge);
108 void ConstructionPlugin_Axis::createAxisByPointAndDirection()
110 AttributeSelectionPtr aRef1 = data()->selection(ConstructionPlugin_Axis::POINT_FIRST());
111 AttributeDoublePtr aXAttr = data()->real(ConstructionPlugin_Axis::X_DIRECTION());
112 AttributeDoublePtr aYAttr = data()->real(ConstructionPlugin_Axis::Y_DIRECTION());
113 AttributeDoublePtr aZAttr = data()->real(ConstructionPlugin_Axis::Z_DIRECTION());
114 if ((aRef1.get() != NULL) && (aXAttr.get() != NULL) &&
115 (aYAttr.get() != NULL) && (aZAttr.get() != NULL)) {
116 GeomShapePtr aShape1 = aRef1->value();
118 aShape1 = aRef1->context()->shape();
120 std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aXAttr->value(),
123 if (aShape1->isVertex() && (!aShape1->isEqual(aVertex))) {
124 std::shared_ptr<GeomAPI_Pnt> aStart = GeomAlgoAPI_PointBuilder::point(aShape1);
125 std::shared_ptr<GeomAPI_Pnt> anEnd = aVertex->point();
126 if (aStart->distance(anEnd) > ConstructionPlugin_Axis::MINIMAL_LENGTH()) {
127 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
129 ResultConstructionPtr aConstr = document()->createConstruction(data());
130 aConstr->setInfinite(true);
131 aConstr->setShape(anEdge);
139 void ConstructionPlugin_Axis::createAxisByCylindricalFace()
141 std::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(CYLINDRICAL_FACE())->value();
142 // update arguments due to the selection value
143 if (aSelection && !aSelection->isNull() && aSelection->isFace()) {
144 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::cylinderAxis(aSelection);
146 ResultConstructionPtr aConstr = document()->createConstruction(data());
147 aConstr->setInfinite(true);
148 aConstr->setShape(anEdge);
153 void ConstructionPlugin_Axis::createAxisByDimensions()
155 // Start by getting these dimensions
156 double aDX = data()->real(DX())->value();
157 double aDY = data()->real(DY())->value();
158 double aDZ = data()->real(DZ())->value();
160 if (fabs(aDX) < MINIMAL_LENGTH() && fabs(aDY) < MINIMAL_LENGTH() && fabs(aDZ) < MINIMAL_LENGTH()){
161 setError("Axis builder with dimensions :: all dimensions are null", false);
165 // Make the axis, build the ResultConstructionPtr and write it
166 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aDX, aDY, aDZ);
167 ResultConstructionPtr aConstr = document()->createConstruction(data());
168 aConstr->setInfinite(true);
169 aConstr->setShape(anEdge);
173 void ConstructionPlugin_Axis::createAxisByLine()
176 AttributeSelectionPtr anEdgeSelection = selection(LINE());
177 GeomShapePtr aLineShape = anEdgeSelection->value();
178 if(!aLineShape.get()) {
179 aLineShape = anEdgeSelection->context()->shape();
181 std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aLineShape));
183 ResultConstructionPtr aConstr = document()->createConstruction(data());
184 aConstr->setInfinite(true);
185 aConstr->setShape(anEdge);
189 void ConstructionPlugin_Axis::createAxisByPlaneAndPoint()
192 AttributeSelectionPtr aFaceSelection = selection(PLANE());
193 GeomShapePtr aFaceShape = aFaceSelection->value();
194 if(!aFaceShape.get()) {
195 aFaceShape = aFaceSelection->context()->shape();
197 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(aFaceShape));
198 std::shared_ptr<GeomAPI_Pln> aPln = aFace->getPlane();
201 AttributeSelectionPtr aPointSelection = selection(POINT());
202 GeomShapePtr aPointShape = aPointSelection->value();
203 if(!aPointShape.get()) {
204 aPointShape = aPointSelection->context()->shape();
206 std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aPointShape));
207 std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
209 std::shared_ptr<GeomAPI_Pnt> aProjPnt = aPln->project(aPnt);
211 if(aProjPnt->isEqual(aPnt)) {
212 aPnt->translate(aPln->direction(), 10);
215 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aProjPnt, aPnt);
217 ResultConstructionPtr aConstr = document()->createConstruction(data());
218 aConstr->setInfinite(true);
219 aConstr->setShape(anEdge);
223 void ConstructionPlugin_Axis::execute()
225 AttributeStringPtr aMethodTypeAttr = string(ConstructionPlugin_Axis::METHOD());
226 std::string aMethodType = aMethodTypeAttr->value();
227 if (aMethodType == "AxisByPointsCase") {
228 createAxisByTwoPoints();
229 } else if (aMethodType == "AxisByCylindricalFaceCase") {
230 createAxisByCylindricalFace();
231 } else if (aMethodType == "AxisByPointAndDirection") {
232 createAxisByPointAndDirection();
233 } else if (aMethodType == "AxisByDimensionsCase") {
234 createAxisByDimensions();
235 } else if(aMethodType == CREATION_METHOD_BY_LINE()) {
237 } else if(aMethodType == CREATION_METHOD_BY_PLANE_AND_POINT()) {
238 createAxisByPlaneAndPoint();
242 bool ConstructionPlugin_Axis::customisePresentation(ResultPtr theResult, AISObjectPtr thePrs,
243 std::shared_ptr<GeomAPI_ICustomPrs> theDefaultPrs)
245 bool isCustomized = theDefaultPrs.get() != NULL &&
246 theDefaultPrs->customisePresentation(theResult, thePrs, theDefaultPrs);
248 isCustomized = thePrs->setLineStyle(3) || isCustomized;
249 isCustomized = thePrs->setWidth(2) || isCustomized;