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>
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));
1108 QPushButton *aReplaceButton =
1110 aMessageBox.addButton(QObject::tr("Replace"), QMessageBox::ActionRole);
1113 if (!aText.isEmpty()) {
1114 aMessageBox.setText(aText);
1115 aMessageBox.setInformativeText(QObject::tr("Would you like to continue?"));
1116 if (!aDetailedText.isEmpty())
1117 aMessageBox.setDetailedText(aDetailedText);
1119 QMessageBox::ButtonRole aButtonRole = aMessageBox.buttonRole(aMessageBox.clickedButton());
1121 if (aButtonRole == QMessageBox::NoRole)
1124 if (aButtonRole == QMessageBox::ActionRole) {
1125 foreach (FeaturePtr aObj, aParameterFeatures)
1126 ModelAPI_ReplaceParameterMessage::send(aObj, 0);
1129 theReferencesToDelete.insert(aFeaturesRefsToParameterOnly.begin(),
1130 aFeaturesRefsToParameterOnly.end());
1135 //**************************************************************
1136 bool warningAboutConflict(QWidget* theParent, const std::string& theWarningText)
1138 QMessageBox aMessageBox(theParent);
1139 aMessageBox.setWindowTitle(QObject::tr("Conflicts in constraint"));
1140 aMessageBox.setIcon(QMessageBox::Warning);
1141 aMessageBox.setText((theWarningText + "\nConstraints will be removed or substituted").c_str());
1143 QCheckBox* aCheckBox = new QCheckBox;
1145 aCheckBox->setTristate(false);
1146 aCheckBox->setText("switch off the notifications.");
1148 aMessageBox.setCheckBox(aCheckBox);
1149 aMessageBox.setStandardButtons(QMessageBox::Ok);
1153 if (aCheckBox->isChecked())
1155 ModuleBase_Preferences::resourceMgr()->setValue(SKETCH_TAB_NAME,
1156 "notify_change_constraint", false);
1162 //**************************************************************
1163 void convertToFeatures(const QObjectPtrList& theObjects, std::set<FeaturePtr>& theFeatures)
1165 QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
1166 for(; anIt != aLast; anIt++) {
1167 ObjectPtr anObject = *anIt;
1168 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
1169 // for parameter result, use the corresponded reature to be removed
1170 if (!aFeature.get() && anObject->groupName() == ModelAPI_ResultParameter::group()) {
1171 aFeature = ModelAPI_Feature::feature(anObject);
1174 theFeatures.insert(aFeature);
1178 //**************************************************************
1179 void convertToFolders(const QObjectPtrList& theObjects,
1180 std::set<FolderPtr>& theFolders)
1182 QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
1183 for(; anIt != aLast; anIt++) {
1184 ObjectPtr anObject = *anIt;
1185 FolderPtr aFeature = std::dynamic_pointer_cast<ModelAPI_Folder>(anObject);
1187 theFolders.insert(aFeature);
1192 //**************************************************************
1193 QString translate(const Events_InfoMessage& theMessage)
1197 if (!theMessage.empty()) {
1198 std::string aStr = Config_Translator::translate(theMessage);
1199 if (!aStr.empty()) {
1200 std::string aCodec = Config_Translator::codec(theMessage);
1201 aMessage = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
1208 QString translate(const std::string& theContext, const std::string& theMessage)
1212 if (!theMessage.empty()) {
1213 std::string aStr = Config_Translator::translate(theContext, theMessage);
1214 if (!aStr.empty()) {
1215 std::string aCodec = Config_Translator::codec(theContext);
1216 aMessage = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
1223 void setPointBallHighlighting(AIS_InteractiveObject* theAIS)
1225 static Handle(Image_AlienPixMap) aPixMap;
1226 if(aPixMap.IsNull()) {
1227 // Load icon for the presentation
1229 char* anEnv = getenv("SHAPER_ROOT_DIR");
1231 aFile = std::string(anEnv) +
1232 FSEP + "share" + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper";
1234 anEnv = getenv("CADBUILDER_ROOT_DIR");
1236 aFile = std::string(anEnv) + FSEP + "resources";
1240 static const std::string aMarkerName = "marker_dot.png";
1241 aFile += aMarkerName;
1242 aPixMap = new Image_AlienPixMap();
1243 if(!aPixMap->Load(aFile.c_str())) {
1244 // The icon for constraint is not found
1245 static const std::string aMsg =
1246 "Error: Point market not found by path: \"" + aFile + "\". Falling back.";
1247 //Events_InfoMessage("ModuleBase_Tools::setPointBallHighlighting", aMsg).send();
1251 Handle(Graphic3d_AspectMarker3d) anAspect;
1252 Handle(Prs3d_Drawer) aDrawer = theAIS->DynamicHilightAttributes();
1253 if (aDrawer.IsNull()) {
1254 if (ModuleBase_IViewer::DefaultHighlightDrawer.IsNull())
1256 aDrawer = new Prs3d_Drawer(*ModuleBase_IViewer::DefaultHighlightDrawer);
1257 if (!aDrawer->HasOwnPointAspect()) {
1258 aDrawer->SetPointAspect(new Prs3d_PointAspect(Aspect_TOM_BALL, Quantity_NOC_BLACK, 2.0));
1261 if(aDrawer->HasOwnPointAspect()) {
1262 Handle(Prs3d_PointAspect) aPntAspect = aDrawer->PointAspect();
1263 if(aPixMap->IsEmpty()) {
1264 anAspect = aPntAspect->Aspect();
1265 anAspect->SetType(Aspect_TOM_BALL);
1267 if(aPixMap->Format() == Image_PixMap::ImgGray) {
1268 aPixMap->SetFormat (Image_PixMap::ImgAlpha);
1269 } else if(aPixMap->Format() == Image_PixMap::ImgGrayF) {
1270 aPixMap->SetFormat (Image_PixMap::ImgAlphaF);
1272 anAspect = new Graphic3d_AspectMarker3d(aPixMap);
1273 aPntAspect->SetAspect(anAspect);
1275 aDrawer->SetPointAspect(aPntAspect);
1276 theAIS->SetDynamicHilightAttributes(aDrawer);
1280 FeaturePtr createParameter(const QString& theText)
1282 FeaturePtr aParameter;
1283 QStringList aList = theText.split("=");
1284 if (aList.count() != 2) {
1287 QString aParamName = aList.at(0).trimmed();
1289 if (isNameExist(aParamName, FeaturePtr())) {
1293 if (!ModelAPI_Expression::isVariable(aParamName.toStdString())) {
1297 QString aExpression = aList.at(1).trimmed();
1298 if (aExpression.isEmpty()) {
1302 SessionPtr aMgr = ModelAPI_Session::get();
1303 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1305 aParameter = aDoc->addFeature("Parameter", false);
1306 if (aParameter.get()) {
1307 AttributeStringPtr aNameAttr = aParameter->string("variable");
1308 aNameAttr->setValue(aParamName.toStdString());
1310 AttributeStringPtr aExprAttr = aParameter->string("expression");
1311 aExprAttr->setValue(aExpression.toStdString());
1312 aParameter->execute();
1314 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
1315 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
1320 void editParameter(FeaturePtr theParam, const QString& theText)
1322 QStringList aList = theText.split("=");
1323 QString aParamName = aList.at(0).trimmed();
1325 QString aExpression = aList.at(1).trimmed();
1326 if (aExpression.isEmpty()) {
1330 if (isNameExist(aParamName, theParam)) {
1333 AttributeStringPtr aNameAttr = theParam->string("variable");
1334 aNameAttr->setValue(aParamName.toStdString());
1336 AttributeStringPtr aExprAttr = theParam->string("expression");
1337 aExprAttr->setValue(aExpression.toStdString());
1338 theParam->execute();
1340 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
1343 bool isNameExist(const QString& theName, FeaturePtr theIgnoreParameter)
1345 SessionPtr aMgr = ModelAPI_Session::get();
1346 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1347 FeaturePtr aParamFeature;
1348 int aNbFeatures = aDoc->numInternalFeatures();
1349 std::wstring aName = theName.toStdWString();
1350 for (int i = 0; i < aNbFeatures; i++) {
1351 aParamFeature = aDoc->internalFeature(i);
1352 if (aParamFeature && aParamFeature->getKind() == "Parameter") {
1353 if ((theIgnoreParameter != aParamFeature) && (aParamFeature->name() == aName))
1360 FeaturePtr findParameter(const QString& theName)
1362 SessionPtr aMgr = ModelAPI_Session::get();
1363 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1364 FeaturePtr aParamFeature;
1365 int aNbFeatures = aDoc->numInternalFeatures();
1366 std::wstring aName = theName.toStdWString();
1367 for (int i = 0; i < aNbFeatures; i++) {
1368 aParamFeature = aDoc->internalFeature(i);
1369 if (aParamFeature && aParamFeature->getKind() == "Parameter") {
1370 if (aParamFeature->name() == aName)
1371 return aParamFeature;
1374 return FeaturePtr();
1378 //********************************************************************
1379 std::wstring generateName(const AttributePtr& theAttribute,
1380 ModuleBase_IWorkshop* theWorkshop)
1383 if (theAttribute.get() != NULL) {
1384 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
1385 if (aFeature.get()) {
1386 std::string aXmlCfg, aDescription;
1387 theWorkshop->module()->getXMLRepresentation(aFeature->getKind(), aXmlCfg, aDescription);
1389 ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop);
1390 std::string anAttributeTitle;
1391 aFactory.getAttributeTitle(theAttribute->id(), anAttributeTitle);
1393 std::wstringstream aStreamName;
1394 aStreamName << theAttribute->owner()->data()->name() << "/" << anAttributeTitle.c_str();
1395 aName = aStreamName.str();
1401 bool isSameShape(const TopoDS_Shape& theShape1, const TopoDS_Shape& theShape2)
1403 // In case of compound we cannot rely on simple comparison method.
1404 // If the compound is generated by Group feature then this compound is alwais new.
1405 // So, we have to compare content of these compounds
1406 if (theShape1.ShapeType() != theShape2.ShapeType())
1409 if (theShape1.ShapeType() != TopAbs_COMPOUND)
1410 return theShape1.IsSame(theShape2);
1412 TopoDS_Iterator aIt1(theShape1);
1413 TopoDS_Iterator aIt2(theShape2);
1415 for (; aIt1.More() && aIt2.More(); aIt1.Next(), aIt2.Next()) {
1416 if (!(aIt1.Value()).IsSame(aIt2.Value()))
1422 qreal currentPixelRatio()
1424 QWindowList aWnds = qApp->topLevelWindows();
1425 if (aWnds.size() > 0)
1426 return aWnds.first()->devicePixelRatio();
1427 return qApp->primaryScreen()->devicePixelRatio();
1431 // Set displaying status to every element on group
1432 static void setDisplayingByLoop(DocumentPtr theDoc, int theSize,
1433 std::string theGroup, bool theDisplayFromScript, int theDisplayingId)
1435 for (int anIndex = theSize - 1; anIndex >= 0; --anIndex) {
1436 ObjectPtr anObject = theDoc->object(theGroup, anIndex);
1437 anObject->setDisplayed((theDisplayingId == 1 && anIndex == theSize - 1) ||
1438 theDisplayingId == 2);
1442 void setDisplaying(ResultPartPtr thePart, bool theDisplayFromScript)
1444 static bool isDoingDisplay = false;
1449 isDoingDisplay = true;
1450 DocumentPtr aDoc = thePart->partDoc();
1451 int aConstructionSize = aDoc->size(ModelAPI_ResultConstruction::group());
1452 int aGroupSize = aDoc->size(ModelAPI_ResultGroup::group());
1453 int aFieldSize = aDoc->size(ModelAPI_ResultField::group());
1454 int aResultSize = aDoc->size(ModelAPI_ResultBody::group());
1456 int aDisplayingId = -1;
1457 if (theDisplayFromScript) {
1458 aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General",
1459 "part_visualization_script", -1);
1460 // Increase ID to prevert using "As stored in HDF"
1464 aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General",
1465 "part_visualization_study", -1);
1467 // if chosen "As stored in HDF" then don't change displaying
1468 if (aDisplayingId == 0)
1472 setDisplayingByLoop(aDoc, aConstructionSize, ModelAPI_ResultConstruction::group(),
1473 theDisplayFromScript, aDisplayingId);
1474 setDisplayingByLoop(aDoc, aGroupSize, ModelAPI_ResultGroup::group(),
1475 theDisplayFromScript, aDisplayingId);
1476 setDisplayingByLoop(aDoc, aFieldSize, ModelAPI_ResultField::group(),
1477 theDisplayFromScript, aDisplayingId);
1478 setDisplayingByLoop(aDoc, aResultSize, ModelAPI_ResultBody::group(),
1479 theDisplayFromScript, aDisplayingId);
1480 isDoingDisplay = false;
1483 } // namespace ModuleBase_Tools