1 // Copyright (C) 2014-2022 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>
57 #include <SUIT_ResourceMgr.h>
60 #include <SUIT_Application.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>
101 #pragma warning(disable : 4996) // for getenv
104 const double tolerance = 1e-7;
105 const double DEFAULT_DEVIATION_COEFFICIENT = 1.e-4;
107 //#define DEBUG_ACTIVATE_WINDOW
108 //#define DEBUG_SET_FOCUS
116 namespace ModuleBase_Tools {
118 //******************************************************************
120 //! Waits for REDISPLAY message and set the Visible flag to the entities
121 //! according to Preferences choice.
122 class ModuleBase_RedisplayListener : public Events_Listener
125 static std::shared_ptr<ModuleBase_RedisplayListener> instance()
127 static std::shared_ptr<ModuleBase_RedisplayListener>
128 anInstance(new ModuleBase_RedisplayListener);
132 void processEvent(const std::shared_ptr<Events_Message>& theMessage)
134 if (theMessage->eventID() == Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY))
137 // If the python script is being loaded now, the preferences should be used
138 // to display the required object
139 SUIT_Session* aSession = SUIT_Session::session();
142 SUIT_Application * anApp = aSession->activeApplication();
145 QVariant aVar = anApp->property("IsLoadedScript");
146 if (!aVar.isNull() && aVar.toBool()) {
147 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
148 int aSize = aRootDoc->size(ModelAPI_ResultPart::group());
150 ObjectPtr anPartObject = aRootDoc->object(ModelAPI_ResultPart::group(), aSize - 1);
151 ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(anPartObject);
152 ModuleBase_Tools::setDisplaying(aPart, true);
160 ModuleBase_RedisplayListener()
162 Events_Loop::loop()->registerListener(this,
163 Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
167 static std::shared_ptr<ModuleBase_RedisplayListener>
168 RL = ModuleBase_RedisplayListener::instance();
170 //******************************************************************
172 void adjustMargins(QWidget* theWidget)
176 adjustMargins(theWidget->layout());
179 void adjustMargins(QLayout* theLayout)
183 theLayout->setContentsMargins(2, 5, 2, 5);
184 theLayout->setSpacing(4);
187 void zeroMargins(QWidget* theWidget)
191 zeroMargins(theWidget->layout());
194 void zeroMargins(QLayout* theLayout)
198 theLayout->setContentsMargins(0, 0, 0, 0);
199 theLayout->setSpacing(5);
202 void activateWindow(QWidget* theWidget, const QString& theInfo)
205 theWidget->activateWindow();
209 #ifdef DEBUG_ACTIVATE_WINDOW
210 qDebug(QString("activateWindow: %1").arg(theInfo).toStdString().c_str());
214 void setFocus(QWidget* theWidget, const QString& theInfo)
216 activateWindow(theWidget);
217 theWidget->setFocus();
218 // rectangle of focus is not visible on tool button widgets
220 #ifdef DEBUG_SET_FOCUS
221 qDebug(QString("setFocus: %1").arg(theInfo).toStdString().c_str());
225 void setShadowEffect(QWidget* theWidget, const bool isSetEffect)
228 QGraphicsDropShadowEffect* aGlowEffect = new QGraphicsDropShadowEffect();
229 aGlowEffect->setOffset(.0);
230 aGlowEffect->setBlurRadius(10.0);
231 aGlowEffect->setColor(QColor(0, 170, 255)); // Light-blue color, #00AAFF
232 theWidget->setGraphicsEffect(aGlowEffect);
235 QGraphicsEffect* anEffect = theWidget->graphicsEffect();
237 anEffect->deleteLater();
238 theWidget->setGraphicsEffect(NULL);
242 QPixmap composite(const QString& theAdditionalIcon, const QString& theIcon)
244 QImage anIcon = ModuleBase_IconFactory::loadImage(theIcon);
245 QImage anAditional(theAdditionalIcon);
246 return composite(anAditional, anIcon);
249 QPixmap composite(const QImage& theAdditionalIcon, QImage& theIcon)
251 if (theIcon.isNull())
254 int anAddWidth = theAdditionalIcon.width();
255 int anAddHeight = theAdditionalIcon.height();
257 int aWidth = theIcon.width();
258 int aHeight = theIcon.height();
260 int aStartWidthPos = aWidth - anAddWidth;
261 int aStartHeightPos = aHeight - anAddHeight;
263 for (int i = 0; i < anAddWidth && i + aStartWidthPos < aWidth; i++)
265 for (int j = 0; j < anAddHeight && j + aStartHeightPos < aHeight; j++)
267 if (qAlpha(theAdditionalIcon.pixel(i, j)) > 0)
268 theIcon.setPixel(i + aStartWidthPos, j + aStartHeightPos, theAdditionalIcon.pixel(i, j));
271 return QPixmap::fromImage(theIcon);
274 QPixmap lighter(const QString& theIcon, const int theLighterValue)
276 QImage anIcon = ModuleBase_IconFactory::loadImage(theIcon);
280 QImage aResult = ModuleBase_IconFactory::loadImage(theIcon);
281 for (int i = 0; i < anIcon.width(); i++)
283 for (int j = 0; j < anIcon.height(); j++)
285 QRgb anRgb = anIcon.pixel(i, j);
286 QColor aPixelColor(qRed(anRgb), qGreen(anRgb), qBlue(anRgb),
287 qAlpha(aResult.pixel(i, j)));
289 QColor aLighterColor = aPixelColor.lighter(theLighterValue);
290 aResult.setPixel(i, j, qRgba(aLighterColor.red(), aLighterColor.green(),
291 aLighterColor.blue(), aLighterColor.alpha()));
294 return QPixmap::fromImage(aResult);
297 void setSpinText(ModuleBase_ParamSpinBox* theSpin, const QString& theText)
299 if (theSpin->text() == theText)
301 // In order to avoid extra text setting because it will
302 // reset cursor position in control
303 bool isBlocked = theSpin->blockSignals(true);
304 theSpin->setText(theText);
305 theSpin->blockSignals(isBlocked);
308 void setSpinValue(QDoubleSpinBox* theSpin, double theValue)
310 if (fabs(theSpin->value() - theValue) < tolerance)
312 bool isBlocked = theSpin->blockSignals(true);
313 theSpin->setValue(theValue);
314 theSpin->blockSignals(isBlocked);
317 void setSpinValue(ModuleBase_ParamSpinBox* theSpin, double theValue)
319 if (!theSpin->text().isEmpty() && fabs(theSpin->value() - theValue) < tolerance)
321 bool isBlocked = theSpin->blockSignals(true);
322 theSpin->setValue(theValue);
323 theSpin->blockSignals(isBlocked);
326 void setSpinText(ModuleBase_ParamIntSpinBox* theSpin, const QString& theText)
328 // In order to avoid extra text setting because it will
329 // reset cursor position in control
330 if (theSpin->text() == theText)
332 bool isBlocked = theSpin->blockSignals(true);
333 theSpin->setText(theText);
334 theSpin->blockSignals(isBlocked);
337 void setSpinValue(ModuleBase_ParamIntSpinBox* theSpin, int theValue)
339 if (theSpin->value() == theValue)
341 bool isBlocked = theSpin->blockSignals(true);
342 theSpin->setValue(theValue);
343 theSpin->blockSignals(isBlocked);
346 QAction* createAction(const QIcon& theIcon, const QString& theText,
347 QObject* theParent, const QObject* theReceiver,
348 const char* theMember, const QString& theToolTip,
349 const QString& theStatusTip)
351 QAction* anAction = new QAction(theIcon, theText, theParent);
352 anAction->setToolTip(theToolTip.isEmpty() ? theText : theToolTip);
353 anAction->setStatusTip(!theStatusTip.isEmpty() ? theStatusTip :
354 (!theToolTip.isEmpty() ? theToolTip : theText));
356 QObject::connect(anAction, SIGNAL(triggered(bool)), theReceiver, theMember);
362 QString objectName(const ObjectPtr& theObj)
367 return QString::fromStdWString(theObj->data()->name());
370 QString objectInfo(const ObjectPtr& theObj, const bool isUseAttributesInfo)
372 QString aFeatureStr = "feature";
376 std::ostringstream aPtrStr;
377 aPtrStr << "[" << theObj.get() << "]";
379 ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObj);
380 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObj);
382 aFeatureStr.append(QString("(result%1)").arg(aPtrStr.str().c_str()).toStdString() .c_str());
383 if (aRes->isDisabled())
384 aFeatureStr.append("[disabled]");
385 if (aRes->isConcealed())
386 aFeatureStr.append("[concealed]");
387 if (ModelAPI_Tools::hasSubResults(aRes))
388 aFeatureStr.append("[hasSubResults]");
390 aFeature = ModelAPI_Feature::feature(aRes);
393 aFeatureStr.append(aPtrStr.str().c_str());
395 if (aFeature.get()) {
396 aFeatureStr.append(QString(": %1").arg(aFeature->getKind().c_str()).toStdString().c_str());
397 if (aFeature->data()->isValid()) {
398 aFeatureStr.append(QString(", name=%1")
399 .arg(QString::fromStdWString(theObj->data()->name())).toStdString().c_str());
401 if (isUseAttributesInfo) {
402 std::set<std::shared_ptr<ModelAPI_Attribute> > anAttributes;
403 std::string aPointsInfo = ModelGeomAlgo_Point2D::getPontAttributesInfo(aFeature,
404 anAttributes).c_str();
405 if (!aPointsInfo.empty())
406 aFeatureStr.append(QString(", attributes: %1")
407 .arg(aPointsInfo.c_str()).toStdString().c_str());
415 typedef QMap<QString, int> ShapeTypes;
416 static ShapeTypes myShapeTypes;
418 int shapeType(const QString& theType)
420 if (myShapeTypes.count() == 0) {
421 myShapeTypes["compound"] = TopAbs_COMPOUND;
422 myShapeTypes["compounds"] = TopAbs_COMPOUND;
423 myShapeTypes["compsolid"] = TopAbs_COMPSOLID;
424 myShapeTypes["compsolids"] = TopAbs_COMPSOLID;
425 myShapeTypes["solid"] = TopAbs_SOLID;
426 myShapeTypes["solids"] = TopAbs_SOLID;
427 myShapeTypes["shell"] = TopAbs_SHELL;
428 myShapeTypes["shells"] = TopAbs_SHELL;
429 myShapeTypes["face"] = TopAbs_FACE;
430 myShapeTypes["faces"] = TopAbs_FACE;
431 myShapeTypes["wire"] = TopAbs_WIRE;
432 myShapeTypes["wires"] = TopAbs_WIRE;
433 myShapeTypes["edge"] = TopAbs_EDGE;
434 myShapeTypes["edges"] = TopAbs_EDGE;
435 myShapeTypes["vertex"] = TopAbs_VERTEX;
436 myShapeTypes["vertices"] = TopAbs_VERTEX;
437 myShapeTypes["object"] = ModuleBase_ResultPrs::Sel_Result;
438 myShapeTypes["objects"] = ModuleBase_ResultPrs::Sel_Result;
440 QString aType = theType.toLower();
441 if(myShapeTypes.contains(aType))
442 return myShapeTypes[aType];
443 Events_InfoMessage("ModuleBase_Tools", "Shape type defined in XML is not implemented!").send();
447 void checkObjects(const QObjectPtrList& theObjects, bool& hasResult, bool& hasFeature,
448 bool& hasParameter, bool& hasCompositeOwner, bool& hasResultInHistory,
449 bool& hasFolder, bool &hasGroupsOnly)
453 hasParameter = false;
454 hasCompositeOwner = false;
455 hasResultInHistory = false;
457 bool hasNonGroup = false;
458 foreach(ObjectPtr aObj, theObjects) {
459 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
460 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
461 ResultGroupPtr aGroup = std::dynamic_pointer_cast<ModelAPI_ResultGroup>(aObj);
462 FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(aObj);
463 ResultParameterPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aResult);
464 FieldStepPtr aStep = std::dynamic_pointer_cast<ModelAPI_ResultField::ModelAPI_FieldStep>(aObj);
466 hasResult |= ((aResult.get() != NULL) || (aStep.get() != NULL));
467 hasFeature |= (aFeature.get() != NULL);
468 hasFolder |= (aFolder.get() != NULL);
469 hasParameter |= (aConstruction.get() != NULL);
470 hasNonGroup |= (aGroup.get() == NULL);
472 hasCompositeOwner |= (ModelAPI_Tools::compositeOwner(aFeature) != NULL);
473 else if (aResult.get())
474 hasCompositeOwner |= (ModelAPI_Tools::bodyOwner(aResult) != NULL);
476 if (!hasResultInHistory && aResult.get()) {
477 aFeature = ModelAPI_Feature::feature(aResult);
478 hasResultInHistory = aFeature.get() && aFeature->isInHistory();
481 if (hasFeature && hasResult && hasParameter && hasCompositeOwner && hasNonGroup)
484 hasGroupsOnly = !hasNonGroup;
487 void setDefaultDeviationCoefficient(const TopoDS_Shape& theShape,
488 const Handle(Prs3d_Drawer)& theDrawer)
490 if (theShape.IsNull())
492 if (theDrawer.IsNull())
495 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape());
496 aGeomShape->setImpl(new TopoDS_Shape(theShape));
498 // if the shape could not be exploded on faces, it contains only wires, edges, and vertices
499 // correction of deviation for them should not influence to the application performance
500 GeomAPI_ShapeExplorer anExp(aGeomShape, GeomAPI_Shape::FACE);
501 bool isConstruction = !anExp.more();
505 aDeflection = Config_PropManager::real("Visualization", "construction_deflection");
507 aDeflection = Config_PropManager::real("Visualization", "body_deflection");
509 theDrawer->SetDeviationCoefficient(aDeflection);
512 Quantity_Color color(const std::string& theSection,
513 const std::string& theName)
515 std::vector<int> aColor = Config_PropManager::color(theSection, theName);
516 return Quantity_Color(aColor[0] / 255., aColor[1] / 255., aColor[2] / 255., Quantity_TOC_RGB);
519 ObjectPtr getObject(const AttributePtr& theAttribute)
522 std::string anAttrType = theAttribute->attributeType();
523 if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
524 AttributeRefAttrPtr anAttr =
525 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
526 if (anAttr != NULL && anAttr->isObject())
527 anObject = anAttr->object();
529 if (anAttrType == ModelAPI_AttributeSelection::typeId()) {
530 AttributeSelectionPtr anAttr =
531 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
533 anObject = anAttr->context();
535 if (anAttrType == ModelAPI_AttributeReference::typeId()) {
536 AttributeReferencePtr anAttr =
537 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
538 if (anAttr.get() != NULL)
539 anObject = anAttr->value();
544 TopAbs_ShapeEnum getCompoundSubType(const TopoDS_Shape& theShape)
546 TopAbs_ShapeEnum aShapeType = theShape.ShapeType();
548 // for compounds check sub-shapes: it may be compound of needed type:
549 // Booleans may produce compounds of Solids
550 if (aShapeType == TopAbs_COMPOUND) {
551 for(TopoDS_Iterator aSubs(theShape); aSubs.More(); aSubs.Next()) {
552 if (!aSubs.Value().IsNull()) {
553 TopAbs_ShapeEnum aSubType = aSubs.Value().ShapeType();
554 if (aSubType == TopAbs_COMPOUND) { // compound of compound(s)
555 aShapeType = TopAbs_COMPOUND;
558 if (aShapeType == TopAbs_COMPOUND) {
559 aShapeType = aSubType;
560 } else if (aShapeType != aSubType) { // compound of shapes of different types
561 aShapeType = TopAbs_COMPOUND;
570 TopoDS_Shape getSelectedShape(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs)
572 if (thePrs->shape().get())
573 return thePrs->shape()->impl<TopoDS_Shape>();
575 Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast(thePrs->owner());
576 if (!anOwner.IsNull())
577 return anOwner->Shape();
579 return TopoDS_Shape();
582 void getParameters(QStringList& theParameters)
584 theParameters.clear();
586 SessionPtr aSession = ModelAPI_Session::get();
587 std::list<DocumentPtr> aDocList;
588 DocumentPtr anActiveDocument = aSession->activeDocument();
589 DocumentPtr aRootDocument = aSession->moduleDocument();
590 aDocList.push_back(anActiveDocument);
591 if (anActiveDocument != aRootDocument) {
592 aDocList.push_back(aRootDocument);
594 std::string aGroupId = ModelAPI_ResultParameter::group();
595 for(std::list<DocumentPtr>::const_iterator it = aDocList.begin(); it != aDocList.end(); ++it) {
596 DocumentPtr aDocument = *it;
597 int aSize = aDocument->size(aGroupId);
598 for (int i = 0; i < aSize; i++) {
599 ObjectPtr anObject = aDocument->object(aGroupId, i);
600 std::wstring aParameterName = anObject->data()->name();
601 theParameters.append(QString::fromStdWString(aParameterName));
606 std::string findGreedAttribute(ModuleBase_IWorkshop* theWorkshop,
607 const FeaturePtr& theFeature)
609 std::string anAttributeId;
611 std::string aXmlCfg, aDescription;
612 theWorkshop->module()->getXMLRepresentation(theFeature->getKind(), aXmlCfg, aDescription);
614 ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop);
615 std::string anAttributeTitle;
616 aFactory.getGreedAttribute(anAttributeId);
618 return anAttributeId;
621 bool hasObject(const AttributePtr& theAttribute, const ObjectPtr& theObject,
622 const std::shared_ptr<GeomAPI_Shape>& theShape,
623 ModuleBase_IWorkshop* theWorkshop,
624 const bool theTemporarily)
626 bool aHasObject = false;
627 if (!theAttribute.get())
630 std::string aType = theAttribute->attributeType();
631 if (aType == ModelAPI_AttributeReference::typeId()) {
632 AttributeReferencePtr aRef =
633 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
634 ObjectPtr aObject = aRef->value();
635 aHasObject = aObject && aObject->isSame(theObject);
636 //if (!(aObject && aObject->isSame(theObject))) {
637 // aRef->setValue(theObject);
639 } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
640 AttributeRefAttrPtr aRefAttr =
641 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
643 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
644 if (anAttribute.get()) {
645 //aRefAttr->setAttr(anAttribute);
648 ObjectPtr aObject = aRefAttr->object();
649 aHasObject = aObject && aObject->isSame(theObject);
650 //if (!(aObject && aObject->isSame(theObject))) {
651 // aRefAttr->setObject(theObject);
654 } else if (aType == ModelAPI_AttributeSelection::typeId()) {
655 /*AttributeSelectionPtr aSelectAttr =
656 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
657 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
658 if (aSelectAttr.get() != NULL) {
659 aSelectAttr->setValue(aResult, theShape, theTemporarily);
662 if (aType == ModelAPI_AttributeSelectionList::typeId()) {
663 AttributeSelectionListPtr aSelectionListAttr =
664 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
665 aHasObject = aSelectionListAttr->isInList(theObject, theShape, theTemporarily);
667 else if (aType == ModelAPI_AttributeRefList::typeId()) {
668 AttributeRefListPtr aRefListAttr =
669 std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttribute);
670 aHasObject = aRefListAttr->isInList(theObject);
671 //if (!theCheckIfAttributeHasObject || !aRefListAttr->isInList(theObject))
672 // aRefListAttr->append(theObject);
674 else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
675 AttributeRefAttrListPtr aRefAttrListAttr =
676 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(theAttribute);
677 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
679 if (anAttribute.get()) {
680 aHasObject = aRefAttrListAttr->isInList(anAttribute);
681 //if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(anAttribute))
682 // aRefAttrListAttr->append(anAttribute);
685 aHasObject = aRefAttrListAttr->isInList(theObject);
686 //if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(theObject))
687 // aRefAttrListAttr->append(theObject);
693 bool setObject(const AttributePtr& theAttribute, const ObjectPtr& theObject,
694 const GeomShapePtr& theShape, ModuleBase_IWorkshop* theWorkshop,
695 const bool theTemporarily, const bool theCheckIfAttributeHasObject)
697 if (!theAttribute.get())
701 std::string aType = theAttribute->attributeType();
702 if (aType == ModelAPI_AttributeReference::typeId()) {
703 AttributeReferencePtr aRef =
704 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
705 ObjectPtr aObject = aRef->value();
706 if (!(aObject && aObject->isSame(theObject))) {
707 aRef->setValue(theObject);
709 } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
710 AttributeRefAttrPtr aRefAttr =
711 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
713 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
714 if (anAttribute.get())
715 aRefAttr->setAttr(anAttribute);
717 ObjectPtr aObject = aRefAttr->object();
718 if (!(aObject && aObject->isSame(theObject))) {
719 aRefAttr->setObject(theObject);
722 } else if (aType == ModelAPI_AttributeSelection::typeId()) {
723 AttributeSelectionPtr aSelectAttr =
724 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
725 if (aSelectAttr.get() != NULL) {
726 aSelectAttr->setValue(theObject, theShape, theTemporarily);
729 if (aType == ModelAPI_AttributeSelectionList::typeId()) {
730 AttributeSelectionListPtr aSelectionListAttr =
731 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
732 if (!theCheckIfAttributeHasObject ||
733 !aSelectionListAttr->isInList(theObject, theShape, theTemporarily))
734 aSelectionListAttr->append(theObject, theShape, theTemporarily);
736 else if (aType == ModelAPI_AttributeRefList::typeId()) {
737 AttributeRefListPtr aRefListAttr =
738 std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttribute);
739 if (!theCheckIfAttributeHasObject || !aRefListAttr->isInList(theObject)) {
741 aRefListAttr->append(theObject);
746 else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
747 AttributeRefAttrListPtr aRefAttrListAttr =
748 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(theAttribute);
749 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
751 if (anAttribute.get()) {
752 if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(anAttribute))
753 aRefAttrListAttr->append(anAttribute);
756 if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(theObject)) {
758 aRefAttrListAttr->append(theObject);
767 GeomShapePtr getShape(const AttributePtr& theAttribute, ModuleBase_IWorkshop* theWorkshop)
770 if (!theAttribute.get())
773 std::string aType = theAttribute->attributeType();
774 if (aType == ModelAPI_AttributeReference::typeId()) {
775 } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
776 AttributeRefAttrPtr aRefAttr =
777 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
778 if (aRefAttr.get() && !aRefAttr->isObject()) {
779 AttributePtr anAttribute = aRefAttr->attr();
780 aShape = theWorkshop->module()->findShape(anAttribute);
782 } else if (aType == ModelAPI_AttributeSelection::typeId()) {
783 AttributeSelectionPtr aSelectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
785 aShape = aSelectAttr->value();
787 else // Geom2D point processing
788 aShape = theWorkshop->module()->findShape(theAttribute);
792 void flushUpdated(ObjectPtr theObject)
794 blockUpdateViewer(true);
796 // Fix the problem of not previewed results of constraints applied. Flush Create/Delete
797 // (for the sketch result) to start processing of the sketch in the solver.
798 // TODO: these flushes should be moved in a separate method provided by Model
799 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
800 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_VISUAL_ATTRIBUTES));
801 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
802 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_UPDATE_SELECTION));
803 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
805 blockUpdateViewer(false);
808 void blockUpdateViewer(const bool theValue)
810 // the viewer update should be blocked in order to avoid the temporary feature content
811 // when the solver processes the feature, the redisplay message can be flushed
812 // what caused the display in the viewer preliminary states of object
813 // e.g. fillet feature, angle value change
814 std::shared_ptr<Events_Message> aMsg;
816 aMsg = std::shared_ptr<Events_Message>(
817 new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED)));
820 // the viewer update should be unblocked
821 aMsg = std::shared_ptr<Events_Message>(
822 new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)));
824 Events_Loop::loop()->send(aMsg);
827 QString wrapTextByWords(const QString& theValue, QWidget* theWidget,
828 int theMaxLineInPixels)
830 static QFontMetrics tfm(theWidget ? theWidget->font() : QApplication::font());
831 static qreal phi = 2.618;
833 QRect aBounds = tfm.boundingRect(theValue);
834 if(aBounds.width() <= theMaxLineInPixels)
837 qreal s = aBounds.width() * aBounds.height();
838 qreal aGoldWidth = sqrt(s*phi);
840 QStringList aWords = theValue.split(" ", QString::SkipEmptyParts);
842 int n = aWords.count();
844 for (int i = 0; i < n; i++) {
845 QString aLineExt = i == 0 ? aWords[i] : aLine + " " + aWords[i];
846 qreal anWidthNonExt = tfm.boundingRect(aLine).width();
847 qreal anWidthExt = tfm.boundingRect(aLineExt).width();
848 qreal aDeltaNonExt = fabs(anWidthNonExt-aGoldWidth);
849 qreal aDeltaExt = fabs(anWidthExt-aGoldWidth);
850 if(aDeltaNonExt < aDeltaExt) {
852 aLines.append(aLine);
860 aLines.append(aLine);
862 QString aResult = aLines.join("\n");
866 //**************************************************************
867 QLocale doubleLocale()
869 // VSR 01/07/2010: Disable thousands separator for spin box
870 // (to avoid inconsistency of double-2-string and string-2-double conversion)
872 aLocale.setNumberOptions(aLocale.numberOptions() |
873 QLocale::OmitGroupSeparator |
874 QLocale::RejectGroupSeparator);
878 //**************************************************************
879 void refsToFeatureInFeatureDocument(const ObjectPtr& theObject,
880 std::set<FeaturePtr>& theRefFeatures)
882 FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
883 if (aFeature.get()) {
884 DocumentPtr aFeatureDoc = aFeature->document();
885 // 1. find references in the current document
886 aFeatureDoc->refsToFeature(aFeature, theRefFeatures, false);
891 //**************************************************************
892 /*bool isSubOfComposite(const ObjectPtr& theObject)
895 std::set<FeaturePtr> aRefFeatures;
896 refsToFeatureInFeatureDocument(theObject, aRefFeatures);
897 std::set<FeaturePtr>::const_iterator anIt = aRefFeatures.begin(),
898 aLast = aRefFeatures.end();
899 for (; anIt != aLast && !isSub; anIt++) {
900 isSub = isSubOfComposite(theObject, *anIt);
905 //**************************************************************
906 /*bool isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature)
909 CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
910 if (aComposite.get()) {
911 isSub = aComposite->isSub(theObject);
912 // the recursive is possible, the parameters are sketch circle and extrusion cut. They are
913 // separated by composite sketch feature
915 int aNbSubs = aComposite->numberOfSubs();
916 for (int aSub = 0; aSub < aNbSubs && !isSub; aSub++) {
917 isSub = isSubOfComposite(theObject, aComposite->subFeature(aSub));
924 //**************************************************************
925 ResultPtr firstResult(const ObjectPtr& theObject)
927 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
928 if (!aResult.get()) {
929 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
931 aResult = aFeature->firstResult();
936 //**************************************************************
937 bool isFeatureOfResult(const FeaturePtr& theFeature, const std::string& theGroupOfResult)
939 bool isResult = false;
941 if (!theFeature->data()->isValid())
944 ResultPtr aFirstResult = theFeature->firstResult();
945 if (!aFirstResult.get())
948 return aFirstResult->groupName() == theGroupOfResult;
951 //**************************************************************
952 bool hasModuleDocumentFeature(const std::set<FeaturePtr>& theFeatures)
954 bool aFoundModuleDocumentObject = false;
955 DocumentPtr aModuleDoc = ModelAPI_Session::get()->moduleDocument();
957 std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(), aLast = theFeatures.end();
958 for (; anIt != aLast && !aFoundModuleDocumentObject; anIt++) {
959 FeaturePtr aFeature = *anIt;
960 ResultPtr aResult = ModuleBase_Tools::firstResult(aFeature);
961 if (aResult.get() && aResult->groupName() == ModelAPI_ResultPart::group())
963 aFoundModuleDocumentObject = aFeature->document() == aModuleDoc;
966 return aFoundModuleDocumentObject;
969 //**************************************************************
970 bool askToDelete(const std::set<FeaturePtr> theFeatures,
971 const std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
973 std::set<FeaturePtr>& theReferencesToDelete,
974 const std::string& thePrefixInfo)
976 QString aNotActivatedDocWrn;
977 std::wstring aNotActivatedNames;
978 if (!ModelAPI_Tools::allDocumentsActivated(aNotActivatedNames)) {
979 if (ModuleBase_Tools::hasModuleDocumentFeature(theFeatures))
980 aNotActivatedDocWrn =
981 QObject::tr("Selected objects can be used in Part documents which are not loaded: %1.\n")
982 .arg(QString::fromStdWString(aNotActivatedNames));
985 std::set<FeaturePtr> aFeaturesRefsTo;
986 std::set<FeaturePtr> aFeaturesRefsToParameter;
987 std::set<FeaturePtr> aParameterFeatures;
988 QStringList aPartFeatureNames;
989 std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),
990 aLast = theFeatures.end();
991 // separate features to references to parameter features and references to others
992 for (; anIt != aLast; anIt++) {
993 FeaturePtr aFeature = *anIt;
994 if (theReferences.find(aFeature) == theReferences.end())
997 if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group()))
998 aPartFeatureNames.append(QString::fromStdWString(aFeature->name()));
1000 std::set<FeaturePtr> aRefFeatures;
1001 std::set<FeaturePtr> aRefList = theReferences.at(aFeature);
1002 std::set<FeaturePtr>::const_iterator aRefIt = aRefList.begin(), aRefLast = aRefList.end();
1003 for (; aRefIt != aRefLast; aRefIt++) {
1004 FeaturePtr aRefFeature = *aRefIt;
1005 if (theFeatures.find(aRefFeature) == theFeatures.end() && // it is not selected
1006 aRefFeatures.find(aRefFeature) == aRefFeatures.end()) // it is not added
1007 aRefFeatures.insert(aRefFeature);
1010 if (isFeatureOfResult(aFeature, ModelAPI_ResultParameter::group())) {
1011 aFeaturesRefsToParameter.insert(aRefFeatures.begin(), aRefFeatures.end());
1012 aParameterFeatures.insert(aFeature);
1015 theReferencesToDelete.insert(aRefFeatures.begin(), aRefFeatures.end());
1019 std::set<FeaturePtr> aFeaturesRefsToParameterOnly;
1020 anIt = aFeaturesRefsToParameter.begin();
1021 aLast = aFeaturesRefsToParameter.end();
1022 // separate features to references to parameter features and references to others
1023 QStringList aParamFeatureNames;
1024 for (; anIt != aLast; anIt++) {
1025 FeaturePtr aFeature = *anIt;
1026 if (theReferencesToDelete.find(aFeature) == theReferencesToDelete.end()) {
1027 aFeaturesRefsToParameterOnly.insert(aFeature);
1028 aParamFeatureNames.append(QString::fromStdWString(aFeature->name()));
1031 aParamFeatureNames.sort();
1032 QStringList anOtherFeatureNames;
1033 anIt = theReferencesToDelete.begin();
1034 aLast = theReferencesToDelete.end();
1035 for (; anIt != aLast; anIt++) {
1036 FeaturePtr aFeature = *anIt;
1037 if (aFeature->getKind() == "RemoveResults")
1038 continue; // skip the remove results feature mentioning: result will be removed anyway
1039 if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group()))
1040 aPartFeatureNames.append(QString::fromStdWString(aFeature->name()));
1042 anOtherFeatureNames.append(QString::fromStdWString(aFeature->name()));
1044 aPartFeatureNames.sort();
1045 anOtherFeatureNames.sort();
1047 QMessageBox aMessageBox(theParent);
1048 aMessageBox.setWindowTitle(QObject::tr("Delete features"));
1049 aMessageBox.setIcon(QMessageBox::Warning);
1050 aMessageBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
1051 aMessageBox.setDefaultButton(QMessageBox::No);
1053 QString aText, aDetailedText;
1054 if (!thePrefixInfo.empty())
1055 aText = thePrefixInfo.c_str();
1056 QString aSep = ", ";
1057 if (!aPartFeatureNames.empty()) {
1058 aText += QString(QObject::tr("The following parts will be deleted: %1.\n"))
1059 .arg(aPartFeatureNames.join(aSep));
1061 if (!aNotActivatedDocWrn.isEmpty())
1062 aText += aNotActivatedDocWrn;
1063 if (!anOtherFeatureNames.empty()) {
1064 const char* aMsg = "The selected features are used in some\n"
1065 "other features, which will also be deleted.\n";
1066 const char* aMsgDetails = "The selected features are used"
1067 " in the following features: %1.\n";
1068 aText += QString(QObject::tr(aMsg));
1069 aDetailedText += QString(QObject::tr(aMsgDetails))
1070 .arg(anOtherFeatureNames.join(aSep));
1072 if (!aParamFeatureNames.empty()) {
1073 const char* aMsg = "The selected parameters are used directly or through\n"
1074 "a sequence of dependencies in some features.\n"
1075 "These features will be deleted.\n"
1076 "Or parameters could be replaced by their values.\n";
1077 const char* aMsgDetails = "Parameters are used in the following features: %1.\n";
1078 aText += QString(QObject::tr(aMsg));
1079 aDetailedText += QString(QObject::tr(aMsgDetails))
1080 .arg(aParamFeatureNames.join(aSep));
1081 aMessageBox.addButton(QObject::tr("Replace"), QMessageBox::ActionRole);
1084 if (!aText.isEmpty()) {
1085 aMessageBox.setText(aText);
1086 aMessageBox.setInformativeText(QObject::tr("Would you like to continue?"));
1087 if (!aDetailedText.isEmpty())
1088 aMessageBox.setDetailedText(aDetailedText);
1090 QMessageBox::ButtonRole aButtonRole = aMessageBox.buttonRole(aMessageBox.clickedButton());
1092 if (aButtonRole == QMessageBox::NoRole)
1095 if (aButtonRole == QMessageBox::ActionRole) {
1096 foreach (FeaturePtr aObj, aParameterFeatures)
1097 ModelAPI_ReplaceParameterMessage::send(aObj, 0);
1100 theReferencesToDelete.insert(aFeaturesRefsToParameterOnly.begin(),
1101 aFeaturesRefsToParameterOnly.end());
1106 //**************************************************************
1107 bool warningAboutConflict(QWidget* theParent, const std::string& theWarningText)
1109 QMessageBox aMessageBox(theParent);
1110 aMessageBox.setWindowTitle(QObject::tr("Conflicts in constraint"));
1111 aMessageBox.setIcon(QMessageBox::Warning);
1112 aMessageBox.setText((theWarningText + "\nConstraints will be removed or substituted").c_str());
1114 QCheckBox* aCheckBox = new QCheckBox;
1116 aCheckBox->setTristate(false);
1117 aCheckBox->setText("switch off the notifications.");
1119 aMessageBox.setCheckBox(aCheckBox);
1120 aMessageBox.setStandardButtons(QMessageBox::Ok);
1124 if (aCheckBox->isChecked())
1126 ModuleBase_Preferences::resourceMgr()->setValue(SKETCH_TAB_NAME,
1127 "notify_change_constraint", false);
1133 //**************************************************************
1134 void convertToFeatures(const QObjectPtrList& theObjects, std::set<FeaturePtr>& theFeatures)
1136 QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
1137 for(; anIt != aLast; anIt++) {
1138 ObjectPtr anObject = *anIt;
1139 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
1140 // for parameter result, use the corresponded reature to be removed
1141 if (!aFeature.get() && anObject->groupName() == ModelAPI_ResultParameter::group()) {
1142 aFeature = ModelAPI_Feature::feature(anObject);
1145 theFeatures.insert(aFeature);
1149 //**************************************************************
1150 void convertToFolders(const QObjectPtrList& theObjects,
1151 std::set<FolderPtr>& theFolders)
1153 QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
1154 for(; anIt != aLast; anIt++) {
1155 ObjectPtr anObject = *anIt;
1156 FolderPtr aFeature = std::dynamic_pointer_cast<ModelAPI_Folder>(anObject);
1158 theFolders.insert(aFeature);
1163 //**************************************************************
1164 QString translate(const Events_InfoMessage& theMessage)
1168 if (!theMessage.empty()) {
1169 std::string aStr = Config_Translator::translate(theMessage);
1170 if (!aStr.empty()) {
1171 std::string aCodec = Config_Translator::codec(theMessage);
1172 aMessage = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
1179 QString translate(const std::string& theContext, const std::string& theMessage)
1183 if (!theMessage.empty()) {
1184 std::string aStr = Config_Translator::translate(theContext, theMessage);
1185 if (!aStr.empty()) {
1186 std::string aCodec = Config_Translator::codec(theContext);
1187 aMessage = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
1194 void setPointBallHighlighting(AIS_InteractiveObject* theAIS)
1196 static Handle(Image_AlienPixMap) aPixMap;
1197 if(aPixMap.IsNull()) {
1198 // Load icon for the presentation
1200 char* anEnv = getenv("SHAPER_ROOT_DIR");
1202 aFile = std::string(anEnv) +
1203 FSEP + "share" + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper";
1205 anEnv = getenv("CADBUILDER_ROOT_DIR");
1207 aFile = std::string(anEnv) + FSEP + "resources";
1211 static const std::string aMarkerName = "marker_dot.png";
1212 aFile += aMarkerName;
1213 aPixMap = new Image_AlienPixMap();
1214 if(!aPixMap->Load(aFile.c_str())) {
1215 // The icon for constraint is not found
1216 static const std::string aMsg =
1217 "Error: Point market not found by path: \"" + aFile + "\". Falling back.";
1218 //Events_InfoMessage("ModuleBase_Tools::setPointBallHighlighting", aMsg).send();
1222 Handle(Graphic3d_AspectMarker3d) anAspect;
1223 Handle(Prs3d_Drawer) aDrawer = theAIS->DynamicHilightAttributes();
1224 if (aDrawer.IsNull()) {
1225 if (ModuleBase_IViewer::DefaultHighlightDrawer.IsNull())
1227 aDrawer = new Prs3d_Drawer(*ModuleBase_IViewer::DefaultHighlightDrawer);
1228 if (!aDrawer->HasOwnPointAspect()) {
1229 aDrawer->SetPointAspect(new Prs3d_PointAspect(Aspect_TOM_BALL, Quantity_NOC_BLACK, 2.0));
1232 if(aDrawer->HasOwnPointAspect()) {
1233 Handle(Prs3d_PointAspect) aPntAspect = aDrawer->PointAspect();
1234 if(aPixMap->IsEmpty()) {
1235 anAspect = aPntAspect->Aspect();
1236 anAspect->SetType(Aspect_TOM_BALL);
1238 if(aPixMap->Format() == Image_PixMap::ImgGray) {
1239 aPixMap->SetFormat (Image_PixMap::ImgAlpha);
1240 } else if(aPixMap->Format() == Image_PixMap::ImgGrayF) {
1241 aPixMap->SetFormat (Image_PixMap::ImgAlphaF);
1243 anAspect = new Graphic3d_AspectMarker3d(aPixMap);
1244 aPntAspect->SetAspect(anAspect);
1246 aDrawer->SetPointAspect(aPntAspect);
1247 theAIS->SetDynamicHilightAttributes(aDrawer);
1251 FeaturePtr createParameter(const QString& theText)
1253 FeaturePtr aParameter;
1254 QStringList aList = theText.split("=");
1255 if (aList.count() != 2) {
1258 QString aParamName = aList.at(0).trimmed();
1260 if (isNameExist(aParamName, FeaturePtr())) {
1264 if (!ModelAPI_Expression::isVariable(aParamName.toStdString())) {
1268 QString aExpression = aList.at(1).trimmed();
1269 if (aExpression.isEmpty()) {
1273 SessionPtr aMgr = ModelAPI_Session::get();
1274 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1276 aParameter = aDoc->addFeature("Parameter", false);
1277 if (aParameter.get()) {
1278 AttributeStringPtr aNameAttr = aParameter->string("variable");
1279 aNameAttr->setValue(aParamName.toStdString());
1281 AttributeStringPtr aExprAttr = aParameter->string("expression");
1282 aExprAttr->setValue(aExpression.toStdString());
1283 aParameter->execute();
1285 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
1286 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
1291 void editParameter(FeaturePtr theParam, const QString& theText)
1293 QStringList aList = theText.split("=");
1294 QString aParamName = aList.at(0).trimmed();
1296 QString aExpression = aList.at(1).trimmed();
1297 if (aExpression.isEmpty()) {
1301 if (isNameExist(aParamName, theParam)) {
1304 AttributeStringPtr aNameAttr = theParam->string("variable");
1305 aNameAttr->setValue(aParamName.toStdString());
1307 AttributeStringPtr aExprAttr = theParam->string("expression");
1308 aExprAttr->setValue(aExpression.toStdString());
1309 theParam->execute();
1311 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
1314 bool isNameExist(const QString& theName, FeaturePtr theIgnoreParameter)
1316 SessionPtr aMgr = ModelAPI_Session::get();
1317 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1318 FeaturePtr aParamFeature;
1319 int aNbFeatures = aDoc->numInternalFeatures();
1320 std::wstring aName = theName.toStdWString();
1321 for (int i = 0; i < aNbFeatures; i++) {
1322 aParamFeature = aDoc->internalFeature(i);
1323 if (aParamFeature && aParamFeature->getKind() == "Parameter") {
1324 if ((theIgnoreParameter != aParamFeature) && (aParamFeature->name() == aName))
1331 FeaturePtr findParameter(const QString& theName)
1333 SessionPtr aMgr = ModelAPI_Session::get();
1334 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1335 FeaturePtr aParamFeature;
1336 int aNbFeatures = aDoc->numInternalFeatures();
1337 std::wstring aName = theName.toStdWString();
1338 for (int i = 0; i < aNbFeatures; i++) {
1339 aParamFeature = aDoc->internalFeature(i);
1340 if (aParamFeature && aParamFeature->getKind() == "Parameter") {
1341 if (aParamFeature->name() == aName)
1342 return aParamFeature;
1345 return FeaturePtr();
1349 //********************************************************************
1350 std::wstring generateName(const AttributePtr& theAttribute,
1351 ModuleBase_IWorkshop* theWorkshop)
1354 if (theAttribute.get() != NULL) {
1355 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
1356 if (aFeature.get()) {
1357 std::string aXmlCfg, aDescription;
1358 theWorkshop->module()->getXMLRepresentation(aFeature->getKind(), aXmlCfg, aDescription);
1360 ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop);
1361 std::string anAttributeTitle;
1362 aFactory.getAttributeTitle(theAttribute->id(), anAttributeTitle);
1364 std::wstringstream aStreamName;
1365 aStreamName << theAttribute->owner()->data()->name() << "/" << anAttributeTitle.c_str();
1366 aName = aStreamName.str();
1372 bool isSameShape(const TopoDS_Shape& theShape1, const TopoDS_Shape& theShape2)
1374 // In case of compound we cannot rely on simple comparison method.
1375 // If the compound is generated by Group feature then this compound is alwais new.
1376 // So, we have to compare content of these compounds
1377 if (theShape1.ShapeType() != theShape2.ShapeType())
1380 if (theShape1.ShapeType() != TopAbs_COMPOUND)
1381 return theShape1.IsSame(theShape2);
1383 TopoDS_Iterator aIt1(theShape1);
1384 TopoDS_Iterator aIt2(theShape2);
1386 for (; aIt1.More() && aIt2.More(); aIt1.Next(), aIt2.Next()) {
1387 if (!(aIt1.Value()).IsSame(aIt2.Value()))
1393 qreal currentPixelRatio()
1395 QWindowList aWnds = qApp->topLevelWindows();
1396 if (aWnds.size() > 0)
1397 return aWnds.first()->devicePixelRatio();
1398 return qApp->primaryScreen()->devicePixelRatio();
1402 // Set displaying status to every element on group
1403 static void setDisplayingByLoop(DocumentPtr theDoc, int theSize,
1404 std::string theGroup, bool theDisplayFromScript, int theDisplayingId)
1406 for (int anIndex = theSize - 1; anIndex >= 0; --anIndex) {
1407 ObjectPtr anObject = theDoc->object(theGroup, anIndex);
1408 anObject->setDisplayed((theDisplayingId == 1 && anIndex == theSize - 1) ||
1409 theDisplayingId == 2);
1413 void setDisplaying(ResultPartPtr thePart, bool theDisplayFromScript)
1415 static bool isDoingDisplay = false;
1420 isDoingDisplay = true;
1421 DocumentPtr aDoc = thePart->partDoc();
1422 int aConstructionSize = aDoc->size(ModelAPI_ResultConstruction::group());
1423 int aGroupSize = aDoc->size(ModelAPI_ResultGroup::group());
1424 int aFieldSize = aDoc->size(ModelAPI_ResultField::group());
1425 int aResultSize = aDoc->size(ModelAPI_ResultBody::group());
1427 int aDisplayingId = -1;
1428 if (theDisplayFromScript) {
1429 aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General",
1430 "part_visualization_script", -1);
1431 // Increase ID to prevert using "As stored in HDF"
1435 aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General",
1436 "part_visualization_study", -1);
1438 // if chosen "As stored in HDF" then don't change displaying
1439 if (aDisplayingId == 0)
1443 setDisplayingByLoop(aDoc, aConstructionSize, ModelAPI_ResultConstruction::group(),
1444 theDisplayFromScript, aDisplayingId);
1445 setDisplayingByLoop(aDoc, aGroupSize, ModelAPI_ResultGroup::group(),
1446 theDisplayFromScript, aDisplayingId);
1447 setDisplayingByLoop(aDoc, aFieldSize, ModelAPI_ResultField::group(),
1448 theDisplayFromScript, aDisplayingId);
1449 setDisplayingByLoop(aDoc, aResultSize, ModelAPI_ResultBody::group(),
1450 theDisplayFromScript, aDisplayingId);
1451 isDoingDisplay = false;
1454 } // namespace ModuleBase_Tools