Salome HOME
bec5a5d647eb866c59e43dbc94baf347d840de5d
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_InspectBoundingBox.cpp
1 // Copyright (C) 2018-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 "FeaturesPlugin_InspectBoundingBox.h"
21
22 #include <Config_PropManager.h>
23
24 #include <FeaturesPlugin_BoundingBox.h>
25
26 #include <GeomAlgoAPI_BoundingBox.h>
27
28 #include <ModelAPI_AttributeSelection.h>
29 #include <ModelAPI_AttributeDoubleArray.h>
30 #include <ModelAPI_AttributeBoolean.h>
31 #include <ModelAPI_AttributeString.h>
32 #include <ModelAPI_Data.h>
33 #include <ModelAPI_Session.h>
34 #include <ModelAPI_Validator.h>
35
36 #include <iomanip>
37 #include <sstream>
38
39 //=================================================================================================
40 FeaturesPlugin_InspectBoundingBox::FeaturesPlugin_InspectBoundingBox()
41 {
42 }
43
44 //=================================================================================================
45 void FeaturesPlugin_InspectBoundingBox::initAttributes()
46 {
47   // attribute for object selected
48   data()->addAttribute(OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
49
50   // attributes for result message and values
51   data()->addAttribute(X_MIN_COORD_ID(), ModelAPI_AttributeString::typeId());
52   data()->addAttribute(Y_MIN_COORD_ID(), ModelAPI_AttributeString::typeId());
53   data()->addAttribute(Z_MIN_COORD_ID(), ModelAPI_AttributeString::typeId());
54   data()->addAttribute(X_MAX_COORD_ID(), ModelAPI_AttributeString::typeId());
55   data()->addAttribute(Y_MAX_COORD_ID(), ModelAPI_AttributeString::typeId());
56   data()->addAttribute(Z_MAX_COORD_ID(), ModelAPI_AttributeString::typeId());
57   data()->addAttribute(CREATEBOX_ID(), ModelAPI_AttributeBoolean::typeId());
58
59   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), X_MIN_COORD_ID());
60   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), Y_MIN_COORD_ID());
61   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), Z_MIN_COORD_ID());
62   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), X_MAX_COORD_ID());
63   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), Y_MAX_COORD_ID());
64   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), Z_MAX_COORD_ID());
65   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CREATEBOX_ID());
66   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), RESULT_VALUES_ID());
67
68   data()->addAttribute(RESULT_VALUES_ID(), ModelAPI_AttributeDoubleArray::typeId());
69
70   data()->realArray(RESULT_VALUES_ID())->setSize(6);
71
72 }
73
74 //=================================================================================================
75 void FeaturesPlugin_InspectBoundingBox::execute()
76 {
77   if (!updateValues())
78     return;
79
80   createBoxByTwoPoints();
81
82   if (boolean(CREATEBOX_ID())->value()) {
83     if (!myCreateFeature.get())
84       createBox();
85     updateBox();
86   } else {
87     if (myCreateFeature.get()) {
88       myCreateFeature->eraseResults();
89       SessionPtr aSession = ModelAPI_Session::get();
90       DocumentPtr aDoc =  aSession->activeDocument();
91       aDoc->removeFeature(myCreateFeature);
92       myCreateFeature.reset();
93     }
94   }
95 }
96
97 //=================================================================================================
98 void FeaturesPlugin_InspectBoundingBox::attributeChanged(const std::string& theID)
99 {
100   if (theID == OBJECT_ID()) {
101     if (myCreateFeature.get())
102       updateBox();
103   }
104 }
105
106 //=================================================================================================
107 AttributePtr FeaturesPlugin_InspectBoundingBox::attributResultValues()
108 {
109    return attribute(RESULT_VALUES_ID());
110 }
111
112 //=================================================================================================
113 bool FeaturesPlugin_InspectBoundingBox::updateValues()
114 {
115   AttributeSelectionPtr aSelection = selection(OBJECT_ID());
116   if (aSelection->isInitialized()) {
117     AttributeDoubleArrayPtr aValues =
118       std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
119     std::stringstream streamxmin;
120     std::stringstream streamymin;
121     std::stringstream streamzmin;
122     std::stringstream streamxmax;
123     std::stringstream streamymax;
124     std::stringstream streamzmax;
125
126     GeomShapePtr aShape;
127     if (aSelection && aSelection->isInitialized()) {
128       aShape = aSelection->value();
129       if (!aShape && aSelection->context())
130         aShape = aSelection->context()->shape();
131     }
132
133     if (aShape && !aShape->isEqual(myShape)) {
134       double aXmin, aXmax, aYmin, aYmax, aZmin, aZmax;
135       std::string anError;
136       if (!GetBoundingBox(aShape,
137                           aXmin, aXmax,
138                           aYmin, aYmax,
139                           aZmin, aZmax,
140                           anError)) {
141         setError("Error in bounding box calculation :" +  anError);
142         return false;
143       }
144
145       myShape = aShape;
146       streamxmin << std::setprecision(14) << aXmin;
147       aValues->setValue(0, aXmin);
148       streamxmax << std::setprecision(14) << aXmax;
149       aValues->setValue(1, aXmax);
150       streamymin << std::setprecision(14) << aYmin;
151       aValues->setValue(2, aYmin);
152       streamymax << std::setprecision(14) << aYmax;
153       aValues->setValue(3, aYmax);
154       streamzmin << std::setprecision(14) << aZmin;
155       aValues->setValue(4, aZmin);
156       streamzmax << std::setprecision(14) << aZmax;
157       aValues->setValue(5, aZmax);
158       string(X_MIN_COORD_ID() )->setValue( "X = " +  streamxmin.str() );
159       string(Y_MIN_COORD_ID() )->setValue( "Y = " +  streamymin.str() );
160       string(Z_MIN_COORD_ID() )->setValue( "Z = " +  streamzmin.str() );
161       string(X_MAX_COORD_ID() )->setValue( "X = " +  streamxmax.str() );
162       string(Y_MAX_COORD_ID() )->setValue( "Y = " +  streamymax.str() );
163       string(Z_MAX_COORD_ID() )->setValue( "Z = " +  streamzmax.str() );
164     }
165   }
166   return true;
167 }
168
169 //=================================================================================================
170 void FeaturesPlugin_InspectBoundingBox::createBox()
171 {
172   SessionPtr aSession = ModelAPI_Session::get();
173
174   DocumentPtr aDoc =  aSession->activeDocument();
175
176   if (aDoc.get()) {
177     myCreateFeature = aDoc->addFeature(FeaturesPlugin_BoundingBox::ID());
178   }
179 }
180
181 //=================================================================================================
182 void FeaturesPlugin_InspectBoundingBox::updateBox()
183 {
184   myCreateFeature->boolean(FeaturesPlugin_BoundingBox::COMPUTE_ID())->setValue(false);
185   myCreateFeature->selection(FeaturesPlugin_BoundingBox::OBJECT_ID())
186                         ->setValue(selection(OBJECT_ID())->context(),
187                                    selection(OBJECT_ID())->value());
188
189   AttributeDoubleArrayPtr aValuesFeatures =
190     std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>
191                               (myCreateFeature->attribute(RESULT_VALUES_ID()));
192   AttributeDoubleArrayPtr aValues =
193     std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
194   for (int anI=0; anI < 6; anI++)
195     aValuesFeatures->setValue(anI,aValues->value(anI));
196
197   myCreateFeature->execute();
198   myCreateFeature->boolean(FeaturesPlugin_BoundingBox::COMPUTE_ID())->setValue(true);
199 }