1 // Copyright (C) 2019-2020 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 <PartSet_WidgetBSplinePoints.h>
22 #include <PartSet_CenterPrs.h>
23 #include <PartSet_ExternalObjectsMgr.h>
24 #include <PartSet_Module.h>
25 #include <PartSet_SketcherReentrantMgr.h>
26 #include <PartSet_WidgetPoint2d.h>
28 #include <XGUI_Tools.h>
29 #include <XGUI_Workshop.h>
30 #include <XGUI_Displayer.h>
32 #include <ModuleBase_ISelection.h>
33 #include <ModuleBase_IViewer.h>
34 #include <ModuleBase_IViewWindow.h>
35 #include <ModuleBase_LabelValue.h>
36 #include <ModuleBase_Tools.h>
37 #include <ModuleBase_ViewerPrs.h>
38 #include <ModuleBase_WidgetValidator.h>
39 #include <ModuleBase_WidgetValidated.h>
41 #include <Config_Keywords.h>
42 #include <Config_WidgetAPI.h>
44 #include <Events_Loop.h>
46 #include <ModelAPI_Events.h>
47 #include <ModelAPI_AttributeDoubleArray.h>
48 #include <ModelAPI_AttributeRefAttrList.h>
49 #include <ModelAPI_CompositeFeature.h>
51 #include <GeomDataAPI_Point2D.h>
52 #include <GeomDataAPI_Point2DArray.h>
54 #include <GeomAPI_Pnt2d.h>
55 #include <GeomAPI_IPresentable.h>
57 #include <SketchPlugin_Feature.h>
59 #include <QGridLayout>
61 #include <QMouseEvent>
62 #include <QGraphicsEffect>
63 #include <QScrollArea>
65 static const double MaxCoordinate = 1e12;
67 static bool IsPointCreated = false;
70 PartSet_WidgetBSplinePoints::PartSet_WidgetBSplinePoints(QWidget* theParent,
71 ModuleBase_IWorkshop* theWorkshop,
72 const Config_WidgetAPI* theData)
73 : ModuleBase_ModelWidget(theParent, theData), myWorkshop(theWorkshop),
74 myValueIsCashed(false), myIsFeatureVisibleInCash(true),
75 myXValueInCash(0), myYValueInCash(0),
76 myPointIndex(0), myFinished(false)
78 myRefAttribute = theData->getProperty("reference_attribute");
79 QVBoxLayout* aMainLayout = new QVBoxLayout(this);
80 ModuleBase_Tools::zeroMargins(aMainLayout);
82 // the control should accept the focus, so the boolean flag is corrected to be true
83 myIsObligatory = true;
84 QString aPageName = translate(theData->getProperty(CONTAINER_PAGE_NAME));
85 myBox = new QGroupBox(aPageName, theParent);
86 myBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
87 myBox->setFlat(false);
88 aMainLayout->addWidget(myBox);
91 bool aAcceptVariables =
93 theData->getBooleanAttribute(DOUBLE_WDG_ACCEPT_EXPRESSIONS, true);
95 // B-spline weights attribute
96 myWeightsAttr = theData->getProperty("weights");
98 QVBoxLayout* aLayout = new QVBoxLayout(myBox);
99 ModuleBase_Tools::adjustMargins(aLayout);
101 myScrollArea = new QScrollArea(myBox);
102 myScrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
103 myScrollArea->setWidgetResizable(true);
104 myScrollArea->setFrameStyle(QFrame::NoFrame);
105 aLayout->addWidget(myScrollArea);
107 QWidget* aContainer = new QWidget(myScrollArea);
108 QVBoxLayout* aBoxLay = new QVBoxLayout(aContainer);
109 aBoxLay->setContentsMargins(0, 0, 0, 0);
111 myGroupBox = new QWidget(aContainer);
112 QGridLayout* aGroupLay = new QGridLayout(myGroupBox);
113 ModuleBase_Tools::adjustMargins(aGroupLay);
114 aGroupLay->setSpacing(4);
115 aGroupLay->setColumnStretch(1, 1);
117 aBoxLay->addWidget(myGroupBox);
118 aBoxLay->addStretch(1);
120 myScrollArea->setWidget(aContainer);
122 myWidgetValidator = new ModuleBase_WidgetValidator(this, myWorkshop);
123 myExternalObjectMgr = new PartSet_ExternalObjectsMgr(theData->getProperty("use_external"),
124 theData->getProperty("can_create_external"), true);
127 void PartSet_WidgetBSplinePoints::createNextPoint()
131 QGridLayout* aGroupLay = dynamic_cast<QGridLayout*>(myGroupBox->layout());
132 int row = (int)myXSpin.size();
134 QString aPoleStr = translate("Pole %1");
135 aPoleStr = aPoleStr.arg(myXSpin.size() + 1);
137 QGroupBox* aPoleGroupBox = new QGroupBox(aPoleStr, myGroupBox);
138 QGridLayout* aPoleLay = new QGridLayout(aPoleGroupBox);
139 ModuleBase_Tools::adjustMargins(aPoleLay);
140 aPoleLay->setSpacing(2);
141 aPoleLay->setColumnStretch(1, 1);
143 myXSpin.push_back(new ModuleBase_LabelValue(aPoleGroupBox, tr("X")));
144 aPoleLay->addWidget(myXSpin.back(), 0, 1);
145 myYSpin.push_back(new ModuleBase_LabelValue(aPoleGroupBox, tr("Y")));
146 aPoleLay->addWidget(myYSpin.back(), 1, 1);
148 aGroupLay->addWidget(aPoleGroupBox, row, 1);
149 IsPointCreated = true;
152 void PartSet_WidgetBSplinePoints::removeLastPoint()
154 QGridLayout* aGroupLay = dynamic_cast<QGridLayout*>(myGroupBox->layout());
155 QWidget* aXSpin = myXSpin.back();
156 QWidget* aYSpin = myYSpin.back();
157 QWidget* aBox = myXSpin.back()->parentWidget();
161 aGroupLay->removeWidget(aXSpin);
162 aGroupLay->removeWidget(aYSpin);
163 aGroupLay->removeWidget(aBox);
167 // update B-spline feature attributes
171 bool PartSet_WidgetBSplinePoints::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr& theValue)
173 PartSet_Module* aModule = dynamic_cast<PartSet_Module*>(myWorkshop->module());
174 if (aModule->sketchReentranceMgr()->isInternalEditActive())
175 return true; // when internal edit is started a new feature is created. I has not results, AIS
177 // the selection is not possible if the current feature has no presentation for the current
178 // attribute not in AIS not in results. If so, no object in current feature where make
179 // coincidence, so selection is not necessary
180 GeomShapePtr anAISShape;
181 GeomPresentablePtr aPrs = std::dynamic_pointer_cast<GeomAPI_IPresentable>(myFeature);
184 anAIS = aPrs->getAISObject(anAIS);
186 anAISShape = anAIS->getShape();
189 const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = myFeature->results();
190 if (!anAISShape.get() && aResults.empty())
193 AttributeRefAttrListPtr aRefAttrList = attributeRefAttrList();
195 return isValidSelectionForAttribute_(theValue, myFeature->attribute(attributeID()));
199 bool PartSet_WidgetBSplinePoints::isValidSelectionForAttribute_(
200 const ModuleBase_ViewerPrsPtr& theValue,
201 const AttributePtr& theAttribute)
205 // stores the current values of the widget attribute
206 bool isFlushesActived, isAttributeSetInitializedBlocked, isAttributeSendUpdatedBlocked;
208 AttributeRefAttrListPtr aRefAttrList = attributeRefAttrList();
209 ModuleBase_WidgetValidated::blockFeatureAttribute(aRefAttrList, myFeature, true,
210 isFlushesActived, isAttributeSetInitializedBlocked, isAttributeSendUpdatedBlocked);
211 myWidgetValidator->storeAttributeValue(aRefAttrList);
213 // saves the owner value to the widget attribute
214 aValid = setSelectionCustom(theValue);
216 // checks the attribute validity
217 aValid = myWidgetValidator->isValidAttribute(theAttribute);
219 // restores the current values of the widget attribute
220 myWidgetValidator->restoreAttributeValue(aRefAttrList, aValid);
221 myExternalObjectMgr->removeExternal(sketch(), myFeature, myWorkshop, true);
223 ModuleBase_WidgetValidated::blockFeatureAttribute(aRefAttrList, myFeature, false,
224 isFlushesActived, isAttributeSetInitializedBlocked, isAttributeSendUpdatedBlocked);
228 bool PartSet_WidgetBSplinePoints::setSelectionCustom(const ModuleBase_ViewerPrsPtr& theValue)
231 GeomShapePtr aShape = theValue->shape();
232 if (aShape.get() && !aShape->isNull()) {
233 Handle(V3d_View) aView = myWorkshop->viewer()->activeView();
234 const TopoDS_Shape& aTDShape = aShape->impl<TopoDS_Shape>();
235 GeomPnt2dPtr aPnt = PartSet_Tools::getPnt2d(aView, aTDShape, mySketch);
237 fillRefAttribute(aPnt, theValue);
240 else if (aTDShape.ShapeType() == TopAbs_EDGE) {
241 fillRefAttribute(theValue);
248 static void fillLabels(std::vector<ModuleBase_LabelValue*>& theLabels, const double theValue)
250 for (std::vector<ModuleBase_LabelValue*>::iterator anIt = theLabels.begin();
251 anIt != theLabels.end(); ++anIt)
252 (*anIt)->setValue(theValue);
255 bool PartSet_WidgetBSplinePoints::resetCustom()
258 if (!isUseReset() || isComputedDefault())
261 if (myValueIsCashed) {
262 // if the restored value should be hidden, aDone = true to set
263 // reset state for the widget in the parent
264 aDone = restoreCurentValue();
265 emit objectUpdated();
268 // it is important to block the spin box control in order to do not through out the
269 // locking of the validating state.
270 fillLabels(myXSpin, 0.0);
271 fillLabels(myYSpin, 0.0);
280 PartSet_WidgetBSplinePoints::~PartSet_WidgetBSplinePoints()
282 delete myExternalObjectMgr;
285 bool PartSet_WidgetBSplinePoints::setPoint(double theX, double theY)
287 if (fabs(theX) >= MaxCoordinate || fabs(theY) >= MaxCoordinate)
290 myXSpin.back()->setValue(theX);
291 myYSpin.back()->setValue(theY);
297 void PartSet_WidgetBSplinePoints::storePolesAndWeights() const
299 std::shared_ptr<ModelAPI_Data> aData = myFeature->data();
300 AttributePoint2DArrayPtr aPointArray = std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(
301 aData->attribute(attributeID()));
302 AttributeDoubleArrayPtr aWeightsArray = aData->realArray(myWeightsAttr);
304 int aSize = (int)myXSpin.size();
305 aPointArray->setSize(aSize);
306 aWeightsArray->setSize(aSize);
308 std::vector<ModuleBase_LabelValue*>::const_iterator aXIt = myXSpin.begin();
309 std::vector<ModuleBase_LabelValue*>::const_iterator aYIt = myYSpin.begin();
310 for (int anIndex = 0; aXIt != myXSpin.end() && aYIt != myYSpin.end(); ++anIndex, ++aXIt, ++aYIt)
311 aPointArray->setPnt(anIndex, (*aXIt)->value(), (*aYIt)->value());
313 double aWeight = Config_PropManager::real(SKETCH_TAB_NAME, "spline_weight");
314 for (int anIndex = 0; anIndex < aSize; ++anIndex)
315 aWeightsArray->setValue(anIndex, aWeight);
318 bool PartSet_WidgetBSplinePoints::storeValueCustom()
320 std::shared_ptr<ModelAPI_Data> aData = myFeature->data();
321 if (!aData || !aData->isValid()) // can be on abort of sketcher element
323 AttributePoint2DArrayPtr aPointArray = std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(
324 aData->attribute(attributeID()));
325 AttributeDoubleArrayPtr aWeightsArray = aData->realArray(myWeightsAttr);
327 PartSet_WidgetBSplinePoints* that = (PartSet_WidgetBSplinePoints*) this;
328 bool isBlocked = that->blockSignals(true);
329 bool isImmutable = aPointArray->setImmutable(true);
331 if (myFeature->isMacro()) {
332 // Moving points of macro-features has been processed directly (without solver)
333 storePolesAndWeights();
334 updateObject(myFeature);
337 if (!aPointArray->isInitialized()) {
338 storePolesAndWeights();
341 std::shared_ptr<ModelAPI_ObjectMovedMessage> aMessage(
342 new ModelAPI_ObjectMovedMessage(this));
343 aMessage->setMovedAttribute(aPointArray, aPointArray->size() - 1);
344 aMessage->setOriginalPosition(aPointArray->pnt(aPointArray->size() - 1));
345 aMessage->setCurrentPosition(myXSpin.back()->value(), myYSpin.back()->value());
346 Events_Loop::loop()->send(aMessage);
349 aPointArray->setImmutable(isImmutable);
350 that->blockSignals(isBlocked);
355 bool PartSet_WidgetBSplinePoints::restoreValueCustom()
357 std::shared_ptr<ModelAPI_Data> aData = myFeature->data();
358 AttributePoint2DArrayPtr aPointArray = std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(
359 aData->attribute(attributeID()));
360 AttributeDoubleArrayPtr aWeightsArray = aData->realArray(myWeightsAttr);
362 if (aPointArray->isInitialized()) {
363 while ((int)myXSpin.size() < aPointArray->size())
366 std::vector<ModuleBase_LabelValue*>::iterator aXIt = myXSpin.begin();
367 std::vector<ModuleBase_LabelValue*>::iterator aYIt = myYSpin.begin();
368 for (int anIndex = 0; aXIt != myXSpin.end() && aYIt != myYSpin.end();
369 ++anIndex, ++aXIt, ++aYIt) {
370 GeomPnt2dPtr aPoint = aPointArray->pnt(anIndex);
371 (*aXIt)->setValue(aPoint->x());
372 (*aYIt)->setValue(aPoint->y());
379 myXSpin.back()->setValue(0.0);
380 myYSpin.back()->setValue(0.0);
386 static void storeArray(const std::vector<ModuleBase_LabelValue*>& theLabels,
387 std::vector<double>& theValues)
390 theValues.reserve(theLabels.size());
391 for (std::vector<ModuleBase_LabelValue*>::const_iterator anIt = theLabels.begin();
392 anIt != theLabels.end(); ++anIt)
393 theValues.push_back((*anIt)->value());
396 void PartSet_WidgetBSplinePoints::storeCurentValue()
398 myValueIsCashed = true;
399 myIsFeatureVisibleInCash = XGUI_Displayer::isVisible(
400 XGUI_Tools::workshop(myWorkshop)->displayer(), myFeature);
402 storeArray(myXSpin, myXValueInCash);
403 storeArray(myYSpin, myYValueInCash);
406 static void restoreArray(std::vector<double>& theCacheValues,
407 std::vector<ModuleBase_LabelValue*>& theLabels)
409 std::vector<double>::iterator aCIt = theCacheValues.begin();
410 std::vector<ModuleBase_LabelValue*>::iterator anIt = theLabels.begin();
411 for (; anIt != theLabels.end(); ++anIt) {
412 if (aCIt != theCacheValues.end())
413 (*anIt)->setValue(*aCIt++);
415 (*anIt)->setValue(0.0);
417 theCacheValues.clear();
420 bool PartSet_WidgetBSplinePoints::restoreCurentValue()
422 bool aRestoredAndHidden = true;
424 bool isVisible = myIsFeatureVisibleInCash;
426 myValueIsCashed = false;
427 myIsFeatureVisibleInCash = true;
428 // fill the control widgets by the cashed value
429 restoreArray(myXValueInCash, myXSpin);
430 restoreArray(myYValueInCash, myYSpin);
432 // store value to the model
435 setValueState(Stored);
436 aRestoredAndHidden = false;
439 aRestoredAndHidden = true;
441 return aRestoredAndHidden;
444 QList<QWidget*> PartSet_WidgetBSplinePoints::getControls() const
446 QList<QWidget*> aControls;
447 aControls.append(myScrollArea);
451 void PartSet_WidgetBSplinePoints::selectionModes(int& theModuleSelectionModes, QIntList& theModes)
453 theModuleSelectionModes = -1;
454 theModes << TopAbs_VERTEX;
455 theModes << TopAbs_EDGE;
458 void PartSet_WidgetBSplinePoints::deactivate()
460 // the value of the control should be stored to model if it was not
461 // initialized yet. It is important when we leave this control by Tab key.
462 // It should not be performed by the widget activation as the preview
463 // is visualized with default value. Line point is moved to origin.
464 AttributePtr anAttribute = myFeature->data()->attribute(attributeID());
465 if (anAttribute && !anAttribute->isInitialized())
468 ModuleBase_ModelWidget::deactivate();
471 void PartSet_WidgetBSplinePoints::mouseReleased(ModuleBase_IViewWindow* theWindow,
472 QMouseEvent* theEvent)
474 // the contex menu release by the right button should not be processed by this widget
475 if (theEvent->button() != Qt::LeftButton)
478 ModuleBase_ISelection* aSelection = myWorkshop->selection();
479 Handle(V3d_View) aView = theWindow->v3dView();
481 QList<ModuleBase_ViewerPrsPtr> aList = aSelection->getSelected(ModuleBase_ISelection::Viewer);
482 ModuleBase_ViewerPrsPtr aFirstValue =
483 aList.size() > 0 ? aList.first() : ModuleBase_ViewerPrsPtr();
484 if (!aFirstValue.get() && myPreSelected.get()) {
485 aFirstValue = myPreSelected;
488 TopoDS_Shape aSelectedShape;
489 ObjectPtr aSelectedObject;
491 // if we have selection and use it
492 if (aFirstValue.get() && isValidSelectionCustom(aFirstValue) &&
493 aFirstValue->shape().get()) { // Trihedron Axis may be selected, but shape is empty
494 GeomShapePtr aGeomShape = aFirstValue->shape();
495 aSelectedShape = aGeomShape->impl<TopoDS_Shape>();
496 aSelectedObject = aFirstValue->object();
498 FeaturePtr aSelectedFeature = ModelAPI_Feature::feature(aSelectedObject);
499 std::shared_ptr<SketchPlugin_Feature> aSPFeature;
500 if (aSelectedFeature.get())
501 aSPFeature = std::dynamic_pointer_cast<SketchPlugin_Feature>(aSelectedFeature);
503 bool isSketchExternalFeature = aSPFeature.get() && aSPFeature->isExternal();
504 if ((!aSPFeature && !aSelectedShape.IsNull()) || isSketchExternalFeature) {
505 ObjectPtr aFixedObject =
506 PartSet_Tools::findFixedObjectByExternal(aSelectedShape, aSelectedObject, mySketch);
508 aSelectedObject = aFixedObject;
509 else if (!isSketchExternalFeature) {
510 FeaturePtr aCreatedFeature;
511 aSelectedObject = PartSet_Tools::createFixedObjectByExternal(
512 aGeomShape, aSelectedObject, mySketch, false, aCreatedFeature);
516 // The selection could be a center of an external circular object
517 else if (aFirstValue.get() && (!aFirstValue->interactive().IsNull())) {
518 Handle(PartSet_CenterPrs) aAIS =
519 Handle(PartSet_CenterPrs)::DownCast(aFirstValue->interactive());
520 if (!aAIS.IsNull()) {
521 gp_Pnt aPntComp = aAIS->Component()->Pnt();
522 GeomVertexPtr aVertPtr(new GeomAPI_Vertex(aPntComp.X(), aPntComp.Y(), aPntComp.Z()));
523 aSelectedShape = aVertPtr->impl<TopoDS_Shape>();
526 PartSet_Tools::findFixedObjectByExternal(aSelectedShape, aAIS->object(), mySketch);
527 if (!aSelectedObject.get())
529 FeaturePtr aCreatedFeature;
530 aSelectedObject = PartSet_Tools::createFixedByExternalCenter(aAIS->object(), aAIS->edge(),
531 aAIS->centerType(), mySketch, false, aCreatedFeature);
536 GeomPnt2dPtr aSelectedPoint = PartSet_Tools::getPnt2d(aView, aSelectedShape, mySketch);
537 if (!aSelectedPoint) {
538 aSelectedPoint = PartSet_Tools::getPnt2d(theEvent, theWindow, mySketch);
539 setValueState(Stored); // in case of edge selection, Apply state should also be updated
542 fillRefAttribute(aSelectedObject);
544 fillRefAttribute(aSelectedPoint, aFirstValue);
546 // next pole of B-spline
550 void PartSet_WidgetBSplinePoints::mouseMoved(ModuleBase_IViewWindow* theWindow,
551 QMouseEvent* theEvent)
553 PartSet_Module* aModule = dynamic_cast<PartSet_Module*>(myWorkshop->module());
555 if (myFinished || isEditingMode() || aModule->sketchReentranceMgr()->isInternalEditActive())
558 gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView());
560 double aX = 0, aY = 0;
561 PartSet_Tools::convertTo2D(aPoint, mySketch, theWindow->v3dView(), aX, aY);
562 if (myState != ModifiedInViewer)
564 // we need to block the value state change
565 bool isBlocked = blockValueState(true);
567 blockValueState(isBlocked);
568 setValueState(ModifiedInViewer);
570 if (IsPointCreated) {
571 QPoint aPnt = myGroupBox->geometry().bottomLeft();
572 myScrollArea->ensureVisible(aPnt.x(), aPnt.y());
573 IsPointCreated = false;
577 bool PartSet_WidgetBSplinePoints::processEscape()
579 bool isProcessed = !isEditingMode();
581 // remove widgets corrsponding to the last pole/weight of B-spline
585 emit focusOutWidget(this);
590 bool PartSet_WidgetBSplinePoints::useSelectedShapes() const
595 AttributeRefAttrListPtr PartSet_WidgetBSplinePoints::attributeRefAttrList() const
597 if (myRefAttribute.empty())
598 return AttributeRefAttrListPtr();
600 AttributePtr anAttributeRef = feature()->attribute(myRefAttribute);
601 if (!anAttributeRef.get())
602 return AttributeRefAttrListPtr();
604 return std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(anAttributeRef);
607 void PartSet_WidgetBSplinePoints::fillRefAttribute(GeomPnt2dPtr theClickedPoint,
608 const std::shared_ptr<ModuleBase_ViewerPrs>& theValue)
610 AttributeRefAttrListPtr aRefAttrList = attributeRefAttrList();
611 if (!aRefAttrList.get())
614 FeaturePtr aFeature = feature();
615 std::string anAttribute = attributeID();
617 if (aFeature.get()) {
618 AttributePoint2DPtr aClickedFeaturePoint =
619 PartSet_WidgetPoint2D::findFirstEqualPointInSketch(mySketch, aFeature, theClickedPoint);
620 if (aClickedFeaturePoint.get())
621 aRefAttrList->append(aClickedFeaturePoint);
623 fillRefAttribute(theValue);
627 void PartSet_WidgetBSplinePoints::fillRefAttribute(const ModuleBase_ViewerPrsPtr& theValue)
631 anObject = getGeomSelection(theValue);
632 fillRefAttribute(anObject);
635 void PartSet_WidgetBSplinePoints::fillRefAttribute(const ObjectPtr& theObject)
637 AttributeRefAttrListPtr aRefAttrList = attributeRefAttrList();
638 if (aRefAttrList.get())
639 aRefAttrList->append(theObject);
642 ObjectPtr PartSet_WidgetBSplinePoints::getGeomSelection(const ModuleBase_ViewerPrsPtr& theValue)
646 ModuleBase_ISelection* aSelection = myWorkshop->selection();
647 anObject = aSelection->getResult(theValue);
648 aShape = aSelection->getShape(theValue);
649 myExternalObjectMgr->getGeomSelection(theValue, anObject, aShape, myWorkshop, sketch(), true);