1 // Copyright (C) 2014-2021 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "ModuleBase_Tools.h"
22 #include <ModuleBase_ParamIntSpinBox.h>
23 #include <ModuleBase_ParamSpinBox.h>
24 #include <ModuleBase_Preferences.h>
25 #include <ModuleBase_WidgetFactory.h>
26 #include <ModuleBase_IWorkshop.h>
27 #include <ModuleBase_IModule.h>
28 #include <ModuleBase_IViewer.h>
29 #include <ModuleBase_IconFactory.h>
30 #include <ModuleBase_ResultPrs.h>
31 #include <ModuleBase_ViewerPrs.h>
33 #include <ModelAPI_Attribute.h>
34 #include <ModelAPI_AttributeRefAttr.h>
35 #include <ModelAPI_AttributeReference.h>
36 #include <ModelAPI_AttributeSelection.h>
37 #include <ModelAPI_AttributeSelectionList.h>
38 #include <ModelAPI_AttributeRefList.h>
39 #include <ModelAPI_AttributeRefAttrList.h>
40 #include <ModelAPI_ResultGroup.h>
41 #include <ModelAPI_ResultPart.h>
42 #include <ModelAPI_ResultConstruction.h>
43 #include <ModelAPI_AttributeString.h>
44 #include <ModelAPI_Expression.h>
45 #include <ModelAPI_ResultField.h>
46 #include <Events_Loop.h>
48 #include <ModelAPI_Data.h>
49 #include <ModelAPI_Result.h>
50 #include <ModelAPI_ResultParameter.h>
51 #include <ModelAPI_Tools.h>
52 #include <ModelAPI_Session.h>
53 #include <ModelAPI_Events.h>
54 #include <ModelAPI_Folder.h>
56 #include <ModelGeomAlgo_Point2D.h>
59 #include <SUIT_Application.h>
60 #include <SUIT_ResourceMgr.h>
61 #include <SUIT_Session.h>
64 #include <StdSelect_BRepOwner.hxx>
65 #include <TopoDS_Iterator.hxx>
66 #include <AIS_InteractiveContext.hxx>
67 #include <Prs3d_LineAspect.hxx>
68 #include <Prs3d_PlaneAspect.hxx>
70 #include <GeomDataAPI_Point2D.h>
71 #include <Events_InfoMessage.h>
72 #include <GeomAPI_ShapeExplorer.h>
74 #include <Config_PropManager.h>
75 #include <Config_Translator.h>
77 #include <Prs3d_PointAspect.hxx>
78 #include <Graphic3d_AspectMarker3d.hxx>
80 #include <Image_AlienPixMap.hxx>
86 #include <QDoubleSpinBox>
87 #include <QGraphicsDropShadowEffect>
89 #include <QApplication>
90 #include <QMessageBox>
100 #pragma warning(disable : 4996) // for getenv
103 const double tolerance = 1e-7;
104 const double DEFAULT_DEVIATION_COEFFICIENT = 1.e-4;
106 //#define DEBUG_ACTIVATE_WINDOW
107 //#define DEBUG_SET_FOCUS
115 namespace ModuleBase_Tools {
117 //******************************************************************
119 //! Waits for REDISPLAY message and set the Visible flag to the entities
120 //! according to Preferences choice.
121 class ModuleBase_RedisplayListener : public Events_Listener
124 static std::shared_ptr<ModuleBase_RedisplayListener> instance()
126 static std::shared_ptr<ModuleBase_RedisplayListener>
127 anInstance(new ModuleBase_RedisplayListener);
131 void processEvent(const std::shared_ptr<Events_Message>& theMessage)
133 if (theMessage->eventID() == Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY))
136 // If the python script is being loaded now, the preferences should be used
137 // to display the required object
138 SUIT_Session* aSession = SUIT_Session::session();
141 SUIT_Application * anApp = aSession->activeApplication();
144 QVariant aVar = anApp->property("IsLoadedScript");
145 if (!aVar.isNull() && aVar.toBool()) {
146 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
147 int aSize = aRootDoc->size(ModelAPI_ResultPart::group());
149 ObjectPtr anPartObject = aRootDoc->object(ModelAPI_ResultPart::group(), aSize - 1);
150 ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(anPartObject);
151 ModuleBase_Tools::setDisplaying(aPart, true);
159 ModuleBase_RedisplayListener()
161 Events_Loop::loop()->registerListener(this,
162 Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
166 static std::shared_ptr<ModuleBase_RedisplayListener>
167 RL = ModuleBase_RedisplayListener::instance();
169 //******************************************************************
171 void adjustMargins(QWidget* theWidget)
175 adjustMargins(theWidget->layout());
178 void adjustMargins(QLayout* theLayout)
182 theLayout->setContentsMargins(2, 5, 2, 5);
183 theLayout->setSpacing(4);
186 void zeroMargins(QWidget* theWidget)
190 zeroMargins(theWidget->layout());
193 void zeroMargins(QLayout* theLayout)
197 theLayout->setContentsMargins(0, 0, 0, 0);
198 theLayout->setSpacing(5);
201 void activateWindow(QWidget* theWidget, const QString& theInfo)
204 theWidget->activateWindow();
208 #ifdef DEBUG_ACTIVATE_WINDOW
209 qDebug(QString("activateWindow: %1").arg(theInfo).toStdString().c_str());
213 void setFocus(QWidget* theWidget, const QString& theInfo)
215 activateWindow(theWidget);
216 theWidget->setFocus();
217 // rectangle of focus is not visible on tool button widgets
219 #ifdef DEBUG_SET_FOCUS
220 qDebug(QString("setFocus: %1").arg(theInfo).toStdString().c_str());
224 void setShadowEffect(QWidget* theWidget, const bool isSetEffect)
227 QGraphicsDropShadowEffect* aGlowEffect = new QGraphicsDropShadowEffect();
228 aGlowEffect->setOffset(.0);
229 aGlowEffect->setBlurRadius(10.0);
230 aGlowEffect->setColor(QColor(0, 170, 255)); // Light-blue color, #00AAFF
231 theWidget->setGraphicsEffect(aGlowEffect);
234 QGraphicsEffect* anEffect = theWidget->graphicsEffect();
236 anEffect->deleteLater();
237 theWidget->setGraphicsEffect(NULL);
241 QPixmap composite(const QString& theAdditionalIcon, const QString& theIcon)
243 QImage anIcon = ModuleBase_IconFactory::loadImage(theIcon);
244 QImage anAditional(theAdditionalIcon);
245 return composite(anAditional, anIcon);
248 QPixmap composite(const QImage& theAdditionalIcon, QImage& theIcon)
250 if (theIcon.isNull())
253 int anAddWidth = theAdditionalIcon.width();
254 int anAddHeight = theAdditionalIcon.height();
256 int aWidth = theIcon.width();
257 int aHeight = theIcon.height();
259 int aStartWidthPos = aWidth - anAddWidth;
260 int aStartHeightPos = aHeight - anAddHeight;
262 for (int i = 0; i < anAddWidth && i + aStartWidthPos < aWidth; i++)
264 for (int j = 0; j < anAddHeight && j + aStartHeightPos < aHeight; j++)
266 if (qAlpha(theAdditionalIcon.pixel(i, j)) > 0)
267 theIcon.setPixel(i + aStartWidthPos, j + aStartHeightPos, theAdditionalIcon.pixel(i, j));
270 return QPixmap::fromImage(theIcon);
273 QPixmap lighter(const QString& theIcon, const int theLighterValue)
275 QImage anIcon = ModuleBase_IconFactory::loadImage(theIcon);
279 QImage aResult = ModuleBase_IconFactory::loadImage(theIcon);
280 for (int i = 0; i < anIcon.width(); i++)
282 for (int j = 0; j < anIcon.height(); j++)
284 QRgb anRgb = anIcon.pixel(i, j);
285 QColor aPixelColor(qRed(anRgb), qGreen(anRgb), qBlue(anRgb),
286 qAlpha(aResult.pixel(i, j)));
288 QColor aLighterColor = aPixelColor.lighter(theLighterValue);
289 aResult.setPixel(i, j, qRgba(aLighterColor.red(), aLighterColor.green(),
290 aLighterColor.blue(), aLighterColor.alpha()));
293 return QPixmap::fromImage(aResult);
296 void setSpinText(ModuleBase_ParamSpinBox* theSpin, const QString& theText)
298 if (theSpin->text() == theText)
300 // In order to avoid extra text setting because it will
301 // reset cursor position in control
302 bool isBlocked = theSpin->blockSignals(true);
303 theSpin->setText(theText);
304 theSpin->blockSignals(isBlocked);
307 void setSpinValue(QDoubleSpinBox* theSpin, double theValue)
309 if (fabs(theSpin->value() - theValue) < tolerance)
311 bool isBlocked = theSpin->blockSignals(true);
312 theSpin->setValue(theValue);
313 theSpin->blockSignals(isBlocked);
316 void setSpinValue(ModuleBase_ParamSpinBox* theSpin, double theValue)
318 if (!theSpin->text().isEmpty() && fabs(theSpin->value() - theValue) < tolerance)
320 bool isBlocked = theSpin->blockSignals(true);
321 theSpin->setValue(theValue);
322 theSpin->blockSignals(isBlocked);
325 void setSpinText(ModuleBase_ParamIntSpinBox* theSpin, const QString& theText)
327 // In order to avoid extra text setting because it will
328 // reset cursor position in control
329 if (theSpin->text() == theText)
331 bool isBlocked = theSpin->blockSignals(true);
332 theSpin->setText(theText);
333 theSpin->blockSignals(isBlocked);
336 void setSpinValue(ModuleBase_ParamIntSpinBox* theSpin, int theValue)
338 if (theSpin->value() == theValue)
340 bool isBlocked = theSpin->blockSignals(true);
341 theSpin->setValue(theValue);
342 theSpin->blockSignals(isBlocked);
345 QAction* createAction(const QIcon& theIcon, const QString& theText,
346 QObject* theParent, const QObject* theReceiver,
347 const char* theMember, const QString& theToolTip,
348 const QString& theStatusTip)
350 QAction* anAction = new QAction(theIcon, theText, theParent);
351 anAction->setToolTip(theToolTip.isEmpty() ? theText : theToolTip);
352 anAction->setStatusTip(!theStatusTip.isEmpty() ? theStatusTip :
353 (!theToolTip.isEmpty() ? theToolTip : theText));
355 QObject::connect(anAction, SIGNAL(triggered(bool)), theReceiver, theMember);
361 QString objectName(const ObjectPtr& theObj)
366 return QString::fromStdWString(theObj->data()->name());
369 QString objectInfo(const ObjectPtr& theObj, const bool isUseAttributesInfo)
371 QString aFeatureStr = "feature";
375 std::ostringstream aPtrStr;
376 aPtrStr << "[" << theObj.get() << "]";
378 ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObj);
379 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObj);
381 aFeatureStr.append(QString("(result%1)").arg(aPtrStr.str().c_str()).toStdString() .c_str());
382 if (aRes->isDisabled())
383 aFeatureStr.append("[disabled]");
384 if (aRes->isConcealed())
385 aFeatureStr.append("[concealed]");
386 if (ModelAPI_Tools::hasSubResults(aRes))
387 aFeatureStr.append("[hasSubResults]");
389 aFeature = ModelAPI_Feature::feature(aRes);
392 aFeatureStr.append(aPtrStr.str().c_str());
394 if (aFeature.get()) {
395 aFeatureStr.append(QString(": %1").arg(aFeature->getKind().c_str()).toStdString().c_str());
396 if (aFeature->data()->isValid()) {
397 aFeatureStr.append(QString(", name=%1")
398 .arg(QString::fromStdWString(theObj->data()->name())).toStdString().c_str());
400 if (isUseAttributesInfo) {
401 std::set<std::shared_ptr<ModelAPI_Attribute> > anAttributes;
402 std::string aPointsInfo = ModelGeomAlgo_Point2D::getPontAttributesInfo(aFeature,
403 anAttributes).c_str();
404 if (!aPointsInfo.empty())
405 aFeatureStr.append(QString(", attributes: %1")
406 .arg(aPointsInfo.c_str()).toStdString().c_str());
414 typedef QMap<QString, int> ShapeTypes;
415 static ShapeTypes myShapeTypes;
417 int shapeType(const QString& theType)
419 if (myShapeTypes.count() == 0) {
420 myShapeTypes["compound"] = TopAbs_COMPOUND;
421 myShapeTypes["compounds"] = TopAbs_COMPOUND;
422 myShapeTypes["compsolid"] = TopAbs_COMPSOLID;
423 myShapeTypes["compsolids"] = TopAbs_COMPSOLID;
424 myShapeTypes["solid"] = TopAbs_SOLID;
425 myShapeTypes["solids"] = TopAbs_SOLID;
426 myShapeTypes["shell"] = TopAbs_SHELL;
427 myShapeTypes["shells"] = TopAbs_SHELL;
428 myShapeTypes["face"] = TopAbs_FACE;
429 myShapeTypes["faces"] = TopAbs_FACE;
430 myShapeTypes["wire"] = TopAbs_WIRE;
431 myShapeTypes["wires"] = TopAbs_WIRE;
432 myShapeTypes["edge"] = TopAbs_EDGE;
433 myShapeTypes["edges"] = TopAbs_EDGE;
434 myShapeTypes["vertex"] = TopAbs_VERTEX;
435 myShapeTypes["vertices"] = TopAbs_VERTEX;
436 myShapeTypes["object"] = ModuleBase_ResultPrs::Sel_Result;
437 myShapeTypes["objects"] = ModuleBase_ResultPrs::Sel_Result;
439 QString aType = theType.toLower();
440 if(myShapeTypes.contains(aType))
441 return myShapeTypes[aType];
442 Events_InfoMessage("ModuleBase_Tools", "Shape type defined in XML is not implemented!").send();
446 void checkObjects(const QObjectPtrList& theObjects, bool& hasResult, bool& hasFeature,
447 bool& hasParameter, bool& hasCompositeOwner, bool& hasResultInHistory,
452 hasParameter = false;
453 hasCompositeOwner = false;
454 hasResultInHistory = false;
456 foreach(ObjectPtr aObj, theObjects) {
457 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
458 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
459 FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(aObj);
460 ResultParameterPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aResult);
461 FieldStepPtr aStep = std::dynamic_pointer_cast<ModelAPI_ResultField::ModelAPI_FieldStep>(aObj);
463 hasResult |= ((aResult.get() != NULL) || (aStep.get() != NULL));
464 hasFeature |= (aFeature.get() != NULL);
465 hasFolder |= (aFolder.get() != NULL);
466 hasParameter |= (aConstruction.get() != NULL);
468 hasCompositeOwner |= (ModelAPI_Tools::compositeOwner(aFeature) != NULL);
469 else if (aResult.get())
470 hasCompositeOwner |= (ModelAPI_Tools::bodyOwner(aResult) != NULL);
472 if (!hasResultInHistory && aResult.get()) {
473 aFeature = ModelAPI_Feature::feature(aResult);
474 hasResultInHistory = aFeature.get() && aFeature->isInHistory();
477 if (hasFeature && hasResult && hasParameter && hasCompositeOwner)
482 /*bool setDefaultDeviationCoefficient(std::shared_ptr<GeomAPI_Shape> theGeomShape)
484 if (!theGeomShape.get())
486 // if the shape could not be exploded on faces, it contains only wires, edges, and vertices
487 // correction of deviation for them should not influence to the application performance
488 GeomAPI_ShapeExplorer anExp(theGeomShape, GeomAPI_Shape::FACE);
489 bool anEmpty = anExp.empty();
490 return !anExp.more();
493 /*void setDefaultDeviationCoefficient(const std::shared_ptr<ModelAPI_Result>& theResult,
494 const Handle(Prs3d_Drawer)& theDrawer)
496 if (!theResult.get())
498 bool aUseDeviation = false;
500 std::string aResultGroup = theResult->groupName();
501 if (aResultGroup == ModelAPI_ResultConstruction::group())
502 aUseDeviation = true;
503 else if (aResultGroup == ModelAPI_ResultBody::group()) {
504 GeomShapePtr aGeomShape = theResult->shape();
505 if (aGeomShape.get())
506 aUseDeviation = setDefaultDeviationCoefficient(aGeomShape);
509 theDrawer->SetDeviationCoefficient(DEFAULT_DEVIATION_COEFFICIENT);
512 void setDefaultDeviationCoefficient(const TopoDS_Shape& theShape,
513 const Handle(Prs3d_Drawer)& theDrawer)
515 if (theShape.IsNull())
517 if (theDrawer.IsNull())
520 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape());
521 aGeomShape->setImpl(new TopoDS_Shape(theShape));
523 // if the shape could not be exploded on faces, it contains only wires, edges, and vertices
524 // correction of deviation for them should not influence to the application performance
525 GeomAPI_ShapeExplorer anExp(aGeomShape, GeomAPI_Shape::FACE);
526 bool isConstruction = !anExp.more();
530 aDeflection = Config_PropManager::real("Visualization", "construction_deflection");
532 aDeflection = Config_PropManager::real("Visualization", "body_deflection");
534 theDrawer->SetDeviationCoefficient(aDeflection);
537 Quantity_Color color(const std::string& theSection,
538 const std::string& theName)
540 std::vector<int> aColor = Config_PropManager::color(theSection, theName);
541 return Quantity_Color(aColor[0] / 255., aColor[1] / 255., aColor[2] / 255., Quantity_TOC_RGB);
544 ObjectPtr getObject(const AttributePtr& theAttribute)
547 std::string anAttrType = theAttribute->attributeType();
548 if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
549 AttributeRefAttrPtr anAttr =
550 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
551 if (anAttr != NULL && anAttr->isObject())
552 anObject = anAttr->object();
554 if (anAttrType == ModelAPI_AttributeSelection::typeId()) {
555 AttributeSelectionPtr anAttr =
556 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
558 anObject = anAttr->context();
560 if (anAttrType == ModelAPI_AttributeReference::typeId()) {
561 AttributeReferencePtr anAttr =
562 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
563 if (anAttr.get() != NULL)
564 anObject = anAttr->value();
569 TopAbs_ShapeEnum getCompoundSubType(const TopoDS_Shape& theShape)
571 TopAbs_ShapeEnum aShapeType = theShape.ShapeType();
573 // for compounds check sub-shapes: it may be compound of needed type:
574 // Booleans may produce compounds of Solids
575 if (aShapeType == TopAbs_COMPOUND) {
576 for(TopoDS_Iterator aSubs(theShape); aSubs.More(); aSubs.Next()) {
577 if (!aSubs.Value().IsNull()) {
578 TopAbs_ShapeEnum aSubType = aSubs.Value().ShapeType();
579 if (aSubType == TopAbs_COMPOUND) { // compound of compound(s)
580 aShapeType = TopAbs_COMPOUND;
583 if (aShapeType == TopAbs_COMPOUND) {
584 aShapeType = aSubType;
585 } else if (aShapeType != aSubType) { // compound of shapes of different types
586 aShapeType = TopAbs_COMPOUND;
595 TopoDS_Shape getSelectedShape(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs)
597 if (thePrs->shape().get())
598 return thePrs->shape()->impl<TopoDS_Shape>();
600 Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast(thePrs->owner());
601 if (!anOwner.IsNull())
602 return anOwner->Shape();
604 return TopoDS_Shape();
607 void getParameters(QStringList& theParameters)
609 theParameters.clear();
611 SessionPtr aSession = ModelAPI_Session::get();
612 std::list<DocumentPtr> aDocList;
613 DocumentPtr anActiveDocument = aSession->activeDocument();
614 DocumentPtr aRootDocument = aSession->moduleDocument();
615 aDocList.push_back(anActiveDocument);
616 if (anActiveDocument != aRootDocument) {
617 aDocList.push_back(aRootDocument);
619 std::string aGroupId = ModelAPI_ResultParameter::group();
620 for(std::list<DocumentPtr>::const_iterator it = aDocList.begin(); it != aDocList.end(); ++it) {
621 DocumentPtr aDocument = *it;
622 int aSize = aDocument->size(aGroupId);
623 for (int i = 0; i < aSize; i++) {
624 ObjectPtr anObject = aDocument->object(aGroupId, i);
625 std::wstring aParameterName = anObject->data()->name();
626 theParameters.append(QString::fromStdWString(aParameterName));
631 std::string findGreedAttribute(ModuleBase_IWorkshop* theWorkshop,
632 const FeaturePtr& theFeature)
634 std::string anAttributeId;
636 std::string aXmlCfg, aDescription;
637 theWorkshop->module()->getXMLRepresentation(theFeature->getKind(), aXmlCfg, aDescription);
639 ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop);
640 std::string anAttributeTitle;
641 aFactory.getGreedAttribute(anAttributeId);
643 return anAttributeId;
646 bool hasObject(const AttributePtr& theAttribute, const ObjectPtr& theObject,
647 const std::shared_ptr<GeomAPI_Shape>& theShape,
648 ModuleBase_IWorkshop* theWorkshop,
649 const bool theTemporarily)
651 bool aHasObject = false;
652 if (!theAttribute.get())
655 std::string aType = theAttribute->attributeType();
656 if (aType == ModelAPI_AttributeReference::typeId()) {
657 AttributeReferencePtr aRef =
658 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
659 ObjectPtr aObject = aRef->value();
660 aHasObject = aObject && aObject->isSame(theObject);
661 //if (!(aObject && aObject->isSame(theObject))) {
662 // aRef->setValue(theObject);
664 } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
665 AttributeRefAttrPtr aRefAttr =
666 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
668 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
669 if (anAttribute.get()) {
670 //aRefAttr->setAttr(anAttribute);
673 ObjectPtr aObject = aRefAttr->object();
674 aHasObject = aObject && aObject->isSame(theObject);
675 //if (!(aObject && aObject->isSame(theObject))) {
676 // aRefAttr->setObject(theObject);
679 } else if (aType == ModelAPI_AttributeSelection::typeId()) {
680 /*AttributeSelectionPtr aSelectAttr =
681 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
682 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
683 if (aSelectAttr.get() != NULL) {
684 aSelectAttr->setValue(aResult, theShape, theTemporarily);
687 if (aType == ModelAPI_AttributeSelectionList::typeId()) {
688 AttributeSelectionListPtr aSelectionListAttr =
689 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
690 aHasObject = aSelectionListAttr->isInList(theObject, theShape, theTemporarily);
692 else if (aType == ModelAPI_AttributeRefList::typeId()) {
693 AttributeRefListPtr aRefListAttr =
694 std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttribute);
695 aHasObject = aRefListAttr->isInList(theObject);
696 //if (!theCheckIfAttributeHasObject || !aRefListAttr->isInList(theObject))
697 // aRefListAttr->append(theObject);
699 else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
700 AttributeRefAttrListPtr aRefAttrListAttr =
701 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(theAttribute);
702 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
704 if (anAttribute.get()) {
705 aHasObject = aRefAttrListAttr->isInList(anAttribute);
706 //if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(anAttribute))
707 // aRefAttrListAttr->append(anAttribute);
710 aHasObject = aRefAttrListAttr->isInList(theObject);
711 //if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(theObject))
712 // aRefAttrListAttr->append(theObject);
718 bool setObject(const AttributePtr& theAttribute, const ObjectPtr& theObject,
719 const GeomShapePtr& theShape, ModuleBase_IWorkshop* theWorkshop,
720 const bool theTemporarily, const bool theCheckIfAttributeHasObject)
722 if (!theAttribute.get())
726 std::string aType = theAttribute->attributeType();
727 if (aType == ModelAPI_AttributeReference::typeId()) {
728 AttributeReferencePtr aRef =
729 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
730 ObjectPtr aObject = aRef->value();
731 if (!(aObject && aObject->isSame(theObject))) {
732 aRef->setValue(theObject);
734 } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
735 AttributeRefAttrPtr aRefAttr =
736 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
738 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
739 if (anAttribute.get())
740 aRefAttr->setAttr(anAttribute);
742 ObjectPtr aObject = aRefAttr->object();
743 if (!(aObject && aObject->isSame(theObject))) {
744 aRefAttr->setObject(theObject);
747 } else if (aType == ModelAPI_AttributeSelection::typeId()) {
748 AttributeSelectionPtr aSelectAttr =
749 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
750 if (aSelectAttr.get() != NULL) {
751 aSelectAttr->setValue(theObject, theShape, theTemporarily);
754 if (aType == ModelAPI_AttributeSelectionList::typeId()) {
755 AttributeSelectionListPtr aSelectionListAttr =
756 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
757 if (!theCheckIfAttributeHasObject ||
758 !aSelectionListAttr->isInList(theObject, theShape, theTemporarily))
759 aSelectionListAttr->append(theObject, theShape, theTemporarily);
761 else if (aType == ModelAPI_AttributeRefList::typeId()) {
762 AttributeRefListPtr aRefListAttr =
763 std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttribute);
764 if (!theCheckIfAttributeHasObject || !aRefListAttr->isInList(theObject)) {
766 aRefListAttr->append(theObject);
771 else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
772 AttributeRefAttrListPtr aRefAttrListAttr =
773 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(theAttribute);
774 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
776 if (anAttribute.get()) {
777 if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(anAttribute))
778 aRefAttrListAttr->append(anAttribute);
781 if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(theObject)) {
783 aRefAttrListAttr->append(theObject);
792 GeomShapePtr getShape(const AttributePtr& theAttribute, ModuleBase_IWorkshop* theWorkshop)
795 if (!theAttribute.get())
798 std::string aType = theAttribute->attributeType();
799 if (aType == ModelAPI_AttributeReference::typeId()) {
800 } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
801 AttributeRefAttrPtr aRefAttr =
802 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
803 if (aRefAttr.get() && !aRefAttr->isObject()) {
804 AttributePtr anAttribute = aRefAttr->attr();
805 aShape = theWorkshop->module()->findShape(anAttribute);
807 } else if (aType == ModelAPI_AttributeSelection::typeId()) {
808 AttributeSelectionPtr aSelectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
810 aShape = aSelectAttr->value();
812 else // Geom2D point processing
813 aShape = theWorkshop->module()->findShape(theAttribute);
817 void flushUpdated(ObjectPtr theObject)
819 blockUpdateViewer(true);
821 // Fix the problem of not previewed results of constraints applied. Flush Create/Delete
822 // (for the sketch result) to start processing of the sketch in the solver.
823 // TODO: these flushes should be moved in a separate method provided by Model
824 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
825 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_VISUAL_ATTRIBUTES));
826 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
827 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_UPDATE_SELECTION));
828 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
830 blockUpdateViewer(false);
833 void blockUpdateViewer(const bool theValue)
835 // the viewer update should be blocked in order to avoid the temporary feature content
836 // when the solver processes the feature, the redisplay message can be flushed
837 // what caused the display in the viewer preliminary states of object
838 // e.g. fillet feature, angle value change
839 std::shared_ptr<Events_Message> aMsg;
841 aMsg = std::shared_ptr<Events_Message>(
842 new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED)));
845 // the viewer update should be unblocked
846 aMsg = std::shared_ptr<Events_Message>(
847 new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)));
849 Events_Loop::loop()->send(aMsg);
852 QString wrapTextByWords(const QString& theValue, QWidget* theWidget,
853 int theMaxLineInPixels)
855 static QFontMetrics tfm(theWidget ? theWidget->font() : QApplication::font());
856 static qreal phi = 2.618;
858 QRect aBounds = tfm.boundingRect(theValue);
859 if(aBounds.width() <= theMaxLineInPixels)
862 qreal s = aBounds.width() * aBounds.height();
863 qreal aGoldWidth = sqrt(s*phi);
865 QStringList aWords = theValue.split(" ", QString::SkipEmptyParts);
867 int n = aWords.count();
869 for (int i = 0; i < n; i++) {
870 QString aLineExt = i == 0 ? aWords[i] : aLine + " " + aWords[i];
871 qreal anWidthNonExt = tfm.boundingRect(aLine).width();
872 qreal anWidthExt = tfm.boundingRect(aLineExt).width();
873 qreal aDeltaNonExt = fabs(anWidthNonExt-aGoldWidth);
874 qreal aDeltaExt = fabs(anWidthExt-aGoldWidth);
875 if(aDeltaNonExt < aDeltaExt) {
877 aLines.append(aLine);
885 aLines.append(aLine);
887 QString aResult = aLines.join("\n");
891 //**************************************************************
892 QLocale doubleLocale()
894 // VSR 01/07/2010: Disable thousands separator for spin box
895 // (to avoid inconsistency of double-2-string and string-2-double conversion)
897 aLocale.setNumberOptions(aLocale.numberOptions() |
898 QLocale::OmitGroupSeparator |
899 QLocale::RejectGroupSeparator);
903 //**************************************************************
904 void refsToFeatureInFeatureDocument(const ObjectPtr& theObject,
905 std::set<FeaturePtr>& theRefFeatures)
907 FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
908 if (aFeature.get()) {
909 DocumentPtr aFeatureDoc = aFeature->document();
910 // 1. find references in the current document
911 aFeatureDoc->refsToFeature(aFeature, theRefFeatures, false);
916 //**************************************************************
917 /*bool isSubOfComposite(const ObjectPtr& theObject)
920 std::set<FeaturePtr> aRefFeatures;
921 refsToFeatureInFeatureDocument(theObject, aRefFeatures);
922 std::set<FeaturePtr>::const_iterator anIt = aRefFeatures.begin(),
923 aLast = aRefFeatures.end();
924 for (; anIt != aLast && !isSub; anIt++) {
925 isSub = isSubOfComposite(theObject, *anIt);
930 //**************************************************************
931 /*bool isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature)
934 CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
935 if (aComposite.get()) {
936 isSub = aComposite->isSub(theObject);
937 // the recursive is possible, the parameters are sketch circle and extrusion cut. They are
938 // separated by composite sketch feature
940 int aNbSubs = aComposite->numberOfSubs();
941 for (int aSub = 0; aSub < aNbSubs && !isSub; aSub++) {
942 isSub = isSubOfComposite(theObject, aComposite->subFeature(aSub));
949 //**************************************************************
950 ResultPtr firstResult(const ObjectPtr& theObject)
952 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
953 if (!aResult.get()) {
954 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
956 aResult = aFeature->firstResult();
961 //**************************************************************
962 bool isFeatureOfResult(const FeaturePtr& theFeature, const std::string& theGroupOfResult)
964 bool isResult = false;
966 if (!theFeature->data()->isValid())
969 ResultPtr aFirstResult = theFeature->firstResult();
970 if (!aFirstResult.get())
973 return aFirstResult->groupName() == theGroupOfResult;
976 //**************************************************************
977 bool hasModuleDocumentFeature(const std::set<FeaturePtr>& theFeatures)
979 bool aFoundModuleDocumentObject = false;
980 DocumentPtr aModuleDoc = ModelAPI_Session::get()->moduleDocument();
982 std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(), aLast = theFeatures.end();
983 for (; anIt != aLast && !aFoundModuleDocumentObject; anIt++) {
984 FeaturePtr aFeature = *anIt;
985 ResultPtr aResult = ModuleBase_Tools::firstResult(aFeature);
986 if (aResult.get() && aResult->groupName() == ModelAPI_ResultPart::group())
988 aFoundModuleDocumentObject = aFeature->document() == aModuleDoc;
991 return aFoundModuleDocumentObject;
994 //**************************************************************
995 bool askToDelete(const std::set<FeaturePtr> theFeatures,
996 const std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
998 std::set<FeaturePtr>& theReferencesToDelete,
999 const std::string& thePrefixInfo)
1001 QString aNotActivatedDocWrn;
1002 std::wstring aNotActivatedNames;
1003 if (!ModelAPI_Tools::allDocumentsActivated(aNotActivatedNames)) {
1004 if (ModuleBase_Tools::hasModuleDocumentFeature(theFeatures))
1005 aNotActivatedDocWrn =
1006 QObject::tr("Selected objects can be used in Part documents which are not loaded: %1.\n")
1007 .arg(QString::fromStdWString(aNotActivatedNames));
1010 std::set<FeaturePtr> aFeaturesRefsTo;
1011 std::set<FeaturePtr> aFeaturesRefsToParameter;
1012 std::set<FeaturePtr> aParameterFeatures;
1013 QStringList aPartFeatureNames;
1014 std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),
1015 aLast = theFeatures.end();
1016 // separate features to references to parameter features and references to others
1017 for (; anIt != aLast; anIt++) {
1018 FeaturePtr aFeature = *anIt;
1019 if (theReferences.find(aFeature) == theReferences.end())
1022 if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group()))
1023 aPartFeatureNames.append(QString::fromStdWString(aFeature->name()));
1025 std::set<FeaturePtr> aRefFeatures;
1026 std::set<FeaturePtr> aRefList = theReferences.at(aFeature);
1027 std::set<FeaturePtr>::const_iterator aRefIt = aRefList.begin(), aRefLast = aRefList.end();
1028 for (; aRefIt != aRefLast; aRefIt++) {
1029 FeaturePtr aRefFeature = *aRefIt;
1030 if (theFeatures.find(aRefFeature) == theFeatures.end() && // it is not selected
1031 aRefFeatures.find(aRefFeature) == aRefFeatures.end()) // it is not added
1032 aRefFeatures.insert(aRefFeature);
1035 if (isFeatureOfResult(aFeature, ModelAPI_ResultParameter::group())) {
1036 aFeaturesRefsToParameter.insert(aRefFeatures.begin(), aRefFeatures.end());
1037 aParameterFeatures.insert(aFeature);
1040 theReferencesToDelete.insert(aRefFeatures.begin(), aRefFeatures.end());
1044 std::set<FeaturePtr> aFeaturesRefsToParameterOnly;
1045 anIt = aFeaturesRefsToParameter.begin();
1046 aLast = aFeaturesRefsToParameter.end();
1047 // separate features to references to parameter features and references to others
1048 QStringList aParamFeatureNames;
1049 for (; anIt != aLast; anIt++) {
1050 FeaturePtr aFeature = *anIt;
1051 if (theReferencesToDelete.find(aFeature) == theReferencesToDelete.end()) {
1052 aFeaturesRefsToParameterOnly.insert(aFeature);
1053 aParamFeatureNames.append(QString::fromStdWString(aFeature->name()));
1056 aParamFeatureNames.sort();
1057 QStringList anOtherFeatureNames;
1058 anIt = theReferencesToDelete.begin();
1059 aLast = theReferencesToDelete.end();
1060 for (; anIt != aLast; anIt++) {
1061 FeaturePtr aFeature = *anIt;
1062 if (aFeature->getKind() == "RemoveResults")
1063 continue; // skip the remove results feature mentioning: result will be removed anyway
1064 if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group()))
1065 aPartFeatureNames.append(QString::fromStdWString(aFeature->name()));
1067 anOtherFeatureNames.append(QString::fromStdWString(aFeature->name()));
1069 aPartFeatureNames.sort();
1070 anOtherFeatureNames.sort();
1072 QMessageBox aMessageBox(theParent);
1073 aMessageBox.setWindowTitle(QObject::tr("Delete features"));
1074 aMessageBox.setIcon(QMessageBox::Warning);
1075 aMessageBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
1076 aMessageBox.setDefaultButton(QMessageBox::No);
1078 QString aText, aDetailedText;
1079 if (!thePrefixInfo.empty())
1080 aText = thePrefixInfo.c_str();
1081 QString aSep = ", ";
1082 if (!aPartFeatureNames.empty()) {
1083 aText += QString(QObject::tr("The following parts will be deleted: %1.\n"))
1084 .arg(aPartFeatureNames.join(aSep));
1086 if (!aNotActivatedDocWrn.isEmpty())
1087 aText += aNotActivatedDocWrn;
1088 if (!anOtherFeatureNames.empty()) {
1089 const char* aMsg = "The selected features are used in some\n"
1090 "other features, which will also be deleted.\n";
1091 const char* aMsgDetails = "The selected features are used"
1092 " in the following features: %1.\n";
1093 aText += QString(QObject::tr(aMsg));
1094 aDetailedText += QString(QObject::tr(aMsgDetails))
1095 .arg(anOtherFeatureNames.join(aSep));
1097 if (!aParamFeatureNames.empty()) {
1098 const char* aMsg = "The selected parameters are used directly or through\n"
1099 "a sequence of dependencies in some features.\n"
1100 "These features will be deleted.\n"
1101 "Or parameters could be replaced by their values.\n";
1102 const char* aMsgDetails = "Parameters are used in the following features: %1.\n";
1103 aText += QString(QObject::tr(aMsg));
1104 aDetailedText += QString(QObject::tr(aMsgDetails))
1105 .arg(aParamFeatureNames.join(aSep));
1107 QPushButton *aReplaceButton =
1109 aMessageBox.addButton(QObject::tr("Replace"), QMessageBox::ActionRole);
1112 if (!aText.isEmpty()) {
1113 aMessageBox.setText(aText);
1114 aMessageBox.setInformativeText(QObject::tr("Would you like to continue?"));
1115 if (!aDetailedText.isEmpty())
1116 aMessageBox.setDetailedText(aDetailedText);
1118 QMessageBox::ButtonRole aButtonRole = aMessageBox.buttonRole(aMessageBox.clickedButton());
1120 if (aButtonRole == QMessageBox::NoRole)
1123 if (aButtonRole == QMessageBox::ActionRole) {
1124 foreach (FeaturePtr aObj, aParameterFeatures)
1125 ModelAPI_ReplaceParameterMessage::send(aObj, 0);
1128 theReferencesToDelete.insert(aFeaturesRefsToParameterOnly.begin(),
1129 aFeaturesRefsToParameterOnly.end());
1134 //**************************************************************
1135 void convertToFeatures(const QObjectPtrList& theObjects, std::set<FeaturePtr>& theFeatures)
1137 QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
1138 for(; anIt != aLast; anIt++) {
1139 ObjectPtr anObject = *anIt;
1140 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
1141 // for parameter result, use the corresponded reature to be removed
1142 if (!aFeature.get() && anObject->groupName() == ModelAPI_ResultParameter::group()) {
1143 aFeature = ModelAPI_Feature::feature(anObject);
1146 theFeatures.insert(aFeature);
1150 //**************************************************************
1151 void convertToFolders(const QObjectPtrList& theObjects,
1152 std::set<FolderPtr>& theFolders)
1154 QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
1155 for(; anIt != aLast; anIt++) {
1156 ObjectPtr anObject = *anIt;
1157 FolderPtr aFeature = std::dynamic_pointer_cast<ModelAPI_Folder>(anObject);
1159 theFolders.insert(aFeature);
1164 //**************************************************************
1165 QString translate(const Events_InfoMessage& theMessage)
1169 if (!theMessage.empty()) {
1170 std::string aStr = Config_Translator::translate(theMessage);
1171 if (!aStr.empty()) {
1172 std::string aCodec = Config_Translator::codec(theMessage);
1173 aMessage = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
1180 QString translate(const std::string& theContext, const std::string& theMessage)
1184 if (!theMessage.empty()) {
1185 std::string aStr = Config_Translator::translate(theContext, theMessage);
1186 if (!aStr.empty()) {
1187 std::string aCodec = Config_Translator::codec(theContext);
1188 aMessage = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
1195 void setPointBallHighlighting(AIS_InteractiveObject* theAIS)
1197 static Handle(Image_AlienPixMap) aPixMap;
1198 if(aPixMap.IsNull()) {
1199 // Load icon for the presentation
1201 char* anEnv = getenv("SHAPER_ROOT_DIR");
1203 aFile = std::string(anEnv) +
1204 FSEP + "share" + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper";
1206 anEnv = getenv("CADBUILDER_ROOT_DIR");
1208 aFile = std::string(anEnv) + FSEP + "resources";
1212 static const std::string aMarkerName = "marker_dot.png";
1213 aFile += aMarkerName;
1214 aPixMap = new Image_AlienPixMap();
1215 if(!aPixMap->Load(aFile.c_str())) {
1216 // The icon for constraint is not found
1217 static const std::string aMsg =
1218 "Error: Point market not found by path: \"" + aFile + "\". Falling back.";
1219 //Events_InfoMessage("ModuleBase_Tools::setPointBallHighlighting", aMsg).send();
1223 Handle(Graphic3d_AspectMarker3d) anAspect;
1224 Handle(Prs3d_Drawer) aDrawer = theAIS->DynamicHilightAttributes();
1225 if (aDrawer.IsNull()) {
1226 if (ModuleBase_IViewer::DefaultHighlightDrawer.IsNull())
1228 aDrawer = new Prs3d_Drawer(*ModuleBase_IViewer::DefaultHighlightDrawer);
1229 if (!aDrawer->HasOwnPointAspect()) {
1230 aDrawer->SetPointAspect(new Prs3d_PointAspect(Aspect_TOM_BALL, Quantity_NOC_BLACK, 2.0));
1233 if(aDrawer->HasOwnPointAspect()) {
1234 Handle(Prs3d_PointAspect) aPntAspect = aDrawer->PointAspect();
1235 if(aPixMap->IsEmpty()) {
1236 anAspect = aPntAspect->Aspect();
1237 anAspect->SetType(Aspect_TOM_BALL);
1239 if(aPixMap->Format() == Image_PixMap::ImgGray) {
1240 aPixMap->SetFormat (Image_PixMap::ImgAlpha);
1241 } else if(aPixMap->Format() == Image_PixMap::ImgGrayF) {
1242 aPixMap->SetFormat (Image_PixMap::ImgAlphaF);
1244 anAspect = new Graphic3d_AspectMarker3d(aPixMap);
1245 aPntAspect->SetAspect(anAspect);
1247 aDrawer->SetPointAspect(aPntAspect);
1248 theAIS->SetDynamicHilightAttributes(aDrawer);
1252 FeaturePtr createParameter(const QString& theText)
1254 FeaturePtr aParameter;
1255 QStringList aList = theText.split("=");
1256 if (aList.count() != 2) {
1259 QString aParamName = aList.at(0).trimmed();
1261 if (isNameExist(aParamName, FeaturePtr())) {
1265 if (!ModelAPI_Expression::isVariable(aParamName.toStdString())) {
1269 QString aExpression = aList.at(1).trimmed();
1270 if (aExpression.isEmpty()) {
1274 SessionPtr aMgr = ModelAPI_Session::get();
1275 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1277 aParameter = aDoc->addFeature("Parameter", false);
1278 if (aParameter.get()) {
1279 AttributeStringPtr aNameAttr = aParameter->string("variable");
1280 aNameAttr->setValue(aParamName.toStdString());
1282 AttributeStringPtr aExprAttr = aParameter->string("expression");
1283 aExprAttr->setValue(aExpression.toStdString());
1284 aParameter->execute();
1286 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
1287 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
1292 void editParameter(FeaturePtr theParam, const QString& theText)
1294 QStringList aList = theText.split("=");
1295 QString aParamName = aList.at(0).trimmed();
1297 QString aExpression = aList.at(1).trimmed();
1298 if (aExpression.isEmpty()) {
1302 if (isNameExist(aParamName, theParam)) {
1305 AttributeStringPtr aNameAttr = theParam->string("variable");
1306 aNameAttr->setValue(aParamName.toStdString());
1308 AttributeStringPtr aExprAttr = theParam->string("expression");
1309 aExprAttr->setValue(aExpression.toStdString());
1310 theParam->execute();
1312 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
1315 bool isNameExist(const QString& theName, FeaturePtr theIgnoreParameter)
1317 SessionPtr aMgr = ModelAPI_Session::get();
1318 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1319 FeaturePtr aParamFeature;
1320 int aNbFeatures = aDoc->numInternalFeatures();
1321 std::wstring aName = theName.toStdWString();
1322 for (int i = 0; i < aNbFeatures; i++) {
1323 aParamFeature = aDoc->internalFeature(i);
1324 if (aParamFeature && aParamFeature->getKind() == "Parameter") {
1325 if ((theIgnoreParameter != aParamFeature) && (aParamFeature->name() == aName))
1332 FeaturePtr findParameter(const QString& theName)
1334 SessionPtr aMgr = ModelAPI_Session::get();
1335 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1336 FeaturePtr aParamFeature;
1337 int aNbFeatures = aDoc->numInternalFeatures();
1338 std::wstring aName = theName.toStdWString();
1339 for (int i = 0; i < aNbFeatures; i++) {
1340 aParamFeature = aDoc->internalFeature(i);
1341 if (aParamFeature && aParamFeature->getKind() == "Parameter") {
1342 if (aParamFeature->name() == aName)
1343 return aParamFeature;
1346 return FeaturePtr();
1350 //********************************************************************
1351 std::wstring generateName(const AttributePtr& theAttribute,
1352 ModuleBase_IWorkshop* theWorkshop)
1355 if (theAttribute.get() != NULL) {
1356 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
1357 if (aFeature.get()) {
1358 std::string aXmlCfg, aDescription;
1359 theWorkshop->module()->getXMLRepresentation(aFeature->getKind(), aXmlCfg, aDescription);
1361 ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop);
1362 std::string anAttributeTitle;
1363 aFactory.getAttributeTitle(theAttribute->id(), anAttributeTitle);
1365 std::wstringstream aStreamName;
1366 aStreamName << theAttribute->owner()->data()->name() << "/" << anAttributeTitle.c_str();
1367 aName = aStreamName.str();
1373 bool isSameShape(const TopoDS_Shape& theShape1, const TopoDS_Shape& theShape2)
1375 // In case of compound we cannot rely on simple comparison method.
1376 // If the compound is generated by Group feature then this compound is alwais new.
1377 // So, we have to compare content of these compounds
1378 if (theShape1.ShapeType() != theShape2.ShapeType())
1381 if (theShape1.ShapeType() != TopAbs_COMPOUND)
1382 return theShape1.IsSame(theShape2);
1384 TopoDS_Iterator aIt1(theShape1);
1385 TopoDS_Iterator aIt2(theShape2);
1387 for (; aIt1.More() && aIt2.More(); aIt1.Next(), aIt2.Next()) {
1388 if (!(aIt1.Value()).IsSame(aIt2.Value()))
1394 qreal currentPixelRatio()
1396 QWindowList aWnds = qApp->topLevelWindows();
1397 if (aWnds.size() > 0)
1398 return aWnds.first()->devicePixelRatio();
1399 return qApp->primaryScreen()->devicePixelRatio();
1403 // Set displaying status to every element on group
1404 static void setDisplayingByLoop(DocumentPtr theDoc, int theSize,
1405 std::string theGroup, bool theDisplayFromScript)
1407 int aDisplayingId = -1;
1408 if (theDisplayFromScript) {
1409 aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General",
1410 "part_visualization_script", -1);
1411 // Increase ID to prevert using "As stored in HDF"
1415 aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General",
1416 "part_visualization_study", -1);
1418 // if chosen "As stored in HDF" then don't change displaying
1419 if (aDisplayingId == 0)
1423 for (int anIndex = theSize - 1; anIndex >= 0; --anIndex) {
1424 ObjectPtr anObject = theDoc->object(theGroup, anIndex);
1425 anObject->setDisplayed((aDisplayingId == 1 && anIndex == theSize - 1) || aDisplayingId == 2);
1429 void setDisplaying(ResultPartPtr thePart, bool theDisplayFromScript)
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());
1436 setDisplayingByLoop(aDoc, aConstructionSize,
1437 ModelAPI_ResultConstruction::group(), theDisplayFromScript);
1438 setDisplayingByLoop(aDoc, aGroupSize, ModelAPI_ResultGroup::group(), theDisplayFromScript);
1439 setDisplayingByLoop(aDoc, aFieldSize, ModelAPI_ResultField::group(), theDisplayFromScript);
1440 setDisplayingByLoop(aDoc, aResultSize, ModelAPI_ResultBody::group(), theDisplayFromScript);
1443 } // namespace ModuleBase_Tools