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