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