Salome HOME
Merge branch 'master' into cgt/devCEA
[modules/shaper.git] / src / PrimitivesPlugin / PrimitivesPlugin_Cylinder.cpp
1 // Copyright (C) 2014-201x CEA/DEN, EDF R&D
2
3 // File:        PrimitivesPlugin_Cylinder.cpp
4 // Created:     09 Jan 2017
5 // Author:      Clarisse Genrault (CEA)
6
7 #include <PrimitivesPlugin_Cylinder.h>
8
9 #include <GeomAPI_Dir.h>
10 #include <GeomAPI_Edge.h>
11 #include <GeomAPI_Lin.h>
12
13 #include <GeomAlgoAPI_PointBuilder.h>
14
15 #include <ModelAPI_AttributeDouble.h>
16 #include <ModelAPI_AttributeSelection.h>
17 #include <ModelAPI_AttributeString.h>
18 #include <ModelAPI_ResultBody.h>
19 #include <ModelAPI_ResultConstruction.h>
20 #include <ModelAPI_Session.h>
21
22 #include <iostream>
23
24 //=================================================================================================
25 PrimitivesPlugin_Cylinder::PrimitivesPlugin_Cylinder()
26 {
27 }
28
29 //=================================================================================================
30 void PrimitivesPlugin_Cylinder::initAttributes()
31 {
32   data()->addAttribute(PrimitivesPlugin_Cylinder::CREATION_METHOD(),
33                        ModelAPI_AttributeString::typeId());
34
35   data()->addAttribute(PrimitivesPlugin_Cylinder::BASE_POINT_ID(),
36                        ModelAPI_AttributeSelection::typeId());
37   data()->addAttribute(PrimitivesPlugin_Cylinder::AXIS_ID(),
38                        ModelAPI_AttributeSelection::typeId());
39
40   data()->addAttribute(PrimitivesPlugin_Cylinder::RADIUS_ID(),
41                        ModelAPI_AttributeDouble::typeId());
42   data()->addAttribute(PrimitivesPlugin_Cylinder::HEIGHT_ID(),
43                        ModelAPI_AttributeDouble::typeId());
44   data()->addAttribute(PrimitivesPlugin_Cylinder::ANGLE_ID(),
45                        ModelAPI_AttributeDouble::typeId());
46
47   // Initialize the base point of the cylinder at the origin if the base point is not filled.
48   AttributeSelectionPtr aBasePoint = data()->selection(BASE_POINT_ID());
49   if (!aBasePoint->isInitialized()) {
50     ObjectPtr aPointObj = ModelAPI_Session::get()->moduleDocument()
51       ->objectByName(ModelAPI_ResultConstruction::group(), "Origin");
52     if (aPointObj.get()) {
53       ResultPtr aPointRes = std::dynamic_pointer_cast<ModelAPI_Result>(aPointObj);
54       aBasePoint->setValue(aPointRes, std::shared_ptr<GeomAPI_Shape>());
55     }
56   }
57
58   // Initialize the axis at the OZ axis if the axis is not filled.
59   AttributeSelectionPtr anAxis = data()->selection(AXIS_ID());
60   if (!anAxis->isInitialized()) {
61     ObjectPtr anAxisObj = ModelAPI_Session::get()->moduleDocument()
62       ->objectByName(ModelAPI_ResultConstruction::group(), "OZ");
63     if (anAxisObj.get()) {
64       ResultPtr anAxisRes = std::dynamic_pointer_cast<ModelAPI_Result>(anAxisObj);
65       anAxis->setValue(anAxisRes, std::shared_ptr<GeomAPI_Shape>());
66     }
67   }
68 }
69
70 //=================================================================================================
71 void PrimitivesPlugin_Cylinder::execute()
72 {
73   AttributeStringPtr aMethodTypeAttr = string(PrimitivesPlugin_Cylinder::CREATION_METHOD());
74   std::string aMethodType = aMethodTypeAttr->value();
75
76   if (aMethodType == CREATION_METHOD_CYLINDER()) {
77     createCylinder(false);
78   }
79
80   if (aMethodType == CREATION_METHOD_CYLINDER_PORTION()) {
81     createCylinder(true);
82   }
83 }
84
85 //=================================================================================================
86 void PrimitivesPlugin_Cylinder::createCylinder(bool withAngle)
87 {
88   // Getting point.
89   std::shared_ptr<GeomAPI_Pnt> aBasePoint;
90   std::shared_ptr<ModelAPI_AttributeSelection> aPointRef =
91     selection(PrimitivesPlugin_Cylinder::BASE_POINT_ID());
92   if (aPointRef.get() != NULL) {
93     GeomShapePtr aShape1 = aPointRef->value();
94     if (!aShape1.get()) {
95       aShape1 = aPointRef->context()->shape();
96     }
97     if (aShape1) {
98       aBasePoint = GeomAlgoAPI_PointBuilder::point(aShape1);
99     }
100   }
101
102   // Getting axis.
103   std::shared_ptr<GeomAPI_Ax2> anAxis;
104   std::shared_ptr<GeomAPI_Edge> anEdge;
105   std::shared_ptr<ModelAPI_AttributeSelection> anEdgeRef =
106     selection(PrimitivesPlugin_Cylinder::AXIS_ID());
107   if(anEdgeRef && anEdgeRef->value() && anEdgeRef->value()->isEdge()) {
108     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anEdgeRef->value()));
109   } else if (anEdgeRef && !anEdgeRef->value() && anEdgeRef->context() &&
110              anEdgeRef->context()->shape() && anEdgeRef->context()->shape()->isEdge()) {
111     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anEdgeRef->context()->shape()));
112   }
113   if(anEdge) {
114     anAxis = std::shared_ptr<GeomAPI_Ax2>(new GeomAPI_Ax2(aBasePoint,
115                                                           anEdge->line()->direction()));
116   }
117
118   // Getting radius and height
119   double aRadius = real(PrimitivesPlugin_Cylinder::RADIUS_ID())->value();
120   double aHeight = real(PrimitivesPlugin_Cylinder::HEIGHT_ID())->value();
121
122   std::shared_ptr<GeomAlgoAPI_Cylinder> aCylinderAlgo;
123   if (withAngle) {
124     // Getting angle
125     double anAngle = real(PrimitivesPlugin_Cylinder::ANGLE_ID())->value();
126     aCylinderAlgo =
127       std::shared_ptr<GeomAlgoAPI_Cylinder>(new GeomAlgoAPI_Cylinder(anAxis,
128                                                                      aRadius, aHeight,
129                                                                      anAngle));
130   } else {
131     aCylinderAlgo =
132       std::shared_ptr<GeomAlgoAPI_Cylinder>(new GeomAlgoAPI_Cylinder(anAxis,
133                                                                      aRadius, aHeight));
134   }
135
136   // These checks should be made to the GUI for the feature but
137   // the corresponding validator does not exist yet.
138   if (!aCylinderAlgo->check()) {
139     setError(aCylinderAlgo->getError(), false);
140     return;
141   }
142
143   // Build the cylinder
144   aCylinderAlgo->build();
145
146   // Check if the creation of the cylinder
147   if(!aCylinderAlgo->isDone()) {
148     // The error is not displayed in a popup window. It must be in the message console.
149     setError(aCylinderAlgo->getError(), false);
150     return;
151   }
152   if(!aCylinderAlgo->checkValid("Cylinder builder")) {
153     // The error is not displayed in a popup window. It must be in the message console.
154     setError(aCylinderAlgo->getError(), false);
155     return;
156   }
157
158   int aResultIndex = 0;
159   ResultBodyPtr aResultBox = document()->createBody(data(), aResultIndex);
160   loadNamingDS(aCylinderAlgo, aResultBox);
161   setResult(aResultBox, aResultIndex);
162 }
163
164 //=================================================================================================
165 void PrimitivesPlugin_Cylinder::loadNamingDS(std::shared_ptr<GeomAlgoAPI_Cylinder> theCylinderAlgo,
166                                              std::shared_ptr<ModelAPI_ResultBody> theResultCylinder)
167 {
168   // Load the result
169   theResultCylinder->store(theCylinderAlgo->shape());
170
171   // Prepare the naming
172   theCylinderAlgo->prepareNamingFaces();
173
174   // Insert to faces
175   int num = 1;
176   std::map< std::string, std::shared_ptr<GeomAPI_Shape> > listOfFaces =
177     theCylinderAlgo->getCreatedFaces();
178   for (std::map< std::string, std::shared_ptr<GeomAPI_Shape> >::iterator
179        it=listOfFaces.begin(); it!=listOfFaces.end(); ++it) {
180     std::shared_ptr<GeomAPI_Shape> aFace = (*it).second;
181     theResultCylinder->generated(aFace, (*it).first, num++);
182   }
183 }