1 // Copyright (C) 2014-2023 CEA, EDF
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>
59 #include <Basics_OCCTVersion.hxx>
62 #include <SUIT_Application.h>
63 #include <SUIT_Session.h>
66 #include <StdSelect_BRepOwner.hxx>
67 #include <TopoDS_Iterator.hxx>
68 #include <AIS_InteractiveContext.hxx>
69 #include <Prs3d_LineAspect.hxx>
70 #include <Prs3d_PlaneAspect.hxx>
72 #include <GeomDataAPI_Point2D.h>
73 #include <Events_InfoMessage.h>
74 #include <GeomAPI_ShapeExplorer.h>
76 #include <Config_PropManager.h>
77 #include <Config_Translator.h>
79 #include <Prs3d_PointAspect.hxx>
80 #include <Graphic3d_AspectMarker3d.hxx>
82 #include <Image_AlienPixMap.hxx>
88 #include <QDoubleSpinBox>
89 #include <QGraphicsDropShadowEffect>
91 #include <QApplication>
92 #include <QMessageBox>
103 #pragma warning(disable : 4996) // for getenv
106 const double tolerance = 1e-7;
107 const double DEFAULT_DEVIATION_COEFFICIENT = 1.e-4;
109 //#define DEBUG_ACTIVATE_WINDOW
110 //#define DEBUG_SET_FOCUS
118 namespace ModuleBase_Tools {
120 //******************************************************************
122 //! Waits for REDISPLAY message and set the Visible flag to the entities
123 //! according to Preferences choice.
124 class ModuleBase_RedisplayListener : public Events_Listener
127 static std::shared_ptr<ModuleBase_RedisplayListener> instance()
129 static std::shared_ptr<ModuleBase_RedisplayListener>
130 anInstance(new ModuleBase_RedisplayListener);
134 void processEvent(const std::shared_ptr<Events_Message>& theMessage)
136 if (theMessage->eventID() == Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY))
139 // If the python script is being loaded now, the preferences should be used
140 // to display the required object
141 SUIT_Session* aSession = SUIT_Session::session();
144 SUIT_Application * anApp = aSession->activeApplication();
147 QVariant aVar = anApp->property("IsLoadedScript");
148 if (!aVar.isNull() && aVar.toBool()) {
149 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
150 int aSize = aRootDoc->size(ModelAPI_ResultPart::group());
152 ObjectPtr anPartObject = aRootDoc->object(ModelAPI_ResultPart::group(), aSize - 1);
153 ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(anPartObject);
154 ModuleBase_Tools::setDisplaying(aPart, true);
162 ModuleBase_RedisplayListener()
164 Events_Loop::loop()->registerListener(this,
165 Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
169 static std::shared_ptr<ModuleBase_RedisplayListener>
170 RL = ModuleBase_RedisplayListener::instance();
172 //******************************************************************
174 void adjustMargins(QWidget* theWidget)
178 adjustMargins(theWidget->layout());
181 void adjustMargins(QLayout* theLayout)
185 theLayout->setContentsMargins(2, 5, 2, 5);
186 theLayout->setSpacing(4);
189 void zeroMargins(QWidget* theWidget)
193 zeroMargins(theWidget->layout());
196 void zeroMargins(QLayout* theLayout)
200 theLayout->setContentsMargins(0, 0, 0, 0);
201 theLayout->setSpacing(5);
204 void activateWindow(QWidget* theWidget, const QString& theInfo)
207 theWidget->activateWindow();
211 #ifdef DEBUG_ACTIVATE_WINDOW
212 qDebug(QString("activateWindow: %1").arg(theInfo).toStdString().c_str());
216 void setFocus(QWidget* theWidget, const QString& theInfo)
218 activateWindow(theWidget);
219 theWidget->setFocus();
220 // rectangle of focus is not visible on tool button widgets
222 #ifdef DEBUG_SET_FOCUS
223 qDebug(QString("setFocus: %1").arg(theInfo).toStdString().c_str());
227 void setShadowEffect(QWidget* theWidget, const bool isSetEffect)
230 QGraphicsDropShadowEffect* aGlowEffect = new QGraphicsDropShadowEffect();
231 aGlowEffect->setOffset(.0);
232 aGlowEffect->setBlurRadius(10.0);
233 aGlowEffect->setColor(QColor(0, 170, 255)); // Light-blue color, #00AAFF
234 theWidget->setGraphicsEffect(aGlowEffect);
237 QGraphicsEffect* anEffect = theWidget->graphicsEffect();
239 anEffect->deleteLater();
240 theWidget->setGraphicsEffect(NULL);
244 QPixmap composite(const QString& theAdditionalIcon, const QString& theIcon)
246 QImage anIcon = ModuleBase_IconFactory::loadImage(theIcon);
247 QImage anAditional(theAdditionalIcon);
248 return composite(anAditional, anIcon);
251 QPixmap composite(const QImage& theAdditionalIcon, QImage& theIcon)
253 if (theIcon.isNull())
256 int anAddWidth = theAdditionalIcon.width();
257 int anAddHeight = theAdditionalIcon.height();
259 int aWidth = theIcon.width();
260 int aHeight = theIcon.height();
262 int aStartWidthPos = aWidth - anAddWidth;
263 int aStartHeightPos = aHeight - anAddHeight;
265 for (int i = 0; i < anAddWidth && i + aStartWidthPos < aWidth; i++)
267 for (int j = 0; j < anAddHeight && j + aStartHeightPos < aHeight; j++)
269 if (qAlpha(theAdditionalIcon.pixel(i, j)) > 0)
270 theIcon.setPixel(i + aStartWidthPos, j + aStartHeightPos, theAdditionalIcon.pixel(i, j));
273 return QPixmap::fromImage(theIcon);
276 QPixmap lighter(const QString& theIcon, const int theLighterValue)
278 QImage anIcon = ModuleBase_IconFactory::loadImage(theIcon);
282 QImage aResult = ModuleBase_IconFactory::loadImage(theIcon);
283 for (int i = 0; i < anIcon.width(); i++)
285 for (int j = 0; j < anIcon.height(); j++)
287 QRgb anRgb = anIcon.pixel(i, j);
288 QColor aPixelColor(qRed(anRgb), qGreen(anRgb), qBlue(anRgb),
289 qAlpha(aResult.pixel(i, j)));
291 QColor aLighterColor = aPixelColor.lighter(theLighterValue);
292 aResult.setPixel(i, j, qRgba(aLighterColor.red(), aLighterColor.green(),
293 aLighterColor.blue(), aLighterColor.alpha()));
296 return QPixmap::fromImage(aResult);
299 void setSpinText(ModuleBase_ParamSpinBox* theSpin, const QString& theText)
301 if (theSpin->text() == theText)
303 // In order to avoid extra text setting because it will
304 // reset cursor position in control
305 bool isBlocked = theSpin->blockSignals(true);
306 theSpin->setText(theText);
307 theSpin->blockSignals(isBlocked);
310 void setSpinValue(QDoubleSpinBox* theSpin, double theValue)
312 if (fabs(theSpin->value() - theValue) < tolerance)
314 bool isBlocked = theSpin->blockSignals(true);
315 theSpin->setValue(theValue);
316 theSpin->blockSignals(isBlocked);
319 void setSpinValue(ModuleBase_ParamSpinBox* theSpin, double theValue)
321 if (!theSpin->text().isEmpty() && fabs(theSpin->value() - theValue) < tolerance)
323 bool isBlocked = theSpin->blockSignals(true);
324 theSpin->setValue(theValue);
325 theSpin->blockSignals(isBlocked);
328 void setSpinText(ModuleBase_ParamIntSpinBox* theSpin, const QString& theText)
330 // In order to avoid extra text setting because it will
331 // reset cursor position in control
332 if (theSpin->text() == theText)
334 bool isBlocked = theSpin->blockSignals(true);
335 theSpin->setText(theText);
336 theSpin->blockSignals(isBlocked);
339 void setSpinValue(ModuleBase_ParamIntSpinBox* theSpin, int theValue)
341 if (theSpin->value() == theValue)
343 bool isBlocked = theSpin->blockSignals(true);
344 theSpin->setValue(theValue);
345 theSpin->blockSignals(isBlocked);
348 QAction* createAction(const QIcon& theIcon, const QString& theText,
349 QObject* theParent, const QObject* theReceiver,
350 const char* theMember, const QString& theToolTip,
351 const QString& theStatusTip)
353 QAction* anAction = new QAction(theIcon, theText, theParent);
354 anAction->setToolTip(theToolTip.isEmpty() ? theText : theToolTip);
355 anAction->setStatusTip(!theStatusTip.isEmpty() ? theStatusTip :
356 (!theToolTip.isEmpty() ? theToolTip : theText));
358 QObject::connect(anAction, SIGNAL(triggered(bool)), theReceiver, theMember);
364 QString objectName(const ObjectPtr& theObj)
369 return QString::fromStdWString(theObj->data()->name());
372 QString objectInfo(const ObjectPtr& theObj, const bool isUseAttributesInfo)
374 QString aFeatureStr = "feature";
378 std::ostringstream aPtrStr;
379 aPtrStr << "[" << theObj.get() << "]";
381 ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObj);
382 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObj);
384 aFeatureStr.append(QString("(result%1)").arg(aPtrStr.str().c_str()).toStdString() .c_str());
385 if (aRes->isDisabled())
386 aFeatureStr.append("[disabled]");
387 if (aRes->isConcealed())
388 aFeatureStr.append("[concealed]");
389 if (ModelAPI_Tools::hasSubResults(aRes))
390 aFeatureStr.append("[hasSubResults]");
392 aFeature = ModelAPI_Feature::feature(aRes);
395 aFeatureStr.append(aPtrStr.str().c_str());
397 if (aFeature.get()) {
398 aFeatureStr.append(QString(": %1").arg(aFeature->getKind().c_str()).toStdString().c_str());
399 if (aFeature->data()->isValid()) {
400 aFeatureStr.append(QString(", name=%1")
401 .arg(QString::fromStdWString(theObj->data()->name())).toStdString().c_str());
403 if (isUseAttributesInfo) {
404 std::set<std::shared_ptr<ModelAPI_Attribute> > anAttributes;
405 std::string aPointsInfo = ModelGeomAlgo_Point2D::getPontAttributesInfo(aFeature,
406 anAttributes).c_str();
407 if (!aPointsInfo.empty())
408 aFeatureStr.append(QString(", attributes: %1")
409 .arg(aPointsInfo.c_str()).toStdString().c_str());
417 typedef QMap<QString, int> ShapeTypes;
418 static ShapeTypes myShapeTypes;
420 int shapeType(const QString& theType)
422 if (myShapeTypes.count() == 0) {
423 myShapeTypes["compound"] = TopAbs_COMPOUND;
424 myShapeTypes["compounds"] = TopAbs_COMPOUND;
425 myShapeTypes["compsolid"] = TopAbs_COMPSOLID;
426 myShapeTypes["compsolids"] = TopAbs_COMPSOLID;
427 myShapeTypes["solid"] = TopAbs_SOLID;
428 myShapeTypes["solids"] = TopAbs_SOLID;
429 myShapeTypes["shell"] = TopAbs_SHELL;
430 myShapeTypes["shells"] = TopAbs_SHELL;
431 myShapeTypes["face"] = TopAbs_FACE;
432 myShapeTypes["faces"] = TopAbs_FACE;
433 myShapeTypes["wire"] = TopAbs_WIRE;
434 myShapeTypes["wires"] = TopAbs_WIRE;
435 myShapeTypes["edge"] = TopAbs_EDGE;
436 myShapeTypes["edges"] = TopAbs_EDGE;
437 myShapeTypes["vertex"] = TopAbs_VERTEX;
438 myShapeTypes["vertices"] = TopAbs_VERTEX;
439 myShapeTypes["object"] = ModuleBase_ResultPrs::Sel_Result;
440 myShapeTypes["objects"] = ModuleBase_ResultPrs::Sel_Result;
442 QString aType = theType.toLower();
443 if(myShapeTypes.contains(aType))
444 return myShapeTypes[aType];
445 Events_InfoMessage("ModuleBase_Tools", "Shape type defined in XML is not implemented!").send();
449 void checkObjects(const QObjectPtrList& theObjects, bool& hasResult, bool& hasFeature,
450 bool& hasParameter, bool& hasCompositeOwner, bool& hasResultInHistory,
451 bool& hasFolder, bool &hasGroupsOnly)
455 hasParameter = false;
456 hasCompositeOwner = false;
457 hasResultInHistory = false;
459 bool hasNonGroup = false;
460 foreach(ObjectPtr aObj, theObjects) {
461 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
462 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
463 ResultGroupPtr aGroup = std::dynamic_pointer_cast<ModelAPI_ResultGroup>(aObj);
464 FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(aObj);
465 ResultParameterPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aResult);
466 FieldStepPtr aStep = std::dynamic_pointer_cast<ModelAPI_ResultField::ModelAPI_FieldStep>(aObj);
468 hasResult |= ((aResult.get() != NULL) || (aStep.get() != NULL));
469 hasFeature |= (aFeature.get() != NULL);
470 hasFolder |= (aFolder.get() != NULL);
471 hasParameter |= (aConstruction.get() != NULL);
472 hasNonGroup |= (aGroup.get() == NULL);
474 hasCompositeOwner |= (ModelAPI_Tools::compositeOwner(aFeature) != NULL);
475 else if (aResult.get())
476 hasCompositeOwner |= (ModelAPI_Tools::bodyOwner(aResult) != NULL);
478 if (!hasResultInHistory && aResult.get()) {
479 aFeature = ModelAPI_Feature::feature(aResult);
480 hasResultInHistory = aFeature.get() && aFeature->isInHistory();
483 if (hasFeature && hasResult && hasParameter && hasCompositeOwner && hasNonGroup)
486 hasGroupsOnly = !hasNonGroup;
489 void setDefaultDeviationCoefficient(const TopoDS_Shape& theShape,
490 const Handle(Prs3d_Drawer)& theDrawer)
492 if (theShape.IsNull())
494 if (theDrawer.IsNull())
497 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape());
498 aGeomShape->setImpl(new TopoDS_Shape(theShape));
500 // if the shape could not be exploded on faces, it contains only wires, edges, and vertices
501 // correction of deviation for them should not influence to the application performance
502 GeomAPI_ShapeExplorer anExp(aGeomShape, GeomAPI_Shape::FACE);
503 bool isConstruction = !anExp.more();
507 aDeflection = Config_PropManager::real("Visualization", "construction_deflection");
509 aDeflection = Config_PropManager::real("Visualization", "body_deflection");
511 theDrawer->SetDeviationCoefficient(aDeflection);
514 Quantity_Color color(const std::string& theSection,
515 const std::string& theName)
517 std::vector<int> aColor = Config_PropManager::color(theSection, theName);
518 return Quantity_Color(aColor[0] / 255., aColor[1] / 255., aColor[2] / 255., Quantity_TOC_RGB);
521 ObjectPtr getObject(const AttributePtr& theAttribute)
524 std::string anAttrType = theAttribute->attributeType();
525 if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
526 AttributeRefAttrPtr anAttr =
527 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
528 if (anAttr != NULL && anAttr->isObject())
529 anObject = anAttr->object();
531 if (anAttrType == ModelAPI_AttributeSelection::typeId()) {
532 AttributeSelectionPtr anAttr =
533 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
535 anObject = anAttr->context();
537 if (anAttrType == ModelAPI_AttributeReference::typeId()) {
538 AttributeReferencePtr anAttr =
539 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
540 if (anAttr.get() != NULL)
541 anObject = anAttr->value();
546 TopAbs_ShapeEnum getCompoundSubType(const TopoDS_Shape& theShape)
548 TopAbs_ShapeEnum aShapeType = theShape.ShapeType();
550 // for compounds check sub-shapes: it may be compound of needed type:
551 // Booleans may produce compounds of Solids
552 if (aShapeType == TopAbs_COMPOUND) {
553 for(TopoDS_Iterator aSubs(theShape); aSubs.More(); aSubs.Next()) {
554 if (!aSubs.Value().IsNull()) {
555 TopAbs_ShapeEnum aSubType = aSubs.Value().ShapeType();
556 if (aSubType == TopAbs_COMPOUND) { // compound of compound(s)
557 aShapeType = TopAbs_COMPOUND;
560 if (aShapeType == TopAbs_COMPOUND) {
561 aShapeType = aSubType;
562 } else if (aShapeType != aSubType) { // compound of shapes of different types
563 aShapeType = TopAbs_COMPOUND;
572 TopoDS_Shape getSelectedShape(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs)
574 if (thePrs->shape().get())
575 return thePrs->shape()->impl<TopoDS_Shape>();
577 Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast(thePrs->owner());
578 if (!anOwner.IsNull())
579 return anOwner->Shape();
581 return TopoDS_Shape();
584 void getParameters(QStringList& theParameters)
586 theParameters.clear();
588 SessionPtr aSession = ModelAPI_Session::get();
589 std::list<DocumentPtr> aDocList;
590 DocumentPtr anActiveDocument = aSession->activeDocument();
591 DocumentPtr aRootDocument = aSession->moduleDocument();
592 aDocList.push_back(anActiveDocument);
593 if (anActiveDocument != aRootDocument) {
594 aDocList.push_back(aRootDocument);
596 std::string aGroupId = ModelAPI_ResultParameter::group();
597 for(std::list<DocumentPtr>::const_iterator it = aDocList.begin(); it != aDocList.end(); ++it) {
598 DocumentPtr aDocument = *it;
599 int aSize = aDocument->size(aGroupId);
600 for (int i = 0; i < aSize; i++) {
601 ObjectPtr anObject = aDocument->object(aGroupId, i);
602 std::wstring aParameterName = anObject->data()->name();
603 theParameters.append(QString::fromStdWString(aParameterName));
608 std::string findGreedAttribute(ModuleBase_IWorkshop* theWorkshop,
609 const FeaturePtr& theFeature)
611 std::string anAttributeId;
613 std::string aXmlCfg, aDescription;
614 theWorkshop->module()->getXMLRepresentation(theFeature->getKind(), aXmlCfg, aDescription);
616 ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop);
617 std::string anAttributeTitle;
618 aFactory.getGreedAttribute(anAttributeId);
620 return anAttributeId;
623 bool hasObject(const AttributePtr& theAttribute, const ObjectPtr& theObject,
624 const std::shared_ptr<GeomAPI_Shape>& theShape,
625 ModuleBase_IWorkshop* theWorkshop,
626 const bool theTemporarily)
628 bool aHasObject = false;
629 if (!theAttribute.get())
632 std::string aType = theAttribute->attributeType();
633 if (aType == ModelAPI_AttributeReference::typeId()) {
634 AttributeReferencePtr aRef =
635 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
636 ObjectPtr aObject = aRef->value();
637 aHasObject = aObject && aObject->isSame(theObject);
638 //if (!(aObject && aObject->isSame(theObject))) {
639 // aRef->setValue(theObject);
641 } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
642 AttributeRefAttrPtr aRefAttr =
643 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
645 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
646 if (anAttribute.get()) {
647 //aRefAttr->setAttr(anAttribute);
650 ObjectPtr aObject = aRefAttr->object();
651 aHasObject = aObject && aObject->isSame(theObject);
652 //if (!(aObject && aObject->isSame(theObject))) {
653 // aRefAttr->setObject(theObject);
656 } else if (aType == ModelAPI_AttributeSelection::typeId()) {
657 /*AttributeSelectionPtr aSelectAttr =
658 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
659 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
660 if (aSelectAttr.get() != NULL) {
661 aSelectAttr->setValue(aResult, theShape, theTemporarily);
664 if (aType == ModelAPI_AttributeSelectionList::typeId()) {
665 AttributeSelectionListPtr aSelectionListAttr =
666 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
667 aHasObject = aSelectionListAttr->isInList(theObject, theShape, theTemporarily);
669 else if (aType == ModelAPI_AttributeRefList::typeId()) {
670 AttributeRefListPtr aRefListAttr =
671 std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttribute);
672 aHasObject = aRefListAttr->isInList(theObject);
673 //if (!theCheckIfAttributeHasObject || !aRefListAttr->isInList(theObject))
674 // aRefListAttr->append(theObject);
676 else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
677 AttributeRefAttrListPtr aRefAttrListAttr =
678 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(theAttribute);
679 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
681 if (anAttribute.get()) {
682 aHasObject = aRefAttrListAttr->isInList(anAttribute);
683 //if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(anAttribute))
684 // aRefAttrListAttr->append(anAttribute);
687 aHasObject = aRefAttrListAttr->isInList(theObject);
688 //if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(theObject))
689 // aRefAttrListAttr->append(theObject);
695 bool setObject(const AttributePtr& theAttribute, const ObjectPtr& theObject,
696 const GeomShapePtr& theShape, ModuleBase_IWorkshop* theWorkshop,
697 const bool theTemporarily, const bool theCheckIfAttributeHasObject)
699 if (!theAttribute.get())
703 std::string aType = theAttribute->attributeType();
704 if (aType == ModelAPI_AttributeReference::typeId()) {
705 AttributeReferencePtr aRef =
706 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
707 ObjectPtr aObject = aRef->value();
708 if (!(aObject && aObject->isSame(theObject))) {
709 aRef->setValue(theObject);
711 } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
712 AttributeRefAttrPtr aRefAttr =
713 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
715 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
716 if (anAttribute.get())
717 aRefAttr->setAttr(anAttribute);
719 ObjectPtr aObject = aRefAttr->object();
720 if (!(aObject && aObject->isSame(theObject))) {
721 aRefAttr->setObject(theObject);
724 } else if (aType == ModelAPI_AttributeSelection::typeId()) {
725 AttributeSelectionPtr aSelectAttr =
726 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
727 if (aSelectAttr.get() != NULL) {
728 aSelectAttr->setValue(theObject, theShape, theTemporarily);
731 if (aType == ModelAPI_AttributeSelectionList::typeId()) {
732 AttributeSelectionListPtr aSelectionListAttr =
733 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
734 if (!theCheckIfAttributeHasObject ||
735 !aSelectionListAttr->isInList(theObject, theShape, theTemporarily))
736 aSelectionListAttr->append(theObject, theShape, theTemporarily);
738 else if (aType == ModelAPI_AttributeRefList::typeId()) {
739 AttributeRefListPtr aRefListAttr =
740 std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttribute);
741 if (!theCheckIfAttributeHasObject || !aRefListAttr->isInList(theObject)) {
743 aRefListAttr->append(theObject);
748 else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
749 AttributeRefAttrListPtr aRefAttrListAttr =
750 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(theAttribute);
751 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
753 if (anAttribute.get()) {
754 if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(anAttribute))
755 aRefAttrListAttr->append(anAttribute);
758 if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(theObject)) {
760 aRefAttrListAttr->append(theObject);
769 GeomShapePtr getShape(const AttributePtr& theAttribute, ModuleBase_IWorkshop* theWorkshop)
772 if (!theAttribute.get())
775 std::string aType = theAttribute->attributeType();
776 if (aType == ModelAPI_AttributeReference::typeId()) {
777 } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
778 AttributeRefAttrPtr aRefAttr =
779 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
780 if (aRefAttr.get() && !aRefAttr->isObject()) {
781 AttributePtr anAttribute = aRefAttr->attr();
782 aShape = theWorkshop->module()->findShape(anAttribute);
784 } else if (aType == ModelAPI_AttributeSelection::typeId()) {
785 AttributeSelectionPtr aSelectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
787 aShape = aSelectAttr->value();
789 else // Geom2D point processing
790 aShape = theWorkshop->module()->findShape(theAttribute);
794 void flushUpdated(ObjectPtr theObject)
796 blockUpdateViewer(true);
798 // Fix the problem of not previewed results of constraints applied. Flush Create/Delete
799 // (for the sketch result) to start processing of the sketch in the solver.
800 // TODO: these flushes should be moved in a separate method provided by Model
801 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
802 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_VISUAL_ATTRIBUTES));
803 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
804 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_UPDATE_SELECTION));
805 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
807 blockUpdateViewer(false);
810 void blockUpdateViewer(const bool theValue)
812 // the viewer update should be blocked in order to avoid the temporary feature content
813 // when the solver processes the feature, the redisplay message can be flushed
814 // what caused the display in the viewer preliminary states of object
815 // e.g. fillet feature, angle value change
816 std::shared_ptr<Events_Message> aMsg;
818 aMsg = std::shared_ptr<Events_Message>(
819 new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED)));
822 // the viewer update should be unblocked
823 aMsg = std::shared_ptr<Events_Message>(
824 new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)));
826 Events_Loop::loop()->send(aMsg);
829 QString wrapTextByWords(const QString& theValue, QWidget* theWidget,
830 int theMaxLineInPixels)
832 static QFontMetrics tfm(theWidget ? theWidget->font() : QApplication::font());
833 static qreal phi = 2.618;
835 QRect aBounds = tfm.boundingRect(theValue);
836 if(aBounds.width() <= theMaxLineInPixels)
839 qreal s = aBounds.width() * aBounds.height();
840 qreal aGoldWidth = sqrt(s*phi);
842 QStringList aWords = theValue.split(" ", QString::SkipEmptyParts);
844 int n = aWords.count();
846 for (int i = 0; i < n; i++) {
847 QString aLineExt = i == 0 ? aWords[i] : aLine + " " + aWords[i];
848 qreal anWidthNonExt = tfm.boundingRect(aLine).width();
849 qreal anWidthExt = tfm.boundingRect(aLineExt).width();
850 qreal aDeltaNonExt = fabs(anWidthNonExt-aGoldWidth);
851 qreal aDeltaExt = fabs(anWidthExt-aGoldWidth);
852 if(aDeltaNonExt < aDeltaExt) {
854 aLines.append(aLine);
862 aLines.append(aLine);
864 QString aResult = aLines.join("\n");
868 //**************************************************************
869 QLocale doubleLocale()
871 // VSR 01/07/2010: Disable thousands separator for spin box
872 // (to avoid inconsistency of double-2-string and string-2-double conversion)
874 aLocale.setNumberOptions(aLocale.numberOptions() |
875 QLocale::OmitGroupSeparator |
876 QLocale::RejectGroupSeparator);
880 //**************************************************************
881 void refsToFeatureInFeatureDocument(const ObjectPtr& theObject,
882 std::set<FeaturePtr>& theRefFeatures)
884 FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
885 if (aFeature.get()) {
886 DocumentPtr aFeatureDoc = aFeature->document();
887 // 1. find references in the current document
888 aFeatureDoc->refsToFeature(aFeature, theRefFeatures, false);
893 //**************************************************************
894 /*bool isSubOfComposite(const ObjectPtr& theObject)
897 std::set<FeaturePtr> aRefFeatures;
898 refsToFeatureInFeatureDocument(theObject, aRefFeatures);
899 std::set<FeaturePtr>::const_iterator anIt = aRefFeatures.begin(),
900 aLast = aRefFeatures.end();
901 for (; anIt != aLast && !isSub; anIt++) {
902 isSub = isSubOfComposite(theObject, *anIt);
907 //**************************************************************
908 /*bool isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature)
911 CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
912 if (aComposite.get()) {
913 isSub = aComposite->isSub(theObject);
914 // the recursive is possible, the parameters are sketch circle and extrusion cut. They are
915 // separated by composite sketch feature
917 int aNbSubs = aComposite->numberOfSubs();
918 for (int aSub = 0; aSub < aNbSubs && !isSub; aSub++) {
919 isSub = isSubOfComposite(theObject, aComposite->subFeature(aSub));
926 //**************************************************************
927 ResultPtr firstResult(const ObjectPtr& theObject)
929 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
930 if (!aResult.get()) {
931 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
933 aResult = aFeature->firstResult();
938 //**************************************************************
939 bool isFeatureOfResult(const FeaturePtr& theFeature, const std::string& theGroupOfResult)
941 bool isResult = false;
943 if (!theFeature->data()->isValid())
946 ResultPtr aFirstResult = theFeature->firstResult();
947 if (!aFirstResult.get())
950 return aFirstResult->groupName() == theGroupOfResult;
953 //**************************************************************
954 bool hasModuleDocumentFeature(const std::set<FeaturePtr>& theFeatures)
956 bool aFoundModuleDocumentObject = false;
957 DocumentPtr aModuleDoc = ModelAPI_Session::get()->moduleDocument();
959 std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(), aLast = theFeatures.end();
960 for (; anIt != aLast && !aFoundModuleDocumentObject; anIt++) {
961 FeaturePtr aFeature = *anIt;
962 ResultPtr aResult = ModuleBase_Tools::firstResult(aFeature);
963 if (aResult.get() && aResult->groupName() == ModelAPI_ResultPart::group())
965 aFoundModuleDocumentObject = aFeature->document() == aModuleDoc;
968 return aFoundModuleDocumentObject;
971 //**************************************************************
972 bool askToDelete(const std::set<FeaturePtr> theFeatures,
973 const std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
975 std::set<FeaturePtr>& theReferencesToDelete,
976 const std::string& thePrefixInfo)
978 QString aNotActivatedDocWrn;
979 std::wstring aNotActivatedNames;
980 if (!ModelAPI_Tools::allDocumentsActivated(aNotActivatedNames)) {
981 if (ModuleBase_Tools::hasModuleDocumentFeature(theFeatures))
982 aNotActivatedDocWrn =
983 QObject::tr("Selected objects can be used in Part documents which are not loaded: %1.\n")
984 .arg(QString::fromStdWString(aNotActivatedNames));
987 std::set<FeaturePtr> aFeaturesRefsTo;
988 std::set<FeaturePtr> aFeaturesRefsToParameter;
989 std::set<FeaturePtr> aParameterFeatures;
990 QStringList aPartFeatureNames;
991 std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),
992 aLast = theFeatures.end();
993 // separate features to references to parameter features and references to others
994 for (; anIt != aLast; anIt++) {
995 FeaturePtr aFeature = *anIt;
996 if (theReferences.find(aFeature) == theReferences.end())
999 if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group()))
1000 aPartFeatureNames.append(QString::fromStdWString(aFeature->name()));
1002 std::set<FeaturePtr> aRefFeatures;
1003 std::set<FeaturePtr> aRefList = theReferences.at(aFeature);
1004 std::set<FeaturePtr>::const_iterator aRefIt = aRefList.begin(), aRefLast = aRefList.end();
1005 for (; aRefIt != aRefLast; aRefIt++) {
1006 FeaturePtr aRefFeature = *aRefIt;
1007 if (theFeatures.find(aRefFeature) == theFeatures.end() && // it is not selected
1008 aRefFeatures.find(aRefFeature) == aRefFeatures.end()) // it is not added
1009 aRefFeatures.insert(aRefFeature);
1012 if (isFeatureOfResult(aFeature, ModelAPI_ResultParameter::group())) {
1013 aFeaturesRefsToParameter.insert(aRefFeatures.begin(), aRefFeatures.end());
1014 aParameterFeatures.insert(aFeature);
1017 theReferencesToDelete.insert(aRefFeatures.begin(), aRefFeatures.end());
1021 std::set<FeaturePtr> aFeaturesRefsToParameterOnly;
1022 anIt = aFeaturesRefsToParameter.begin();
1023 aLast = aFeaturesRefsToParameter.end();
1024 // separate features to references to parameter features and references to others
1025 QStringList aParamFeatureNames;
1026 for (; anIt != aLast; anIt++) {
1027 FeaturePtr aFeature = *anIt;
1028 if (theReferencesToDelete.find(aFeature) == theReferencesToDelete.end()) {
1029 aFeaturesRefsToParameterOnly.insert(aFeature);
1030 aParamFeatureNames.append(QString::fromStdWString(aFeature->name()));
1033 aParamFeatureNames.sort();
1034 QStringList anOtherFeatureNames;
1035 anIt = theReferencesToDelete.begin();
1036 aLast = theReferencesToDelete.end();
1037 for (; anIt != aLast; anIt++) {
1038 FeaturePtr aFeature = *anIt;
1039 if (aFeature->getKind() == "RemoveResults")
1040 continue; // skip the remove results feature mentioning: result will be removed anyway
1041 if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group()))
1042 aPartFeatureNames.append(QString::fromStdWString(aFeature->name()));
1044 anOtherFeatureNames.append(QString::fromStdWString(aFeature->name()));
1046 aPartFeatureNames.sort();
1047 anOtherFeatureNames.sort();
1049 QMessageBox aMessageBox(theParent);
1050 aMessageBox.setWindowTitle(QObject::tr("Delete features"));
1051 aMessageBox.setIcon(QMessageBox::Warning);
1052 aMessageBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
1053 aMessageBox.setDefaultButton(QMessageBox::No);
1055 QString aText, aDetailedText;
1056 if (!thePrefixInfo.empty())
1057 aText = thePrefixInfo.c_str();
1058 QString aSep = ", ";
1059 if (!aPartFeatureNames.empty()) {
1060 aText += QString(QObject::tr("The following parts will be deleted: %1.\n"))
1061 .arg(aPartFeatureNames.join(aSep));
1063 if (!aNotActivatedDocWrn.isEmpty())
1064 aText += aNotActivatedDocWrn;
1065 if (!anOtherFeatureNames.empty()) {
1066 const char* aMsg = "The selected features are used in some\n"
1067 "other features, which will also be deleted.\n";
1068 const char* aMsgDetails = "The selected features are used"
1069 " in the following features: %1.\n";
1070 aText += QString(QObject::tr(aMsg));
1071 aDetailedText += QString(QObject::tr(aMsgDetails))
1072 .arg(anOtherFeatureNames.join(aSep));
1074 if (!aParamFeatureNames.empty()) {
1075 const char* aMsg = "The selected parameters are used directly or through\n"
1076 "a sequence of dependencies in some features.\n"
1077 "These features will be deleted.\n"
1078 "Or parameters could be replaced by their values.\n";
1079 const char* aMsgDetails = "Parameters are used in the following features: %1.\n";
1080 aText += QString(QObject::tr(aMsg));
1081 aDetailedText += QString(QObject::tr(aMsgDetails))
1082 .arg(aParamFeatureNames.join(aSep));
1083 aMessageBox.addButton(QObject::tr("Replace"), QMessageBox::ActionRole);
1086 if (!aText.isEmpty()) {
1087 aMessageBox.setText(aText);
1088 aMessageBox.setInformativeText(QObject::tr("Would you like to continue?"));
1089 if (!aDetailedText.isEmpty())
1090 aMessageBox.setDetailedText(aDetailedText);
1092 QMessageBox::ButtonRole aButtonRole = aMessageBox.buttonRole(aMessageBox.clickedButton());
1094 if (aButtonRole == QMessageBox::NoRole)
1097 if (aButtonRole == QMessageBox::ActionRole) {
1098 foreach (FeaturePtr aObj, aParameterFeatures)
1099 ModelAPI_ReplaceParameterMessage::send(aObj, 0);
1102 theReferencesToDelete.insert(aFeaturesRefsToParameterOnly.begin(),
1103 aFeaturesRefsToParameterOnly.end());
1108 //**************************************************************
1109 bool warningAboutConflict(QWidget* theParent, const std::string& theWarningText)
1111 QMessageBox aMessageBox(theParent);
1112 aMessageBox.setWindowTitle(QObject::tr("Conflicts in constraint"));
1113 aMessageBox.setIcon(QMessageBox::Warning);
1114 aMessageBox.setText((theWarningText + "\nConstraints will be removed or substituted").c_str());
1116 QCheckBox* aCheckBox = new QCheckBox;
1118 aCheckBox->setTristate(false);
1119 aCheckBox->setText("switch off the notifications.");
1121 aMessageBox.setCheckBox(aCheckBox);
1122 aMessageBox.setStandardButtons(QMessageBox::Ok);
1126 if (aCheckBox->isChecked())
1128 ModuleBase_Preferences::resourceMgr()->setValue(SKETCH_TAB_NAME,
1129 "notify_change_constraint", false);
1135 //**************************************************************
1136 void convertToFeatures(const QObjectPtrList& theObjects, std::set<FeaturePtr>& theFeatures)
1138 QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
1139 for(; anIt != aLast; anIt++) {
1140 ObjectPtr anObject = *anIt;
1141 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
1142 // for parameter result, use the corresponded reature to be removed
1143 if (!aFeature.get() && anObject->groupName() == ModelAPI_ResultParameter::group()) {
1144 aFeature = ModelAPI_Feature::feature(anObject);
1147 theFeatures.insert(aFeature);
1151 //**************************************************************
1152 void convertToFolders(const QObjectPtrList& theObjects,
1153 std::set<FolderPtr>& theFolders)
1155 QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
1156 for(; anIt != aLast; anIt++) {
1157 ObjectPtr anObject = *anIt;
1158 FolderPtr aFeature = std::dynamic_pointer_cast<ModelAPI_Folder>(anObject);
1160 theFolders.insert(aFeature);
1165 //**************************************************************
1166 QString translate(const Events_InfoMessage& theMessage)
1170 if (!theMessage.empty()) {
1171 std::string aStr = Config_Translator::translate(theMessage);
1172 if (!aStr.empty()) {
1173 std::string aCodec = Config_Translator::codec(theMessage);
1174 aMessage = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
1181 QString translate(const std::string& theContext, const std::string& theMessage)
1185 if (!theMessage.empty()) {
1186 std::string aStr = Config_Translator::translate(theContext, theMessage);
1187 if (!aStr.empty()) {
1188 std::string aCodec = Config_Translator::codec(theContext);
1189 aMessage = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
1196 void setPointBallHighlighting(AIS_InteractiveObject* theAIS)
1198 static Handle(Image_AlienPixMap) aPixMap;
1199 if(aPixMap.IsNull()) {
1200 // Load icon for the presentation
1202 char* anEnv = getenv("SHAPER_ROOT_DIR");
1204 aFile = std::string(anEnv) +
1205 FSEP + "share" + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper";
1207 anEnv = getenv("CADBUILDER_ROOT_DIR");
1209 aFile = std::string(anEnv) + FSEP + "resources";
1213 static const std::string aMarkerName = "marker_dot.png";
1214 aFile += aMarkerName;
1215 aPixMap = new Image_AlienPixMap();
1216 if(!aPixMap->Load(aFile.c_str())) {
1217 // The icon for constraint is not found
1218 static const std::string aMsg =
1219 "Error: Point market not found by path: \"" + aFile + "\". Falling back.";
1220 //Events_InfoMessage("ModuleBase_Tools::setPointBallHighlighting", aMsg).send();
1224 Handle(Graphic3d_AspectMarker3d) anAspect;
1225 Handle(Prs3d_Drawer) aDrawer = theAIS->DynamicHilightAttributes();
1226 if (aDrawer.IsNull()) {
1227 if (ModuleBase_IViewer::DefaultHighlightDrawer.IsNull())
1229 aDrawer = new Prs3d_Drawer(*ModuleBase_IViewer::DefaultHighlightDrawer);
1230 if (!aDrawer->HasOwnPointAspect()) {
1231 aDrawer->SetPointAspect(new Prs3d_PointAspect(Aspect_TOM_BALL, Quantity_NOC_BLACK, 2.0));
1234 if(aDrawer->HasOwnPointAspect()) {
1235 Handle(Prs3d_PointAspect) aPntAspect = aDrawer->PointAspect();
1236 if(aPixMap->IsEmpty()) {
1237 anAspect = aPntAspect->Aspect();
1238 anAspect->SetType(Aspect_TOM_BALL);
1240 #if OCC_VERSION_LARGE < 0x07070000
1241 if(aPixMap->Format() == Image_PixMap::ImgGray) {
1242 aPixMap->SetFormat (Image_PixMap::ImgAlpha);
1243 } else if(aPixMap->Format() == Image_PixMap::ImgGrayF) {
1244 aPixMap->SetFormat (Image_PixMap::ImgAlphaF);
1247 if(aPixMap->Format() == Image_Format_Gray) {
1248 aPixMap->SetFormat (Image_Format_Alpha);
1249 } else if(aPixMap->Format() == Image_Format_GrayF) {
1250 aPixMap->SetFormat (Image_Format_AlphaF);
1253 anAspect = new Graphic3d_AspectMarker3d(aPixMap);
1254 aPntAspect->SetAspect(anAspect);
1256 aDrawer->SetPointAspect(aPntAspect);
1257 theAIS->SetDynamicHilightAttributes(aDrawer);
1261 FeaturePtr createParameter(const QString& theText)
1263 FeaturePtr aParameter;
1264 QStringList aList = theText.split("=");
1265 if (aList.count() != 2) {
1268 QString aParamName = aList.at(0).trimmed();
1270 if (isNameExist(aParamName, FeaturePtr())) {
1274 if (!ModelAPI_Expression::isVariable(aParamName.toStdString())) {
1278 QString aExpression = aList.at(1).trimmed();
1279 if (aExpression.isEmpty()) {
1283 SessionPtr aMgr = ModelAPI_Session::get();
1284 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1286 aParameter = aDoc->addFeature("Parameter", false);
1287 if (aParameter.get()) {
1288 AttributeStringPtr aNameAttr = aParameter->string("variable");
1289 aNameAttr->setValue(aParamName.toStdString());
1291 AttributeStringPtr aExprAttr = aParameter->string("expression");
1292 aExprAttr->setValue(aExpression.toStdString());
1293 aParameter->execute();
1295 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
1296 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
1301 void editParameter(FeaturePtr theParam, const QString& theText)
1303 QStringList aList = theText.split("=");
1304 QString aParamName = aList.at(0).trimmed();
1306 QString aExpression = aList.at(1).trimmed();
1307 if (aExpression.isEmpty()) {
1311 if (isNameExist(aParamName, theParam)) {
1314 AttributeStringPtr aNameAttr = theParam->string("variable");
1315 aNameAttr->setValue(aParamName.toStdString());
1317 AttributeStringPtr aExprAttr = theParam->string("expression");
1318 aExprAttr->setValue(aExpression.toStdString());
1319 theParam->execute();
1321 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
1324 bool isNameExist(const QString& theName, FeaturePtr theIgnoreParameter)
1326 SessionPtr aMgr = ModelAPI_Session::get();
1327 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1328 FeaturePtr aParamFeature;
1329 int aNbFeatures = aDoc->numInternalFeatures();
1330 std::wstring aName = theName.toStdWString();
1331 for (int i = 0; i < aNbFeatures; i++) {
1332 aParamFeature = aDoc->internalFeature(i);
1333 if (aParamFeature && aParamFeature->getKind() == "Parameter") {
1334 if ((theIgnoreParameter != aParamFeature) && (aParamFeature->name() == aName))
1341 FeaturePtr findParameter(const QString& theName)
1343 SessionPtr aMgr = ModelAPI_Session::get();
1344 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1345 FeaturePtr aParamFeature;
1346 int aNbFeatures = aDoc->numInternalFeatures();
1347 std::wstring aName = theName.toStdWString();
1348 for (int i = 0; i < aNbFeatures; i++) {
1349 aParamFeature = aDoc->internalFeature(i);
1350 if (aParamFeature && aParamFeature->getKind() == "Parameter") {
1351 if (aParamFeature->name() == aName)
1352 return aParamFeature;
1355 return FeaturePtr();
1359 //********************************************************************
1360 std::wstring generateName(const AttributePtr& theAttribute,
1361 ModuleBase_IWorkshop* theWorkshop)
1364 if (theAttribute.get() != NULL) {
1365 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
1366 if (aFeature.get()) {
1367 std::string aXmlCfg, aDescription;
1368 theWorkshop->module()->getXMLRepresentation(aFeature->getKind(), aXmlCfg, aDescription);
1370 ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop);
1371 std::string anAttributeTitle;
1372 aFactory.getAttributeTitle(theAttribute->id(), anAttributeTitle);
1374 std::wstringstream aStreamName;
1375 aStreamName << theAttribute->owner()->data()->name() << "/" << anAttributeTitle.c_str();
1376 aName = aStreamName.str();
1382 bool isSameShape(const TopoDS_Shape& theShape1, const TopoDS_Shape& theShape2)
1384 // In case of compound we cannot rely on simple comparison method.
1385 // If the compound is generated by Group feature then this compound is alwais new.
1386 // So, we have to compare content of these compounds
1387 if (theShape1.ShapeType() != theShape2.ShapeType())
1390 if (theShape1.ShapeType() != TopAbs_COMPOUND)
1391 return theShape1.IsSame(theShape2);
1393 TopoDS_Iterator aIt1(theShape1);
1394 TopoDS_Iterator aIt2(theShape2);
1396 for (; aIt1.More() && aIt2.More(); aIt1.Next(), aIt2.Next()) {
1397 if (!(aIt1.Value()).IsSame(aIt2.Value()))
1403 qreal currentPixelRatio()
1405 QWindowList aWnds = qApp->topLevelWindows();
1406 if (aWnds.size() > 0)
1407 return aWnds.first()->devicePixelRatio();
1408 return qApp->primaryScreen()->devicePixelRatio();
1412 // Set displaying status to every element on group
1413 static void setDisplayingByLoop(DocumentPtr theDoc, int theSize,
1414 std::string theGroup, bool theDisplayFromScript, int theDisplayingId)
1416 for (int anIndex = theSize - 1; anIndex >= 0; --anIndex) {
1417 ObjectPtr anObject = theDoc->object(theGroup, anIndex);
1418 anObject->setDisplayed((theDisplayingId == 1 && anIndex == theSize - 1) ||
1419 theDisplayingId == 2);
1423 void setDisplaying(ResultPartPtr thePart, bool theDisplayFromScript)
1425 static bool isDoingDisplay = false;
1430 isDoingDisplay = true;
1431 DocumentPtr aDoc = thePart->partDoc();
1432 int aConstructionSize = aDoc->size(ModelAPI_ResultConstruction::group());
1433 int aGroupSize = aDoc->size(ModelAPI_ResultGroup::group());
1434 int aFieldSize = aDoc->size(ModelAPI_ResultField::group());
1435 int aResultSize = aDoc->size(ModelAPI_ResultBody::group());
1437 int aDisplayingId = -1;
1438 if (theDisplayFromScript) {
1439 aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General",
1440 "part_visualization_script", -1);
1441 // Increase ID to prevert using "As stored in HDF"
1445 aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General",
1446 "part_visualization_study", -1);
1448 // if chosen "As stored in HDF" then don't change displaying
1449 if (aDisplayingId == 0)
1453 setDisplayingByLoop(aDoc, aConstructionSize, ModelAPI_ResultConstruction::group(),
1454 theDisplayFromScript, aDisplayingId);
1455 setDisplayingByLoop(aDoc, aGroupSize, ModelAPI_ResultGroup::group(),
1456 theDisplayFromScript, aDisplayingId);
1457 setDisplayingByLoop(aDoc, aFieldSize, ModelAPI_ResultField::group(),
1458 theDisplayFromScript, aDisplayingId);
1459 setDisplayingByLoop(aDoc, aResultSize, ModelAPI_ResultBody::group(),
1460 theDisplayFromScript, aDisplayingId);
1461 isDoingDisplay = false;
1464 } // namespace ModuleBase_Tools