1 // Copyright (C) 2014-2021 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "ModuleBase_Tools.h"
22 #include <ModuleBase_ParamIntSpinBox.h>
23 #include <ModuleBase_ParamSpinBox.h>
24 #include <ModuleBase_Preferences.h>
25 #include <ModuleBase_WidgetFactory.h>
26 #include <ModuleBase_IWorkshop.h>
27 #include <ModuleBase_IModule.h>
28 #include <ModuleBase_IViewer.h>
29 #include <ModuleBase_IconFactory.h>
30 #include <ModuleBase_ResultPrs.h>
31 #include <ModuleBase_ViewerPrs.h>
33 #include <ModelAPI_Attribute.h>
34 #include <ModelAPI_AttributeRefAttr.h>
35 #include <ModelAPI_AttributeReference.h>
36 #include <ModelAPI_AttributeSelection.h>
37 #include <ModelAPI_AttributeSelectionList.h>
38 #include <ModelAPI_AttributeRefList.h>
39 #include <ModelAPI_AttributeRefAttrList.h>
40 #include <ModelAPI_ResultGroup.h>
41 #include <ModelAPI_ResultPart.h>
42 #include <ModelAPI_ResultConstruction.h>
43 #include <ModelAPI_AttributeString.h>
44 #include <ModelAPI_Expression.h>
45 #include <ModelAPI_ResultField.h>
46 #include <Events_Loop.h>
48 #include <ModelAPI_Data.h>
49 #include <ModelAPI_Result.h>
50 #include <ModelAPI_ResultParameter.h>
51 #include <ModelAPI_Tools.h>
52 #include <ModelAPI_Session.h>
53 #include <ModelAPI_Events.h>
54 #include <ModelAPI_Folder.h>
56 #include <ModelGeomAlgo_Point2D.h>
59 #include <SUIT_Application.h>
60 #include <SUIT_ResourceMgr.h>
61 #include <SUIT_Session.h>
64 #include <StdSelect_BRepOwner.hxx>
65 #include <TopoDS_Iterator.hxx>
66 #include <AIS_InteractiveContext.hxx>
67 #include <Prs3d_LineAspect.hxx>
68 #include <Prs3d_PlaneAspect.hxx>
70 #include <GeomDataAPI_Point2D.h>
71 #include <Events_InfoMessage.h>
72 #include <GeomAPI_ShapeExplorer.h>
74 #include <Config_PropManager.h>
75 #include <Config_Translator.h>
77 #include <Prs3d_PointAspect.hxx>
78 #include <Graphic3d_AspectMarker3d.hxx>
80 #include <Image_AlienPixMap.hxx>
86 #include <QDoubleSpinBox>
87 #include <QGraphicsDropShadowEffect>
89 #include <QApplication>
90 #include <QMessageBox>
100 #pragma warning(disable : 4996) // for getenv
103 const double tolerance = 1e-7;
104 const double DEFAULT_DEVIATION_COEFFICIENT = 1.e-4;
106 //#define DEBUG_ACTIVATE_WINDOW
107 //#define DEBUG_SET_FOCUS
115 namespace ModuleBase_Tools {
117 //******************************************************************
119 //! Waits for REDISPLAY message and set the Visible flag to the entities
120 //! according to Preferences choice.
121 class ModuleBase_RedisplayListener : public Events_Listener
124 static std::shared_ptr<ModuleBase_RedisplayListener> instance()
126 static std::shared_ptr<ModuleBase_RedisplayListener>
127 anInstance(new ModuleBase_RedisplayListener);
131 void processEvent(const std::shared_ptr<Events_Message>& theMessage)
133 if (theMessage->eventID() == Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY))
136 // If the python script is being loaded now, the preferences should be used
137 // to display the required object
138 SUIT_Application * app = SUIT_Session::session()->activeApplication();
139 QVariant aVar = app->property("IsLoadedScript");
140 if (!aVar.isNull() && aVar.toBool()) {
141 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
142 int aSize = aRootDoc->size(ModelAPI_ResultPart::group());
144 ObjectPtr anPartObject = aRootDoc->object(ModelAPI_ResultPart::group(), aSize - 1);
145 ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(anPartObject);
146 ModuleBase_Tools::setDisplaying(aPart, true);
154 ModuleBase_RedisplayListener()
156 Events_Loop::loop()->registerListener(this,
157 Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
161 static std::shared_ptr<ModuleBase_RedisplayListener>
162 RL = ModuleBase_RedisplayListener::instance();
164 //******************************************************************
166 void adjustMargins(QWidget* theWidget)
170 adjustMargins(theWidget->layout());
173 void adjustMargins(QLayout* theLayout)
177 theLayout->setContentsMargins(2, 5, 2, 5);
178 theLayout->setSpacing(4);
181 void zeroMargins(QWidget* theWidget)
185 zeroMargins(theWidget->layout());
188 void zeroMargins(QLayout* theLayout)
192 theLayout->setContentsMargins(0, 0, 0, 0);
193 theLayout->setSpacing(5);
196 void activateWindow(QWidget* theWidget, const QString& theInfo)
199 theWidget->activateWindow();
203 #ifdef DEBUG_ACTIVATE_WINDOW
204 qDebug(QString("activateWindow: %1").arg(theInfo).toStdString().c_str());
208 void setFocus(QWidget* theWidget, const QString& theInfo)
210 activateWindow(theWidget);
211 theWidget->setFocus();
212 // rectangle of focus is not visible on tool button widgets
214 #ifdef DEBUG_SET_FOCUS
215 qDebug(QString("setFocus: %1").arg(theInfo).toStdString().c_str());
219 void setShadowEffect(QWidget* theWidget, const bool isSetEffect)
222 QGraphicsDropShadowEffect* aGlowEffect = new QGraphicsDropShadowEffect();
223 aGlowEffect->setOffset(.0);
224 aGlowEffect->setBlurRadius(10.0);
225 aGlowEffect->setColor(QColor(0, 170, 255)); // Light-blue color, #00AAFF
226 theWidget->setGraphicsEffect(aGlowEffect);
229 QGraphicsEffect* anEffect = theWidget->graphicsEffect();
231 anEffect->deleteLater();
232 theWidget->setGraphicsEffect(NULL);
236 QPixmap composite(const QString& theAdditionalIcon, const QString& theIcon)
238 QImage anIcon = ModuleBase_IconFactory::loadImage(theIcon);
239 QImage anAditional(theAdditionalIcon);
240 return composite(anAditional, anIcon);
243 QPixmap composite(const QImage& theAdditionalIcon, QImage& theIcon)
245 if (theIcon.isNull())
248 int anAddWidth = theAdditionalIcon.width();
249 int anAddHeight = theAdditionalIcon.height();
251 int aWidth = theIcon.width();
252 int aHeight = theIcon.height();
254 int aStartWidthPos = aWidth - anAddWidth;
255 int aStartHeightPos = aHeight - anAddHeight;
257 for (int i = 0; i < anAddWidth && i + aStartWidthPos < aWidth; i++)
259 for (int j = 0; j < anAddHeight && j + aStartHeightPos < aHeight; j++)
261 if (qAlpha(theAdditionalIcon.pixel(i, j)) > 0)
262 theIcon.setPixel(i + aStartWidthPos, j + aStartHeightPos, theAdditionalIcon.pixel(i, j));
265 return QPixmap::fromImage(theIcon);
268 QPixmap lighter(const QString& theIcon, const int theLighterValue)
270 QImage anIcon = ModuleBase_IconFactory::loadImage(theIcon);
274 QImage aResult = ModuleBase_IconFactory::loadImage(theIcon);
275 for (int i = 0; i < anIcon.width(); i++)
277 for (int j = 0; j < anIcon.height(); j++)
279 QRgb anRgb = anIcon.pixel(i, j);
280 QColor aPixelColor(qRed(anRgb), qGreen(anRgb), qBlue(anRgb),
281 qAlpha(aResult.pixel(i, j)));
283 QColor aLighterColor = aPixelColor.lighter(theLighterValue);
284 aResult.setPixel(i, j, qRgba(aLighterColor.red(), aLighterColor.green(),
285 aLighterColor.blue(), aLighterColor.alpha()));
288 return QPixmap::fromImage(aResult);
291 void setSpinText(ModuleBase_ParamSpinBox* theSpin, const QString& theText)
293 if (theSpin->text() == theText)
295 // In order to avoid extra text setting because it will
296 // reset cursor position in control
297 bool isBlocked = theSpin->blockSignals(true);
298 theSpin->setText(theText);
299 theSpin->blockSignals(isBlocked);
302 void setSpinValue(QDoubleSpinBox* theSpin, double theValue)
304 if (fabs(theSpin->value() - theValue) < tolerance)
306 bool isBlocked = theSpin->blockSignals(true);
307 theSpin->setValue(theValue);
308 theSpin->blockSignals(isBlocked);
311 void setSpinValue(ModuleBase_ParamSpinBox* theSpin, double theValue)
313 if (!theSpin->text().isEmpty() && fabs(theSpin->value() - theValue) < tolerance)
315 bool isBlocked = theSpin->blockSignals(true);
316 theSpin->setValue(theValue);
317 theSpin->blockSignals(isBlocked);
320 void setSpinText(ModuleBase_ParamIntSpinBox* theSpin, const QString& theText)
322 // In order to avoid extra text setting because it will
323 // reset cursor position in control
324 if (theSpin->text() == theText)
326 bool isBlocked = theSpin->blockSignals(true);
327 theSpin->setText(theText);
328 theSpin->blockSignals(isBlocked);
331 void setSpinValue(ModuleBase_ParamIntSpinBox* theSpin, int theValue)
333 if (theSpin->value() == theValue)
335 bool isBlocked = theSpin->blockSignals(true);
336 theSpin->setValue(theValue);
337 theSpin->blockSignals(isBlocked);
340 QAction* createAction(const QIcon& theIcon, const QString& theText,
341 QObject* theParent, const QObject* theReceiver,
342 const char* theMember, const QString& theToolTip,
343 const QString& theStatusTip)
345 QAction* anAction = new QAction(theIcon, theText, theParent);
346 anAction->setToolTip(theToolTip.isEmpty() ? theText : theToolTip);
347 anAction->setStatusTip(!theStatusTip.isEmpty() ? theStatusTip :
348 (!theToolTip.isEmpty() ? theToolTip : theText));
350 QObject::connect(anAction, SIGNAL(triggered(bool)), theReceiver, theMember);
356 QString objectName(const ObjectPtr& theObj)
361 return QString::fromStdWString(theObj->data()->name());
364 QString objectInfo(const ObjectPtr& theObj, const bool isUseAttributesInfo)
366 QString aFeatureStr = "feature";
370 std::ostringstream aPtrStr;
371 aPtrStr << "[" << theObj.get() << "]";
373 ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObj);
374 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObj);
376 aFeatureStr.append(QString("(result%1)").arg(aPtrStr.str().c_str()).toStdString() .c_str());
377 if (aRes->isDisabled())
378 aFeatureStr.append("[disabled]");
379 if (aRes->isConcealed())
380 aFeatureStr.append("[concealed]");
381 if (ModelAPI_Tools::hasSubResults(aRes))
382 aFeatureStr.append("[hasSubResults]");
384 aFeature = ModelAPI_Feature::feature(aRes);
387 aFeatureStr.append(aPtrStr.str().c_str());
389 if (aFeature.get()) {
390 aFeatureStr.append(QString(": %1").arg(aFeature->getKind().c_str()).toStdString().c_str());
391 if (aFeature->data()->isValid()) {
392 aFeatureStr.append(QString(", name=%1")
393 .arg(QString::fromStdWString(theObj->data()->name())).toStdString().c_str());
395 if (isUseAttributesInfo) {
396 std::set<std::shared_ptr<ModelAPI_Attribute> > anAttributes;
397 std::string aPointsInfo = ModelGeomAlgo_Point2D::getPontAttributesInfo(aFeature,
398 anAttributes).c_str();
399 if (!aPointsInfo.empty())
400 aFeatureStr.append(QString(", attributes: %1")
401 .arg(aPointsInfo.c_str()).toStdString().c_str());
409 typedef QMap<QString, int> ShapeTypes;
410 static ShapeTypes myShapeTypes;
412 int shapeType(const QString& theType)
414 if (myShapeTypes.count() == 0) {
415 myShapeTypes["compound"] = TopAbs_COMPOUND;
416 myShapeTypes["compounds"] = TopAbs_COMPOUND;
417 myShapeTypes["compsolid"] = TopAbs_COMPSOLID;
418 myShapeTypes["compsolids"] = TopAbs_COMPSOLID;
419 myShapeTypes["solid"] = TopAbs_SOLID;
420 myShapeTypes["solids"] = TopAbs_SOLID;
421 myShapeTypes["shell"] = TopAbs_SHELL;
422 myShapeTypes["shells"] = TopAbs_SHELL;
423 myShapeTypes["face"] = TopAbs_FACE;
424 myShapeTypes["faces"] = TopAbs_FACE;
425 myShapeTypes["wire"] = TopAbs_WIRE;
426 myShapeTypes["wires"] = TopAbs_WIRE;
427 myShapeTypes["edge"] = TopAbs_EDGE;
428 myShapeTypes["edges"] = TopAbs_EDGE;
429 myShapeTypes["vertex"] = TopAbs_VERTEX;
430 myShapeTypes["vertices"] = TopAbs_VERTEX;
431 myShapeTypes["object"] = ModuleBase_ResultPrs::Sel_Result;
432 myShapeTypes["objects"] = ModuleBase_ResultPrs::Sel_Result;
434 QString aType = theType.toLower();
435 if(myShapeTypes.contains(aType))
436 return myShapeTypes[aType];
437 Events_InfoMessage("ModuleBase_Tools", "Shape type defined in XML is not implemented!").send();
441 void checkObjects(const QObjectPtrList& theObjects, bool& hasResult, bool& hasFeature,
442 bool& hasParameter, bool& hasCompositeOwner, bool& hasResultInHistory,
447 hasParameter = false;
448 hasCompositeOwner = false;
449 hasResultInHistory = false;
451 foreach(ObjectPtr aObj, theObjects) {
452 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
453 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
454 FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(aObj);
455 ResultParameterPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aResult);
456 FieldStepPtr aStep = std::dynamic_pointer_cast<ModelAPI_ResultField::ModelAPI_FieldStep>(aObj);
458 hasResult |= ((aResult.get() != NULL) || (aStep.get() != NULL));
459 hasFeature |= (aFeature.get() != NULL);
460 hasFolder |= (aFolder.get() != NULL);
461 hasParameter |= (aConstruction.get() != NULL);
463 hasCompositeOwner |= (ModelAPI_Tools::compositeOwner(aFeature) != NULL);
464 else if (aResult.get())
465 hasCompositeOwner |= (ModelAPI_Tools::bodyOwner(aResult) != NULL);
467 if (!hasResultInHistory && aResult.get()) {
468 aFeature = ModelAPI_Feature::feature(aResult);
469 hasResultInHistory = aFeature.get() && aFeature->isInHistory();
472 if (hasFeature && hasResult && hasParameter && hasCompositeOwner)
477 /*bool setDefaultDeviationCoefficient(std::shared_ptr<GeomAPI_Shape> theGeomShape)
479 if (!theGeomShape.get())
481 // if the shape could not be exploded on faces, it contains only wires, edges, and vertices
482 // correction of deviation for them should not influence to the application performance
483 GeomAPI_ShapeExplorer anExp(theGeomShape, GeomAPI_Shape::FACE);
484 bool anEmpty = anExp.empty();
485 return !anExp.more();
488 /*void setDefaultDeviationCoefficient(const std::shared_ptr<ModelAPI_Result>& theResult,
489 const Handle(Prs3d_Drawer)& theDrawer)
491 if (!theResult.get())
493 bool aUseDeviation = false;
495 std::string aResultGroup = theResult->groupName();
496 if (aResultGroup == ModelAPI_ResultConstruction::group())
497 aUseDeviation = true;
498 else if (aResultGroup == ModelAPI_ResultBody::group()) {
499 GeomShapePtr aGeomShape = theResult->shape();
500 if (aGeomShape.get())
501 aUseDeviation = setDefaultDeviationCoefficient(aGeomShape);
504 theDrawer->SetDeviationCoefficient(DEFAULT_DEVIATION_COEFFICIENT);
507 void setDefaultDeviationCoefficient(const TopoDS_Shape& theShape,
508 const Handle(Prs3d_Drawer)& theDrawer)
510 if (theShape.IsNull())
512 if (theDrawer.IsNull())
515 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape());
516 aGeomShape->setImpl(new TopoDS_Shape(theShape));
518 // if the shape could not be exploded on faces, it contains only wires, edges, and vertices
519 // correction of deviation for them should not influence to the application performance
520 GeomAPI_ShapeExplorer anExp(aGeomShape, GeomAPI_Shape::FACE);
521 bool isConstruction = !anExp.more();
525 aDeflection = Config_PropManager::real("Visualization", "construction_deflection");
527 aDeflection = Config_PropManager::real("Visualization", "body_deflection");
529 theDrawer->SetDeviationCoefficient(aDeflection);
532 Quantity_Color color(const std::string& theSection,
533 const std::string& theName)
535 std::vector<int> aColor = Config_PropManager::color(theSection, theName);
536 return Quantity_Color(aColor[0] / 255., aColor[1] / 255., aColor[2] / 255., Quantity_TOC_RGB);
539 ObjectPtr getObject(const AttributePtr& theAttribute)
542 std::string anAttrType = theAttribute->attributeType();
543 if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
544 AttributeRefAttrPtr anAttr =
545 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
546 if (anAttr != NULL && anAttr->isObject())
547 anObject = anAttr->object();
549 if (anAttrType == ModelAPI_AttributeSelection::typeId()) {
550 AttributeSelectionPtr anAttr =
551 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
553 anObject = anAttr->context();
555 if (anAttrType == ModelAPI_AttributeReference::typeId()) {
556 AttributeReferencePtr anAttr =
557 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
558 if (anAttr.get() != NULL)
559 anObject = anAttr->value();
564 TopAbs_ShapeEnum getCompoundSubType(const TopoDS_Shape& theShape)
566 TopAbs_ShapeEnum aShapeType = theShape.ShapeType();
568 // for compounds check sub-shapes: it may be compound of needed type:
569 // Booleans may produce compounds of Solids
570 if (aShapeType == TopAbs_COMPOUND) {
571 for(TopoDS_Iterator aSubs(theShape); aSubs.More(); aSubs.Next()) {
572 if (!aSubs.Value().IsNull()) {
573 TopAbs_ShapeEnum aSubType = aSubs.Value().ShapeType();
574 if (aSubType == TopAbs_COMPOUND) { // compound of compound(s)
575 aShapeType = TopAbs_COMPOUND;
578 if (aShapeType == TopAbs_COMPOUND) {
579 aShapeType = aSubType;
580 } else if (aShapeType != aSubType) { // compound of shapes of different types
581 aShapeType = TopAbs_COMPOUND;
590 TopoDS_Shape getSelectedShape(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs)
592 if (thePrs->shape().get())
593 return thePrs->shape()->impl<TopoDS_Shape>();
595 Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast(thePrs->owner());
596 if (!anOwner.IsNull())
597 return anOwner->Shape();
599 return TopoDS_Shape();
602 void getParameters(QStringList& theParameters)
604 theParameters.clear();
606 SessionPtr aSession = ModelAPI_Session::get();
607 std::list<DocumentPtr> aDocList;
608 DocumentPtr anActiveDocument = aSession->activeDocument();
609 DocumentPtr aRootDocument = aSession->moduleDocument();
610 aDocList.push_back(anActiveDocument);
611 if (anActiveDocument != aRootDocument) {
612 aDocList.push_back(aRootDocument);
614 std::string aGroupId = ModelAPI_ResultParameter::group();
615 for(std::list<DocumentPtr>::const_iterator it = aDocList.begin(); it != aDocList.end(); ++it) {
616 DocumentPtr aDocument = *it;
617 int aSize = aDocument->size(aGroupId);
618 for (int i = 0; i < aSize; i++) {
619 ObjectPtr anObject = aDocument->object(aGroupId, i);
620 std::wstring aParameterName = anObject->data()->name();
621 theParameters.append(QString::fromStdWString(aParameterName));
626 std::string findGreedAttribute(ModuleBase_IWorkshop* theWorkshop,
627 const FeaturePtr& theFeature)
629 std::string anAttributeId;
631 std::string aXmlCfg, aDescription;
632 theWorkshop->module()->getXMLRepresentation(theFeature->getKind(), aXmlCfg, aDescription);
634 ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop);
635 std::string anAttributeTitle;
636 aFactory.getGreedAttribute(anAttributeId);
638 return anAttributeId;
641 bool hasObject(const AttributePtr& theAttribute, const ObjectPtr& theObject,
642 const std::shared_ptr<GeomAPI_Shape>& theShape,
643 ModuleBase_IWorkshop* theWorkshop,
644 const bool theTemporarily)
646 bool aHasObject = false;
647 if (!theAttribute.get())
650 std::string aType = theAttribute->attributeType();
651 if (aType == ModelAPI_AttributeReference::typeId()) {
652 AttributeReferencePtr aRef =
653 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
654 ObjectPtr aObject = aRef->value();
655 aHasObject = aObject && aObject->isSame(theObject);
656 //if (!(aObject && aObject->isSame(theObject))) {
657 // aRef->setValue(theObject);
659 } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
660 AttributeRefAttrPtr aRefAttr =
661 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
663 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
664 if (anAttribute.get()) {
665 //aRefAttr->setAttr(anAttribute);
668 ObjectPtr aObject = aRefAttr->object();
669 aHasObject = aObject && aObject->isSame(theObject);
670 //if (!(aObject && aObject->isSame(theObject))) {
671 // aRefAttr->setObject(theObject);
674 } else if (aType == ModelAPI_AttributeSelection::typeId()) {
675 /*AttributeSelectionPtr aSelectAttr =
676 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
677 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
678 if (aSelectAttr.get() != NULL) {
679 aSelectAttr->setValue(aResult, theShape, theTemporarily);
682 if (aType == ModelAPI_AttributeSelectionList::typeId()) {
683 AttributeSelectionListPtr aSelectionListAttr =
684 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
685 aHasObject = aSelectionListAttr->isInList(theObject, theShape, theTemporarily);
687 else if (aType == ModelAPI_AttributeRefList::typeId()) {
688 AttributeRefListPtr aRefListAttr =
689 std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttribute);
690 aHasObject = aRefListAttr->isInList(theObject);
691 //if (!theCheckIfAttributeHasObject || !aRefListAttr->isInList(theObject))
692 // aRefListAttr->append(theObject);
694 else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
695 AttributeRefAttrListPtr aRefAttrListAttr =
696 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(theAttribute);
697 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
699 if (anAttribute.get()) {
700 aHasObject = aRefAttrListAttr->isInList(anAttribute);
701 //if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(anAttribute))
702 // aRefAttrListAttr->append(anAttribute);
705 aHasObject = aRefAttrListAttr->isInList(theObject);
706 //if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(theObject))
707 // aRefAttrListAttr->append(theObject);
713 bool setObject(const AttributePtr& theAttribute, const ObjectPtr& theObject,
714 const GeomShapePtr& theShape, ModuleBase_IWorkshop* theWorkshop,
715 const bool theTemporarily, const bool theCheckIfAttributeHasObject)
717 if (!theAttribute.get())
721 std::string aType = theAttribute->attributeType();
722 if (aType == ModelAPI_AttributeReference::typeId()) {
723 AttributeReferencePtr aRef =
724 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
725 ObjectPtr aObject = aRef->value();
726 if (!(aObject && aObject->isSame(theObject))) {
727 aRef->setValue(theObject);
729 } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
730 AttributeRefAttrPtr aRefAttr =
731 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
733 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
734 if (anAttribute.get())
735 aRefAttr->setAttr(anAttribute);
737 ObjectPtr aObject = aRefAttr->object();
738 if (!(aObject && aObject->isSame(theObject))) {
739 aRefAttr->setObject(theObject);
742 } else if (aType == ModelAPI_AttributeSelection::typeId()) {
743 AttributeSelectionPtr aSelectAttr =
744 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
745 if (aSelectAttr.get() != NULL) {
746 aSelectAttr->setValue(theObject, theShape, theTemporarily);
749 if (aType == ModelAPI_AttributeSelectionList::typeId()) {
750 AttributeSelectionListPtr aSelectionListAttr =
751 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
752 if (!theCheckIfAttributeHasObject ||
753 !aSelectionListAttr->isInList(theObject, theShape, theTemporarily))
754 aSelectionListAttr->append(theObject, theShape, theTemporarily);
756 else if (aType == ModelAPI_AttributeRefList::typeId()) {
757 AttributeRefListPtr aRefListAttr =
758 std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttribute);
759 if (!theCheckIfAttributeHasObject || !aRefListAttr->isInList(theObject)) {
761 aRefListAttr->append(theObject);
766 else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
767 AttributeRefAttrListPtr aRefAttrListAttr =
768 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(theAttribute);
769 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
771 if (anAttribute.get()) {
772 if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(anAttribute))
773 aRefAttrListAttr->append(anAttribute);
776 if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(theObject)) {
778 aRefAttrListAttr->append(theObject);
787 GeomShapePtr getShape(const AttributePtr& theAttribute, ModuleBase_IWorkshop* theWorkshop)
790 if (!theAttribute.get())
793 std::string aType = theAttribute->attributeType();
794 if (aType == ModelAPI_AttributeReference::typeId()) {
795 } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
796 AttributeRefAttrPtr aRefAttr =
797 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
798 if (aRefAttr.get() && !aRefAttr->isObject()) {
799 AttributePtr anAttribute = aRefAttr->attr();
800 aShape = theWorkshop->module()->findShape(anAttribute);
802 } else if (aType == ModelAPI_AttributeSelection::typeId()) {
803 AttributeSelectionPtr aSelectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
805 aShape = aSelectAttr->value();
807 else // Geom2D point processing
808 aShape = theWorkshop->module()->findShape(theAttribute);
812 void flushUpdated(ObjectPtr theObject)
814 blockUpdateViewer(true);
816 // Fix the problem of not previewed results of constraints applied. Flush Create/Delete
817 // (for the sketch result) to start processing of the sketch in the solver.
818 // TODO: these flushes should be moved in a separate method provided by Model
819 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
820 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_VISUAL_ATTRIBUTES));
821 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
822 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_UPDATE_SELECTION));
823 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
825 blockUpdateViewer(false);
828 void blockUpdateViewer(const bool theValue)
830 // the viewer update should be blocked in order to avoid the temporary feature content
831 // when the solver processes the feature, the redisplay message can be flushed
832 // what caused the display in the viewer preliminary states of object
833 // e.g. fillet feature, angle value change
834 std::shared_ptr<Events_Message> aMsg;
836 aMsg = std::shared_ptr<Events_Message>(
837 new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED)));
840 // the viewer update should be unblocked
841 aMsg = std::shared_ptr<Events_Message>(
842 new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)));
844 Events_Loop::loop()->send(aMsg);
847 QString wrapTextByWords(const QString& theValue, QWidget* theWidget,
848 int theMaxLineInPixels)
850 static QFontMetrics tfm(theWidget ? theWidget->font() : QApplication::font());
851 static qreal phi = 2.618;
853 QRect aBounds = tfm.boundingRect(theValue);
854 if(aBounds.width() <= theMaxLineInPixels)
857 qreal s = aBounds.width() * aBounds.height();
858 qreal aGoldWidth = sqrt(s*phi);
860 QStringList aWords = theValue.split(" ", QString::SkipEmptyParts);
862 int n = aWords.count();
864 for (int i = 0; i < n; i++) {
865 QString aLineExt = i == 0 ? aWords[i] : aLine + " " + aWords[i];
866 qreal anWidthNonExt = tfm.boundingRect(aLine).width();
867 qreal anWidthExt = tfm.boundingRect(aLineExt).width();
868 qreal aDeltaNonExt = fabs(anWidthNonExt-aGoldWidth);
869 qreal aDeltaExt = fabs(anWidthExt-aGoldWidth);
870 if(aDeltaNonExt < aDeltaExt) {
872 aLines.append(aLine);
880 aLines.append(aLine);
882 QString aResult = aLines.join("\n");
886 //**************************************************************
887 QLocale doubleLocale()
889 // VSR 01/07/2010: Disable thousands separator for spin box
890 // (to avoid inconsistency of double-2-string and string-2-double conversion)
892 aLocale.setNumberOptions(aLocale.numberOptions() |
893 QLocale::OmitGroupSeparator |
894 QLocale::RejectGroupSeparator);
898 //**************************************************************
899 void refsToFeatureInFeatureDocument(const ObjectPtr& theObject,
900 std::set<FeaturePtr>& theRefFeatures)
902 FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
903 if (aFeature.get()) {
904 DocumentPtr aFeatureDoc = aFeature->document();
905 // 1. find references in the current document
906 aFeatureDoc->refsToFeature(aFeature, theRefFeatures, false);
911 //**************************************************************
912 /*bool isSubOfComposite(const ObjectPtr& theObject)
915 std::set<FeaturePtr> aRefFeatures;
916 refsToFeatureInFeatureDocument(theObject, aRefFeatures);
917 std::set<FeaturePtr>::const_iterator anIt = aRefFeatures.begin(),
918 aLast = aRefFeatures.end();
919 for (; anIt != aLast && !isSub; anIt++) {
920 isSub = isSubOfComposite(theObject, *anIt);
925 //**************************************************************
926 /*bool isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature)
929 CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
930 if (aComposite.get()) {
931 isSub = aComposite->isSub(theObject);
932 // the recursive is possible, the parameters are sketch circle and extrusion cut. They are
933 // separated by composite sketch feature
935 int aNbSubs = aComposite->numberOfSubs();
936 for (int aSub = 0; aSub < aNbSubs && !isSub; aSub++) {
937 isSub = isSubOfComposite(theObject, aComposite->subFeature(aSub));
944 //**************************************************************
945 ResultPtr firstResult(const ObjectPtr& theObject)
947 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
948 if (!aResult.get()) {
949 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
951 aResult = aFeature->firstResult();
956 //**************************************************************
957 bool isFeatureOfResult(const FeaturePtr& theFeature, const std::string& theGroupOfResult)
959 bool isResult = false;
961 if (!theFeature->data()->isValid())
964 ResultPtr aFirstResult = theFeature->firstResult();
965 if (!aFirstResult.get())
968 return aFirstResult->groupName() == theGroupOfResult;
971 //**************************************************************
972 bool hasModuleDocumentFeature(const std::set<FeaturePtr>& theFeatures)
974 bool aFoundModuleDocumentObject = false;
975 DocumentPtr aModuleDoc = ModelAPI_Session::get()->moduleDocument();
977 std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(), aLast = theFeatures.end();
978 for (; anIt != aLast && !aFoundModuleDocumentObject; anIt++) {
979 FeaturePtr aFeature = *anIt;
980 ResultPtr aResult = ModuleBase_Tools::firstResult(aFeature);
981 if (aResult.get() && aResult->groupName() == ModelAPI_ResultPart::group())
983 aFoundModuleDocumentObject = aFeature->document() == aModuleDoc;
986 return aFoundModuleDocumentObject;
989 //**************************************************************
990 bool askToDelete(const std::set<FeaturePtr> theFeatures,
991 const std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
993 std::set<FeaturePtr>& theReferencesToDelete,
994 const std::string& thePrefixInfo)
996 QString aNotActivatedDocWrn;
997 std::wstring aNotActivatedNames;
998 if (!ModelAPI_Tools::allDocumentsActivated(aNotActivatedNames)) {
999 if (ModuleBase_Tools::hasModuleDocumentFeature(theFeatures))
1000 aNotActivatedDocWrn =
1001 QObject::tr("Selected objects can be used in Part documents which are not loaded: %1.\n")
1002 .arg(QString::fromStdWString(aNotActivatedNames));
1005 std::set<FeaturePtr> aFeaturesRefsTo;
1006 std::set<FeaturePtr> aFeaturesRefsToParameter;
1007 std::set<FeaturePtr> aParameterFeatures;
1008 QStringList aPartFeatureNames;
1009 std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),
1010 aLast = theFeatures.end();
1011 // separate features to references to parameter features and references to others
1012 for (; anIt != aLast; anIt++) {
1013 FeaturePtr aFeature = *anIt;
1014 if (theReferences.find(aFeature) == theReferences.end())
1017 if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group()))
1018 aPartFeatureNames.append(QString::fromStdWString(aFeature->name()));
1020 std::set<FeaturePtr> aRefFeatures;
1021 std::set<FeaturePtr> aRefList = theReferences.at(aFeature);
1022 std::set<FeaturePtr>::const_iterator aRefIt = aRefList.begin(), aRefLast = aRefList.end();
1023 for (; aRefIt != aRefLast; aRefIt++) {
1024 FeaturePtr aRefFeature = *aRefIt;
1025 if (theFeatures.find(aRefFeature) == theFeatures.end() && // it is not selected
1026 aRefFeatures.find(aRefFeature) == aRefFeatures.end()) // it is not added
1027 aRefFeatures.insert(aRefFeature);
1030 if (isFeatureOfResult(aFeature, ModelAPI_ResultParameter::group())) {
1031 aFeaturesRefsToParameter.insert(aRefFeatures.begin(), aRefFeatures.end());
1032 aParameterFeatures.insert(aFeature);
1035 theReferencesToDelete.insert(aRefFeatures.begin(), aRefFeatures.end());
1039 std::set<FeaturePtr> aFeaturesRefsToParameterOnly;
1040 anIt = aFeaturesRefsToParameter.begin();
1041 aLast = aFeaturesRefsToParameter.end();
1042 // separate features to references to parameter features and references to others
1043 QStringList aParamFeatureNames;
1044 for (; anIt != aLast; anIt++) {
1045 FeaturePtr aFeature = *anIt;
1046 if (theReferencesToDelete.find(aFeature) == theReferencesToDelete.end()) {
1047 aFeaturesRefsToParameterOnly.insert(aFeature);
1048 aParamFeatureNames.append(QString::fromStdWString(aFeature->name()));
1051 aParamFeatureNames.sort();
1052 QStringList anOtherFeatureNames;
1053 anIt = theReferencesToDelete.begin();
1054 aLast = theReferencesToDelete.end();
1055 for (; anIt != aLast; anIt++) {
1056 FeaturePtr aFeature = *anIt;
1057 if (aFeature->getKind() == "RemoveResults")
1058 continue; // skip the remove results feature mentioning: result will be removed anyway
1059 if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group()))
1060 aPartFeatureNames.append(QString::fromStdWString(aFeature->name()));
1062 anOtherFeatureNames.append(QString::fromStdWString(aFeature->name()));
1064 aPartFeatureNames.sort();
1065 anOtherFeatureNames.sort();
1067 QMessageBox aMessageBox(theParent);
1068 aMessageBox.setWindowTitle(QObject::tr("Delete features"));
1069 aMessageBox.setIcon(QMessageBox::Warning);
1070 aMessageBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
1071 aMessageBox.setDefaultButton(QMessageBox::No);
1073 QString aText, aDetailedText;
1074 if (!thePrefixInfo.empty())
1075 aText = thePrefixInfo.c_str();
1076 QString aSep = ", ";
1077 if (!aPartFeatureNames.empty()) {
1078 aText += QString(QObject::tr("The following parts will be deleted: %1.\n"))
1079 .arg(aPartFeatureNames.join(aSep));
1081 if (!aNotActivatedDocWrn.isEmpty())
1082 aText += aNotActivatedDocWrn;
1083 if (!anOtherFeatureNames.empty()) {
1084 const char* aMsg = "The selected features are used in some\n"
1085 "other features, which will also be deleted.\n";
1086 const char* aMsgDetails = "The selected features are used"
1087 " in the following features: %1.\n";
1088 aText += QString(QObject::tr(aMsg));
1089 aDetailedText += QString(QObject::tr(aMsgDetails))
1090 .arg(anOtherFeatureNames.join(aSep));
1092 if (!aParamFeatureNames.empty()) {
1093 const char* aMsg = "The selected parameters are used directly or through\n"
1094 "a sequence of dependencies in some features.\n"
1095 "These features will be deleted.\n"
1096 "Or parameters could be replaced by their values.\n";
1097 const char* aMsgDetails = "Parameters are used in the following features: %1.\n";
1098 aText += QString(QObject::tr(aMsg));
1099 aDetailedText += QString(QObject::tr(aMsgDetails))
1100 .arg(aParamFeatureNames.join(aSep));
1102 QPushButton *aReplaceButton =
1104 aMessageBox.addButton(QObject::tr("Replace"), QMessageBox::ActionRole);
1107 if (!aText.isEmpty()) {
1108 aMessageBox.setText(aText);
1109 aMessageBox.setInformativeText(QObject::tr("Would you like to continue?"));
1110 if (!aDetailedText.isEmpty())
1111 aMessageBox.setDetailedText(aDetailedText);
1113 QMessageBox::ButtonRole aButtonRole = aMessageBox.buttonRole(aMessageBox.clickedButton());
1115 if (aButtonRole == QMessageBox::NoRole)
1118 if (aButtonRole == QMessageBox::ActionRole) {
1119 foreach (FeaturePtr aObj, aParameterFeatures)
1120 ModelAPI_ReplaceParameterMessage::send(aObj, 0);
1123 theReferencesToDelete.insert(aFeaturesRefsToParameterOnly.begin(),
1124 aFeaturesRefsToParameterOnly.end());
1129 //**************************************************************
1130 void convertToFeatures(const QObjectPtrList& theObjects, std::set<FeaturePtr>& theFeatures)
1132 QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
1133 for(; anIt != aLast; anIt++) {
1134 ObjectPtr anObject = *anIt;
1135 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
1136 // for parameter result, use the corresponded reature to be removed
1137 if (!aFeature.get() && anObject->groupName() == ModelAPI_ResultParameter::group()) {
1138 aFeature = ModelAPI_Feature::feature(anObject);
1141 theFeatures.insert(aFeature);
1145 //**************************************************************
1146 void convertToFolders(const QObjectPtrList& theObjects,
1147 std::set<FolderPtr>& theFolders)
1149 QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
1150 for(; anIt != aLast; anIt++) {
1151 ObjectPtr anObject = *anIt;
1152 FolderPtr aFeature = std::dynamic_pointer_cast<ModelAPI_Folder>(anObject);
1154 theFolders.insert(aFeature);
1159 //**************************************************************
1160 QString translate(const Events_InfoMessage& theMessage)
1164 if (!theMessage.empty()) {
1165 std::string aStr = Config_Translator::translate(theMessage);
1166 if (!aStr.empty()) {
1167 std::string aCodec = Config_Translator::codec(theMessage);
1168 aMessage = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
1175 QString translate(const std::string& theContext, const std::string& theMessage)
1179 if (!theMessage.empty()) {
1180 std::string aStr = Config_Translator::translate(theContext, theMessage);
1181 if (!aStr.empty()) {
1182 std::string aCodec = Config_Translator::codec(theContext);
1183 aMessage = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
1190 void setPointBallHighlighting(AIS_InteractiveObject* theAIS)
1192 static Handle(Image_AlienPixMap) aPixMap;
1193 if(aPixMap.IsNull()) {
1194 // Load icon for the presentation
1196 char* anEnv = getenv("SHAPER_ROOT_DIR");
1198 aFile = std::string(anEnv) +
1199 FSEP + "share" + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper";
1201 anEnv = getenv("CADBUILDER_ROOT_DIR");
1203 aFile = std::string(anEnv) + FSEP + "resources";
1207 static const std::string aMarkerName = "marker_dot.png";
1208 aFile += aMarkerName;
1209 aPixMap = new Image_AlienPixMap();
1210 if(!aPixMap->Load(aFile.c_str())) {
1211 // The icon for constraint is not found
1212 static const std::string aMsg =
1213 "Error: Point market not found by path: \"" + aFile + "\". Falling back.";
1214 //Events_InfoMessage("ModuleBase_Tools::setPointBallHighlighting", aMsg).send();
1218 Handle(Graphic3d_AspectMarker3d) anAspect;
1219 Handle(Prs3d_Drawer) aDrawer = theAIS->DynamicHilightAttributes();
1220 if (aDrawer.IsNull()) {
1221 if (ModuleBase_IViewer::DefaultHighlightDrawer.IsNull())
1223 aDrawer = new Prs3d_Drawer(*ModuleBase_IViewer::DefaultHighlightDrawer);
1224 if (!aDrawer->HasOwnPointAspect()) {
1225 aDrawer->SetPointAspect(new Prs3d_PointAspect(Aspect_TOM_BALL, Quantity_NOC_BLACK, 2.0));
1228 if(aDrawer->HasOwnPointAspect()) {
1229 Handle(Prs3d_PointAspect) aPntAspect = aDrawer->PointAspect();
1230 if(aPixMap->IsEmpty()) {
1231 anAspect = aPntAspect->Aspect();
1232 anAspect->SetType(Aspect_TOM_BALL);
1234 if(aPixMap->Format() == Image_PixMap::ImgGray) {
1235 aPixMap->SetFormat (Image_PixMap::ImgAlpha);
1236 } else if(aPixMap->Format() == Image_PixMap::ImgGrayF) {
1237 aPixMap->SetFormat (Image_PixMap::ImgAlphaF);
1239 anAspect = new Graphic3d_AspectMarker3d(aPixMap);
1240 aPntAspect->SetAspect(anAspect);
1242 aDrawer->SetPointAspect(aPntAspect);
1243 theAIS->SetDynamicHilightAttributes(aDrawer);
1247 FeaturePtr createParameter(const QString& theText)
1249 FeaturePtr aParameter;
1250 QStringList aList = theText.split("=");
1251 if (aList.count() != 2) {
1254 QString aParamName = aList.at(0).trimmed();
1256 if (isNameExist(aParamName, FeaturePtr())) {
1260 if (!ModelAPI_Expression::isVariable(aParamName.toStdString())) {
1264 QString aExpression = aList.at(1).trimmed();
1265 if (aExpression.isEmpty()) {
1269 SessionPtr aMgr = ModelAPI_Session::get();
1270 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1272 aParameter = aDoc->addFeature("Parameter", false);
1273 if (aParameter.get()) {
1274 AttributeStringPtr aNameAttr = aParameter->string("variable");
1275 aNameAttr->setValue(aParamName.toStdString());
1277 AttributeStringPtr aExprAttr = aParameter->string("expression");
1278 aExprAttr->setValue(aExpression.toStdString());
1279 aParameter->execute();
1281 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
1282 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
1287 void editParameter(FeaturePtr theParam, const QString& theText)
1289 QStringList aList = theText.split("=");
1290 QString aParamName = aList.at(0).trimmed();
1292 QString aExpression = aList.at(1).trimmed();
1293 if (aExpression.isEmpty()) {
1297 if (isNameExist(aParamName, theParam)) {
1300 AttributeStringPtr aNameAttr = theParam->string("variable");
1301 aNameAttr->setValue(aParamName.toStdString());
1303 AttributeStringPtr aExprAttr = theParam->string("expression");
1304 aExprAttr->setValue(aExpression.toStdString());
1305 theParam->execute();
1307 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
1310 bool isNameExist(const QString& theName, FeaturePtr theIgnoreParameter)
1312 SessionPtr aMgr = ModelAPI_Session::get();
1313 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1314 FeaturePtr aParamFeature;
1315 int aNbFeatures = aDoc->numInternalFeatures();
1316 std::wstring aName = theName.toStdWString();
1317 for (int i = 0; i < aNbFeatures; i++) {
1318 aParamFeature = aDoc->internalFeature(i);
1319 if (aParamFeature && aParamFeature->getKind() == "Parameter") {
1320 if ((theIgnoreParameter != aParamFeature) && (aParamFeature->name() == aName))
1327 FeaturePtr findParameter(const QString& theName)
1329 SessionPtr aMgr = ModelAPI_Session::get();
1330 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1331 FeaturePtr aParamFeature;
1332 int aNbFeatures = aDoc->numInternalFeatures();
1333 std::wstring aName = theName.toStdWString();
1334 for (int i = 0; i < aNbFeatures; i++) {
1335 aParamFeature = aDoc->internalFeature(i);
1336 if (aParamFeature && aParamFeature->getKind() == "Parameter") {
1337 if (aParamFeature->name() == aName)
1338 return aParamFeature;
1341 return FeaturePtr();
1345 //********************************************************************
1346 std::wstring generateName(const AttributePtr& theAttribute,
1347 ModuleBase_IWorkshop* theWorkshop)
1350 if (theAttribute.get() != NULL) {
1351 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
1352 if (aFeature.get()) {
1353 std::string aXmlCfg, aDescription;
1354 theWorkshop->module()->getXMLRepresentation(aFeature->getKind(), aXmlCfg, aDescription);
1356 ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop);
1357 std::string anAttributeTitle;
1358 aFactory.getAttributeTitle(theAttribute->id(), anAttributeTitle);
1360 std::wstringstream aStreamName;
1361 aStreamName << theAttribute->owner()->data()->name() << "/" << anAttributeTitle.c_str();
1362 aName = aStreamName.str();
1368 bool isSameShape(const TopoDS_Shape& theShape1, const TopoDS_Shape& theShape2)
1370 // In case of compound we cannot rely on simple comparison method.
1371 // If the compound is generated by Group feature then this compound is alwais new.
1372 // So, we have to compare content of these compounds
1373 if (theShape1.ShapeType() != theShape2.ShapeType())
1376 if (theShape1.ShapeType() != TopAbs_COMPOUND)
1377 return theShape1.IsSame(theShape2);
1379 TopoDS_Iterator aIt1(theShape1);
1380 TopoDS_Iterator aIt2(theShape2);
1382 for (; aIt1.More() && aIt2.More(); aIt1.Next(), aIt2.Next()) {
1383 if (!(aIt1.Value()).IsSame(aIt2.Value()))
1389 qreal currentPixelRatio()
1391 QWindowList aWnds = qApp->topLevelWindows();
1392 if (aWnds.size() > 0)
1393 return aWnds.first()->devicePixelRatio();
1394 return qApp->primaryScreen()->devicePixelRatio();
1398 // Set displaying status to every element on group
1399 static void setDisplayingByLoop(DocumentPtr theDoc, int theSize,
1400 std::string theGroup, bool theDisplayFromScript)
1402 int aDisplayingId = -1;
1403 if (theDisplayFromScript) {
1404 aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General",
1405 "part_visualization_script", -1);
1406 // Increase ID to prevert using "As stored in HDF"
1410 aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General",
1411 "part_visualization_study", -1);
1413 // if chosen "As stored in HDF" then don't change displaying
1414 if (aDisplayingId == 0)
1418 for (int anIndex = theSize - 1; anIndex >= 0; --anIndex) {
1419 ObjectPtr anObject = theDoc->object(theGroup, anIndex);
1420 anObject->setDisplayed((aDisplayingId == 1 && anIndex == theSize - 1) || aDisplayingId == 2);
1424 void setDisplaying(ResultPartPtr thePart, bool theDisplayFromScript)
1426 DocumentPtr aDoc = thePart->partDoc();
1427 int aConstructionSize = aDoc->size(ModelAPI_ResultConstruction::group());
1428 int aGroupSize = aDoc->size(ModelAPI_ResultGroup::group());
1429 int aFieldSize = aDoc->size(ModelAPI_ResultField::group());
1430 int aResultSize = aDoc->size(ModelAPI_ResultBody::group());
1431 setDisplayingByLoop(aDoc, aConstructionSize,
1432 ModelAPI_ResultConstruction::group(), theDisplayFromScript);
1433 setDisplayingByLoop(aDoc, aGroupSize, ModelAPI_ResultGroup::group(), theDisplayFromScript);
1434 setDisplayingByLoop(aDoc, aFieldSize, ModelAPI_ResultField::group(), theDisplayFromScript);
1435 setDisplayingByLoop(aDoc, aResultSize, ModelAPI_ResultBody::group(), theDisplayFromScript);
1438 } // namespace ModuleBase_Tools