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