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