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