Salome HOME
using a better solution to do compare doubles for shape physical properties
[modules/shaper.git] / src / PrimitivesPlugin / PrimitivesPlugin_Sphere.cpp
1 // Copyright (C) 2017-2024  CEA, EDF
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_Sphere.cpp
21 // Created:     15 Mar 2017
22 // Author:      Clarisse Genrault (CEA)
23
24 #include <PrimitivesPlugin_Sphere.h>
25
26 #include <GeomAPI_ShapeExplorer.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 #include <sstream>
38
39 //=================================================================================================
40 PrimitivesPlugin_Sphere::PrimitivesPlugin_Sphere()
41 {
42 }
43
44 //=================================================================================================
45 void PrimitivesPlugin_Sphere::initAttributes()
46 {
47   // Attention! A fix for 37570 Tuleap issue.
48   // We could have studies with aCenterPoint at the first position (old studies)
49   // and studies with CREATION_METHOD() at the first position (new studies)
50
51   // data for the first mode : by a point and a radius
52   AttributeSelectionPtr aCenterPoint = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
53     (data()->addAttribute(PrimitivesPlugin_Sphere::CENTER_POINT_ID(),
54                           ModelAPI_AttributeSelection::typeId())); // #1 (old studies)
55   if (aCenterPoint->isInitialized()) {
56     // we are opening an old study:
57     // #1 Center Point
58     // #2 Radius
59     // #3 Creation method (initialize now)
60
61     data()->addAttribute(PrimitivesPlugin_Sphere::RADIUS_ID(),
62                          ModelAPI_AttributeDouble::typeId()); // #2 (old studies)
63
64     AttributeStringPtr aMethod = std::dynamic_pointer_cast<ModelAPI_AttributeString>
65       (data()->addAttribute(PrimitivesPlugin_Sphere::CREATION_METHOD(),
66                             ModelAPI_AttributeString::typeId())); // #3
67     aMethod->setValue(CREATION_METHOD_BY_PT_RADIUS());
68   }
69   else {
70     // we are opening a new study or creating Sphere from scratch
71     // #1 Creation method
72     // #2 Center Point
73     // #3 Radius
74
75     data()->addAttribute(PrimitivesPlugin_Sphere::CREATION_METHOD(),
76                          ModelAPI_AttributeString::typeId(),
77                          1); // #1 new studies or from scratch
78
79     aCenterPoint = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
80       (data()->addAttribute(PrimitivesPlugin_Sphere::CENTER_POINT_ID(),
81                             ModelAPI_AttributeSelection::typeId(),
82                             2)); // #2
83
84     // Initialize the center point of the sphere at the origin if the center point is not filled.
85     if (!aCenterPoint->isInitialized()) {
86       ObjectPtr aPointObj = ModelAPI_Session::get()->moduleDocument()
87         ->objectByName(ModelAPI_ResultConstruction::group(), L"Origin");
88       if (aPointObj.get()) {
89         ResultPtr aPointRes = std::dynamic_pointer_cast<ModelAPI_Result>(aPointObj);
90         aCenterPoint->setValue(aPointRes, std::shared_ptr<GeomAPI_Shape>());
91       }
92     }
93
94     data()->addAttribute(PrimitivesPlugin_Sphere::RADIUS_ID(),
95                          ModelAPI_AttributeDouble::typeId(),
96                          3); // #3
97   }
98
99   // data for the second mode : by dimensions
100   data()->addAttribute(PrimitivesPlugin_Sphere::RMIN_ID(), ModelAPI_AttributeDouble::typeId());
101   data()->addAttribute(PrimitivesPlugin_Sphere::RMAX_ID(), ModelAPI_AttributeDouble::typeId());
102   data()->addAttribute(PrimitivesPlugin_Sphere::PHIMIN_ID(), ModelAPI_AttributeDouble::typeId());
103   data()->addAttribute(PrimitivesPlugin_Sphere::PHIMAX_ID(), ModelAPI_AttributeDouble::typeId());
104   data()->addAttribute(PrimitivesPlugin_Sphere::THETAMIN_ID(), ModelAPI_AttributeDouble::typeId());
105   data()->addAttribute(PrimitivesPlugin_Sphere::THETAMAX_ID(), ModelAPI_AttributeDouble::typeId());
106 }
107
108 //=================================================================================================
109 void PrimitivesPlugin_Sphere::execute()
110 {
111   AttributeStringPtr aMethodTypeAttr = string(PrimitivesPlugin_Sphere::CREATION_METHOD());
112   std::string aMethodType = aMethodTypeAttr->value();
113
114   if (aMethodType == CREATION_METHOD_BY_PT_RADIUS())
115     createSphereByPtRadius();
116
117   if (aMethodType == CREATION_METHOD_BY_DIMENSIONS())
118     createShereByDimensions();
119 }
120
121
122 //=================================================================================================
123 void PrimitivesPlugin_Sphere::createSphereByPtRadius()
124 {
125   // Getting point.
126   std::shared_ptr<GeomAPI_Pnt> aCenterPoint;
127   std::shared_ptr<ModelAPI_AttributeSelection> aPointRef =
128     selection(PrimitivesPlugin_Sphere::CENTER_POINT_ID());
129   if (aPointRef.get() != NULL) {
130     GeomShapePtr aShape1 = aPointRef->value();
131     if (!aShape1.get()) {
132       aShape1 = aPointRef->context()->shape();
133     }
134     if (aShape1) {
135         aCenterPoint = GeomAlgoAPI_PointBuilder::point(aShape1);
136     }
137   }
138
139   // Getting radius
140   double aRadius = real(PrimitivesPlugin_Sphere::RADIUS_ID())->value();
141
142   std::shared_ptr<GeomAlgoAPI_Sphere> aSphereAlgo =
143     std::shared_ptr<GeomAlgoAPI_Sphere>(new GeomAlgoAPI_Sphere(aCenterPoint, aRadius));
144
145   // These checks should be made to the GUI for the feature but
146   // the corresponding validator does not exist yet.
147   if (!aSphereAlgo->check()) {
148     setError(aSphereAlgo->getError());
149     return;
150   }
151
152   // Build the sphere
153   aSphereAlgo->build();
154
155   // Check if the creation of the sphere is OK
156   if(!aSphereAlgo->isDone()) {
157     setError(aSphereAlgo->getError());
158     return;
159   }
160   if(!aSphereAlgo->checkValid("Sphere builder")) {
161     setError(aSphereAlgo->getError());
162     return;
163   }
164
165   int aResultIndex = 0;
166   ResultBodyPtr aResultBox = document()->createBody(data(), aResultIndex);
167   loadNamingDS(aSphereAlgo, aResultBox);
168   setResult(aResultBox, aResultIndex);
169 }
170
171 //=================================================================================================
172 void PrimitivesPlugin_Sphere::createShereByDimensions()
173 {
174   // Getting rmin, rmax, phimin, phimax, thetamin et thetamax
175   double aRMin = real(PrimitivesPlugin_Sphere::RMIN_ID())->value();
176   double aRMax = real(PrimitivesPlugin_Sphere::RMAX_ID())->value();
177   double aPhiMin = real(PrimitivesPlugin_Sphere::PHIMIN_ID())->value();
178   double aPhiMax = real(PrimitivesPlugin_Sphere::PHIMAX_ID())->value();
179   double aThetaMin = real(PrimitivesPlugin_Sphere::THETAMIN_ID())->value();
180   double aThetaMax = real(PrimitivesPlugin_Sphere::THETAMAX_ID())->value();
181
182   std::shared_ptr<GeomAlgoAPI_Sphere> aSphereAlgo = std::shared_ptr<GeomAlgoAPI_Sphere>(
183       new GeomAlgoAPI_Sphere(aRMin, aRMax, aPhiMin, aPhiMax, aThetaMin, aThetaMax));
184
185   // These checks should be made to the GUI for the feature but
186   // the corresponding validator does not exist yet.
187   if (!aSphereAlgo->check()) {
188     setError(aSphereAlgo->getError());
189     return;
190   }
191
192   // Build the sphere
193   aSphereAlgo->build();
194
195   // Check if the creation of the sphere is OK
196   if(!aSphereAlgo->isDone()) {
197     // The error is not displayed in a popup window. It must be in the message console.
198     setError(aSphereAlgo->getError());
199     return;
200   }
201   if(!aSphereAlgo->checkValid("Sphere Builder")) {
202     // The error is not displayed in a popup window. It must be in the message console.
203     setError(aSphereAlgo->getError());
204     return;
205   }
206
207   int aResultIndex = 0;
208   ResultBodyPtr aResultBox = document()->createBody(data(), aResultIndex);
209   loadNamingDS(aSphereAlgo, aResultBox);
210   setResult(aResultBox, aResultIndex);
211 }
212
213 //=================================================================================================
214 void PrimitivesPlugin_Sphere::loadNamingDS(std::shared_ptr<GeomAlgoAPI_Sphere> theSphereAlgo,
215                                            std::shared_ptr<ModelAPI_ResultBody> theResultSphere)
216 {
217   // Load the result
218   theResultSphere->store(theSphereAlgo->shape());
219
220   // Prepare the naming
221   theSphereAlgo->prepareNamingFaces();
222
223   // Insert to faces
224   // Naming for faces and edges
225   std::map< std::string, std::shared_ptr<GeomAPI_Shape> > listOfFaces =
226       theSphereAlgo->getCreatedFaces();
227   for (std::map< std::string, std::shared_ptr<GeomAPI_Shape> >::iterator it = listOfFaces.begin();
228        it != listOfFaces.end();
229        ++it)
230   {
231     theResultSphere->generated((*it).second, (*it).first);
232   }
233
234   // Naming vertices
235   GeomAPI_DataMapOfShapeShape aVertices;
236   int anIndex = 1;
237   for (GeomAPI_ShapeExplorer aVertExp(theSphereAlgo->shape(), GeomAPI_Shape::VERTEX);
238        aVertExp.more();
239        aVertExp.next())
240   {
241     if (!aVertices.isBound(aVertExp.current())) {
242       std::ostringstream aStream;
243       aStream<<"Vertex_"<<anIndex++;
244       theResultSphere->generated(aVertExp.current(), aStream.str());
245       aVertices.bind(aVertExp.current(), aVertExp.current());
246     }
247   }
248 }