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 void setDefaultDeviationCoefficient(const TopoDS_Shape& theShape,
484 const Handle(Prs3d_Drawer)& theDrawer)
486 if (theShape.IsNull())
488 if (theDrawer.IsNull())
491 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape());
492 aGeomShape->setImpl(new TopoDS_Shape(theShape));
494 // if the shape could not be exploded on faces, it contains only wires, edges, and vertices
495 // correction of deviation for them should not influence to the application performance
496 GeomAPI_ShapeExplorer anExp(aGeomShape, GeomAPI_Shape::FACE);
497 bool isConstruction = !anExp.more();
501 aDeflection = Config_PropManager::real("Visualization", "construction_deflection");
503 aDeflection = Config_PropManager::real("Visualization", "body_deflection");
505 theDrawer->SetDeviationCoefficient(aDeflection);
508 Quantity_Color color(const std::string& theSection,
509 const std::string& theName)
511 std::vector<int> aColor = Config_PropManager::color(theSection, theName);
512 return Quantity_Color(aColor[0] / 255., aColor[1] / 255., aColor[2] / 255., Quantity_TOC_RGB);
515 ObjectPtr getObject(const AttributePtr& theAttribute)
518 std::string anAttrType = theAttribute->attributeType();
519 if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
520 AttributeRefAttrPtr anAttr =
521 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
522 if (anAttr != NULL && anAttr->isObject())
523 anObject = anAttr->object();
525 if (anAttrType == ModelAPI_AttributeSelection::typeId()) {
526 AttributeSelectionPtr anAttr =
527 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
529 anObject = anAttr->context();
531 if (anAttrType == ModelAPI_AttributeReference::typeId()) {
532 AttributeReferencePtr anAttr =
533 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
534 if (anAttr.get() != NULL)
535 anObject = anAttr->value();
540 TopAbs_ShapeEnum getCompoundSubType(const TopoDS_Shape& theShape)
542 TopAbs_ShapeEnum aShapeType = theShape.ShapeType();
544 // for compounds check sub-shapes: it may be compound of needed type:
545 // Booleans may produce compounds of Solids
546 if (aShapeType == TopAbs_COMPOUND) {
547 for(TopoDS_Iterator aSubs(theShape); aSubs.More(); aSubs.Next()) {
548 if (!aSubs.Value().IsNull()) {
549 TopAbs_ShapeEnum aSubType = aSubs.Value().ShapeType();
550 if (aSubType == TopAbs_COMPOUND) { // compound of compound(s)
551 aShapeType = TopAbs_COMPOUND;
554 if (aShapeType == TopAbs_COMPOUND) {
555 aShapeType = aSubType;
556 } else if (aShapeType != aSubType) { // compound of shapes of different types
557 aShapeType = TopAbs_COMPOUND;
566 TopoDS_Shape getSelectedShape(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs)
568 if (thePrs->shape().get())
569 return thePrs->shape()->impl<TopoDS_Shape>();
571 Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast(thePrs->owner());
572 if (!anOwner.IsNull())
573 return anOwner->Shape();
575 return TopoDS_Shape();
578 void getParameters(QStringList& theParameters)
580 theParameters.clear();
582 SessionPtr aSession = ModelAPI_Session::get();
583 std::list<DocumentPtr> aDocList;
584 DocumentPtr anActiveDocument = aSession->activeDocument();
585 DocumentPtr aRootDocument = aSession->moduleDocument();
586 aDocList.push_back(anActiveDocument);
587 if (anActiveDocument != aRootDocument) {
588 aDocList.push_back(aRootDocument);
590 std::string aGroupId = ModelAPI_ResultParameter::group();
591 for(std::list<DocumentPtr>::const_iterator it = aDocList.begin(); it != aDocList.end(); ++it) {
592 DocumentPtr aDocument = *it;
593 int aSize = aDocument->size(aGroupId);
594 for (int i = 0; i < aSize; i++) {
595 ObjectPtr anObject = aDocument->object(aGroupId, i);
596 std::wstring aParameterName = anObject->data()->name();
597 theParameters.append(QString::fromStdWString(aParameterName));
602 std::string findGreedAttribute(ModuleBase_IWorkshop* theWorkshop,
603 const FeaturePtr& theFeature)
605 std::string anAttributeId;
607 std::string aXmlCfg, aDescription;
608 theWorkshop->module()->getXMLRepresentation(theFeature->getKind(), aXmlCfg, aDescription);
610 ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop);
611 std::string anAttributeTitle;
612 aFactory.getGreedAttribute(anAttributeId);
614 return anAttributeId;
617 bool hasObject(const AttributePtr& theAttribute, const ObjectPtr& theObject,
618 const std::shared_ptr<GeomAPI_Shape>& theShape,
619 ModuleBase_IWorkshop* theWorkshop,
620 const bool theTemporarily)
622 bool aHasObject = false;
623 if (!theAttribute.get())
626 std::string aType = theAttribute->attributeType();
627 if (aType == ModelAPI_AttributeReference::typeId()) {
628 AttributeReferencePtr aRef =
629 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
630 ObjectPtr aObject = aRef->value();
631 aHasObject = aObject && aObject->isSame(theObject);
632 //if (!(aObject && aObject->isSame(theObject))) {
633 // aRef->setValue(theObject);
635 } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
636 AttributeRefAttrPtr aRefAttr =
637 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
639 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
640 if (anAttribute.get()) {
641 //aRefAttr->setAttr(anAttribute);
644 ObjectPtr aObject = aRefAttr->object();
645 aHasObject = aObject && aObject->isSame(theObject);
646 //if (!(aObject && aObject->isSame(theObject))) {
647 // aRefAttr->setObject(theObject);
650 } else if (aType == ModelAPI_AttributeSelection::typeId()) {
651 /*AttributeSelectionPtr aSelectAttr =
652 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
653 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
654 if (aSelectAttr.get() != NULL) {
655 aSelectAttr->setValue(aResult, theShape, theTemporarily);
658 if (aType == ModelAPI_AttributeSelectionList::typeId()) {
659 AttributeSelectionListPtr aSelectionListAttr =
660 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
661 aHasObject = aSelectionListAttr->isInList(theObject, theShape, theTemporarily);
663 else if (aType == ModelAPI_AttributeRefList::typeId()) {
664 AttributeRefListPtr aRefListAttr =
665 std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttribute);
666 aHasObject = aRefListAttr->isInList(theObject);
667 //if (!theCheckIfAttributeHasObject || !aRefListAttr->isInList(theObject))
668 // aRefListAttr->append(theObject);
670 else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
671 AttributeRefAttrListPtr aRefAttrListAttr =
672 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(theAttribute);
673 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
675 if (anAttribute.get()) {
676 aHasObject = aRefAttrListAttr->isInList(anAttribute);
677 //if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(anAttribute))
678 // aRefAttrListAttr->append(anAttribute);
681 aHasObject = aRefAttrListAttr->isInList(theObject);
682 //if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(theObject))
683 // aRefAttrListAttr->append(theObject);
689 bool setObject(const AttributePtr& theAttribute, const ObjectPtr& theObject,
690 const GeomShapePtr& theShape, ModuleBase_IWorkshop* theWorkshop,
691 const bool theTemporarily, const bool theCheckIfAttributeHasObject)
693 if (!theAttribute.get())
697 std::string aType = theAttribute->attributeType();
698 if (aType == ModelAPI_AttributeReference::typeId()) {
699 AttributeReferencePtr aRef =
700 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
701 ObjectPtr aObject = aRef->value();
702 if (!(aObject && aObject->isSame(theObject))) {
703 aRef->setValue(theObject);
705 } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
706 AttributeRefAttrPtr aRefAttr =
707 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
709 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
710 if (anAttribute.get())
711 aRefAttr->setAttr(anAttribute);
713 ObjectPtr aObject = aRefAttr->object();
714 if (!(aObject && aObject->isSame(theObject))) {
715 aRefAttr->setObject(theObject);
718 } else if (aType == ModelAPI_AttributeSelection::typeId()) {
719 AttributeSelectionPtr aSelectAttr =
720 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
721 if (aSelectAttr.get() != NULL) {
722 aSelectAttr->setValue(theObject, theShape, theTemporarily);
725 if (aType == ModelAPI_AttributeSelectionList::typeId()) {
726 AttributeSelectionListPtr aSelectionListAttr =
727 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
728 if (!theCheckIfAttributeHasObject ||
729 !aSelectionListAttr->isInList(theObject, theShape, theTemporarily))
730 aSelectionListAttr->append(theObject, theShape, theTemporarily);
732 else if (aType == ModelAPI_AttributeRefList::typeId()) {
733 AttributeRefListPtr aRefListAttr =
734 std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttribute);
735 if (!theCheckIfAttributeHasObject || !aRefListAttr->isInList(theObject)) {
737 aRefListAttr->append(theObject);
742 else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
743 AttributeRefAttrListPtr aRefAttrListAttr =
744 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(theAttribute);
745 AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
747 if (anAttribute.get()) {
748 if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(anAttribute))
749 aRefAttrListAttr->append(anAttribute);
752 if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(theObject)) {
754 aRefAttrListAttr->append(theObject);
763 GeomShapePtr getShape(const AttributePtr& theAttribute, ModuleBase_IWorkshop* theWorkshop)
766 if (!theAttribute.get())
769 std::string aType = theAttribute->attributeType();
770 if (aType == ModelAPI_AttributeReference::typeId()) {
771 } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
772 AttributeRefAttrPtr aRefAttr =
773 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
774 if (aRefAttr.get() && !aRefAttr->isObject()) {
775 AttributePtr anAttribute = aRefAttr->attr();
776 aShape = theWorkshop->module()->findShape(anAttribute);
778 } else if (aType == ModelAPI_AttributeSelection::typeId()) {
779 AttributeSelectionPtr aSelectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
781 aShape = aSelectAttr->value();
783 else // Geom2D point processing
784 aShape = theWorkshop->module()->findShape(theAttribute);
788 void flushUpdated(ObjectPtr theObject)
790 blockUpdateViewer(true);
792 // Fix the problem of not previewed results of constraints applied. Flush Create/Delete
793 // (for the sketch result) to start processing of the sketch in the solver.
794 // TODO: these flushes should be moved in a separate method provided by Model
795 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
796 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_VISUAL_ATTRIBUTES));
797 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
798 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_UPDATE_SELECTION));
799 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
801 blockUpdateViewer(false);
804 void blockUpdateViewer(const bool theValue)
806 // the viewer update should be blocked in order to avoid the temporary feature content
807 // when the solver processes the feature, the redisplay message can be flushed
808 // what caused the display in the viewer preliminary states of object
809 // e.g. fillet feature, angle value change
810 std::shared_ptr<Events_Message> aMsg;
812 aMsg = std::shared_ptr<Events_Message>(
813 new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED)));
816 // the viewer update should be unblocked
817 aMsg = std::shared_ptr<Events_Message>(
818 new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)));
820 Events_Loop::loop()->send(aMsg);
823 QString wrapTextByWords(const QString& theValue, QWidget* theWidget,
824 int theMaxLineInPixels)
826 static QFontMetrics tfm(theWidget ? theWidget->font() : QApplication::font());
827 static qreal phi = 2.618;
829 QRect aBounds = tfm.boundingRect(theValue);
830 if(aBounds.width() <= theMaxLineInPixels)
833 qreal s = aBounds.width() * aBounds.height();
834 qreal aGoldWidth = sqrt(s*phi);
836 QStringList aWords = theValue.split(" ", QString::SkipEmptyParts);
838 int n = aWords.count();
840 for (int i = 0; i < n; i++) {
841 QString aLineExt = i == 0 ? aWords[i] : aLine + " " + aWords[i];
842 qreal anWidthNonExt = tfm.boundingRect(aLine).width();
843 qreal anWidthExt = tfm.boundingRect(aLineExt).width();
844 qreal aDeltaNonExt = fabs(anWidthNonExt-aGoldWidth);
845 qreal aDeltaExt = fabs(anWidthExt-aGoldWidth);
846 if(aDeltaNonExt < aDeltaExt) {
848 aLines.append(aLine);
856 aLines.append(aLine);
858 QString aResult = aLines.join("\n");
862 //**************************************************************
863 QLocale doubleLocale()
865 // VSR 01/07/2010: Disable thousands separator for spin box
866 // (to avoid inconsistency of double-2-string and string-2-double conversion)
868 aLocale.setNumberOptions(aLocale.numberOptions() |
869 QLocale::OmitGroupSeparator |
870 QLocale::RejectGroupSeparator);
874 //**************************************************************
875 void refsToFeatureInFeatureDocument(const ObjectPtr& theObject,
876 std::set<FeaturePtr>& theRefFeatures)
878 FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
879 if (aFeature.get()) {
880 DocumentPtr aFeatureDoc = aFeature->document();
881 // 1. find references in the current document
882 aFeatureDoc->refsToFeature(aFeature, theRefFeatures, false);
887 //**************************************************************
888 /*bool isSubOfComposite(const ObjectPtr& theObject)
891 std::set<FeaturePtr> aRefFeatures;
892 refsToFeatureInFeatureDocument(theObject, aRefFeatures);
893 std::set<FeaturePtr>::const_iterator anIt = aRefFeatures.begin(),
894 aLast = aRefFeatures.end();
895 for (; anIt != aLast && !isSub; anIt++) {
896 isSub = isSubOfComposite(theObject, *anIt);
901 //**************************************************************
902 /*bool isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature)
905 CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
906 if (aComposite.get()) {
907 isSub = aComposite->isSub(theObject);
908 // the recursive is possible, the parameters are sketch circle and extrusion cut. They are
909 // separated by composite sketch feature
911 int aNbSubs = aComposite->numberOfSubs();
912 for (int aSub = 0; aSub < aNbSubs && !isSub; aSub++) {
913 isSub = isSubOfComposite(theObject, aComposite->subFeature(aSub));
920 //**************************************************************
921 ResultPtr firstResult(const ObjectPtr& theObject)
923 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
924 if (!aResult.get()) {
925 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
927 aResult = aFeature->firstResult();
932 //**************************************************************
933 bool isFeatureOfResult(const FeaturePtr& theFeature, const std::string& theGroupOfResult)
935 bool isResult = false;
937 if (!theFeature->data()->isValid())
940 ResultPtr aFirstResult = theFeature->firstResult();
941 if (!aFirstResult.get())
944 return aFirstResult->groupName() == theGroupOfResult;
947 //**************************************************************
948 bool hasModuleDocumentFeature(const std::set<FeaturePtr>& theFeatures)
950 bool aFoundModuleDocumentObject = false;
951 DocumentPtr aModuleDoc = ModelAPI_Session::get()->moduleDocument();
953 std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(), aLast = theFeatures.end();
954 for (; anIt != aLast && !aFoundModuleDocumentObject; anIt++) {
955 FeaturePtr aFeature = *anIt;
956 ResultPtr aResult = ModuleBase_Tools::firstResult(aFeature);
957 if (aResult.get() && aResult->groupName() == ModelAPI_ResultPart::group())
959 aFoundModuleDocumentObject = aFeature->document() == aModuleDoc;
962 return aFoundModuleDocumentObject;
965 //**************************************************************
966 bool askToDelete(const std::set<FeaturePtr> theFeatures,
967 const std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
969 std::set<FeaturePtr>& theReferencesToDelete,
970 const std::string& thePrefixInfo)
972 QString aNotActivatedDocWrn;
973 std::wstring aNotActivatedNames;
974 if (!ModelAPI_Tools::allDocumentsActivated(aNotActivatedNames)) {
975 if (ModuleBase_Tools::hasModuleDocumentFeature(theFeatures))
976 aNotActivatedDocWrn =
977 QObject::tr("Selected objects can be used in Part documents which are not loaded: %1.\n")
978 .arg(QString::fromStdWString(aNotActivatedNames));
981 std::set<FeaturePtr> aFeaturesRefsTo;
982 std::set<FeaturePtr> aFeaturesRefsToParameter;
983 std::set<FeaturePtr> aParameterFeatures;
984 QStringList aPartFeatureNames;
985 std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),
986 aLast = theFeatures.end();
987 // separate features to references to parameter features and references to others
988 for (; anIt != aLast; anIt++) {
989 FeaturePtr aFeature = *anIt;
990 if (theReferences.find(aFeature) == theReferences.end())
993 if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group()))
994 aPartFeatureNames.append(QString::fromStdWString(aFeature->name()));
996 std::set<FeaturePtr> aRefFeatures;
997 std::set<FeaturePtr> aRefList = theReferences.at(aFeature);
998 std::set<FeaturePtr>::const_iterator aRefIt = aRefList.begin(), aRefLast = aRefList.end();
999 for (; aRefIt != aRefLast; aRefIt++) {
1000 FeaturePtr aRefFeature = *aRefIt;
1001 if (theFeatures.find(aRefFeature) == theFeatures.end() && // it is not selected
1002 aRefFeatures.find(aRefFeature) == aRefFeatures.end()) // it is not added
1003 aRefFeatures.insert(aRefFeature);
1006 if (isFeatureOfResult(aFeature, ModelAPI_ResultParameter::group())) {
1007 aFeaturesRefsToParameter.insert(aRefFeatures.begin(), aRefFeatures.end());
1008 aParameterFeatures.insert(aFeature);
1011 theReferencesToDelete.insert(aRefFeatures.begin(), aRefFeatures.end());
1015 std::set<FeaturePtr> aFeaturesRefsToParameterOnly;
1016 anIt = aFeaturesRefsToParameter.begin();
1017 aLast = aFeaturesRefsToParameter.end();
1018 // separate features to references to parameter features and references to others
1019 QStringList aParamFeatureNames;
1020 for (; anIt != aLast; anIt++) {
1021 FeaturePtr aFeature = *anIt;
1022 if (theReferencesToDelete.find(aFeature) == theReferencesToDelete.end()) {
1023 aFeaturesRefsToParameterOnly.insert(aFeature);
1024 aParamFeatureNames.append(QString::fromStdWString(aFeature->name()));
1027 aParamFeatureNames.sort();
1028 QStringList anOtherFeatureNames;
1029 anIt = theReferencesToDelete.begin();
1030 aLast = theReferencesToDelete.end();
1031 for (; anIt != aLast; anIt++) {
1032 FeaturePtr aFeature = *anIt;
1033 if (aFeature->getKind() == "RemoveResults")
1034 continue; // skip the remove results feature mentioning: result will be removed anyway
1035 if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group()))
1036 aPartFeatureNames.append(QString::fromStdWString(aFeature->name()));
1038 anOtherFeatureNames.append(QString::fromStdWString(aFeature->name()));
1040 aPartFeatureNames.sort();
1041 anOtherFeatureNames.sort();
1043 QMessageBox aMessageBox(theParent);
1044 aMessageBox.setWindowTitle(QObject::tr("Delete features"));
1045 aMessageBox.setIcon(QMessageBox::Warning);
1046 aMessageBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
1047 aMessageBox.setDefaultButton(QMessageBox::No);
1049 QString aText, aDetailedText;
1050 if (!thePrefixInfo.empty())
1051 aText = thePrefixInfo.c_str();
1052 QString aSep = ", ";
1053 if (!aPartFeatureNames.empty()) {
1054 aText += QString(QObject::tr("The following parts will be deleted: %1.\n"))
1055 .arg(aPartFeatureNames.join(aSep));
1057 if (!aNotActivatedDocWrn.isEmpty())
1058 aText += aNotActivatedDocWrn;
1059 if (!anOtherFeatureNames.empty()) {
1060 const char* aMsg = "The selected features are used in some\n"
1061 "other features, which will also be deleted.\n";
1062 const char* aMsgDetails = "The selected features are used"
1063 " in the following features: %1.\n";
1064 aText += QString(QObject::tr(aMsg));
1065 aDetailedText += QString(QObject::tr(aMsgDetails))
1066 .arg(anOtherFeatureNames.join(aSep));
1068 if (!aParamFeatureNames.empty()) {
1069 const char* aMsg = "The selected parameters are used directly or through\n"
1070 "a sequence of dependencies in some features.\n"
1071 "These features will be deleted.\n"
1072 "Or parameters could be replaced by their values.\n";
1073 const char* aMsgDetails = "Parameters are used in the following features: %1.\n";
1074 aText += QString(QObject::tr(aMsg));
1075 aDetailedText += QString(QObject::tr(aMsgDetails))
1076 .arg(aParamFeatureNames.join(aSep));
1077 aMessageBox.addButton(QObject::tr("Replace"), QMessageBox::ActionRole);
1080 if (!aText.isEmpty()) {
1081 aMessageBox.setText(aText);
1082 aMessageBox.setInformativeText(QObject::tr("Would you like to continue?"));
1083 if (!aDetailedText.isEmpty())
1084 aMessageBox.setDetailedText(aDetailedText);
1086 QMessageBox::ButtonRole aButtonRole = aMessageBox.buttonRole(aMessageBox.clickedButton());
1088 if (aButtonRole == QMessageBox::NoRole)
1091 if (aButtonRole == QMessageBox::ActionRole) {
1092 foreach (FeaturePtr aObj, aParameterFeatures)
1093 ModelAPI_ReplaceParameterMessage::send(aObj, 0);
1096 theReferencesToDelete.insert(aFeaturesRefsToParameterOnly.begin(),
1097 aFeaturesRefsToParameterOnly.end());
1102 //**************************************************************
1103 bool warningAboutConflict(QWidget* theParent, const std::string& theWarningText)
1105 QMessageBox aMessageBox(theParent);
1106 aMessageBox.setWindowTitle(QObject::tr("Conflicts in constraint"));
1107 aMessageBox.setIcon(QMessageBox::Warning);
1108 aMessageBox.setText((theWarningText + "\nConstraints will be removed or substituted").c_str());
1110 QCheckBox* aCheckBox = new QCheckBox;
1112 aCheckBox->setTristate(false);
1113 aCheckBox->setText("switch off the notifications.");
1115 aMessageBox.setCheckBox(aCheckBox);
1116 aMessageBox.setStandardButtons(QMessageBox::Ok);
1120 if (aCheckBox->isChecked())
1122 ModuleBase_Preferences::resourceMgr()->setValue(SKETCH_TAB_NAME,
1123 "notify_change_constraint", false);
1129 //**************************************************************
1130 void convertToFeatures(const QObjectPtrList& theObjects, std::set<FeaturePtr>& theFeatures)
1132 QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
1133 for(; anIt != aLast; anIt++) {
1134 ObjectPtr anObject = *anIt;
1135 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
1136 // for parameter result, use the corresponded reature to be removed
1137 if (!aFeature.get() && anObject->groupName() == ModelAPI_ResultParameter::group()) {
1138 aFeature = ModelAPI_Feature::feature(anObject);
1141 theFeatures.insert(aFeature);
1145 //**************************************************************
1146 void convertToFolders(const QObjectPtrList& theObjects,
1147 std::set<FolderPtr>& theFolders)
1149 QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
1150 for(; anIt != aLast; anIt++) {
1151 ObjectPtr anObject = *anIt;
1152 FolderPtr aFeature = std::dynamic_pointer_cast<ModelAPI_Folder>(anObject);
1154 theFolders.insert(aFeature);
1159 //**************************************************************
1160 QString translate(const Events_InfoMessage& theMessage)
1164 if (!theMessage.empty()) {
1165 std::string aStr = Config_Translator::translate(theMessage);
1166 if (!aStr.empty()) {
1167 std::string aCodec = Config_Translator::codec(theMessage);
1168 aMessage = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
1175 QString translate(const std::string& theContext, const std::string& theMessage)
1179 if (!theMessage.empty()) {
1180 std::string aStr = Config_Translator::translate(theContext, theMessage);
1181 if (!aStr.empty()) {
1182 std::string aCodec = Config_Translator::codec(theContext);
1183 aMessage = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
1190 void setPointBallHighlighting(AIS_InteractiveObject* theAIS)
1192 static Handle(Image_AlienPixMap) aPixMap;
1193 if(aPixMap.IsNull()) {
1194 // Load icon for the presentation
1196 char* anEnv = getenv("SHAPER_ROOT_DIR");
1198 aFile = std::string(anEnv) +
1199 FSEP + "share" + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper";
1201 anEnv = getenv("CADBUILDER_ROOT_DIR");
1203 aFile = std::string(anEnv) + FSEP + "resources";
1207 static const std::string aMarkerName = "marker_dot.png";
1208 aFile += aMarkerName;
1209 aPixMap = new Image_AlienPixMap();
1210 if(!aPixMap->Load(aFile.c_str())) {
1211 // The icon for constraint is not found
1212 static const std::string aMsg =
1213 "Error: Point market not found by path: \"" + aFile + "\". Falling back.";
1214 //Events_InfoMessage("ModuleBase_Tools::setPointBallHighlighting", aMsg).send();
1218 Handle(Graphic3d_AspectMarker3d) anAspect;
1219 Handle(Prs3d_Drawer) aDrawer = theAIS->DynamicHilightAttributes();
1220 if (aDrawer.IsNull()) {
1221 if (ModuleBase_IViewer::DefaultHighlightDrawer.IsNull())
1223 aDrawer = new Prs3d_Drawer(*ModuleBase_IViewer::DefaultHighlightDrawer);
1224 if (!aDrawer->HasOwnPointAspect()) {
1225 aDrawer->SetPointAspect(new Prs3d_PointAspect(Aspect_TOM_BALL, Quantity_NOC_BLACK, 2.0));
1228 if(aDrawer->HasOwnPointAspect()) {
1229 Handle(Prs3d_PointAspect) aPntAspect = aDrawer->PointAspect();
1230 if(aPixMap->IsEmpty()) {
1231 anAspect = aPntAspect->Aspect();
1232 anAspect->SetType(Aspect_TOM_BALL);
1234 if(aPixMap->Format() == Image_PixMap::ImgGray) {
1235 aPixMap->SetFormat (Image_PixMap::ImgAlpha);
1236 } else if(aPixMap->Format() == Image_PixMap::ImgGrayF) {
1237 aPixMap->SetFormat (Image_PixMap::ImgAlphaF);
1239 anAspect = new Graphic3d_AspectMarker3d(aPixMap);
1240 aPntAspect->SetAspect(anAspect);
1242 aDrawer->SetPointAspect(aPntAspect);
1243 theAIS->SetDynamicHilightAttributes(aDrawer);
1247 FeaturePtr createParameter(const QString& theText)
1249 FeaturePtr aParameter;
1250 QStringList aList = theText.split("=");
1251 if (aList.count() != 2) {
1254 QString aParamName = aList.at(0).trimmed();
1256 if (isNameExist(aParamName, FeaturePtr())) {
1260 if (!ModelAPI_Expression::isVariable(aParamName.toStdString())) {
1264 QString aExpression = aList.at(1).trimmed();
1265 if (aExpression.isEmpty()) {
1269 SessionPtr aMgr = ModelAPI_Session::get();
1270 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1272 aParameter = aDoc->addFeature("Parameter", false);
1273 if (aParameter.get()) {
1274 AttributeStringPtr aNameAttr = aParameter->string("variable");
1275 aNameAttr->setValue(aParamName.toStdString());
1277 AttributeStringPtr aExprAttr = aParameter->string("expression");
1278 aExprAttr->setValue(aExpression.toStdString());
1279 aParameter->execute();
1281 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
1282 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
1287 void editParameter(FeaturePtr theParam, const QString& theText)
1289 QStringList aList = theText.split("=");
1290 QString aParamName = aList.at(0).trimmed();
1292 QString aExpression = aList.at(1).trimmed();
1293 if (aExpression.isEmpty()) {
1297 if (isNameExist(aParamName, theParam)) {
1300 AttributeStringPtr aNameAttr = theParam->string("variable");
1301 aNameAttr->setValue(aParamName.toStdString());
1303 AttributeStringPtr aExprAttr = theParam->string("expression");
1304 aExprAttr->setValue(aExpression.toStdString());
1305 theParam->execute();
1307 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
1310 bool isNameExist(const QString& theName, FeaturePtr theIgnoreParameter)
1312 SessionPtr aMgr = ModelAPI_Session::get();
1313 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1314 FeaturePtr aParamFeature;
1315 int aNbFeatures = aDoc->numInternalFeatures();
1316 std::wstring aName = theName.toStdWString();
1317 for (int i = 0; i < aNbFeatures; i++) {
1318 aParamFeature = aDoc->internalFeature(i);
1319 if (aParamFeature && aParamFeature->getKind() == "Parameter") {
1320 if ((theIgnoreParameter != aParamFeature) && (aParamFeature->name() == aName))
1327 FeaturePtr findParameter(const QString& theName)
1329 SessionPtr aMgr = ModelAPI_Session::get();
1330 std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1331 FeaturePtr aParamFeature;
1332 int aNbFeatures = aDoc->numInternalFeatures();
1333 std::wstring aName = theName.toStdWString();
1334 for (int i = 0; i < aNbFeatures; i++) {
1335 aParamFeature = aDoc->internalFeature(i);
1336 if (aParamFeature && aParamFeature->getKind() == "Parameter") {
1337 if (aParamFeature->name() == aName)
1338 return aParamFeature;
1341 return FeaturePtr();
1345 //********************************************************************
1346 std::wstring generateName(const AttributePtr& theAttribute,
1347 ModuleBase_IWorkshop* theWorkshop)
1350 if (theAttribute.get() != NULL) {
1351 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
1352 if (aFeature.get()) {
1353 std::string aXmlCfg, aDescription;
1354 theWorkshop->module()->getXMLRepresentation(aFeature->getKind(), aXmlCfg, aDescription);
1356 ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop);
1357 std::string anAttributeTitle;
1358 aFactory.getAttributeTitle(theAttribute->id(), anAttributeTitle);
1360 std::wstringstream aStreamName;
1361 aStreamName << theAttribute->owner()->data()->name() << "/" << anAttributeTitle.c_str();
1362 aName = aStreamName.str();
1368 bool isSameShape(const TopoDS_Shape& theShape1, const TopoDS_Shape& theShape2)
1370 // In case of compound we cannot rely on simple comparison method.
1371 // If the compound is generated by Group feature then this compound is alwais new.
1372 // So, we have to compare content of these compounds
1373 if (theShape1.ShapeType() != theShape2.ShapeType())
1376 if (theShape1.ShapeType() != TopAbs_COMPOUND)
1377 return theShape1.IsSame(theShape2);
1379 TopoDS_Iterator aIt1(theShape1);
1380 TopoDS_Iterator aIt2(theShape2);
1382 for (; aIt1.More() && aIt2.More(); aIt1.Next(), aIt2.Next()) {
1383 if (!(aIt1.Value()).IsSame(aIt2.Value()))
1389 qreal currentPixelRatio()
1391 QWindowList aWnds = qApp->topLevelWindows();
1392 if (aWnds.size() > 0)
1393 return aWnds.first()->devicePixelRatio();
1394 return qApp->primaryScreen()->devicePixelRatio();
1398 // Set displaying status to every element on group
1399 static void setDisplayingByLoop(DocumentPtr theDoc, int theSize,
1400 std::string theGroup, bool theDisplayFromScript, int theDisplayingId)
1402 for (int anIndex = theSize - 1; anIndex >= 0; --anIndex) {
1403 ObjectPtr anObject = theDoc->object(theGroup, anIndex);
1404 anObject->setDisplayed((theDisplayingId == 1 && anIndex == theSize - 1) ||
1405 theDisplayingId == 2);
1409 void setDisplaying(ResultPartPtr thePart, bool theDisplayFromScript)
1411 static bool isDoingDisplay = false;
1416 isDoingDisplay = true;
1417 DocumentPtr aDoc = thePart->partDoc();
1418 int aConstructionSize = aDoc->size(ModelAPI_ResultConstruction::group());
1419 int aGroupSize = aDoc->size(ModelAPI_ResultGroup::group());
1420 int aFieldSize = aDoc->size(ModelAPI_ResultField::group());
1421 int aResultSize = aDoc->size(ModelAPI_ResultBody::group());
1423 int aDisplayingId = -1;
1424 if (theDisplayFromScript) {
1425 aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General",
1426 "part_visualization_script", -1);
1427 // Increase ID to prevert using "As stored in HDF"
1431 aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General",
1432 "part_visualization_study", -1);
1434 // if chosen "As stored in HDF" then don't change displaying
1435 if (aDisplayingId == 0)
1439 setDisplayingByLoop(aDoc, aConstructionSize, ModelAPI_ResultConstruction::group(),
1440 theDisplayFromScript, aDisplayingId);
1441 setDisplayingByLoop(aDoc, aGroupSize, ModelAPI_ResultGroup::group(),
1442 theDisplayFromScript, aDisplayingId);
1443 setDisplayingByLoop(aDoc, aFieldSize, ModelAPI_ResultField::group(),
1444 theDisplayFromScript, aDisplayingId);
1445 setDisplayingByLoop(aDoc, aResultSize, ModelAPI_ResultBody::group(),
1446 theDisplayFromScript, aDisplayingId);
1447 isDoingDisplay = false;
1450 } // namespace ModuleBase_Tools