1 // Copyright (C) 2014-2022 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "ModuleBase_Tools.h"
22 #include <ModuleBase_ParamIntSpinBox.h>
23 #include <ModuleBase_ParamSpinBox.h>
24 #include <ModuleBase_Preferences.h>
25 #include <ModuleBase_WidgetFactory.h>
26 #include <ModuleBase_IWorkshop.h>
27 #include <ModuleBase_IModule.h>
28 #include <ModuleBase_IViewer.h>
29 #include <ModuleBase_IconFactory.h>
30 #include <ModuleBase_ResultPrs.h>
31 #include <ModuleBase_ViewerPrs.h>
33 #include <ModelAPI_Attribute.h>
34 #include <ModelAPI_AttributeRefAttr.h>
35 #include <ModelAPI_AttributeReference.h>
36 #include <ModelAPI_AttributeSelection.h>
37 #include <ModelAPI_AttributeSelectionList.h>
38 #include <ModelAPI_AttributeRefList.h>
39 #include <ModelAPI_AttributeRefAttrList.h>
40 #include <ModelAPI_ResultGroup.h>
41 #include <ModelAPI_ResultPart.h>
42 #include <ModelAPI_ResultConstruction.h>
43 #include <ModelAPI_AttributeString.h>
44 #include <ModelAPI_Expression.h>
45 #include <ModelAPI_ResultField.h>
46 #include <Events_Loop.h>
48 #include <ModelAPI_Data.h>
49 #include <ModelAPI_Result.h>
50 #include <ModelAPI_ResultParameter.h>
51 #include <ModelAPI_Tools.h>
52 #include <ModelAPI_Session.h>
53 #include <ModelAPI_Events.h>
54 #include <ModelAPI_Folder.h>
56 #include <ModelGeomAlgo_Point2D.h>
57 #include <SUIT_ResourceMgr.h>
60 #include <SUIT_Application.h>
61 #include <SUIT_Session.h>
64 #include <StdSelect_BRepOwner.hxx>
65 #include <TopoDS_Iterator.hxx>
66 #include <AIS_InteractiveContext.hxx>
67 #include <Prs3d_LineAspect.hxx>
68 #include <Prs3d_PlaneAspect.hxx>
70 #include <GeomDataAPI_Point2D.h>
71 #include <Events_InfoMessage.h>
72 #include <GeomAPI_ShapeExplorer.h>
74 #include <Config_PropManager.h>
75 #include <Config_Translator.h>
77 #include <Prs3d_PointAspect.hxx>
78 #include <Graphic3d_AspectMarker3d.hxx>
80 #include <Image_AlienPixMap.hxx>
86 #include <QDoubleSpinBox>
87 #include <QGraphicsDropShadowEffect>
89 #include <QApplication>
90 #include <QMessageBox>
101 #pragma warning(disable : 4996) // for getenv
104 const double tolerance = 1e-7;
105 const double DEFAULT_DEVIATION_COEFFICIENT = 1.e-4;
107 //#define DEBUG_ACTIVATE_WINDOW
108 //#define DEBUG_SET_FOCUS
116 namespace ModuleBase_Tools {
118 //******************************************************************
120 //! Waits for REDISPLAY message and set the Visible flag to the entities
121 //! according to Preferences choice.
122 class ModuleBase_RedisplayListener : public Events_Listener
125 static std::shared_ptr<ModuleBase_RedisplayListener> instance()
127 static std::shared_ptr<ModuleBase_RedisplayListener>
128 anInstance(new ModuleBase_RedisplayListener);
132 void processEvent(const std::shared_ptr<Events_Message>& theMessage)
134 if (theMessage->eventID() == Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY))
137 // If the python script is being loaded now, the preferences should be used
138 // to display the required object
139 SUIT_Session* aSession = SUIT_Session::session();
142 SUIT_Application * anApp = aSession->activeApplication();
145 QVariant aVar = anApp->property("IsLoadedScript");
146 if (!aVar.isNull() && aVar.toBool()) {
147 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
148 int aSize = aRootDoc->size(ModelAPI_ResultPart::group());
150 ObjectPtr anPartObject = aRootDoc->object(ModelAPI_ResultPart::group(), aSize - 1);
151 ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(anPartObject);
152 ModuleBase_Tools::setDisplaying(aPart, true);
160 ModuleBase_RedisplayListener()
162 Events_Loop::loop()->registerListener(this,
163 Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
167 static std::shared_ptr<ModuleBase_RedisplayListener>
168 RL = ModuleBase_RedisplayListener::instance();
170 //******************************************************************
172 void adjustMargins(QWidget* theWidget)
176 adjustMargins(theWidget->layout());
179 void adjustMargins(QLayout* theLayout)
183 theLayout->setContentsMargins(2, 5, 2, 5);
184 theLayout->setSpacing(4);
187 void zeroMargins(QWidget* theWidget)
191 zeroMargins(theWidget->layout());
194 void zeroMargins(QLayout* theLayout)
198 theLayout->setContentsMargins(0, 0, 0, 0);
199 theLayout->setSpacing(5);
202 void activateWindow(QWidget* theWidget, const QString& theInfo)
205 theWidget->activateWindow();
209 #ifdef DEBUG_ACTIVATE_WINDOW
210 qDebug(QString("activateWindow: %1").arg(theInfo).toStdString().c_str());
214 void setFocus(QWidget* theWidget, const QString& theInfo)
216 activateWindow(theWidget);
217 theWidget->setFocus();
218 // rectangle of focus is not visible on tool button widgets
220 #ifdef DEBUG_SET_FOCUS
221 qDebug(QString("setFocus: %1").arg(theInfo).toStdString().c_str());
225 void setShadowEffect(QWidget* theWidget, const bool isSetEffect)
228 QGraphicsDropShadowEffect* aGlowEffect = new QGraphicsDropShadowEffect();
229 aGlowEffect->setOffset(.0);
230 aGlowEffect->setBlurRadius(10.0);
231 aGlowEffect->setColor(QColor(0, 170, 255)); // Light-blue color, #00AAFF
232 theWidget->setGraphicsEffect(aGlowEffect);
235 QGraphicsEffect* anEffect = theWidget->graphicsEffect();
237 anEffect->deleteLater();
238 theWidget->setGraphicsEffect(NULL);
242 QPixmap composite(const QString& theAdditionalIcon, const QString& theIcon)
244 QImage anIcon = ModuleBase_IconFactory::loadImage(theIcon);
245 QImage anAditional(theAdditionalIcon);
246 return composite(anAditional, anIcon);
249 QPixmap composite(const QImage& theAdditionalIcon, QImage& theIcon)
251 if (theIcon.isNull())
254 int anAddWidth = theAdditionalIcon.width();
255 int anAddHeight = theAdditionalIcon.height();
257 int aWidth = theIcon.width();
258 int aHeight = theIcon.height();
260 int aStartWidthPos = aWidth - anAddWidth;
261 int aStartHeightPos = aHeight - anAddHeight;
263 for (int i = 0; i < anAddWidth && i + aStartWidthPos < aWidth; i++)
265 for (int j = 0; j < anAddHeight && j + aStartHeightPos < aHeight; j++)
267 if (qAlpha(theAdditionalIcon.pixel(i, j)) > 0)
268 theIcon.setPixel(i + aStartWidthPos, j + aStartHeightPos, theAdditionalIcon.pixel(i, j));
271 return QPixmap::fromImage(theIcon);
274 QPixmap lighter(const QString& theIcon, const int theLighterValue)
276 QImage anIcon = ModuleBase_IconFactory::loadImage(theIcon);
280 QImage aResult = ModuleBase_IconFactory::loadImage(theIcon);
281 for (int i = 0; i < anIcon.width(); i++)
283 for (int j = 0; j < anIcon.height(); j++)
285 QRgb anRgb = anIcon.pixel(i, j);
286 QColor aPixelColor(qRed(anRgb), qGreen(anRgb), qBlue(anRgb),
287 qAlpha(aResult.pixel(i, j)));
289 QColor aLighterColor = aPixelColor.lighter(theLighterValue);
290 aResult.setPixel(i, j, qRgba(aLighterColor.red(), aLighterColor.green(),
291 aLighterColor.blue(), aLighterColor.alpha()));
294 return QPixmap::fromImage(aResult);
297 void setSpinText(ModuleBase_ParamSpinBox* theSpin, const QString& theText)
299 if (theSpin->text() == theText)
301 // In order to avoid extra text setting because it will
302 // reset cursor position in control
303 bool isBlocked = theSpin->blockSignals(true);
304 theSpin->setText(theText);
305 theSpin->blockSignals(isBlocked);
308 void setSpinValue(QDoubleSpinBox* theSpin, double theValue)
310 if (fabs(theSpin->value() - theValue) < tolerance)
312 bool isBlocked = theSpin->blockSignals(true);
313 theSpin->setValue(theValue);
314 theSpin->blockSignals(isBlocked);
317 void setSpinValue(ModuleBase_ParamSpinBox* theSpin, double theValue)
319 if (!theSpin->text().isEmpty() && fabs(theSpin->value() - theValue) < tolerance)
321 bool isBlocked = theSpin->blockSignals(true);
322 theSpin->setValue(theValue);
323 theSpin->blockSignals(isBlocked);
326 void setSpinText(ModuleBase_ParamIntSpinBox* theSpin, const QString& theText)
328 // In order to avoid extra text setting because it will
329 // reset cursor position in control
330 if (theSpin->text() == theText)
332 bool isBlocked = theSpin->blockSignals(true);
333 theSpin->setText(theText);
334 theSpin->blockSignals(isBlocked);
337 void setSpinValue(ModuleBase_ParamIntSpinBox* theSpin, int theValue)
339 if (theSpin->value() == theValue)
341 bool isBlocked = theSpin->blockSignals(true);
342 theSpin->setValue(theValue);
343 theSpin->blockSignals(isBlocked);
346 QAction* createAction(const QIcon& theIcon, const QString& theText,
347 QObject* theParent, const QObject* theReceiver,
348 const char* theMember, const QString& theToolTip,
349 const QString& theStatusTip)
351 QAction* anAction = new QAction(theIcon, theText, theParent);
352 anAction->setToolTip(theToolTip.isEmpty() ? theText : theToolTip);
353 anAction->setStatusTip(!theStatusTip.isEmpty() ? theStatusTip :
354 (!theToolTip.isEmpty() ? theToolTip : theText));
356 QObject::connect(anAction, SIGNAL(triggered(bool)), theReceiver, theMember);
362 QString objectName(const ObjectPtr& theObj)
367 return QString::fromStdWString(theObj->data()->name());
370 QString objectInfo(const ObjectPtr& theObj, const bool isUseAttributesInfo)
372 QString aFeatureStr = "feature";
376 std::ostringstream aPtrStr;
377 aPtrStr << "[" << theObj.get() << "]";
379 ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObj);
380 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObj);
382 aFeatureStr.append(QString("(result%1)").arg(aPtrStr.str().c_str()).toStdString() .c_str());
383 if (aRes->isDisabled())
384 aFeatureStr.append("[disabled]");
385 if (aRes->isConcealed())
386 aFeatureStr.append("[concealed]");
387 if (ModelAPI_Tools::hasSubResults(aRes))
388 aFeatureStr.append("[hasSubResults]");
390 aFeature = ModelAPI_Feature::feature(aRes);
393 aFeatureStr.append(aPtrStr.str().c_str());
395 if (aFeature.get()) {
396 aFeatureStr.append(QString(": %1").arg(aFeature->getKind().c_str()).toStdString().c_str());
397 if (aFeature->data()->isValid()) {
398 aFeatureStr.append(QString(", name=%1")
399 .arg(QString::fromStdWString(theObj->data()->name())).toStdString().c_str());
401 if (isUseAttributesInfo) {
402 std::set<std::shared_ptr<ModelAPI_Attribute> > anAttributes;
403 std::string aPointsInfo = ModelGeomAlgo_Point2D::getPontAttributesInfo(aFeature,
404 anAttributes).c_str();
405 if (!aPointsInfo.empty())
406 aFeatureStr.append(QString(", attributes: %1")
407 .arg(aPointsInfo.c_str()).toStdString().c_str());
415 typedef QMap<QString, int> ShapeTypes;
416 static ShapeTypes myShapeTypes;
418 int shapeType(const QString& theType)
420 if (myShapeTypes.count() == 0) {
421 myShapeTypes["compound"] = TopAbs_COMPOUND;
422 myShapeTypes["compounds"] = TopAbs_COMPOUND;
423 myShapeTypes["compsolid"] = TopAbs_COMPSOLID;
424 myShapeTypes["compsolids"] = TopAbs_COMPSOLID;
425 myShapeTypes["solid"] = TopAbs_SOLID;
426 myShapeTypes["solids"] = TopAbs_SOLID;
427 myShapeTypes["shell"] = TopAbs_SHELL;
428 myShapeTypes["shells"] = TopAbs_SHELL;
429 myShapeTypes["face"] = TopAbs_FACE;
430 myShapeTypes["faces"] = TopAbs_FACE;
431 myShapeTypes["wire"] = TopAbs_WIRE;
432 myShapeTypes["wires"] = TopAbs_WIRE;
433 myShapeTypes["edge"] = TopAbs_EDGE;
434 myShapeTypes["edges"] = TopAbs_EDGE;
435 myShapeTypes["vertex"] = TopAbs_VERTEX;
436 myShapeTypes["vertices"] = TopAbs_VERTEX;
437 myShapeTypes["object"] = ModuleBase_ResultPrs::Sel_Result;
438 myShapeTypes["objects"] = ModuleBase_ResultPrs::Sel_Result;
440 QString aType = theType.toLower();
441 if(myShapeTypes.contains(aType))
442 return myShapeTypes[aType];
443 Events_InfoMessage("ModuleBase_Tools", "Shape type defined in XML is not implemented!").send();
447 void checkObjects(const QObjectPtrList& theObjects, bool& hasResult, bool& hasFeature,
448 bool& hasParameter, bool& hasCompositeOwner, bool& hasResultInHistory,
453 hasParameter = false;
454 hasCompositeOwner = false;
455 hasResultInHistory = false;
457 foreach(ObjectPtr aObj, theObjects) {
458 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
459 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
460 FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(aObj);
461 ResultParameterPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aResult);
462 FieldStepPtr aStep = std::dynamic_pointer_cast<ModelAPI_ResultField::ModelAPI_FieldStep>(aObj);
464 hasResult |= ((aResult.get() != NULL) || (aStep.get() != NULL));
465 hasFeature |= (aFeature.get() != NULL);
466 hasFolder |= (aFolder.get() != NULL);
467 hasParameter |= (aConstruction.get() != NULL);
469 hasCompositeOwner |= (ModelAPI_Tools::compositeOwner(aFeature) != NULL);
470 else if (aResult.get())
471 hasCompositeOwner |= (ModelAPI_Tools::bodyOwner(aResult) != NULL);
473 if (!hasResultInHistory && aResult.get()) {
474 aFeature = ModelAPI_Feature::feature(aResult);
475 hasResultInHistory = aFeature.get() && aFeature->isInHistory();
478 if (hasFeature && hasResult && hasParameter && hasCompositeOwner)
483 /*bool setDefaultDeviationCoefficient(std::shared_ptr<GeomAPI_Shape> theGeomShape)
485 if (!theGeomShape.get())
487 // if the shape could not be exploded on faces, it contains only wires, edges, and vertices
488 // correction of deviation for them should not influence to the application performance
489 GeomAPI_ShapeExplorer anExp(theGeomShape, GeomAPI_Shape::FACE);
490 bool anEmpty = anExp.empty();
491 return !anExp.more();
494 /*void setDefaultDeviationCoefficient(const std::shared_ptr<ModelAPI_Result>& theResult,
495 const Handle(Prs3d_Drawer)& theDrawer)
497 if (!theResult.get())
499 bool aUseDeviation = false;
501 std::string aResultGroup = theResult->groupName();
502 if (aResultGroup == ModelAPI_ResultConstruction::group())
503 aUseDeviation = true;
504 else if (aResultGroup == ModelAPI_ResultBody::group()) {
505 GeomShapePtr aGeomShape = theResult->shape();
506 if (aGeomShape.get())
507 aUseDeviation = setDefaultDeviationCoefficient(aGeomShape);
510 theDrawer->SetDeviationCoefficient(DEFAULT_DEVIATION_COEFFICIENT);
513 void setDefaultDeviationCoefficient(const TopoDS_Shape& theShape,
514 const Handle(Prs3d_Drawer)& theDrawer)
516 if (theShape.IsNull())
518 if (theDrawer.IsNull())
521 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape());
522 aGeomShape->setImpl(new TopoDS_Shape(theShape));
524 // if the shape could not be exploded on faces, it contains only wires, edges, and vertices
525 // correction of deviation for them should not influence to the application performance
526 GeomAPI_ShapeExplorer anExp(aGeomShape, GeomAPI_Shape::FACE);
527 bool isConstruction = !anExp.more();
531 aDeflection = Config_PropManager::real("Visualization", "construction_deflection");
533 aDeflection = Config_PropManager::real("Visualization", "body_deflection");
535 theDrawer->SetDeviationCoefficient(aDeflection);
538 Quantity_Color color(const std::string& theSection,
539 const std::string& theName)
541 std::vector<int> aColor = Config_PropManager::color(theSection, theName);
542 return Quantity_Color(aColor[0] / 255., aColor[1] / 255., aColor[2] / 255., Quantity_TOC_RGB);
545 ObjectPtr getObject(const AttributePtr& theAttribute)
548 std::string anAttrType = theAttribute->attributeType();
549 if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
550 AttributeRefAttrPtr anAttr =
551 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
552 if (anAttr != NULL && anAttr->isObject())
553 anObject = anAttr->object();
555 if (anAttrType == ModelAPI_AttributeSelection::typeId()) {
556 AttributeSelectionPtr anAttr =
557 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
559 anObject = anAttr->context();
561 if (anAttrType == ModelAPI_AttributeReference::typeId()) {
562 AttributeReferencePtr anAttr =
563 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
564 if (anAttr.get() != NULL)
565 anObject = anAttr->value();
570 TopAbs_ShapeEnum getCompoundSubType(const TopoDS_Shape& theShape)
572 TopAbs_ShapeEnum aShapeType = theShape.ShapeType();
574 // for compounds check sub-shapes: it may be compound of needed type:
575 // Booleans may produce compounds of Solids
576 if (aShapeType == TopAbs_COMPOUND) {
577 for(TopoDS_Iterator aSubs(theShape); aSubs.More(); aSubs.Next()) {
578 if (!aSubs.Value().IsNull()) {
579 TopAbs_ShapeEnum aSubType = aSubs.Value().ShapeType();
580 if (aSubType == TopAbs_COMPOUND) { // compound of compound(s)
581 aShapeType = TopAbs_COMPOUND;
584 if (aShapeType == TopAbs_COMPOUND) {
585 aShapeType = aSubType;
586 } else if (aShapeType != aSubType) { // compound of shapes of different types
587 aShapeType = TopAbs_COMPOUND;
596 TopoDS_Shape getSelectedShape(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs)
598 if (thePrs->shape().get())
599 return thePrs->shape()->impl<TopoDS_Shape>();
601 Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast(thePrs->owner());
602 if (!anOwner.IsNull())
603 return anOwner->Shape();
605 return TopoDS_Shape();
608 void getParameters(QStringList& theParameters)
610 theParameters.clear();
612 SessionPtr aSession = ModelAPI_Session::get();
613 std::list<DocumentPtr> aDocList;
614 DocumentPtr anActiveDocument = aSession->activeDocument();
615 DocumentPtr aRootDocument = aSession->moduleDocument();
616 aDocList.push_back(anActiveDocument);
617 if (anActiveDocument != aRootDocument) {
618 aDocList.push_back(aRootDocument);
620 std::string aGroupId = ModelAPI_ResultParameter::group();
621 for(std::list<DocumentPtr>::const_iterator it = aDocList.begin(); it != aDocList.end(); ++it) {
622 DocumentPtr aDocument = *it;
623 int aSize = aDocument->size(aGroupId);
624 for (int i = 0; i < aSize; i++) {
625 ObjectPtr anObject = aDocument->object(aGroupId, i);
626 std::wstring aParameterName = anObject->data()->name();
627 theParameters.append(QString::fromStdWString(aParameterName));
632 std::string findGreedAttribute(ModuleBase_IWorkshop* theWorkshop,
633 const FeaturePtr& theFeature)
635 std::string anAttributeId;
637 std::string aXmlCfg, aDescription;
638 theWorkshop->module()->getXMLRepresentation(theFeature->getKind(), aXmlCfg, aDescription);
640 ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop);
641 std::string anAttributeTitle;
642 aFactory.getGreedAttribute(anAttributeId);
644 return anAttributeId;
647 bool hasObject(const AttributePtr& theAttribute, const ObjectPtr& theObject,
648 const std::shared_ptr<GeomAPI_Shape>& theShape,
649 ModuleBase_IWorkshop* theWorkshop,
650 const bool theTemporarily)
652 bool aHasObject = false;
653 if (!theAttribute.get())
656 std::string aType = theAttribute->attributeType();
657 if (aType == ModelAPI_AttributeReference::typeId()) {
658 AttributeReferencePtr aRef =
659 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
660 ObjectPtr aObject = aRef->value();
661 aHasObject = aObject && aObject->isSame(theObject);
662 //if (!(aObject && aObject->isSame(theObject))) {
663 // aRef->setValue(theObject);
665 } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
666 AttributeRefAttrPtr aRefAttr =
667 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
669 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
670 if (anAttribute.get()) {
671 //aRefAttr->setAttr(anAttribute);
674 ObjectPtr aObject = aRefAttr->object();
675 aHasObject = aObject && aObject->isSame(theObject);
676 //if (!(aObject && aObject->isSame(theObject))) {
677 // aRefAttr->setObject(theObject);
680 } else if (aType == ModelAPI_AttributeSelection::typeId()) {
681 /*AttributeSelectionPtr aSelectAttr =
682 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
683 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
684 if (aSelectAttr.get() != NULL) {
685 aSelectAttr->setValue(aResult, theShape, theTemporarily);
688 if (aType == ModelAPI_AttributeSelectionList::typeId()) {
689 AttributeSelectionListPtr aSelectionListAttr =
690 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
691 aHasObject = aSelectionListAttr->isInList(theObject, theShape, theTemporarily);
693 else if (aType == ModelAPI_AttributeRefList::typeId()) {
694 AttributeRefListPtr aRefListAttr =
695 std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttribute);
696 aHasObject = aRefListAttr->isInList(theObject);
697 //if (!theCheckIfAttributeHasObject || !aRefListAttr->isInList(theObject))
698 // aRefListAttr->append(theObject);
700 else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
701 AttributeRefAttrListPtr aRefAttrListAttr =
702 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(theAttribute);
703 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
705 if (anAttribute.get()) {
706 aHasObject = aRefAttrListAttr->isInList(anAttribute);
707 //if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(anAttribute))
708 // aRefAttrListAttr->append(anAttribute);
711 aHasObject = aRefAttrListAttr->isInList(theObject);
712 //if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(theObject))
713 // aRefAttrListAttr->append(theObject);
719 bool setObject(const AttributePtr& theAttribute, const ObjectPtr& theObject,
720 const GeomShapePtr& theShape, ModuleBase_IWorkshop* theWorkshop,
721 const bool theTemporarily, const bool theCheckIfAttributeHasObject)
723 if (!theAttribute.get())
727 std::string aType = theAttribute->attributeType();
728 if (aType == ModelAPI_AttributeReference::typeId()) {
729 AttributeReferencePtr aRef =
730 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
731 ObjectPtr aObject = aRef->value();
732 if (!(aObject && aObject->isSame(theObject))) {
733 aRef->setValue(theObject);
735 } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
736 AttributeRefAttrPtr aRefAttr =
737 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
739 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
740 if (anAttribute.get())
741 aRefAttr->setAttr(anAttribute);
743 ObjectPtr aObject = aRefAttr->object();
744 if (!(aObject && aObject->isSame(theObject))) {
745 aRefAttr->setObject(theObject);
748 } else if (aType == ModelAPI_AttributeSelection::typeId()) {
749 AttributeSelectionPtr aSelectAttr =
750 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
751 if (aSelectAttr.get() != NULL) {
752 aSelectAttr->setValue(theObject, theShape, theTemporarily);
755 if (aType == ModelAPI_AttributeSelectionList::typeId()) {
756 AttributeSelectionListPtr aSelectionListAttr =
757 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
758 if (!theCheckIfAttributeHasObject ||
759 !aSelectionListAttr->isInList(theObject, theShape, theTemporarily))
760 aSelectionListAttr->append(theObject, theShape, theTemporarily);
762 else if (aType == ModelAPI_AttributeRefList::typeId()) {
763 AttributeRefListPtr aRefListAttr =
764 std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttribute);
765 if (!theCheckIfAttributeHasObject || !aRefListAttr->isInList(theObject)) {
767 aRefListAttr->append(theObject);
772 else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
773 AttributeRefAttrListPtr aRefAttrListAttr =
774 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(theAttribute);
775 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
777 if (anAttribute.get()) {
778 if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(anAttribute))
779 aRefAttrListAttr->append(anAttribute);
782 if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(theObject)) {
784 aRefAttrListAttr->append(theObject);
793 GeomShapePtr getShape(const AttributePtr& theAttribute, ModuleBase_IWorkshop* theWorkshop)
796 if (!theAttribute.get())
799 std::string aType = theAttribute->attributeType();
800 if (aType == ModelAPI_AttributeReference::typeId()) {
801 } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
802 AttributeRefAttrPtr aRefAttr =
803 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
804 if (aRefAttr.get() && !aRefAttr->isObject()) {
805 AttributePtr anAttribute = aRefAttr->attr();
806 aShape = theWorkshop->module()->findShape(anAttribute);
808 } else if (aType == ModelAPI_AttributeSelection::typeId()) {
809 AttributeSelectionPtr aSelectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
811 aShape = aSelectAttr->value();
813 else // Geom2D point processing
814 aShape = theWorkshop->module()->findShape(theAttribute);
818 void flushUpdated(ObjectPtr theObject)
820 blockUpdateViewer(true);
822 // Fix the problem of not previewed results of constraints applied. Flush Create/Delete
823 // (for the sketch result) to start processing of the sketch in the solver.
824 // TODO: these flushes should be moved in a separate method provided by Model
825 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
826 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_VISUAL_ATTRIBUTES));
827 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
828 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_UPDATE_SELECTION));
829 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
831 blockUpdateViewer(false);
834 void blockUpdateViewer(const bool theValue)
836 // the viewer update should be blocked in order to avoid the temporary feature content
837 // when the solver processes the feature, the redisplay message can be flushed
838 // what caused the display in the viewer preliminary states of object
839 // e.g. fillet feature, angle value change
840 std::shared_ptr<Events_Message> aMsg;
842 aMsg = std::shared_ptr<Events_Message>(
843 new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED)));
846 // the viewer update should be unblocked
847 aMsg = std::shared_ptr<Events_Message>(
848 new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)));
850 Events_Loop::loop()->send(aMsg);
853 QString wrapTextByWords(const QString& theValue, QWidget* theWidget,
854 int theMaxLineInPixels)
856 static QFontMetrics tfm(theWidget ? theWidget->font() : QApplication::font());
857 static qreal phi = 2.618;
859 QRect aBounds = tfm.boundingRect(theValue);
860 if(aBounds.width() <= theMaxLineInPixels)
863 qreal s = aBounds.width() * aBounds.height();
864 qreal aGoldWidth = sqrt(s*phi);
866 QStringList aWords = theValue.split(" ", QString::SkipEmptyParts);
868 int n = aWords.count();
870 for (int i = 0; i < n; i++) {
871 QString aLineExt = i == 0 ? aWords[i] : aLine + " " + aWords[i];
872 qreal anWidthNonExt = tfm.boundingRect(aLine).width();
873 qreal anWidthExt = tfm.boundingRect(aLineExt).width();
874 qreal aDeltaNonExt = fabs(anWidthNonExt-aGoldWidth);
875 qreal aDeltaExt = fabs(anWidthExt-aGoldWidth);
876 if(aDeltaNonExt < aDeltaExt) {
878 aLines.append(aLine);
886 aLines.append(aLine);
888 QString aResult = aLines.join("\n");
892 //**************************************************************
893 QLocale doubleLocale()
895 // VSR 01/07/2010: Disable thousands separator for spin box
896 // (to avoid inconsistency of double-2-string and string-2-double conversion)
898 aLocale.setNumberOptions(aLocale.numberOptions() |
899 QLocale::OmitGroupSeparator |
900 QLocale::RejectGroupSeparator);
904 //**************************************************************
905 void refsToFeatureInFeatureDocument(const ObjectPtr& theObject,
906 std::set<FeaturePtr>& theRefFeatures)
908 FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
909 if (aFeature.get()) {
910 DocumentPtr aFeatureDoc = aFeature->document();
911 // 1. find references in the current document
912 aFeatureDoc->refsToFeature(aFeature, theRefFeatures, false);
917 //**************************************************************
918 /*bool isSubOfComposite(const ObjectPtr& theObject)
921 std::set<FeaturePtr> aRefFeatures;
922 refsToFeatureInFeatureDocument(theObject, aRefFeatures);
923 std::set<FeaturePtr>::const_iterator anIt = aRefFeatures.begin(),
924 aLast = aRefFeatures.end();
925 for (; anIt != aLast && !isSub; anIt++) {
926 isSub = isSubOfComposite(theObject, *anIt);
931 //**************************************************************
932 /*bool isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature)
935 CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
936 if (aComposite.get()) {
937 isSub = aComposite->isSub(theObject);
938 // the recursive is possible, the parameters are sketch circle and extrusion cut. They are
939 // separated by composite sketch feature
941 int aNbSubs = aComposite->numberOfSubs();
942 for (int aSub = 0; aSub < aNbSubs && !isSub; aSub++) {
943 isSub = isSubOfComposite(theObject, aComposite->subFeature(aSub));
950 //**************************************************************
951 ResultPtr firstResult(const ObjectPtr& theObject)
953 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
954 if (!aResult.get()) {
955 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
957 aResult = aFeature->firstResult();
962 //**************************************************************
963 bool isFeatureOfResult(const FeaturePtr& theFeature, const std::string& theGroupOfResult)
965 bool isResult = false;
967 if (!theFeature->data()->isValid())
970 ResultPtr aFirstResult = theFeature->firstResult();
971 if (!aFirstResult.get())
974 return aFirstResult->groupName() == theGroupOfResult;
977 //**************************************************************
978 bool hasModuleDocumentFeature(const std::set<FeaturePtr>& theFeatures)
980 bool aFoundModuleDocumentObject = false;
981 DocumentPtr aModuleDoc = ModelAPI_Session::get()->moduleDocument();
983 std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(), aLast = theFeatures.end();
984 for (; anIt != aLast && !aFoundModuleDocumentObject; anIt++) {
985 FeaturePtr aFeature = *anIt;
986 ResultPtr aResult = ModuleBase_Tools::firstResult(aFeature);
987 if (aResult.get() && aResult->groupName() == ModelAPI_ResultPart::group())
989 aFoundModuleDocumentObject = aFeature->document() == aModuleDoc;
992 return aFoundModuleDocumentObject;
995 //**************************************************************
996 bool askToDelete(const std::set<FeaturePtr> theFeatures,
997 const std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
999 std::set<FeaturePtr>& theReferencesToDelete,
1000 const std::string& thePrefixInfo)
1002 QString aNotActivatedDocWrn;
1003 std::wstring aNotActivatedNames;
1004 if (!ModelAPI_Tools::allDocumentsActivated(aNotActivatedNames)) {
1005 if (ModuleBase_Tools::hasModuleDocumentFeature(theFeatures))
1006 aNotActivatedDocWrn =
1007 QObject::tr("Selected objects can be used in Part documents which are not loaded: %1.\n")
1008 .arg(QString::fromStdWString(aNotActivatedNames));
1011 std::set<FeaturePtr> aFeaturesRefsTo;
1012 std::set<FeaturePtr> aFeaturesRefsToParameter;
1013 std::set<FeaturePtr> aParameterFeatures;
1014 QStringList aPartFeatureNames;
1015 std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),
1016 aLast = theFeatures.end();
1017 // separate features to references to parameter features and references to others
1018 for (; anIt != aLast; anIt++) {
1019 FeaturePtr aFeature = *anIt;
1020 if (theReferences.find(aFeature) == theReferences.end())
1023 if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group()))
1024 aPartFeatureNames.append(QString::fromStdWString(aFeature->name()));
1026 std::set<FeaturePtr> aRefFeatures;
1027 std::set<FeaturePtr> aRefList = theReferences.at(aFeature);
1028 std::set<FeaturePtr>::const_iterator aRefIt = aRefList.begin(), aRefLast = aRefList.end();
1029 for (; aRefIt != aRefLast; aRefIt++) {
1030 FeaturePtr aRefFeature = *aRefIt;
1031 if (theFeatures.find(aRefFeature) == theFeatures.end() && // it is not selected
1032 aRefFeatures.find(aRefFeature) == aRefFeatures.end()) // it is not added
1033 aRefFeatures.insert(aRefFeature);
1036 if (isFeatureOfResult(aFeature, ModelAPI_ResultParameter::group())) {
1037 aFeaturesRefsToParameter.insert(aRefFeatures.begin(), aRefFeatures.end());
1038 aParameterFeatures.insert(aFeature);
1041 theReferencesToDelete.insert(aRefFeatures.begin(), aRefFeatures.end());
1045 std::set<FeaturePtr> aFeaturesRefsToParameterOnly;
1046 anIt = aFeaturesRefsToParameter.begin();
1047 aLast = aFeaturesRefsToParameter.end();
1048 // separate features to references to parameter features and references to others
1049 QStringList aParamFeatureNames;
1050 for (; anIt != aLast; anIt++) {
1051 FeaturePtr aFeature = *anIt;
1052 if (theReferencesToDelete.find(aFeature) == theReferencesToDelete.end()) {
1053 aFeaturesRefsToParameterOnly.insert(aFeature);
1054 aParamFeatureNames.append(QString::fromStdWString(aFeature->name()));
1057 aParamFeatureNames.sort();
1058 QStringList anOtherFeatureNames;
1059 anIt = theReferencesToDelete.begin();
1060 aLast = theReferencesToDelete.end();
1061 for (; anIt != aLast; anIt++) {
1062 FeaturePtr aFeature = *anIt;
1063 if (aFeature->getKind() == "RemoveResults")
1064 continue; // skip the remove results feature mentioning: result will be removed anyway
1065 if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group()))
1066 aPartFeatureNames.append(QString::fromStdWString(aFeature->name()));
1068 anOtherFeatureNames.append(QString::fromStdWString(aFeature->name()));
1070 aPartFeatureNames.sort();
1071 anOtherFeatureNames.sort();
1073 QMessageBox aMessageBox(theParent);
1074 aMessageBox.setWindowTitle(QObject::tr("Delete features"));
1075 aMessageBox.setIcon(QMessageBox::Warning);
1076 aMessageBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
1077 aMessageBox.setDefaultButton(QMessageBox::No);
1079 QString aText, aDetailedText;
1080 if (!thePrefixInfo.empty())
1081 aText = thePrefixInfo.c_str();
1082 QString aSep = ", ";
1083 if (!aPartFeatureNames.empty()) {
1084 aText += QString(QObject::tr("The following parts will be deleted: %1.\n"))
1085 .arg(aPartFeatureNames.join(aSep));
1087 if (!aNotActivatedDocWrn.isEmpty())
1088 aText += aNotActivatedDocWrn;
1089 if (!anOtherFeatureNames.empty()) {
1090 const char* aMsg = "The selected features are used in some\n"
1091 "other features, which will also be deleted.\n";
1092 const char* aMsgDetails = "The selected features are used"
1093 " in the following features: %1.\n";
1094 aText += QString(QObject::tr(aMsg));
1095 aDetailedText += QString(QObject::tr(aMsgDetails))
1096 .arg(anOtherFeatureNames.join(aSep));
1098 if (!aParamFeatureNames.empty()) {
1099 const char* aMsg = "The selected parameters are used directly or through\n"
1100 "a sequence of dependencies in some features.\n"
1101 "These features will be deleted.\n"
1102 "Or parameters could be replaced by their values.\n";
1103 const char* aMsgDetails = "Parameters are used in the following features: %1.\n";
1104 aText += QString(QObject::tr(aMsg));
1105 aDetailedText += QString(QObject::tr(aMsgDetails))
1106 .arg(aParamFeatureNames.join(aSep));
1107 aMessageBox.addButton(QObject::tr("Replace"), QMessageBox::ActionRole);
1110 if (!aText.isEmpty()) {
1111 aMessageBox.setText(aText);
1112 aMessageBox.setInformativeText(QObject::tr("Would you like to continue?"));
1113 if (!aDetailedText.isEmpty())
1114 aMessageBox.setDetailedText(aDetailedText);
1116 QMessageBox::ButtonRole aButtonRole = aMessageBox.buttonRole(aMessageBox.clickedButton());
1118 if (aButtonRole == QMessageBox::NoRole)
1121 if (aButtonRole == QMessageBox::ActionRole) {
1122 foreach (FeaturePtr aObj, aParameterFeatures)
1123 ModelAPI_ReplaceParameterMessage::send(aObj, 0);
1126 theReferencesToDelete.insert(aFeaturesRefsToParameterOnly.begin(),
1127 aFeaturesRefsToParameterOnly.end());
1132 //**************************************************************
1133 bool warningAboutConflict(QWidget* theParent, const std::string& theWarningText)
1135 QMessageBox aMessageBox(theParent);
1136 aMessageBox.setWindowTitle(QObject::tr("Conflicts in constraint"));
1137 aMessageBox.setIcon(QMessageBox::Warning);
1138 aMessageBox.setText((theWarningText + "\nConstraints will be removed or substituted").c_str());
1140 QCheckBox* aCheckBox = new QCheckBox;
1142 aCheckBox->setTristate(false);
1143 aCheckBox->setText("switch off the notifications.");
1145 aMessageBox.setCheckBox(aCheckBox);
1146 aMessageBox.setStandardButtons(QMessageBox::Ok);
1150 if (aCheckBox->isChecked())
1152 ModuleBase_Preferences::resourceMgr()->setValue(SKETCH_TAB_NAME,
1153 "notify_change_constraint", false);
1159 //**************************************************************
1160 void convertToFeatures(const QObjectPtrList& theObjects, std::set<FeaturePtr>& theFeatures)
1162 QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
1163 for(; anIt != aLast; anIt++) {
1164 ObjectPtr anObject = *anIt;
1165 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
1166 // for parameter result, use the corresponded reature to be removed
1167 if (!aFeature.get() && anObject->groupName() == ModelAPI_ResultParameter::group()) {
1168 aFeature = ModelAPI_Feature::feature(anObject);
1171 theFeatures.insert(aFeature);
1175 //**************************************************************
1176 void convertToFolders(const QObjectPtrList& theObjects,
1177 std::set<FolderPtr>& theFolders)
1179 QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
1180 for(; anIt != aLast; anIt++) {
1181 ObjectPtr anObject = *anIt;
1182 FolderPtr aFeature = std::dynamic_pointer_cast<ModelAPI_Folder>(anObject);
1184 theFolders.insert(aFeature);
1189 //**************************************************************
1190 QString translate(const Events_InfoMessage& theMessage)
1194 if (!theMessage.empty()) {
1195 std::string aStr = Config_Translator::translate(theMessage);
1196 if (!aStr.empty()) {
1197 std::string aCodec = Config_Translator::codec(theMessage);
1198 aMessage = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
1205 QString translate(const std::string& theContext, const std::string& theMessage)
1209 if (!theMessage.empty()) {
1210 std::string aStr = Config_Translator::translate(theContext, theMessage);
1211 if (!aStr.empty()) {
1212 std::string aCodec = Config_Translator::codec(theContext);
1213 aMessage = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
1220 void setPointBallHighlighting(AIS_InteractiveObject* theAIS)
1222 static Handle(Image_AlienPixMap) aPixMap;
1223 if(aPixMap.IsNull()) {
1224 // Load icon for the presentation
1226 char* anEnv = getenv("SHAPER_ROOT_DIR");
1228 aFile = std::string(anEnv) +
1229 FSEP + "share" + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper";
1231 anEnv = getenv("CADBUILDER_ROOT_DIR");
1233 aFile = std::string(anEnv) + FSEP + "resources";
1237 static const std::string aMarkerName = "marker_dot.png";
1238 aFile += aMarkerName;
1239 aPixMap = new Image_AlienPixMap();
1240 if(!aPixMap->Load(aFile.c_str())) {
1241 // The icon for constraint is not found
1242 static const std::string aMsg =
1243 "Error: Point market not found by path: \"" + aFile + "\". Falling back.";
1244 //Events_InfoMessage("ModuleBase_Tools::setPointBallHighlighting", aMsg).send();
1248 Handle(Graphic3d_AspectMarker3d) anAspect;
1249 Handle(Prs3d_Drawer) aDrawer = theAIS->DynamicHilightAttributes();
1250 if (aDrawer.IsNull()) {
1251 if (ModuleBase_IViewer::DefaultHighlightDrawer.IsNull())
1253 aDrawer = new Prs3d_Drawer(*ModuleBase_IViewer::DefaultHighlightDrawer);
1254 if (!aDrawer->HasOwnPointAspect()) {
1255 aDrawer->SetPointAspect(new Prs3d_PointAspect(Aspect_TOM_BALL, Quantity_NOC_BLACK, 2.0));
1258 if(aDrawer->HasOwnPointAspect()) {
1259 Handle(Prs3d_PointAspect) aPntAspect = aDrawer->PointAspect();
1260 if(aPixMap->IsEmpty()) {
1261 anAspect = aPntAspect->Aspect();
1262 anAspect->SetType(Aspect_TOM_BALL);
1264 if(aPixMap->Format() == Image_PixMap::ImgGray) {
1265 aPixMap->SetFormat (Image_PixMap::ImgAlpha);
1266 } else if(aPixMap->Format() == Image_PixMap::ImgGrayF) {
1267 aPixMap->SetFormat (Image_PixMap::ImgAlphaF);
1269 anAspect = new Graphic3d_AspectMarker3d(aPixMap);
1270 aPntAspect->SetAspect(anAspect);
1272 aDrawer->SetPointAspect(aPntAspect);
1273 theAIS->SetDynamicHilightAttributes(aDrawer);
1277 FeaturePtr createParameter(const QString& theText)
1279 FeaturePtr aParameter;
1280 QStringList aList = theText.split("=");
1281 if (aList.count() != 2) {
1284 QString aParamName = aList.at(0).trimmed();
1286 if (isNameExist(aParamName, FeaturePtr())) {
1290 if (!ModelAPI_Expression::isVariable(aParamName.toStdString())) {
1294 QString aExpression = aList.at(1).trimmed();
1295 if (aExpression.isEmpty()) {
1299 SessionPtr aMgr = ModelAPI_Session::get();
1300 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1302 aParameter = aDoc->addFeature("Parameter", false);
1303 if (aParameter.get()) {
1304 AttributeStringPtr aNameAttr = aParameter->string("variable");
1305 aNameAttr->setValue(aParamName.toStdString());
1307 AttributeStringPtr aExprAttr = aParameter->string("expression");
1308 aExprAttr->setValue(aExpression.toStdString());
1309 aParameter->execute();
1311 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
1312 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
1317 void editParameter(FeaturePtr theParam, const QString& theText)
1319 QStringList aList = theText.split("=");
1320 QString aParamName = aList.at(0).trimmed();
1322 QString aExpression = aList.at(1).trimmed();
1323 if (aExpression.isEmpty()) {
1327 if (isNameExist(aParamName, theParam)) {
1330 AttributeStringPtr aNameAttr = theParam->string("variable");
1331 aNameAttr->setValue(aParamName.toStdString());
1333 AttributeStringPtr aExprAttr = theParam->string("expression");
1334 aExprAttr->setValue(aExpression.toStdString());
1335 theParam->execute();
1337 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
1340 bool isNameExist(const QString& theName, FeaturePtr theIgnoreParameter)
1342 SessionPtr aMgr = ModelAPI_Session::get();
1343 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1344 FeaturePtr aParamFeature;
1345 int aNbFeatures = aDoc->numInternalFeatures();
1346 std::wstring aName = theName.toStdWString();
1347 for (int i = 0; i < aNbFeatures; i++) {
1348 aParamFeature = aDoc->internalFeature(i);
1349 if (aParamFeature && aParamFeature->getKind() == "Parameter") {
1350 if ((theIgnoreParameter != aParamFeature) && (aParamFeature->name() == aName))
1357 FeaturePtr findParameter(const QString& theName)
1359 SessionPtr aMgr = ModelAPI_Session::get();
1360 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1361 FeaturePtr aParamFeature;
1362 int aNbFeatures = aDoc->numInternalFeatures();
1363 std::wstring aName = theName.toStdWString();
1364 for (int i = 0; i < aNbFeatures; i++) {
1365 aParamFeature = aDoc->internalFeature(i);
1366 if (aParamFeature && aParamFeature->getKind() == "Parameter") {
1367 if (aParamFeature->name() == aName)
1368 return aParamFeature;
1371 return FeaturePtr();
1375 //********************************************************************
1376 std::wstring generateName(const AttributePtr& theAttribute,
1377 ModuleBase_IWorkshop* theWorkshop)
1380 if (theAttribute.get() != NULL) {
1381 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
1382 if (aFeature.get()) {
1383 std::string aXmlCfg, aDescription;
1384 theWorkshop->module()->getXMLRepresentation(aFeature->getKind(), aXmlCfg, aDescription);
1386 ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop);
1387 std::string anAttributeTitle;
1388 aFactory.getAttributeTitle(theAttribute->id(), anAttributeTitle);
1390 std::wstringstream aStreamName;
1391 aStreamName << theAttribute->owner()->data()->name() << "/" << anAttributeTitle.c_str();
1392 aName = aStreamName.str();
1398 bool isSameShape(const TopoDS_Shape& theShape1, const TopoDS_Shape& theShape2)
1400 // In case of compound we cannot rely on simple comparison method.
1401 // If the compound is generated by Group feature then this compound is alwais new.
1402 // So, we have to compare content of these compounds
1403 if (theShape1.ShapeType() != theShape2.ShapeType())
1406 if (theShape1.ShapeType() != TopAbs_COMPOUND)
1407 return theShape1.IsSame(theShape2);
1409 TopoDS_Iterator aIt1(theShape1);
1410 TopoDS_Iterator aIt2(theShape2);
1412 for (; aIt1.More() && aIt2.More(); aIt1.Next(), aIt2.Next()) {
1413 if (!(aIt1.Value()).IsSame(aIt2.Value()))
1419 qreal currentPixelRatio()
1421 QWindowList aWnds = qApp->topLevelWindows();
1422 if (aWnds.size() > 0)
1423 return aWnds.first()->devicePixelRatio();
1424 return qApp->primaryScreen()->devicePixelRatio();
1428 // Set displaying status to every element on group
1429 static void setDisplayingByLoop(DocumentPtr theDoc, int theSize,
1430 std::string theGroup, bool theDisplayFromScript, int theDisplayingId)
1432 for (int anIndex = theSize - 1; anIndex >= 0; --anIndex) {
1433 ObjectPtr anObject = theDoc->object(theGroup, anIndex);
1434 anObject->setDisplayed((theDisplayingId == 1 && anIndex == theSize - 1) ||
1435 theDisplayingId == 2);
1439 void setDisplaying(ResultPartPtr thePart, bool theDisplayFromScript)
1441 static bool isDoingDisplay = false;
1446 isDoingDisplay = true;
1447 DocumentPtr aDoc = thePart->partDoc();
1448 int aConstructionSize = aDoc->size(ModelAPI_ResultConstruction::group());
1449 int aGroupSize = aDoc->size(ModelAPI_ResultGroup::group());
1450 int aFieldSize = aDoc->size(ModelAPI_ResultField::group());
1451 int aResultSize = aDoc->size(ModelAPI_ResultBody::group());
1453 int aDisplayingId = -1;
1454 if (theDisplayFromScript) {
1455 aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General",
1456 "part_visualization_script", -1);
1457 // Increase ID to prevert using "As stored in HDF"
1461 aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General",
1462 "part_visualization_study", -1);
1464 // if chosen "As stored in HDF" then don't change displaying
1465 if (aDisplayingId == 0)
1469 setDisplayingByLoop(aDoc, aConstructionSize, ModelAPI_ResultConstruction::group(),
1470 theDisplayFromScript, aDisplayingId);
1471 setDisplayingByLoop(aDoc, aGroupSize, ModelAPI_ResultGroup::group(),
1472 theDisplayFromScript, aDisplayingId);
1473 setDisplayingByLoop(aDoc, aFieldSize, ModelAPI_ResultField::group(),
1474 theDisplayFromScript, aDisplayingId);
1475 setDisplayingByLoop(aDoc, aResultSize, ModelAPI_ResultBody::group(),
1476 theDisplayFromScript, aDisplayingId);
1477 isDoingDisplay = false;
1480 } // namespace ModuleBase_Tools