Salome HOME
Issue #1650: Added option to create axis by line.
[modules/shaper.git] / src / ConstructionPlugin / ConstructionPlugin_Axis.cpp
1 // Copyright (C) 2014-2016 CEA/DEN, EDF R&D
2
3 // File:        ConstructionPlugin_Axis.cpp
4 // Created:     12 Dec 2014
5 // Author:      Vitaly Smetannikov
6
7 // Modified by CEA (delegation to Alyotech) : 29 Mar 2016 
8
9 #include "ConstructionPlugin_Axis.h"
10
11 #include <Config_PropManager.h>
12
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>
19
20 #include <GeomAPI_Edge.h>
21 #include <GeomAPI_Vertex.h>
22 #include <GeomAlgoAPI_EdgeBuilder.h>
23 #include <GeomAlgoAPI_PointBuilder.h>
24
25 #include <math.h>
26
27 #ifdef _DEBUG
28 #include <iostream>
29 #endif
30
31 using namespace std;
32
33 ConstructionPlugin_Axis::ConstructionPlugin_Axis()
34 {
35 }
36
37 void ConstructionPlugin_Axis::initAttributes()
38 {
39   data()->addAttribute(ConstructionPlugin_Axis::METHOD(),
40                        ModelAPI_AttributeString::typeId());
41   
42   // Attributes needed to build the axis using the "two points" method
43   data()->addAttribute(ConstructionPlugin_Axis::POINT_FIRST(),
44                        ModelAPI_AttributeSelection::typeId());
45   data()->addAttribute(ConstructionPlugin_Axis::POINT_SECOND(),
46                        ModelAPI_AttributeSelection::typeId());
47
48   // Attributes needed to build the axis using the "cylindrical face" method"
49   data()->addAttribute(ConstructionPlugin_Axis::CYLINDRICAL_FACE(),
50                        ModelAPI_AttributeSelection::typeId());
51   data()->addAttribute(ConstructionPlugin_Axis::X_DIRECTION(),
52                        ModelAPI_AttributeDouble::typeId());
53   data()->addAttribute(ConstructionPlugin_Axis::Y_DIRECTION(),
54                        ModelAPI_AttributeDouble::typeId());
55   data()->addAttribute(ConstructionPlugin_Axis::Z_DIRECTION(),
56                        ModelAPI_AttributeDouble::typeId());
57   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), 
58       ConstructionPlugin_Axis::X_DIRECTION());
59   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), 
60       ConstructionPlugin_Axis::Y_DIRECTION());
61   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), 
62       ConstructionPlugin_Axis::Z_DIRECTION());
63
64   //Attributes needed to build the axis using the "three dimensions" method
65   data()->addAttribute(ConstructionPlugin_Axis::DX(),
66                        ModelAPI_AttributeDouble::typeId());
67   data()->addAttribute(ConstructionPlugin_Axis::DY(),
68                        ModelAPI_AttributeDouble::typeId());
69   data()->addAttribute(ConstructionPlugin_Axis::DZ(),
70                        ModelAPI_AttributeDouble::typeId());
71
72   /// Attributes for axis by line.
73   data()->addAttribute(LINE(), ModelAPI_AttributeSelection::typeId());
74 }
75
76 void ConstructionPlugin_Axis::createAxisByTwoPoints()
77 {
78   AttributeSelectionPtr aRef1 = data()->selection(ConstructionPlugin_Axis::POINT_FIRST());
79   AttributeSelectionPtr aRef2 = data()->selection(ConstructionPlugin_Axis::POINT_SECOND());
80   if ((aRef1.get() != NULL) && (aRef2.get() != NULL)) {
81     GeomShapePtr aShape1 = aRef1->value();
82     if (!aShape1.get())
83       aShape1 = aRef1->context()->shape();
84     GeomShapePtr aShape2 = aRef2->value();
85     if (!aShape2.get())
86       aShape2 = aRef2->context()->shape();
87     if (aShape1->isVertex() && aShape2->isVertex() && (!aShape1->isEqual(aShape2))) {
88       std::shared_ptr<GeomAPI_Pnt> aStart = GeomAlgoAPI_PointBuilder::point(aShape1);
89       std::shared_ptr<GeomAPI_Pnt> anEnd = GeomAlgoAPI_PointBuilder::point(aShape2);
90       if (aStart->distance(anEnd) > ConstructionPlugin_Axis::MINIMAL_LENGTH()) {
91         std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
92
93         ResultConstructionPtr aConstr = document()->createConstruction(data());
94         aConstr->setInfinite(true);
95         aConstr->setShape(anEdge);
96         setResult(aConstr);
97       }
98     }
99   }
100 }
101
102
103 void ConstructionPlugin_Axis::createAxisByPointAndDirection()
104 {
105   AttributeSelectionPtr aRef1 = data()->selection(ConstructionPlugin_Axis::POINT_FIRST());
106   AttributeDoublePtr aXAttr = data()->real(ConstructionPlugin_Axis::X_DIRECTION());
107   AttributeDoublePtr aYAttr = data()->real(ConstructionPlugin_Axis::Y_DIRECTION());
108   AttributeDoublePtr aZAttr = data()->real(ConstructionPlugin_Axis::Z_DIRECTION());
109   if ((aRef1.get() != NULL) && (aXAttr.get() != NULL) && 
110       (aYAttr.get() != NULL) && (aZAttr.get() != NULL)) {
111     GeomShapePtr aShape1 = aRef1->value();
112     if (!aShape1.get())
113       aShape1 = aRef1->context()->shape();
114
115     std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aXAttr->value(), 
116                                                                aYAttr->value(),
117                                                                aZAttr->value()));
118     if (aShape1->isVertex() && (!aShape1->isEqual(aVertex))) {
119       std::shared_ptr<GeomAPI_Pnt> aStart = GeomAlgoAPI_PointBuilder::point(aShape1);
120       std::shared_ptr<GeomAPI_Pnt> anEnd = aVertex->point();
121       if (aStart->distance(anEnd) > ConstructionPlugin_Axis::MINIMAL_LENGTH()) {
122         std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
123
124         ResultConstructionPtr aConstr = document()->createConstruction(data());
125         aConstr->setInfinite(true);
126         aConstr->setShape(anEdge);
127         setResult(aConstr);
128       }
129     }
130   }
131 }
132
133
134 void ConstructionPlugin_Axis::createAxisByCylindricalFace()
135 {
136     std::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(CYLINDRICAL_FACE())->value();
137      // update arguments due to the selection value
138     if (aSelection && !aSelection->isNull() && aSelection->isFace()) {
139       std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::cylinderAxis(aSelection);
140
141       ResultConstructionPtr aConstr = document()->createConstruction(data());
142       aConstr->setInfinite(true);
143       aConstr->setShape(anEdge);
144       setResult(aConstr);
145     }
146 }
147
148 void ConstructionPlugin_Axis::createAxisByDimensions()
149 {
150   // Start by getting these dimensions
151   double aDX = data()->real(DX())->value();
152   double aDY = data()->real(DY())->value();
153   double aDZ = data()->real(DZ())->value();
154
155   if (fabs(aDX) < MINIMAL_LENGTH()  && fabs(aDY) < MINIMAL_LENGTH() && fabs(aDZ) < MINIMAL_LENGTH()){
156     setError("Axis builder with dimensions  :: all dimensions are null", false);
157     return ;
158   }
159
160   // Make the axis, build the ResultConstructionPtr and write it
161   std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aDX, aDY, aDZ);
162   ResultConstructionPtr aConstr = document()->createConstruction(data());
163   aConstr->setInfinite(true);
164   aConstr->setShape(anEdge);
165   setResult(aConstr);    
166 }
167
168 void ConstructionPlugin_Axis::createAxisByLine()
169 {
170   // Get edge.
171   AttributeSelectionPtr anEdgeSelection = selection(LINE());
172   GeomShapePtr aLineShape = anEdgeSelection->value();
173   if(!aLineShape.get()) {
174     aLineShape = anEdgeSelection->context()->shape();
175   }
176   std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aLineShape));
177
178   ResultConstructionPtr aConstr = document()->createConstruction(data());
179   aConstr->setInfinite(true);
180   aConstr->setShape(anEdge);
181   setResult(aConstr);
182 }
183
184 void ConstructionPlugin_Axis::execute()
185 {
186   AttributeStringPtr aMethodTypeAttr = string(ConstructionPlugin_Axis::METHOD());
187   std::string aMethodType = aMethodTypeAttr->value();
188   if (aMethodType == "AxisByPointsCase") {
189     createAxisByTwoPoints();
190   } else if (aMethodType == "AxisByCylindricalFaceCase") {
191     createAxisByCylindricalFace();
192   } else if (aMethodType == "AxisByPointAndDirection") {
193     createAxisByPointAndDirection();
194   } else if (aMethodType == "AxisByDimensionsCase") {
195     createAxisByDimensions();
196   } else if(aMethodType == CREATION_METHOD_BY_LINE()) {
197     createAxisByLine();
198
199   }
200 }
201
202 bool ConstructionPlugin_Axis::customisePresentation(ResultPtr theResult, AISObjectPtr thePrs,
203   std::shared_ptr<GeomAPI_ICustomPrs> theDefaultPrs)
204 {
205   bool isCustomized = theDefaultPrs.get() != NULL &&
206                       theDefaultPrs->customisePresentation(theResult, thePrs, theDefaultPrs);
207
208   isCustomized = thePrs->setLineStyle(3) || isCustomized;
209   isCustomized = thePrs->setWidth(2) || isCustomized;
210
211   return isCustomized;
212 }