Salome HOME
Correct deviation coefficient, it should not be restored because selection is also...
[modules/shaper.git] / src / ModuleBase / ModuleBase_Tools.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        ModuleBase_Tools.cpp
4 // Created:     11 July 2014
5 // Author:      Vitaly Smetannikov
6
7 #include "ModuleBase_Tools.h"
8 #include <ModuleBase_ParamSpinBox.h>
9
10 #include <ModelAPI_Result.h>
11 #include <ModelAPI_Data.h>
12 #include <ModelAPI_Attribute.h>
13 #include <ModelAPI_AttributeRefAttr.h>
14 #include <ModelAPI_ResultParameter.h>
15 #include <ModelAPI_ResultCompSolid.h>
16 #include <ModelAPI_Tools.h>
17
18 #include <GeomDataAPI_Point2D.h>
19 #include <Events_Error.h>
20
21 #include <QWidget>
22 #include <QLayout>
23 #include <QPainter>
24 #include <QBitmap>
25 #include <QDoubleSpinBox>
26
27 #include <sstream>
28
29 namespace ModuleBase_Tools {
30
31 //******************************************************************
32
33 //******************************************************************
34
35 void adjustMargins(QWidget* theWidget)
36 {
37   if(!theWidget)
38     return;
39   adjustMargins(theWidget->layout());
40 }
41
42 void adjustMargins(QLayout* theLayout)
43 {
44   if(!theLayout)
45     return;
46   theLayout->setContentsMargins(2, 5, 2, 5);
47   theLayout->setSpacing(4);
48 }
49
50 void zeroMargins(QWidget* theWidget)
51 {
52   if(!theWidget)
53     return;
54   zeroMargins(theWidget->layout());
55 }
56
57 void zeroMargins(QLayout* theLayout)
58 {
59   if(!theLayout)
60     return;
61   theLayout->setContentsMargins(0, 0, 0, 0);
62   theLayout->setSpacing(5);
63 }
64
65 QPixmap composite(const QString& theAdditionalIcon, const QString& theIcon)
66 {
67   QImage anIcon(theIcon);
68   QImage anAditional(theAdditionalIcon);
69
70   if (anIcon.isNull())
71     return QPixmap();
72
73   int anAddWidth = anAditional.width();
74   int anAddHeight = anAditional.height();
75
76   int aWidth = anIcon.width();
77   int aHeight = anIcon.height();
78
79   int aStartWidthPos = aWidth - anAddWidth - 1;
80   int aStartHeightPos = aHeight - anAddHeight - 1;
81
82   for (int i = 0; i < anAddWidth && i + aStartWidthPos < aWidth; i++)
83   {
84     for (int j = 0; j < anAddHeight && j + aStartHeightPos < aHeight; j++)
85     {
86       if (qAlpha(anAditional.pixel(i, j)) > 0)
87         anIcon.setPixel(i + aStartWidthPos, j + aStartHeightPos, anAditional.pixel(i, j));
88     }
89   }
90   return QPixmap::fromImage(anIcon);
91 }
92
93 QPixmap lighter(const QString& theIcon, const int theLighterValue)
94 {
95   QImage anIcon(theIcon);
96   if (anIcon.isNull())
97     return QPixmap();
98
99   QImage aResult(theIcon);
100   for ( int i = 0; i < anIcon.width(); i++ )
101   {
102     for ( int j = 0; j < anIcon.height(); j++ )
103     {
104       QRgb anRgb = anIcon.pixel( i, j );
105       QColor aPixelColor(qRed(anRgb), qGreen(anRgb), qBlue(anRgb),
106                          qAlpha( aResult.pixel( i, j ) ));
107
108       QColor aLighterColor = aPixelColor.lighter(theLighterValue);
109       aResult.setPixel(i, j, qRgba( aLighterColor.red(), aLighterColor.green(),
110                                     aLighterColor.blue(), aLighterColor.alpha() ) );
111     }
112   }
113   return QPixmap::fromImage(aResult);
114 }
115
116 void setSpinText(ModuleBase_ParamSpinBox* theSpin, const QString& theText)
117 {
118   if (theSpin->text() == theText) 
119     return;
120   // In order to avoid extra text setting because it will
121   // reset cursor position in control
122   bool isBlocked = theSpin->blockSignals(true);
123   theSpin->setText(theText);
124   theSpin->blockSignals(isBlocked);
125 }
126
127 void setSpinValue(QDoubleSpinBox* theSpin, double theValue)
128 {
129   if (theSpin->value() == theValue)
130     return;
131   bool isBlocked = theSpin->blockSignals(true);
132   theSpin->setValue(theValue);
133   theSpin->blockSignals(isBlocked);
134 }
135
136 void setSpinValue(ModuleBase_ParamSpinBox* theSpin, double theValue)
137 {
138   //if (theSpin->value() == theValue)
139   //  return;
140   bool isBlocked = theSpin->blockSignals(true);
141   theSpin->setValue(theValue);
142   theSpin->blockSignals(isBlocked);
143 }
144
145 QString objectInfo(const ObjectPtr& theObj, const bool isUseAttributesInfo)
146 {
147   QString aFeatureStr = "feature";
148   if (!theObj.get())
149     return aFeatureStr;
150
151   std::ostringstream aPtrStr;
152   aPtrStr << "[" << theObj.get() << "]";
153
154   ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObj);
155   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObj);
156   if(aRes.get()) {
157     aFeatureStr.append(QString("(result%1)").arg(aPtrStr.str().c_str()).toStdString() .c_str());
158     if (aRes->isDisabled())
159       aFeatureStr.append("[disabled]");
160     if (aRes->isConcealed())
161       aFeatureStr.append("[concealed]");
162
163     aFeature = ModelAPI_Feature::feature(aRes);
164   }
165   else
166     aFeatureStr.append(aPtrStr.str().c_str());
167
168   if (aFeature.get()) {
169     aFeatureStr.append(QString(": %1").arg(aFeature->getKind().c_str()).toStdString().c_str());
170     if (aFeature->data()->isValid()) {
171       aFeatureStr.append(QString(", name=%1").arg(aFeature->data()->name().c_str()).toStdString()
172                                                                                        .c_str());
173     }
174     if (isUseAttributesInfo) {
175       std::list<AttributePtr> anAttrs = aFeature->data()->attributes("");
176       std::list<AttributePtr>::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end();
177       QStringList aValues;
178       for(; anIt != aLast; anIt++) {
179         AttributePtr anAttr = *anIt;
180         QString aValue = "not defined";
181         std::string aType = anAttr->attributeType();
182         if (aType == GeomDataAPI_Point2D::typeId()) {
183           std::shared_ptr<GeomDataAPI_Point2D> aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
184                                                                                          anAttr);
185           if (aPoint.get())
186             aValue = QString("(%1, %2)").arg(aPoint->x()).arg(aPoint->y());
187         }
188         else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
189         }
190
191         aValues.push_back(QString("%1: %2").arg(anAttr->id().c_str()).arg(aValue).toStdString().c_str());
192       }
193       if (!aValues.empty())
194         aFeatureStr.append(QString(", attributes: %1").arg(aValues.join(", ").toStdString().c_str()));
195     }
196   }
197
198   return aFeatureStr;
199 }
200
201 typedef QMap<QString, TopAbs_ShapeEnum> ShapeTypes;
202 static ShapeTypes MyShapeTypes;
203
204 TopAbs_ShapeEnum shapeType(const QString& theType)
205 {
206   if (MyShapeTypes.count() == 0) {
207     MyShapeTypes["face"] = TopAbs_FACE;
208     MyShapeTypes["faces"] = TopAbs_FACE;
209     MyShapeTypes["vertex"] = TopAbs_VERTEX;
210     MyShapeTypes["vertices"] = TopAbs_VERTEX;
211     MyShapeTypes["wire"] = TopAbs_WIRE;
212     MyShapeTypes["edge"] = TopAbs_EDGE;
213     MyShapeTypes["edges"] = TopAbs_EDGE;
214     MyShapeTypes["shell"] = TopAbs_SHELL;
215     MyShapeTypes["solid"] = TopAbs_SOLID;
216     MyShapeTypes["solids"] = TopAbs_SOLID;
217   }
218   QString aType = theType.toLower();
219   if (MyShapeTypes.contains(aType))
220     return MyShapeTypes[aType];
221   Events_Error::send("Shape type defined in XML is not implemented!");
222   return TopAbs_SHAPE;
223 }
224
225 bool isSubResult(ObjectPtr theObject)
226 {
227   bool aSubResult = false;
228
229   //ResultCompSolidPtr aCompsolidResult = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aResult);
230   return aSubResult;
231 }
232
233 void checkObjects(const QObjectPtrList& theObjects, bool& hasResult, bool& hasFeature, bool& hasParameter, bool& hasSubFeature)
234 {
235   hasResult = false;
236   hasFeature = false;
237   hasParameter = false;
238   hasSubFeature = false;
239   foreach(ObjectPtr aObj, theObjects) {
240     FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
241     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
242     ResultParameterPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aResult);
243
244     bool aSubResult = isSubResult(aResult);
245
246     /// results of compsolids are not processed in SHOW/HIDE/WIREFRAME operations
247     hasResult = (aResult.get() != NULL && !aSubResult);
248     hasFeature = (aFeature.get() != NULL);
249     hasParameter = (aConstruction.get() != NULL);
250     if (hasFeature) 
251       hasSubFeature = (ModelAPI_Tools::compositeOwner(aFeature) != NULL);
252     if (hasFeature && hasResult  && hasParameter && hasSubFeature)
253       break;
254   }
255 }
256
257 double defaultDeviationCoefficient()
258 {
259   // this value is chosen by performance check. Test case is an extrusion on sketch circle.
260   return 1.e-4; // default value is 1.e-3
261 }
262
263 }
264
265