Salome HOME
Fix for the issue #2753 : error when dump/load script
[modules/shaper.git] / src / PrimitivesPlugin / PrimitivesPlugin_Cone.cpp
1 // Copyright (C) 2014-201x CEA/DEN, EDF R&D
2
3 // File:        PrimitivesPlugin_Cone.cpp
4 // Created:     17 Mar 2017
5 // Author:      Clarisse Genrault (CEA)
6
7 #include <PrimitivesPlugin_Cone.h>
8
9 #include <GeomAPI_Edge.h>
10 #include <GeomAPI_Lin.h>
11 #include <GeomAPI_ShapeExplorer.h>
12 #include <GeomAPI_ShapeIterator.h>
13
14 #include <GeomAlgoAPI_PointBuilder.h>
15
16 #include <ModelAPI_AttributeDouble.h>
17 #include <ModelAPI_AttributeSelection.h>
18 #include <ModelAPI_ResultBody.h>
19 #include <ModelAPI_ResultConstruction.h>
20 #include <ModelAPI_Session.h>
21
22 #include <sstream>
23
24 //=================================================================================================
25 PrimitivesPlugin_Cone::PrimitivesPlugin_Cone()
26 {
27 }
28
29 //=================================================================================================
30 void PrimitivesPlugin_Cone::initAttributes()
31 {
32   data()->addAttribute(PrimitivesPlugin_Cone::BASE_POINT_ID(),
33                        ModelAPI_AttributeSelection::typeId());
34   data()->addAttribute(PrimitivesPlugin_Cone::AXIS_ID(),
35                        ModelAPI_AttributeSelection::typeId());
36
37   data()->addAttribute(PrimitivesPlugin_Cone::BASE_RADIUS_ID(),
38                        ModelAPI_AttributeDouble::typeId());
39   data()->addAttribute(PrimitivesPlugin_Cone::TOP_RADIUS_ID(),
40                        ModelAPI_AttributeDouble::typeId());
41   data()->addAttribute(PrimitivesPlugin_Cone::HEIGHT_ID(),
42                        ModelAPI_AttributeDouble::typeId());
43
44   // Initialize the base point of the cone at the origin if the base point is not filled.
45   AttributeSelectionPtr aCenterPoint =
46     data()->selection(PrimitivesPlugin_Cone::BASE_POINT_ID());
47   if (!aCenterPoint->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       aCenterPoint->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(PrimitivesPlugin_Cone::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_Cone::execute()
70 {
71   // Getting base point.
72   std::shared_ptr<GeomAPI_Pnt> aBasePoint;
73   std::shared_ptr<ModelAPI_AttributeSelection> aPointRef =
74     selection(PrimitivesPlugin_Cone::BASE_POINT_ID());
75   if (aPointRef.get() != NULL) {
76     GeomShapePtr aShape1 = aPointRef->value();
77     if (!aShape1.get()) {
78       aShape1 = aPointRef->context()->shape();
79     }
80     if (aShape1) {
81         aBasePoint = GeomAlgoAPI_PointBuilder::point(aShape1);
82     }
83   }
84
85   // Getting axis.
86   static const std::string aSelectionError = "Error: The axis shape selection is bad.";
87   std::shared_ptr<ModelAPI_AttributeSelection> anEdgeRef = selection(AXIS_ID());
88   GeomShapePtr aShape = anEdgeRef->value();
89   if (!aShape.get()) {
90     if (anEdgeRef->context().get()) {
91       aShape = anEdgeRef->context()->shape();
92     }
93   }
94   if (!aShape.get()) {
95     setError(aSelectionError);
96     return;
97   }
98   std::shared_ptr<GeomAPI_Edge> anEdge;
99   if (aShape->isEdge())
100   {
101     anEdge = aShape->edge();
102   }
103   else if (aShape->isCompound())
104   {
105     GeomAPI_ShapeIterator anIt(aShape);
106     anEdge = anIt.current()->edge();
107   }
108   else
109   {
110     setError(aSelectionError);
111     return;
112   }
113
114   if (!anEdge.get())
115   {
116     setError(aSelectionError);
117     return;
118   }
119
120   std::shared_ptr<GeomAPI_Ax2> anAxis(new GeomAPI_Ax2(aBasePoint,
121                                                       anEdge->line()->direction()));
122
123   // Getting base radius, top radius and height
124   double aBaseRadius = real(PrimitivesPlugin_Cone::BASE_RADIUS_ID())->value();
125   double aTopRadius = real(PrimitivesPlugin_Cone::TOP_RADIUS_ID())->value();
126   double aHeight = real(PrimitivesPlugin_Cone::HEIGHT_ID())->value();
127
128   std::shared_ptr<GeomAlgoAPI_Cone> aConeAlgo =
129     std::shared_ptr<GeomAlgoAPI_Cone>(new GeomAlgoAPI_Cone(anAxis,
130                                                            aBaseRadius,
131                                                            aTopRadius,
132                                                            aHeight));
133
134   // These checks should be made to the GUI for the feature but
135   // the corresponding validator does not exist yet.
136   if (!aConeAlgo->check()) {
137     setError(aConeAlgo->getError());
138     return;
139   }
140
141   // Build the sphere
142   aConeAlgo->build();
143
144   // Check if the creation of the cylinder
145   if(!aConeAlgo->isDone()) {
146     setError(aConeAlgo->getError());
147     return;
148   }
149   if(!aConeAlgo->checkValid("Cone builder")) {
150     setError(aConeAlgo->getError());
151     return;
152   }
153
154   int aResultIndex = 0;
155   ResultBodyPtr aResultBox = document()->createBody(data(), aResultIndex);
156   loadNamingDS(aConeAlgo, aResultBox);
157   setResult(aResultBox, aResultIndex);
158 }
159
160 //=================================================================================================
161 void PrimitivesPlugin_Cone::loadNamingDS(std::shared_ptr<GeomAlgoAPI_Cone> theConeAlgo,
162                                          std::shared_ptr<ModelAPI_ResultBody> theResultCone)
163 {
164   // Load the result
165   theResultCone->store(theConeAlgo->shape());
166
167   // Prepare the naming
168   theConeAlgo->prepareNamingFaces();
169
170   // Insert to faces
171   std::map< std::string, std::shared_ptr<GeomAPI_Shape> > listOfFaces =
172       theConeAlgo->getCreatedFaces();
173   int nbFaces = 0;
174   for (std::map< std::string, std::shared_ptr<GeomAPI_Shape> >::iterator
175        it=listOfFaces.begin(); it!=listOfFaces.end(); ++it) {
176     theResultCone->generated((*it).second, (*it).first);
177     nbFaces++;
178   }
179
180   if (nbFaces == 2) {
181     // Naming vertices
182     GeomAPI_DataMapOfShapeShape aVertices;
183     int anIndex = 1;
184     for (GeomAPI_ShapeExplorer aVertExp(theConeAlgo->shape(), GeomAPI_Shape::VERTEX);
185          aVertExp.more();
186          aVertExp.next())
187     {
188       if (!aVertices.isBound(aVertExp.current())) {
189         std::ostringstream aStream;
190         aStream<<"Vertex_"<<anIndex++;
191         theResultCone->generated(aVertExp.current(), aStream.str());
192         aVertices.bind(aVertExp.current(), aVertExp.current());
193       }
194     }
195   }
196 }