1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: ModuleBase_Tools.cpp
4 // Created: 11 July 2014
5 // Author: Vitaly Smetannikov
7 #include "ModuleBase_Tools.h"
9 #include <ModuleBase_ParamIntSpinBox.h>
10 #include <ModuleBase_ParamSpinBox.h>
12 #include <ModelAPI_Attribute.h>
13 #include <ModelAPI_AttributeRefAttr.h>
14 #include <ModelAPI_AttributeReference.h>
15 #include <ModelAPI_AttributeSelection.h>
16 #include <ModelAPI_Data.h>
17 #include <ModelAPI_Result.h>
18 #include <ModelAPI_ResultCompSolid.h>
19 #include <ModelAPI_ResultParameter.h>
20 #include <ModelAPI_Tools.h>
21 #include <ModelAPI_Session.h>
23 #include <TopoDS_Iterator.hxx>
25 #include <GeomDataAPI_Point2D.h>
26 #include <Events_Error.h>
28 #include <Config_PropManager.h>
34 #include <QDoubleSpinBox>
35 #include <QGraphicsDropShadowEffect>
40 const double tolerance = 1e-7;
42 //#define DEBUG_ACTIVATE_WINDOW
43 //#define DEBUG_SET_FOCUS
45 namespace ModuleBase_Tools {
47 //******************************************************************
49 //******************************************************************
51 void adjustMargins(QWidget* theWidget)
55 adjustMargins(theWidget->layout());
58 void adjustMargins(QLayout* theLayout)
62 theLayout->setContentsMargins(2, 5, 2, 5);
63 theLayout->setSpacing(4);
66 void zeroMargins(QWidget* theWidget)
70 zeroMargins(theWidget->layout());
73 void zeroMargins(QLayout* theLayout)
77 theLayout->setContentsMargins(0, 0, 0, 0);
78 theLayout->setSpacing(5);
81 void activateWindow(QWidget* theWidget, const QString& theInfo)
83 theWidget->activateWindow();
85 #ifdef DEBUG_ACTIVATE_WINDOW
86 qDebug(QString("activateWindow: %1").arg(theInfo).toStdString().c_str());
90 void setFocus(QWidget* theWidget, const QString& theInfo)
92 theWidget->setFocus();
94 #ifdef DEBUG_SET_FOCUS
95 qDebug(QString("setFocus: %1").arg(theInfo).toStdString().c_str());
99 void setShadowEffect(QWidget* theWidget, const bool isSetEffect)
102 QGraphicsDropShadowEffect* aGlowEffect = new QGraphicsDropShadowEffect();
103 aGlowEffect->setOffset(.0);
104 aGlowEffect->setBlurRadius(10.0);
105 aGlowEffect->setColor(QColor(0, 170, 255)); // Light-blue color, #00AAFF
106 theWidget->setGraphicsEffect(aGlowEffect);
109 QGraphicsEffect* anEffect = theWidget->graphicsEffect();
111 anEffect->deleteLater();
112 theWidget->setGraphicsEffect(NULL);
116 QPixmap composite(const QString& theAdditionalIcon, const QString& theIcon)
118 QImage anIcon(theIcon);
119 QImage anAditional(theAdditionalIcon);
124 int anAddWidth = anAditional.width();
125 int anAddHeight = anAditional.height();
127 int aWidth = anIcon.width();
128 int aHeight = anIcon.height();
130 int aStartWidthPos = aWidth - anAddWidth - 1;
131 int aStartHeightPos = aHeight - anAddHeight - 1;
133 for (int i = 0; i < anAddWidth && i + aStartWidthPos < aWidth; i++)
135 for (int j = 0; j < anAddHeight && j + aStartHeightPos < aHeight; j++)
137 if (qAlpha(anAditional.pixel(i, j)) > 0)
138 anIcon.setPixel(i + aStartWidthPos, j + aStartHeightPos, anAditional.pixel(i, j));
141 return QPixmap::fromImage(anIcon);
144 QPixmap lighter(const QString& theIcon, const int theLighterValue)
146 QImage anIcon(theIcon);
150 QImage aResult(theIcon);
151 for ( int i = 0; i < anIcon.width(); i++ )
153 for ( int j = 0; j < anIcon.height(); j++ )
155 QRgb anRgb = anIcon.pixel( i, j );
156 QColor aPixelColor(qRed(anRgb), qGreen(anRgb), qBlue(anRgb),
157 qAlpha( aResult.pixel( i, j ) ));
159 QColor aLighterColor = aPixelColor.lighter(theLighterValue);
160 aResult.setPixel(i, j, qRgba( aLighterColor.red(), aLighterColor.green(),
161 aLighterColor.blue(), aLighterColor.alpha() ) );
164 return QPixmap::fromImage(aResult);
167 void setSpinText(ModuleBase_ParamSpinBox* theSpin, const QString& theText)
169 if (theSpin->text() == theText)
171 // In order to avoid extra text setting because it will
172 // reset cursor position in control
173 bool isBlocked = theSpin->blockSignals(true);
174 theSpin->setText(theText);
175 theSpin->blockSignals(isBlocked);
178 void setSpinValue(QDoubleSpinBox* theSpin, double theValue)
180 if (fabs(theSpin->value() - theValue) < tolerance)
182 bool isBlocked = theSpin->blockSignals(true);
183 theSpin->setValue(theValue);
184 theSpin->blockSignals(isBlocked);
187 void setSpinValue(ModuleBase_ParamSpinBox* theSpin, double theValue)
189 if (fabs(theSpin->value() - theValue) < tolerance)
191 bool isBlocked = theSpin->blockSignals(true);
192 theSpin->setValue(theValue);
193 theSpin->blockSignals(isBlocked);
196 void setSpinText(ModuleBase_ParamIntSpinBox* theSpin, const QString& theText)
198 // In order to avoid extra text setting because it will
199 // reset cursor position in control
200 if (theSpin->text() == theText)
202 bool isBlocked = theSpin->blockSignals(true);
203 theSpin->setText(theText);
204 theSpin->blockSignals(isBlocked);
207 void setSpinValue(ModuleBase_ParamIntSpinBox* theSpin, int theValue)
209 if (theSpin->value() == theValue)
211 bool isBlocked = theSpin->blockSignals(true);
212 theSpin->setValue(theValue);
213 theSpin->blockSignals(isBlocked);
216 QString objectInfo(const ObjectPtr& theObj, const bool isUseAttributesInfo)
218 QString aFeatureStr = "feature";
222 std::ostringstream aPtrStr;
223 aPtrStr << "[" << theObj.get() << "]";
225 ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObj);
226 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObj);
228 aFeatureStr.append(QString("(result%1)").arg(aPtrStr.str().c_str()).toStdString() .c_str());
229 if (aRes->isDisabled())
230 aFeatureStr.append("[disabled]");
231 if (aRes->isConcealed())
232 aFeatureStr.append("[concealed]");
233 if (ModelAPI_Tools::hasSubResults(aRes))
234 aFeatureStr.append("[hasSubResults]");
236 aFeature = ModelAPI_Feature::feature(aRes);
239 aFeatureStr.append(aPtrStr.str().c_str());
241 if (aFeature.get()) {
242 aFeatureStr.append(QString(": %1").arg(aFeature->getKind().c_str()).toStdString().c_str());
243 if (aFeature->data()->isValid()) {
244 aFeatureStr.append(QString(", name=%1").arg(aFeature->data()->name().c_str()).toStdString()
247 if (isUseAttributesInfo) {
248 std::list<AttributePtr> anAttrs = aFeature->data()->attributes("");
249 std::list<AttributePtr>::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end();
251 for(; anIt != aLast; anIt++) {
252 AttributePtr anAttr = *anIt;
253 QString aValue = "not defined";
254 std::string aType = anAttr->attributeType();
255 if (aType == GeomDataAPI_Point2D::typeId()) {
256 std::shared_ptr<GeomDataAPI_Point2D> aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
259 aValue = QString("(%1, %2)").arg(aPoint->x()).arg(aPoint->y());
261 else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
264 aValues.push_back(QString("%1: %2").arg(anAttr->id().c_str()).arg(aValue).toStdString().c_str());
266 if (!aValues.empty())
267 aFeatureStr.append(QString(", attributes: %1").arg(aValues.join(", ").toStdString().c_str()));
274 typedef QMap<QString, TopAbs_ShapeEnum> ShapeTypes;
275 static ShapeTypes MyShapeTypes;
277 TopAbs_ShapeEnum shapeType(const QString& theType)
279 if (MyShapeTypes.count() == 0) {
280 MyShapeTypes["face"] = TopAbs_FACE;
281 MyShapeTypes["faces"] = TopAbs_FACE;
282 MyShapeTypes["vertex"] = TopAbs_VERTEX;
283 MyShapeTypes["vertices"] = TopAbs_VERTEX;
284 MyShapeTypes["wire"] = TopAbs_WIRE;
285 MyShapeTypes["edge"] = TopAbs_EDGE;
286 MyShapeTypes["edges"] = TopAbs_EDGE;
287 MyShapeTypes["shell"] = TopAbs_SHELL;
288 MyShapeTypes["solid"] = TopAbs_SOLID;
289 MyShapeTypes["solids"] = TopAbs_SOLID;
290 MyShapeTypes["objects"] = TopAbs_SHAPE;
292 QString aType = theType.toLower();
293 if (MyShapeTypes.contains(aType))
294 return MyShapeTypes[aType];
295 Events_Error::send("Shape type defined in XML is not implemented!");
299 void checkObjects(const QObjectPtrList& theObjects, bool& hasResult, bool& hasFeature, bool& hasParameter, bool& hasSubFeature)
303 hasParameter = false;
304 hasSubFeature = false;
305 foreach(ObjectPtr aObj, theObjects) {
306 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
307 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
308 ResultParameterPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aResult);
310 hasResult |= (aResult.get() != NULL);
311 hasFeature |= (aFeature.get() != NULL);
312 hasParameter |= (aConstruction.get() != NULL);
314 hasSubFeature |= (ModelAPI_Tools::compositeOwner(aFeature) != NULL);
315 if (hasFeature && hasResult && hasParameter && hasSubFeature)
320 void setDefaultDeviationCoefficient(const TopoDS_Shape& theShape,
321 const Handle(Prs3d_Drawer)& theDrawer)
323 if (theShape.IsNull())
325 TopAbs_ShapeEnum aType = theShape.ShapeType();
326 if ((aType == TopAbs_EDGE) || (aType == TopAbs_WIRE))
327 theDrawer->SetDeviationCoefficient(1.e-4);
330 Quantity_Color color(const std::string& theSection,
331 const std::string& theName,
332 const std::string& theDefault)
334 std::vector<int> aColor = Config_PropManager::color(theSection, theName, theDefault);
335 return Quantity_Color(aColor[0] / 255., aColor[1] / 255., aColor[2] / 255., Quantity_TOC_RGB);
338 ObjectPtr getObject(const AttributePtr& theAttribute)
341 std::string anAttrType = theAttribute->attributeType();
342 if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
343 AttributeRefAttrPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
344 if (anAttr != NULL && anAttr->isObject())
345 anObject = anAttr->object();
347 if (anAttrType == ModelAPI_AttributeSelection::typeId()) {
348 AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
350 anObject = anAttr->context();
352 if (anAttrType == ModelAPI_AttributeReference::typeId()) {
353 AttributeReferencePtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
354 if (anAttr.get() != NULL)
355 anObject = anAttr->value();
360 TopAbs_ShapeEnum getCompoundSubType(const TopoDS_Shape& theShape)
362 TopAbs_ShapeEnum aShapeType = theShape.ShapeType();
364 // for compounds check sub-shapes: it may be compound of needed type:
365 // Booleans may produce compounds of Solids
366 if (aShapeType == TopAbs_COMPOUND) {
367 for(TopoDS_Iterator aSubs(theShape); aSubs.More(); aSubs.Next()) {
368 if (!aSubs.Value().IsNull()) {
369 TopAbs_ShapeEnum aSubType = aSubs.Value().ShapeType();
370 if (aSubType == TopAbs_COMPOUND) { // compound of compound(s)
371 aShapeType = TopAbs_COMPOUND;
374 if (aShapeType == TopAbs_COMPOUND) {
375 aShapeType = aSubType;
376 } else if (aShapeType != aSubType) { // compound of shapes of different types
377 aShapeType = TopAbs_COMPOUND;
386 void getParameters(QStringList& theParameters)
388 theParameters.clear();
390 SessionPtr aSession = ModelAPI_Session::get();
391 std::list<DocumentPtr> aDocList;
392 DocumentPtr anActiveDocument = aSession->activeDocument();
393 DocumentPtr aRootDocument = aSession->moduleDocument();
394 aDocList.push_back(anActiveDocument);
395 if (anActiveDocument != aRootDocument) {
396 aDocList.push_back(aRootDocument);
398 std::string aGroupId = ModelAPI_ResultParameter::group();
399 for(std::list<DocumentPtr>::const_iterator it = aDocList.begin(); it != aDocList.end(); ++it) {
400 DocumentPtr aDocument = *it;
401 int aSize = aDocument->size(aGroupId);
402 for (int i = 0; i < aSize; i++) {
403 ObjectPtr anObject = aDocument->object(aGroupId, i);
404 std::string aParameterName = anObject->data()->name();
405 theParameters.append(aParameterName.c_str());
410 } // namespace ModuleBase_Tools