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