1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include "ConstructionPlugin_Axis.h"
23 #include <Config_PropManager.h>
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>
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 <GeomAlgoAPI_EdgeBuilder.h>
39 #include <GeomAlgoAPI_PointBuilder.h>
47 static const double defaultAxisSize = 100;
49 ConstructionPlugin_Axis::ConstructionPlugin_Axis()
53 void ConstructionPlugin_Axis::initAttributes()
55 data()->addAttribute(ConstructionPlugin_Axis::METHOD(),
56 ModelAPI_AttributeString::typeId());
58 // Attributes needed to build the axis using the "two points" method
59 data()->addAttribute(ConstructionPlugin_Axis::POINT_FIRST(),
60 ModelAPI_AttributeSelection::typeId());
61 data()->addAttribute(ConstructionPlugin_Axis::POINT_SECOND(),
62 ModelAPI_AttributeSelection::typeId());
64 // Attributes needed to build the axis using the "cylindrical face" method"
65 data()->addAttribute(ConstructionPlugin_Axis::CYLINDRICAL_FACE(),
66 ModelAPI_AttributeSelection::typeId());
67 data()->addAttribute(ConstructionPlugin_Axis::X_DIRECTION(),
68 ModelAPI_AttributeDouble::typeId());
69 data()->addAttribute(ConstructionPlugin_Axis::Y_DIRECTION(),
70 ModelAPI_AttributeDouble::typeId());
71 data()->addAttribute(ConstructionPlugin_Axis::Z_DIRECTION(),
72 ModelAPI_AttributeDouble::typeId());
73 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
74 ConstructionPlugin_Axis::X_DIRECTION());
75 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
76 ConstructionPlugin_Axis::Y_DIRECTION());
77 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
78 ConstructionPlugin_Axis::Z_DIRECTION());
80 //Attributes needed to build the axis using the "three dimensions" method
81 data()->addAttribute(ConstructionPlugin_Axis::DX(),
82 ModelAPI_AttributeDouble::typeId());
83 data()->addAttribute(ConstructionPlugin_Axis::DY(),
84 ModelAPI_AttributeDouble::typeId());
85 data()->addAttribute(ConstructionPlugin_Axis::DZ(),
86 ModelAPI_AttributeDouble::typeId());
88 /// Attributes for axis by line.
89 data()->addAttribute(LINE(), ModelAPI_AttributeSelection::typeId());
91 /// Attributes for axis by plane and point.
92 data()->addAttribute(PLANE(), ModelAPI_AttributeSelection::typeId());
93 data()->addAttribute(POINT(), ModelAPI_AttributeSelection::typeId());
95 /// Attributes for axis by two planes.
96 data()->addAttribute(PLANE1(), ModelAPI_AttributeSelection::typeId());
97 data()->addAttribute(USE_OFFSET1(), ModelAPI_AttributeString::typeId());
98 data()->addAttribute(OFFSET1(), ModelAPI_AttributeDouble::typeId());
99 data()->addAttribute(REVERSE_OFFSET1(), ModelAPI_AttributeBoolean::typeId());
100 data()->addAttribute(PLANE2(), ModelAPI_AttributeSelection::typeId());
101 data()->addAttribute(USE_OFFSET2(), ModelAPI_AttributeString::typeId());
102 data()->addAttribute(OFFSET2(), ModelAPI_AttributeDouble::typeId());
103 data()->addAttribute(REVERSE_OFFSET2(), ModelAPI_AttributeBoolean::typeId());
106 void ConstructionPlugin_Axis::createAxisByTwoPoints()
108 AttributeSelectionPtr aRef1 = data()->selection(ConstructionPlugin_Axis::POINT_FIRST());
109 AttributeSelectionPtr aRef2 = data()->selection(ConstructionPlugin_Axis::POINT_SECOND());
110 if ((aRef1.get() != NULL) && (aRef2.get() != NULL)) {
111 GeomShapePtr aShape1 = aRef1->value();
113 aShape1 = aRef1->context()->shape();
114 GeomShapePtr aShape2 = aRef2->value();
116 aShape2 = aRef2->context()->shape();
117 if (aShape1->isVertex() && aShape2->isVertex() && (!aShape1->isEqual(aShape2))) {
118 std::shared_ptr<GeomAPI_Pnt> aStart = GeomAlgoAPI_PointBuilder::point(aShape1);
119 std::shared_ptr<GeomAPI_Pnt> anEnd = GeomAlgoAPI_PointBuilder::point(aShape2);
120 if (aStart->distance(anEnd) > ConstructionPlugin_Axis::MINIMAL_LENGTH()) {
121 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
123 ResultConstructionPtr aConstr = document()->createConstruction(data());
124 aConstr->setInfinite(true);
125 aConstr->setShape(anEdge);
133 void ConstructionPlugin_Axis::createAxisByPointAndDirection()
135 AttributeSelectionPtr aRef1 = data()->selection(ConstructionPlugin_Axis::POINT_FIRST());
136 AttributeDoublePtr aXAttr = data()->real(ConstructionPlugin_Axis::X_DIRECTION());
137 AttributeDoublePtr aYAttr = data()->real(ConstructionPlugin_Axis::Y_DIRECTION());
138 AttributeDoublePtr aZAttr = data()->real(ConstructionPlugin_Axis::Z_DIRECTION());
139 if ((aRef1.get() != NULL) && (aXAttr.get() != NULL) &&
140 (aYAttr.get() != NULL) && (aZAttr.get() != NULL)) {
141 GeomShapePtr aShape1 = aRef1->value();
143 aShape1 = aRef1->context()->shape();
145 std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aXAttr->value(),
148 if (aShape1->isVertex() && (!aShape1->isEqual(aVertex))) {
149 std::shared_ptr<GeomAPI_Pnt> aStart = GeomAlgoAPI_PointBuilder::point(aShape1);
150 std::shared_ptr<GeomAPI_Pnt> anEnd = aVertex->point();
151 if (aStart->distance(anEnd) > ConstructionPlugin_Axis::MINIMAL_LENGTH()) {
152 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
154 ResultConstructionPtr aConstr = document()->createConstruction(data());
155 aConstr->setInfinite(true);
156 aConstr->setShape(anEdge);
164 void ConstructionPlugin_Axis::createAxisByCylindricalFace()
166 std::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(CYLINDRICAL_FACE())->value();
167 // update arguments due to the selection value
169 if (!aSelection.get() || aSelection->isNull()) {
173 if (aSelection->isCompound()) {
174 GeomAPI_ShapeIterator anIt(aSelection);
175 aSelection = anIt.current();
178 if (aSelection->isFace()) {
179 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::cylinderAxis(aSelection);
181 ResultConstructionPtr aConstr = document()->createConstruction(data());
182 aConstr->setInfinite(true);
183 aConstr->setShape(anEdge);
188 void ConstructionPlugin_Axis::createAxisByDimensions()
190 // Start by getting these dimensions
191 double aDX = data()->real(DX())->value();
192 double aDY = data()->real(DY())->value();
193 double aDZ = data()->real(DZ())->value();
195 if (fabs(aDX) < MINIMAL_LENGTH() && fabs(aDY) < MINIMAL_LENGTH() &&
196 fabs(aDZ) < MINIMAL_LENGTH()) {
197 setError("Axis builder with dimensions :: all dimensions are null", false);
201 // Make the axis, build the ResultConstructionPtr and write it
202 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aDX, aDY, aDZ);
203 ResultConstructionPtr aConstr = document()->createConstruction(data());
204 aConstr->setInfinite(true);
205 aConstr->setShape(anEdge);
209 void ConstructionPlugin_Axis::createAxisByLine()
212 AttributeSelectionPtr anEdgeSelection = selection(LINE());
213 GeomShapePtr aLineShape = anEdgeSelection->value();
214 if(!aLineShape.get()) {
215 aLineShape = anEdgeSelection->context()->shape();
218 if (aLineShape->isEdge()) {
219 anEdge = aLineShape->edge();
221 else if (aLineShape->isCompound()) {
222 GeomAPI_ShapeIterator anIt(aLineShape);
223 anEdge = anIt.current()->edge();
226 ResultConstructionPtr aConstr = document()->createConstruction(data());
227 aConstr->setInfinite(true);
228 aConstr->setShape(anEdge);
232 void ConstructionPlugin_Axis::createAxisByPlaneAndPoint()
235 AttributeSelectionPtr aFaceSelection = selection(PLANE());
236 GeomShapePtr aFaceShape = aFaceSelection->value();
237 if(!aFaceShape.get()) {
238 aFaceShape = aFaceSelection->context()->shape();
241 if (aFaceShape->isFace()) {
242 aFace = aFaceShape->face();
244 else if (aFaceShape->isCompound()) {
245 GeomAPI_ShapeIterator anIt(aFaceShape);
246 aFace = anIt.current()->face();
248 std::shared_ptr<GeomAPI_Pln> aPln = aFace->getPlane();
251 AttributeSelectionPtr aPointSelection = selection(POINT());
252 GeomShapePtr aPointShape = aPointSelection->value();
253 if(!aPointShape.get()) {
254 aPointShape = aPointSelection->context()->shape();
256 std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aPointShape));
257 std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
259 std::shared_ptr<GeomAPI_Pnt> aProjPnt = aPln->project(aPnt);
261 if(aProjPnt->isEqual(aPnt)) {
262 aPnt->translate(aPln->direction(), defaultAxisSize);
265 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aPnt, aProjPnt);
267 ResultConstructionPtr aConstr = document()->createConstruction(data());
268 aConstr->setInfinite(true);
269 aConstr->setShape(anEdge);
273 void ConstructionPlugin_Axis::createAxisByTwoPlanes()
276 AttributeSelectionPtr aFaceSelection1 = selection(PLANE1());
277 GeomShapePtr aFaceShape1 = aFaceSelection1->value();
278 if(!aFaceShape1.get()) {
279 aFaceShape1 = aFaceSelection1->context()->shape();
281 std::shared_ptr<GeomAPI_Face> aFace1;
282 if (aFaceShape1->isFace()) {
283 aFace1 = aFaceShape1->face();
285 else if (aFaceShape1->isCompound()) {
286 GeomAPI_ShapeIterator anIt(aFaceShape1);
287 aFace1 = anIt.current()->face();
289 std::shared_ptr<GeomAPI_Pln> aPln1 = aFace1->getPlane();
291 std::string useOffset1 = string(USE_OFFSET1())->value();
292 if(!useOffset1.empty()) {
293 double anOffset1 = real(OFFSET1())->value();
294 bool reverseOffset1 = boolean(REVERSE_OFFSET1())->value();
296 anOffset1 = -anOffset1;
298 aPln1->translate(aPln1->direction(), anOffset1);
302 AttributeSelectionPtr aFaceSelection2 = selection(PLANE2());
303 GeomShapePtr aFaceShape2 = aFaceSelection2->value();
304 if(!aFaceShape2.get()) {
305 aFaceShape2 = aFaceSelection2->context()->shape();
307 std::shared_ptr<GeomAPI_Face> aFace2;
308 if (aFaceShape2->isFace()) {
309 aFace2 = aFaceShape2->face();
311 else if (aFaceShape2->isCompound()) {
312 GeomAPI_ShapeIterator anIt(aFaceShape2);
313 aFace2 = anIt.current()->face();
315 std::shared_ptr<GeomAPI_Pln> aPln2 = aFace2->getPlane();
317 std::string useOffset2 = string(USE_OFFSET2())->value();
318 if(!useOffset2.empty()) {
319 double anOffset2 = real(OFFSET2())->value();
320 bool reverseOffset2 = boolean(REVERSE_OFFSET2())->value();
322 anOffset2 = -anOffset2;
324 aPln2->translate(aPln2->direction(), anOffset2);
327 std::shared_ptr<GeomAPI_Lin> aLin = aPln1->intersect(aPln2);
328 std::shared_ptr<GeomAPI_Pnt> aPnt1 = aLin->location();
329 std::shared_ptr<GeomAPI_Pnt> aPnt2 = aLin->location();
330 aPnt2->translate(aLin->direction(), defaultAxisSize);
332 std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aPnt1, aPnt2);
334 ResultConstructionPtr aConstr = document()->createConstruction(data());
335 aConstr->setInfinite(true);
336 aConstr->setShape(anEdge);
340 void ConstructionPlugin_Axis::execute()
342 AttributeStringPtr aMethodTypeAttr = string(ConstructionPlugin_Axis::METHOD());
343 std::string aMethodType = aMethodTypeAttr->value();
344 if (aMethodType == CREATION_METHOD_BY_TWO_POINTS()) {
345 createAxisByTwoPoints();
346 } else if (aMethodType == CREATION_METHOD_BY_CYLINDRICAL_FACE()) {
347 createAxisByCylindricalFace();
348 } else if (aMethodType == CREATION_METHOD_BY_POINT_AND_DIRECTION()) {
349 createAxisByPointAndDirection();
350 } else if (aMethodType == CREATION_METHOD_BY_DIMENSIONS()) {
351 createAxisByDimensions();
352 } else if(aMethodType == CREATION_METHOD_BY_LINE()) {
354 } else if(aMethodType == CREATION_METHOD_BY_PLANE_AND_POINT()) {
355 createAxisByPlaneAndPoint();
356 } else if(aMethodType == CREATION_METHOD_BY_TWO_PLANES()) {
357 createAxisByTwoPlanes();
361 bool ConstructionPlugin_Axis::customisePresentation(ResultPtr theResult, AISObjectPtr thePrs,
362 std::shared_ptr<GeomAPI_ICustomPrs> theDefaultPrs)
364 bool isCustomized = theDefaultPrs.get() != NULL &&
365 theDefaultPrs->customisePresentation(theResult, thePrs, theDefaultPrs);
367 isCustomized = thePrs->setLineStyle(3) || isCustomized;
368 isCustomized = thePrs->setWidth(2) || isCustomized;