X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_WidgetPoint2d.cpp;h=9af640db2587e46b0a5c021e4e1fb6771aea32e0;hb=4a056c17b0d629e17c0825c38014255dedec5c3c;hp=813741c88172a86b3a5f9ead67acb576d3b80bfc;hpb=2214a01e99079a3bfb6d8f15393f0bb870dd0958;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_WidgetPoint2d.cpp b/src/PartSet/PartSet_WidgetPoint2d.cpp index 813741c88..9af640db2 100644 --- a/src/PartSet/PartSet_WidgetPoint2d.cpp +++ b/src/PartSet/PartSet_WidgetPoint2d.cpp @@ -1,12 +1,29 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: PartSet_WidgetPoint2D.cpp -// Created: 25 Apr 2014 -// Author: Natalia ERMOLAEVA +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// #include "PartSet_WidgetPoint2d.h" #include #include +#include +#include +#include #include #include @@ -17,13 +34,22 @@ #include #include #include +#include +#include +#include +#include #include #include #include +#include #include #include +#include +#include +#include +#include #include #include @@ -31,6 +57,9 @@ #include #include +#include +#include + #include #include #include @@ -48,6 +77,7 @@ #include #include #include +#include #include #include @@ -56,14 +86,14 @@ const double MaxCoordinate = 1e12; static QStringList MyFeaturesForCoincedence; -PartSet_WidgetPoint2D::PartSet_WidgetPoint2D(QWidget* theParent, +PartSet_WidgetPoint2D::PartSet_WidgetPoint2D(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop, - const Config_WidgetAPI* theData, - const std::string& theParentId) -: ModuleBase_ModelWidget(theParent, theData, theParentId), myWorkshop(theWorkshop), + const Config_WidgetAPI* theData) +: ModuleBase_ModelWidget(theParent, theData), myWorkshop(theWorkshop), myValueIsCashed(false), myIsFeatureVisibleInCash(true), myXValueInCash(0), myYValueInCash(0) { + myRefAttribute = theData->getProperty("reference_attribute"); if (MyFeaturesForCoincedence.isEmpty()) { MyFeaturesForCoincedence << SketchPlugin_Line::ID().c_str() << SketchPlugin_Arc::ID().c_str() @@ -73,7 +103,6 @@ PartSet_WidgetPoint2D::PartSet_WidgetPoint2D(QWidget* theParent, // the control should accept the focus, so the boolean flag is corrected to be true myIsObligatory = true; - //myOptionParam = theData->getProperty(PREVIOUS_FEATURE_PARAM); QString aPageName = QString::fromStdString(theData->getProperty(CONTAINER_PAGE_NAME)); myGroupBox = new QGroupBox(aPageName, theParent); myGroupBox->setFlat(false); @@ -86,42 +115,154 @@ PartSet_WidgetPoint2D::PartSet_WidgetPoint2D(QWidget* theParent, aGroupLay->setColumnStretch(1, 1); { QLabel* aLabel = new QLabel(myGroupBox); - aLabel->setText(tr("X ")); - aGroupLay->addWidget(aLabel, 0, 0); - - myXSpin = new ModuleBase_ParamSpinBox(myGroupBox); - myXSpin->setAcceptVariables(aAcceptVariables); - myXSpin->setMinimum(-DBL_MAX); - myXSpin->setMaximum(DBL_MAX); - myXSpin->setToolTip(tr("X")); + + myXSpin = new ModuleBase_LabelValue(myGroupBox, tr("X")); + //ModuleBase_ParamSpinBox(myGroupBox); + //myXSpin->setAcceptVariables(aAcceptVariables); + //myXSpin->setMinimum(-DBL_MAX); + //myXSpin->setMaximum(DBL_MAX); + //myXSpin->setToolTip(tr("X")); aGroupLay->addWidget(myXSpin, 0, 1); - connect(myXSpin, SIGNAL(valueChanged(const QString&)), this, SIGNAL(valuesModified())); + //connect(myXSpin, SIGNAL(textChanged(const QString&)), this, SIGNAL(valuesModified())); + //myXSpin->setValueEnabled(isValueEnabled()); } { - QLabel* aLabel = new QLabel(myGroupBox); - aLabel->setText(tr("Y ")); - aGroupLay->addWidget(aLabel, 1, 0); - - myYSpin = new ModuleBase_ParamSpinBox(myGroupBox); - myYSpin->setAcceptVariables(aAcceptVariables); - myYSpin->setMinimum(-DBL_MAX); - myYSpin->setMaximum(DBL_MAX); - myYSpin->setToolTip(tr("Y")); + //QLabel* aLabel = new QLabel(myGroupBox); + //aLabel->setText(tr("Y ")); + //aGroupLay->addWidget(aLabel, 1, 0); + + myYSpin = new ModuleBase_LabelValue(myGroupBox, tr("Y")); + //ModuleBase_ParamSpinBox(myGroupBox); + //myYSpin = new ModuleBase_ParamSpinBox(myGroupBox); + //myYSpin->setAcceptVariables(aAcceptVariables); + //myYSpin->setMinimum(-DBL_MAX); + //myYSpin->setMaximum(DBL_MAX); + //myYSpin->setToolTip(tr("Y")); aGroupLay->addWidget(myYSpin, 1, 1); - connect(myYSpin, SIGNAL(valueChanged(const QString&)), this, SIGNAL(valuesModified())); + //connect(myYSpin, SIGNAL(textChanged(const QString&)), this, SIGNAL(valuesModified())); + //myYSpin->setValueEnabled(isValueEnabled()); } QVBoxLayout* aLayout = new QVBoxLayout(this); ModuleBase_Tools::zeroMargins(aLayout); aLayout->addWidget(myGroupBox); setLayout(aLayout); + + myWidgetValidator = new ModuleBase_WidgetValidator(this, myWorkshop); + myExternalObjectMgr = new PartSet_ExternalObjectsMgr(theData->getProperty("use_external"), + theData->getProperty("can_create_external"), true); +} + +bool PartSet_WidgetPoint2D::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr& theValue) +{ + bool aValid = true; + + PartSet_Module* aModule = dynamic_cast(myWorkshop->module()); + if (aModule->sketchReentranceMgr()->isInternalEditActive()) + return true; /// when internal edit is started a new feature is created. I has not results, AIS + + /// the selection is not possible if the current feature has no presentation for the current + /// attribute not in AIS not in results. If so, no object in current feature where make + /// coincidence, so selection is not necessary + GeomShapePtr anAISShape; + GeomPresentablePtr aPrs = std::dynamic_pointer_cast(myFeature); + if (aPrs.get()) { + AISObjectPtr anAIS; + anAIS = aPrs->getAISObject(anAIS); + if (anAIS.get()) { + anAISShape = anAIS->getShape(); + } + } + const std::list >& aResults = myFeature->results(); + if (!anAISShape.get() && aResults.empty()) + return true; + + AttributeRefAttrPtr aRefAttr = attributeRefAttr(); + if (aRefAttr.get()) + return isValidSelectionForAttribute_(theValue, myFeature->attribute(attributeID())); + else { + bool aFoundPoint = false; + /// Avoid coincidence build to passed point. Coincidence is build later only if there are no + /// reference attribute. + /// The condition is that the selected feature has shape that has after explore a point + /// equal to clicked one. + std::shared_ptr aData = myFeature->data(); + AttributePoint2DPtr aPointAttr = std::dynamic_pointer_cast( + aData->attribute(attributeID())); + std::shared_ptr aPoint = aPointAttr->pnt(); + if (anAISShape.get()) + aFoundPoint = shapeExploreHasVertex(anAISShape, aPoint, mySketch); + + /// analysis of results + std::list >::const_iterator aRIter = aResults.cbegin(); + for (; aRIter != aResults.cend() && !aFoundPoint; aRIter++) { + ResultPtr aResult = *aRIter; + if (aResult.get() && aResult->shape().get()) { + GeomShapePtr aShape = aResult->shape(); + aFoundPoint = shapeExploreHasVertex(aShape, aPoint, mySketch); + } + } + return aFoundPoint; + } + return true; +} + +//******************************************************************** +bool PartSet_WidgetPoint2D::isValidSelectionForAttribute_( + const ModuleBase_ViewerPrsPtr& theValue, + const AttributePtr& theAttribute) +{ + bool aValid = false; + + // stores the current values of the widget attribute + bool isFlushesActived, isAttributeSetInitializedBlocked, isAttributeSendUpdatedBlocked; + + AttributeRefAttrPtr aRefAttr = attributeRefAttr(); + ModuleBase_WidgetValidated::blockFeatureAttribute(aRefAttr, myFeature, true, + isFlushesActived, isAttributeSetInitializedBlocked, isAttributeSendUpdatedBlocked); + myWidgetValidator->storeAttributeValue(aRefAttr); + + // saves the owner value to the widget attribute + aValid = setSelectionCustom(theValue); + if (aValid) + // checks the attribute validity + aValid = myWidgetValidator->isValidAttribute(theAttribute); + + // restores the current values of the widget attribute + myWidgetValidator->restoreAttributeValue(aRefAttr, aValid); + myExternalObjectMgr->removeExternal(sketch(), myFeature, myWorkshop, true); + + ModuleBase_WidgetValidated::blockFeatureAttribute(aRefAttr, myFeature, false, isFlushesActived, + isAttributeSetInitializedBlocked, isAttributeSendUpdatedBlocked); + return aValid; +} + +bool PartSet_WidgetPoint2D::setSelectionCustom(const ModuleBase_ViewerPrsPtr& theValue) +{ + bool isDone = false; + GeomShapePtr aShape = theValue->shape(); + if (aShape.get() && !aShape->isNull()) { + Handle(V3d_View) aView = myWorkshop->viewer()->activeView(); + double aX = 0, aY = 0; + const TopoDS_Shape& aTDShape = aShape->impl(); + if (getPoint2d(aView, aTDShape, aX, aY)) { + fillRefAttribute(aX, aY, theValue); + isDone = true; + } + else if (aTDShape.ShapeType() == TopAbs_EDGE) { + fillRefAttribute(theValue); + isDone = true; + } + } + return isDone; } bool PartSet_WidgetPoint2D::resetCustom() { bool aDone = false; - if (!isUseReset() || isComputedDefault() || myXSpin->hasVariable() || myYSpin->hasVariable()) { + if (!isUseReset() || isComputedDefault() + /*|| myXSpin->hasVariable() || myYSpin->hasVariable()*/) { aDone = false; } else { @@ -129,14 +270,18 @@ bool PartSet_WidgetPoint2D::resetCustom() // if the restored value should be hidden, aDone = true to set // reset state for the widget in the parent aDone = restoreCurentValue(); + emit objectUpdated(); } else { bool isOk; double aDefValue = QString::fromStdString(getDefaultValue()).toDouble(&isOk); // it is important to block the spin box control in order to do not through out the // locking of the validating state. - ModuleBase_Tools::setSpinValue(myXSpin, isOk ? aDefValue : 0.0); - ModuleBase_Tools::setSpinValue(myYSpin, isOk ? aDefValue : 0.0); + myXSpin->setValue(isOk ? aDefValue : 0.0); + myYSpin->setValue(isOk ? aDefValue : 0.0); + + //ModuleBase_Tools::setSpinValue(myXSpin, isOk ? aDefValue : 0.0); + //ModuleBase_Tools::setSpinValue(myYSpin, isOk ? aDefValue : 0.0); storeValueCustom(); aDone = true; } @@ -146,40 +291,27 @@ bool PartSet_WidgetPoint2D::resetCustom() PartSet_WidgetPoint2D::~PartSet_WidgetPoint2D() { + delete myExternalObjectMgr; } -bool PartSet_WidgetPoint2D::setSelection(QList& theValues, +bool PartSet_WidgetPoint2D::setSelection(QList& theValues, const bool theToValidate) { bool isDone = false; if (theValues.empty()) return isDone; - ModuleBase_ViewerPrs aValue = theValues.takeFirst(); - TopoDS_Shape aShape = aValue.shape(); - if (!aShape.IsNull()) { - Handle(V3d_View) aView = myWorkshop->viewer()->activeView(); - double aX, aY; - if (getPoint2d(aView, aShape, aX, aY)) { - isDone = setPoint(aX, aY); - PartSet_Tools::setConstraints(mySketch, feature(), attributeID(), aX, aY); - } - } - else if (canBeActivatedByMove()) { - if (feature()->getKind() == SketchPlugin_Line::ID()) { - FeaturePtr aFeature = std::dynamic_pointer_cast(aValue.object()); - // Initialize new line with first point equal to end of previous - if (aFeature.get()) { - std::shared_ptr aData = aFeature->data(); - std::shared_ptr aPoint = - std::dynamic_pointer_cast( - aData->attribute(SketchPlugin_Line::END_ID())); - if (aPoint) { - setPoint(aPoint->x(), aPoint->y()); - PartSet_Tools::setConstraints(mySketch, feature(), attributeID(), aPoint->x(), - aPoint->y()); - isDone = true; - } + ModuleBase_ViewerPrsPtr aValue = theValues.takeFirst(); + + if (!theToValidate || myWidgetValidator->isValidSelection(aValue)) { + GeomShapePtr aShape = aValue->shape(); + if (aShape.get() && !aShape->isNull()) { + Handle(V3d_View) aView = myWorkshop->viewer()->activeView(); + double aX = 0, aY = 0; + const TopoDS_Shape& aTDShape = aShape->impl(); + if (getPoint2d(aView, aTDShape, aX, aY)) { + isDone = setPoint(aX, aY); + setConstraintToPoint(aX, aY, aValue); } } } @@ -188,7 +320,7 @@ bool PartSet_WidgetPoint2D::setSelection(QList& theValues, void PartSet_WidgetPoint2D::selectContent() { - myXSpin->selectAll(); + // myXSpin->selectAll(); } bool PartSet_WidgetPoint2D::setPoint(double theX, double theY) @@ -198,19 +330,22 @@ bool PartSet_WidgetPoint2D::setPoint(double theX, double theY) if (fabs(theY) >= MaxCoordinate) return false; - ModuleBase_Tools::setSpinValue(myXSpin, theX); - ModuleBase_Tools::setSpinValue(myYSpin, theY); + myXSpin->setValue(theX); + myYSpin->setValue(theY); + + //ModuleBase_Tools::setSpinValue(myXSpin, theX); + //ModuleBase_Tools::setSpinValue(myYSpin, theY); storeValue(); return true; } -bool PartSet_WidgetPoint2D::storeValueCustom() const +bool PartSet_WidgetPoint2D::storeValueCustom() { std::shared_ptr aData = myFeature->data(); - if (!aData) // can be on abort of sketcher element + if (!aData || !aData->isValid()) // can be on abort of sketcher element return false; - std::shared_ptr aPoint = std::dynamic_pointer_cast( + AttributePoint2DPtr aPoint = std::dynamic_pointer_cast( aData->attribute(attributeID())); PartSet_WidgetPoint2D* that = (PartSet_WidgetPoint2D*) this; @@ -219,13 +354,28 @@ bool PartSet_WidgetPoint2D::storeValueCustom() const // if text is not empty then setValue will be ignored // so we should set the text at first - aPoint->setText(myXSpin->hasVariable() ? myXSpin->text().toStdString() : "", - myYSpin->hasVariable() ? myYSpin->text().toStdString() : ""); - aPoint->setValue(!myXSpin->hasVariable() ? myXSpin->value() : aPoint->x(), - !myYSpin->hasVariable() ? myYSpin->value() : aPoint->y()); + //aPoint->setText(myXSpin->hasVariable() ? myXSpin->text().toStdString() : "", + // myYSpin->hasVariable() ? myYSpin->text().toStdString() : ""); + //aPoint->setValue(!myXSpin->hasVariable() ? myXSpin->value() : aPoint->x(), + // !myYSpin->hasVariable() ? myYSpin->value() : aPoint->y()); + + if (myFeature->isMacro()) { + // Moving points of macro-features has been processed directly (without solver) + aPoint->setValue(myXSpin->value(), myYSpin->value()); + updateObject(myFeature); + + } else { + if (!aPoint->isInitialized()) + aPoint->setValue(0., 0.); + + std::shared_ptr aMessage( + new ModelAPI_ObjectMovedMessage(this)); + aMessage->setMovedAttribute(aPoint); + aMessage->setOriginalPosition(aPoint->pnt()); + aMessage->setCurrentPosition(myXSpin->value(), myYSpin->value()); + Events_Loop::loop()->send(aMessage); + } - // after movement the solver will call the update event: optimization - moveObject(myFeature); aPoint->setImmutable(isImmutable); that->blockSignals(isBlocked); @@ -235,46 +385,21 @@ bool PartSet_WidgetPoint2D::storeValueCustom() const bool PartSet_WidgetPoint2D::restoreValueCustom() { std::shared_ptr aData = myFeature->data(); - std::shared_ptr aPoint = std::dynamic_pointer_cast( + AttributePoint2DPtr aPoint = std::dynamic_pointer_cast( aData->attribute(attributeID())); - QString aTextX = QString::fromStdString(aPoint->textX()); - QString aTextY = QString::fromStdString(aPoint->textY()); + double aValueX = aPoint->isInitialized() ? aPoint->x() : 0.; + double aValueY = aPoint->isInitialized() ? aPoint->y() : 0.; + myXSpin->setValue(aValueX); + myYSpin->setValue(aValueY); - bool isDouble = false; - double aVal = 0; - if (aTextX.isEmpty()) { - ModuleBase_Tools::setSpinValue(myXSpin, aPoint->x()); - } else { - aVal = aTextX.toDouble(&isDouble); - if (isDouble) - ModuleBase_Tools::setSpinValue(myXSpin, aVal); - else - ModuleBase_Tools::setSpinText(myXSpin, aTextX); - } - if (aTextY.isEmpty()) { - ModuleBase_Tools::setSpinValue(myYSpin, aPoint->y()); - } else { - aVal = aTextY.toDouble(&isDouble); - if (isDouble) - ModuleBase_Tools::setSpinValue(myYSpin, aVal); - else - ModuleBase_Tools::setSpinText(myYSpin, aTextY); - } - //if (aTextX.empty() || aTextY.empty()) { - // ModuleBase_Tools::setSpinValue(myXSpin, aPoint->x()); - // ModuleBase_Tools::setSpinValue(myYSpin, aPoint->y()); - //} else { - // ModuleBase_Tools::setSpinText(myXSpin, QString::fromStdString(aTextX)); - // ModuleBase_Tools::setSpinText(myYSpin, QString::fromStdString(aTextY)); - //} return true; } void PartSet_WidgetPoint2D::storeCurentValue() { // do not use cash if a variable is used - if (myXSpin->hasVariable() || myYSpin->hasVariable()) - return; + //if (myXSpin->hasVariable() || myYSpin->hasVariable()) + // return; myValueIsCashed = true; myIsFeatureVisibleInCash = XGUI_Displayer::isVisible( @@ -292,8 +417,10 @@ bool PartSet_WidgetPoint2D::restoreCurentValue() myValueIsCashed = false; myIsFeatureVisibleInCash = true; - ModuleBase_Tools::setSpinValue(myXSpin, myXValueInCash); - ModuleBase_Tools::setSpinValue(myYSpin, myYValueInCash); + myXSpin->setValue(myXValueInCash); + myYSpin->setValue(myYValueInCash); + //ModuleBase_Tools::setSpinValue(myXSpin, myXValueInCash); + //ModuleBase_Tools::setSpinValue(myYSpin, myYValueInCash); // store value to the model storeValueCustom(); @@ -315,20 +442,17 @@ QList PartSet_WidgetPoint2D::getControls() const return aControls; } +//******************************************************************** +void PartSet_WidgetPoint2D::selectionModes(int& theModuleSelectionModes, QIntList& theModes) +{ + theModuleSelectionModes = -1; + theModes << TopAbs_VERTEX; + theModes << TopAbs_EDGE; +} +//******************************************************************** void PartSet_WidgetPoint2D::activateCustom() { - ModuleBase_IViewer* aViewer = myWorkshop->viewer(); - connect(aViewer, SIGNAL(mouseMove(ModuleBase_IViewWindow*, QMouseEvent*)), - this, SLOT(onMouseMove(ModuleBase_IViewWindow*, QMouseEvent*))); - connect(aViewer, SIGNAL(mouseRelease(ModuleBase_IViewWindow*, QMouseEvent*)), - this, SLOT(onMouseRelease(ModuleBase_IViewWindow*, QMouseEvent*))); - - QIntList aModes; - aModes << TopAbs_VERTEX; - aModes << TopAbs_EDGE; - myWorkshop->activateSubShapesSelection(aModes); - if (!isEditingMode()) { FeaturePtr aFeature = feature(); if (aFeature.get() && aFeature->getKind() == SketchPlugin_Point::ID()) @@ -336,14 +460,8 @@ void PartSet_WidgetPoint2D::activateCustom() } } -bool PartSet_WidgetPoint2D::canBeActivatedByMove() +void PartSet_WidgetPoint2D::setHighlighted(bool isHighlighted) { - bool aCanBeActivated = false; - if (feature()->getKind() == SketchPlugin_Line::ID() && - attributeID() == SketchPlugin_Line::START_ID()) - aCanBeActivated = true; - - return aCanBeActivated; } void PartSet_WidgetPoint2D::deactivate() @@ -357,17 +475,10 @@ void PartSet_WidgetPoint2D::deactivate() storeValue(); ModuleBase_ModelWidget::deactivate(); - ModuleBase_IViewer* aViewer = myWorkshop->viewer(); - disconnect(aViewer, SIGNAL(mouseMove(ModuleBase_IViewWindow*, QMouseEvent*)), - this, SLOT(onMouseMove(ModuleBase_IViewWindow*, QMouseEvent*))); - disconnect(aViewer, SIGNAL(mouseRelease(ModuleBase_IViewWindow*, QMouseEvent*)), - this, SLOT(onMouseRelease(ModuleBase_IViewWindow*, QMouseEvent*))); - - myWorkshop->deactivateSubShapesSelection(); } -bool PartSet_WidgetPoint2D::getPoint2d(const Handle(V3d_View)& theView, - const TopoDS_Shape& theShape, +bool PartSet_WidgetPoint2D::getPoint2d(const Handle(V3d_View)& theView, + const TopoDS_Shape& theShape, double& theX, double& theY) const { if (!theShape.IsNull()) { @@ -384,108 +495,187 @@ bool PartSet_WidgetPoint2D::getPoint2d(const Handle(V3d_View)& theView, return false; } -void PartSet_WidgetPoint2D::setConstraintWith(const ObjectPtr& theObject) +bool PartSet_WidgetPoint2D::setConstraintToPoint(double theClickedX, double theClickedY, + const std::shared_ptr& theValue) { - std::shared_ptr aFeaturePoint; - if (feature()->isMacro()) { - AttributePtr aThisAttr = feature()->data()->attribute(attributeID()); - std::shared_ptr anAttrPoint = - std::dynamic_pointer_cast(aThisAttr); - if (anAttrPoint.get()) { + AttributeRefAttrPtr aRefAttr = attributeRefAttr(); + if (aRefAttr.get()) + fillRefAttribute(theClickedX, theClickedY, theValue); + else { + FeaturePtr aFeature = feature(); + std::string anAttribute = attributeID(); + + if (!aFeature.get()) + return false; + + std::shared_ptr aClickedPoint = std::shared_ptr( + new GeomAPI_Pnt2d(theClickedX, theClickedY)); + AttributePoint2DPtr aClickedFeaturePoint = findFirstEqualPointInSketch(mySketch, + aFeature, aClickedPoint); + if (!aClickedFeaturePoint.get()) + return false; + + // aRefAttr->setAttr(aClickedFeaturePoint); + //else { + // find a feature point by the selection mode + AttributePoint2DPtr aFeaturePoint; + if (aFeature->isMacro()) { // the macro feature will be removed after the operation is stopped, so we need to build // coicidence to possible sub-features - aFeaturePoint = PartSet_Tools::findFirstEqualPointInArgumentFeatures(feature(), - anAttrPoint->pnt()); + aFeaturePoint = findFirstEqualPointInArgumentFeatures(aFeature, aClickedPoint); + } + else { + aFeaturePoint = std::dynamic_pointer_cast< + GeomDataAPI_Point2D>(aFeature->data()->attribute(anAttribute)); } + if (!aFeaturePoint.get()) + return false; + + PartSet_Tools::createConstraint(mySketch, aClickedFeaturePoint, aFeaturePoint); } - else { - AttributePtr aThisAttr = feature()->data()->attribute(attributeID()); - aFeaturePoint = std::dynamic_pointer_cast(aThisAttr); + return true; +} + +bool PartSet_WidgetPoint2D::setConstraintToObject(const ObjectPtr& theObject) +{ + AttributeRefAttrPtr aRefAttr = attributeRefAttr(); + if (aRefAttr.get()) { + fillRefAttribute(theObject); } - if (!aFeaturePoint.get()) - return; + else { + AttributePoint2DPtr aFeaturePoint; + + if (feature()->isMacro()) { + AttributePtr aThisAttr = feature()->data()->attribute(attributeID()); + AttributePoint2DPtr anAttrPoint = std::dynamic_pointer_cast(aThisAttr); + if (anAttrPoint.get()) { + // the macro feature will be removed after the operation is stopped, so we need to build + // coicidence to possible sub-features + aFeaturePoint = findFirstEqualPointInArgumentFeatures(feature(), + anAttrPoint->pnt()); + } + } + else { + AttributePtr aThisAttr = feature()->data()->attribute(attributeID()); + aFeaturePoint = std::dynamic_pointer_cast(aThisAttr); + } + if (!aFeaturePoint.get()) + return false; - // Create point-edge coincedence - FeaturePtr aFeature = mySketch->addFeature(SketchPlugin_ConstraintCoincidence::ID()); - std::shared_ptr aData = aFeature->data(); + // Create point-edge coincedence + FeaturePtr aFeature = mySketch->addFeature(SketchPlugin_ConstraintCoincidence::ID()); + std::shared_ptr aData = aFeature->data(); - std::shared_ptr aRef1 = std::dynamic_pointer_cast< - ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_A())); + std::shared_ptr aRef1 = std::dynamic_pointer_cast< + ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_A())); - aRef1->setAttr(aFeaturePoint); + aRef1->setAttr(aFeaturePoint); - std::shared_ptr aRef2 = std::dynamic_pointer_cast< - ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_B())); - aRef2->setObject(theObject); + std::shared_ptr aRef2 = std::dynamic_pointer_cast< + ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_B())); + aRef2->setObject(theObject); - Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); + // we need to flush created signal in order to coincidence is processed by solver + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); + } + return true; } -void PartSet_WidgetPoint2D::onMouseRelease(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) +void PartSet_WidgetPoint2D::mouseReleased(ModuleBase_IViewWindow* theWindow, QMouseEvent* theEvent) { // the contex menu release by the right button should not be processed by this widget if (theEvent->button() != Qt::LeftButton) return; ModuleBase_ISelection* aSelection = myWorkshop->selection(); - Handle(V3d_View) aView = theWnd->v3dView(); - // TODO: This fragment doesn't work because bug in OCC Viewer. It can be used after fixing. - NCollection_List aShapes; - std::list aObjects; - aSelection->selectedShapes(aShapes, aObjects); + Handle(V3d_View) aView = theWindow->v3dView(); + + QList aList = aSelection->getSelected(ModuleBase_ISelection::Viewer); + ModuleBase_ViewerPrsPtr aFirstValue = + aList.size() > 0 ? aList.first() : ModuleBase_ViewerPrsPtr(); + if (!aFirstValue.get() && myPreSelected.get()) { + aFirstValue = myPreSelected; + } + // if we have selection and use it - if (aShapes.Extent() > 0 && useSelectedShapes()) { - TopoDS_Shape aShape = aShapes.First(); - ObjectPtr aObject = aObjects.front(); + if (aFirstValue.get() && isValidSelectionCustom(aFirstValue) && + aFirstValue->shape().get()) { /// Trihedron Axis may be selected, but shape is empty + GeomShapePtr aGeomShape = aFirstValue->shape(); + TopoDS_Shape aShape = aGeomShape->impl(); + ObjectPtr aObject = aFirstValue->object(); + FeaturePtr aSelectedFeature = ModelAPI_Feature::feature(aObject); bool anExternal = false; std::shared_ptr aSPFeature; if (aSelectedFeature.get() != NULL) aSPFeature = std::dynamic_pointer_cast(aSelectedFeature); - if ((!aSPFeature && !aShape.IsNull()) || - (aSPFeature.get() && aSPFeature->isExternal())) { - ResultPtr aFixedObject; + + ResultPtr aFixedObject; + bool aSketchExternalFeature = aSPFeature.get() && aSPFeature->isExternal(); + if ((!aSPFeature && !aShape.IsNull()) || aSketchExternalFeature) { + aFixedObject = PartSet_Tools::findFixedObjectByExternal(aShape, aObject, mySketch); + if (aSketchExternalFeature && !aFixedObject.get()) {/// local selection on external feature + anExternal = false; + } + else { anExternal = true; - aFixedObject = PartSet_Tools::findFixedObjectByExternal(aShape, aObject, mySketch); if (!aFixedObject.get()) - aFixedObject = PartSet_Tools::createFixedObjectByExternal(aShape, aObject, mySketch); - double aX, aY; - if (getPoint2d(aView, aShape, aX, aY) && isFeatureContainsPoint(myFeature, aX, aY)) { - // do not create a constraint to the point, which already used by the feature - // if the feature contains the point, focus is not switched - setPoint(aX, aY); + { + FeaturePtr aCreatedFeature; + aFixedObject = PartSet_Tools::createFixedObjectByExternal(aGeomShape, aObject, mySketch, + false, aCreatedFeature); } + } + } + if (anExternal) { + double aX = 0, aY = 0; + if (getPoint2d(aView, aShape, aX, aY) && isFeatureContainsPoint(myFeature, aX, aY)) { + // do not create a constraint to the point, which already used by the feature + // if the feature contains the point, focus is not switched + setPoint(aX, aY); + } + else { + if (getPoint2d(aView, aShape, aX, aY)) + setPoint(aX, aY); else { - if (getPoint2d(aView, aShape, aX, aY)) + if (aShape.ShapeType() == TopAbs_EDGE) { + // point is taken from mouse event and set in attribute. It should be done before set + // coinident constraint to the external line. If a point is created, it should be in + // the mouse clicked point + gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), + theWindow->v3dView()); + PartSet_Tools::convertTo2D(aPoint, mySketch, aView, aX, aY); setPoint(aX, aY); - else - setValueState(Stored); // in case of edge selection, Apply state should also be updated - bool anOrphanPoint = aShape.ShapeType() == TopAbs_VERTEX || - isOrphanPoint(aSelectedFeature, mySketch, aX, aY); - if (anExternal) { - anOrphanPoint = true; // we should not stop reentrant operation on external objects because - // they are not participate in the contour creation excepting external vertices - if (aShape.ShapeType() == TopAbs_VERTEX) { - FeaturePtr aFixedFeature = ModelAPI_Feature::feature(aFixedObject); - if (aFixedFeature.get() && aFixedFeature->getKind() == SketchPlugin_Point::ID()) { - anOrphanPoint = isOrphanPoint(aFixedFeature, mySketch, aX, aY, true); - } + } + setValueState(Stored); // in case of edge selection, Apply state should also be updated + } + bool anOrphanPoint = aShape.ShapeType() == TopAbs_VERTEX || + isOrphanPoint(aSelectedFeature, mySketch, aX, aY); + if (anExternal) { + // we should not stop reentrant operation on external objects because + anOrphanPoint = true; + // they are not participate in the contour creation excepting external vertices + if (aShape.ShapeType() == TopAbs_VERTEX) { + FeaturePtr aFixedFeature = ModelAPI_Feature::feature(aFixedObject); + if (aFixedFeature.get() && aFixedFeature->getKind() == SketchPlugin_Point::ID()) { + anOrphanPoint = isOrphanPoint(aFixedFeature, mySketch, aX, aY); } } - if (aFixedObject.get()) - setConstraintWith(aFixedObject); - // fignal updated should be flushed in order to visualize possible created external objects - // e.g. selection of trihedron axis when input end arc point - updateObject(feature()); + } + if (aFixedObject.get()) + setConstraintToObject(aFixedObject); + // fignal updated should be flushed in order to visualize possible created + // external objects e.g. selection of trihedron axis when input end arc point + updateObject(feature()); - if (!anOrphanPoint) - emit vertexSelected(); // it stops the reentrant operation + if (!anOrphanPoint) + emit vertexSelected(); // it stops the reentrant operation - emit focusOutWidget(this); - } + emit focusOutWidget(this); } + } if (!anExternal) { - double aX, aY; + double aX = 0, aY = 0; bool isProcessed = false; if (getPoint2d(aView, aShape, aX, aY) && isFeatureContainsPoint(myFeature, aX, aY)) { // when the point is selected, the coordinates of the point should be set into the attribute @@ -500,21 +690,20 @@ void PartSet_WidgetPoint2D::onMouseRelease(ModuleBase_IViewWindow* theWnd, QMous bool isAuxiliaryFeature = false; if (getPoint2d(aView, aShape, aX, aY)) { setPoint(aX, aY); - feature()->execute(); - PartSet_Tools::setConstraints(mySketch, feature(), attributeID(), aX, aY); + setConstraintToPoint(aX, aY, aFirstValue); } else if (aShape.ShapeType() == TopAbs_EDGE) { - setConstraintWith(aObject); + // point is taken from mouse event and set in attribute. It should be done before setting + // coinident constraint to the external line. If a point is created, it should be in + // the mouse clicked point + gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView()); + PartSet_Tools::convertTo2D(aPoint, mySketch, aView, aX, aY); + setPoint(aX, aY); + setConstraintToObject(aObject); setValueState(Stored); // in case of edge selection, Apply state should also be updated - - FeaturePtr anObjectFeature = ModelAPI_Feature::feature(aObject); - std::string anAuxiliaryAttribute = SketchPlugin_SketchEntity::AUXILIARY_ID(); - AttributeBooleanPtr anAuxiliaryAttr = std::dynamic_pointer_cast( - anObjectFeature->data()->attribute(anAuxiliaryAttribute)); - if (anAuxiliaryAttr.get()) - isAuxiliaryFeature = anAuxiliaryAttr->value(); + isAuxiliaryFeature = PartSet_Tools::isAuxiliarySketchEntity(aObject); } - // it is important to perform updateObject() in order to the current value is + // it is important to perform updateObject() in order to the current value is // processed by Sketch Solver. Test case: line is created from a previous point // to some distance, but in the area of the highlighting of the point. Constraint // coincidence is created, after the solver is performed, the distance between the @@ -527,51 +716,86 @@ void PartSet_WidgetPoint2D::onMouseRelease(ModuleBase_IViewWindow* theWnd, QMous } } } - // End of Bug dependent fragment + // The selection could be a center of an external circular object + else if (aFirstValue.get() && (!aFirstValue->interactive().IsNull())) { + Handle(PartSet_CenterPrs) aAIS = + Handle(PartSet_CenterPrs)::DownCast(aFirstValue->interactive()); + if (!aAIS.IsNull()) { + gp_Pnt aPntComp = aAIS->Component()->Pnt(); + GeomVertexPtr aVertPtr(new GeomAPI_Vertex(aPntComp.X(), aPntComp.Y(), aPntComp.Z())); + TopoDS_Shape aShape = aVertPtr->impl(); + + ResultPtr aFixedObject = + PartSet_Tools::findFixedObjectByExternal(aShape, aAIS->object(), mySketch); + if (!aFixedObject.get()) + { + FeaturePtr aCreatedFeature; + aFixedObject = PartSet_Tools::createFixedByExternalCenter(aAIS->object(), aAIS->edge(), + aAIS->centerType(), mySketch, false, aCreatedFeature); + } + if (aFixedObject.get()) + setConstraintToObject(aFixedObject); + // fignal updated should be flushed in order to visualize possible created + // external objects e.g. selection of trihedron axis when input end arc point + updateObject(feature()); + + double aX = 0, aY = 0; + if (getPoint2d(aView, aShape, aX, aY)) { + // do not create a constraint to the point, which already used by the feature + // if the feature contains the point, focus is not switched + setPoint(aX, aY); + } + emit vertexSelected(); // it stops the reentrant operation + emit focusOutWidget(this); + } + } else { // A case when point is taken from mouse event - gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWnd->v3dView()); - double aX, anY; - PartSet_Tools::convertTo2D(aPoint, mySketch, aView, aX, anY); + gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView()); + double aX = 0, aY = 0; + PartSet_Tools::convertTo2D(aPoint, mySketch, aView, aX, aY); // if the feature contains the point, focus is not switched - if (!setPoint(aX, anY) || isFeatureContainsPoint(myFeature, aX, anY)) + if (!setPoint(aX, aY) || isFeatureContainsPoint(myFeature, aX, aY)) return; - /// Start alternative code - //std::shared_ptr aFeaturePoint = std::dynamic_pointer_cast< - // GeomDataAPI_Point2D>(feature()->data()->attribute(attributeID())); - //QList aIgnore; - //aIgnore.append(feature()); - - //double aTolerance = aView->Convert(7); - //std::shared_ptr aAttrPnt = - // PartSet_Tools::findAttributePoint(mySketch, aX, anY, aTolerance, aIgnore); - //if (aAttrPnt.get() != NULL) { - // aFeaturePoint->setValue(aAttrPnt->pnt()); - // PartSet_Tools::createConstraint(mySketch, aAttrPnt, aFeaturePoint); - // emit vertexSelected(); - //} - /// End alternative code emit focusOutWidget(this); } } +void PartSet_WidgetPoint2D::setPreSelection( + const std::shared_ptr& thePreSelected, + ModuleBase_IViewWindow* theWnd, + QMouseEvent* theEvent) +{ + myPreSelected = thePreSelected; + mouseReleased(theWnd, theEvent); + myPreSelected = ModuleBase_ViewerPrsPtr(); +} + +void PartSet_WidgetPoint2D::getGeomSelection_(const std::shared_ptr& theValue, + ObjectPtr& theObject, + GeomShapePtr& theShape) +{ + myExternalObjectMgr->getGeomSelection(theValue, theObject, theShape, myWorkshop, sketch(), true); +} -void PartSet_WidgetPoint2D::onMouseMove(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) +void PartSet_WidgetPoint2D::mouseMoved(ModuleBase_IViewWindow* theWindow, QMouseEvent* theEvent) { - if (isEditingMode()) + PartSet_Module* aModule = dynamic_cast(myWorkshop->module()); + + if (isEditingMode() || aModule->sketchReentranceMgr()->isInternalEditActive()) return; - gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWnd->v3dView()); + gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView()); - double aX, anY; - PartSet_Tools::convertTo2D(aPoint, mySketch, theWnd->v3dView(), aX, anY); + double aX = 0, aY = 0; + PartSet_Tools::convertTo2D(aPoint, mySketch, theWindow->v3dView(), aX, aY); if (myState != ModifiedInViewer) storeCurentValue(); - // we need to block the value state change + // we need to block the value state change bool isBlocked = blockValueState(true); - setPoint(aX, anY); + setPoint(aX, aY); blockValueState(isBlocked); setValueState(ModifiedInViewer); } @@ -597,7 +821,7 @@ bool PartSet_WidgetPoint2D::isFeatureContainsPoint(const FeaturePtr& theFeature, AttributePtr aWidgetAttribute = myFeature->attribute(attributeID()); - std::shared_ptr aPnt2d = + std::shared_ptr aPnt2d = std::shared_ptr(new GeomAPI_Pnt2d(theX, theY)); std::list anAttributes = myFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); @@ -625,7 +849,8 @@ void PartSet_WidgetPoint2D::initializeValueByActivate() bool PartSet_WidgetPoint2D::processEnter() { - bool isModified = getValueState() == ModifiedInPP; + return false; + /*bool isModified = getValueState() == ModifiedInPP; if (isModified) { bool isXModified = myXSpin->hasFocus(); emit valuesChanged(); @@ -634,7 +859,7 @@ bool PartSet_WidgetPoint2D::processEnter() else myYSpin->selectAll(); } - return isModified; + return isModified;*/ } bool PartSet_WidgetPoint2D::useSelectedShapes() const @@ -644,11 +869,11 @@ bool PartSet_WidgetPoint2D::useSelectedShapes() const bool PartSet_WidgetPoint2D::isOrphanPoint(const FeaturePtr& theFeature, const CompositeFeaturePtr& theSketch, - double theX, double theY, const bool theSearchInResults) + double theX, double theY) { bool anOrphanPoint = false; if (theFeature.get()) { - std::shared_ptr aPointAttr; + AttributePoint2DPtr aPointAttr; std::string aFeatureKind = theFeature->getKind(); if (aFeatureKind == SketchPlugin_Point::ID()) aPointAttr = std::dynamic_pointer_cast( @@ -675,15 +900,19 @@ bool PartSet_WidgetPoint2D::isOrphanPoint(const FeaturePtr& theFeature, std::shared_ptr aPoint = aPointAttr->pnt(); // we need to find coincidence features in results also, because external object(point) // uses refs to me in another feature. - FeaturePtr aCoincidence = PartSet_Tools::findFirstCoincidence(theFeature, aPoint, theSearchInResults); + FeaturePtr aCoincidence = PartSet_Tools::findFirstCoincidence(theFeature, aPoint); anOrphanPoint = true; // if there is at least one concident line to the point, the point is not an orphant if (aCoincidence.get()) { QList aCoinsideLines; - PartSet_Tools::findCoincidences(aCoincidence, aCoinsideLines, - SketchPlugin_ConstraintCoincidence::ENTITY_A()); - PartSet_Tools::findCoincidences(aCoincidence, aCoinsideLines, - SketchPlugin_ConstraintCoincidence::ENTITY_B()); + QList aCoins; + QList anIsAttributes; + PartSet_Tools::findCoincidences(aCoincidence, aCoinsideLines, aCoins, + SketchPlugin_ConstraintCoincidence::ENTITY_A(), + anIsAttributes); + PartSet_Tools::findCoincidences(aCoincidence, aCoinsideLines, aCoins, + SketchPlugin_ConstraintCoincidence::ENTITY_B(), + anIsAttributes); QList::const_iterator anIt = aCoinsideLines.begin(), aLast = aCoinsideLines.end(); for (; anIt != aLast && anOrphanPoint; anIt++) { @@ -694,3 +923,160 @@ bool PartSet_WidgetPoint2D::isOrphanPoint(const FeaturePtr& theFeature, } return anOrphanPoint; } + +bool PartSet_WidgetPoint2D::shapeExploreHasVertex(const GeomShapePtr& theShape, + const std::shared_ptr& thePoint, + const CompositeFeaturePtr& theSketch) +{ + std::shared_ptr aPoint = PartSet_Tools::point3D(thePoint, theSketch); + + bool aContainPoint = false; + GeomAPI_ShapeExplorer anExp(theShape, GeomAPI_Shape::VERTEX); + for(; anExp.more() && !aContainPoint; anExp.next()) { + std::shared_ptr aVertexInCompSolid = anExp.current(); + std::shared_ptr aVertex(new GeomAPI_Vertex(aVertexInCompSolid)); + if (aVertex.get()) + aContainPoint = aPoint->isEqual(aVertex->point()); + } + return aContainPoint; +} + +AttributeRefAttrPtr PartSet_WidgetPoint2D::attributeRefAttr() const +{ + AttributeRefAttrPtr anAttribute; + if (myRefAttribute.empty()) + return anAttribute; + + AttributePtr anAttributeRef = feature()->attribute(myRefAttribute); + if (!anAttributeRef.get()) + return anAttribute; + + return std::dynamic_pointer_cast(anAttributeRef); +} + +void PartSet_WidgetPoint2D::fillRefAttribute(double theClickedX, double theClickedY, + const std::shared_ptr& theValue) +{ + AttributeRefAttrPtr aRefAttr = attributeRefAttr(); + if (!aRefAttr.get()) + return; + + FeaturePtr aFeature = feature(); + std::string anAttribute = attributeID(); + + if (aFeature.get()) { + std::shared_ptr aClickedPoint = std::shared_ptr( + new GeomAPI_Pnt2d(theClickedX, theClickedY)); + AttributePoint2DPtr aClickedFeaturePoint = findFirstEqualPointInSketch(mySketch, + aFeature, aClickedPoint); + if (aClickedFeaturePoint.get()) + aRefAttr->setAttr(aClickedFeaturePoint); + else { + ObjectPtr anObject = getGeomSelection(theValue); + if (anObject.get()) + aRefAttr->setObject(anObject); + } + } +} + +void PartSet_WidgetPoint2D::fillRefAttribute(const ModuleBase_ViewerPrsPtr& theValue) +{ + fillRefAttribute(getGeomSelection(theValue)); +} + +void PartSet_WidgetPoint2D::fillRefAttribute(const ObjectPtr& theObject) +{ + AttributeRefAttrPtr aRefAttr = attributeRefAttr(); + if (aRefAttr.get()) + aRefAttr->setObject(theObject); +} + +std::shared_ptr PartSet_WidgetPoint2D::findFirstEqualPointInArgumentFeatures( + const FeaturePtr& theFeature, const std::shared_ptr& thePoint) +{ + std::shared_ptr aFeaturePoint; + + // may be feature is not updated yet, execute is not performed and references features + // are not created. Case: rectangle macro feature + ModuleBase_Tools::flushUpdated(theFeature); + + std::list anAttributes = theFeature->data()->attributes( + ModelAPI_AttributeRefList::typeId()); + std::list::const_iterator anIt = anAttributes.begin(), aLast = anAttributes.end(); + for (; anIt != aLast && !aFeaturePoint.get(); anIt++) { + std::shared_ptr aCurSelList = + std::dynamic_pointer_cast(*anIt); + for (int i = 0, aNb = aCurSelList->size(); i < aNb && !aFeaturePoint.get(); i++) { + ObjectPtr anObject = aCurSelList->object(i); + FeaturePtr aFeature = std::dynamic_pointer_cast(anObject); + if (aFeature.get()) + aFeaturePoint = findFirstEqualPoint(aFeature, thePoint); + } + } + return aFeaturePoint; +} + +std::shared_ptr PartSet_WidgetPoint2D::findFirstEqualPoint( + const FeaturePtr& theFeature, + const std::shared_ptr& thePoint) +{ + std::shared_ptr aFPoint; + + // find the given point in the feature attributes + std::list > anAttiributes = + theFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); + std::list >::const_iterator anIt = anAttiributes.begin(), + aLast = anAttiributes.end(); + ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators(); + + for (; anIt != aLast && !aFPoint; anIt++) { + std::shared_ptr aCurPoint = + std::dynamic_pointer_cast(*anIt); + if (aCurPoint && aCurPoint->isInitialized() && + aValidators->isCase(theFeature, aCurPoint->id()) && + (aCurPoint->pnt()->distance(thePoint) < Precision::Confusion())) { + aFPoint = aCurPoint; + break; + } + } + return aFPoint; +} + +std::shared_ptr PartSet_WidgetPoint2D::findFirstEqualPointInSketch( + const CompositeFeaturePtr& theSketch, + const FeaturePtr& theSkipFeature, + const std::shared_ptr& thePoint) +{ + // get all sketch features. If the point with the given coordinates belong to any sketch feature, + // the constraint is created between the feature point and the found sketch point + std::shared_ptr aData = theSketch->data(); + std::shared_ptr aRefList = std::dynamic_pointer_cast< + ModelAPI_AttributeRefList>(aData->attribute(SketchPlugin_Sketch::FEATURES_ID())); + + std::list aFeatures = aRefList->list(); + std::list::const_iterator anIt = aFeatures.begin(), aLast = aFeatures.end(); + std::list > anAttiributes; + + std::shared_ptr aFPoint; + for (; anIt != aLast; anIt++) { + FeaturePtr aFeature = std::dynamic_pointer_cast(*anIt); + if (!aFeature.get() || (theSkipFeature.get() && theSkipFeature == aFeature)) + continue; + aFPoint = PartSet_WidgetPoint2D::findFirstEqualPoint(aFeature, thePoint); + if (aFPoint.get()) + break; + } + return aFPoint; +} + +ObjectPtr PartSet_WidgetPoint2D::getGeomSelection(const ModuleBase_ViewerPrsPtr& theValue) +{ + ObjectPtr anObject; + GeomShapePtr aShape; + ModuleBase_ISelection* aSelection = myWorkshop->selection(); + anObject = aSelection->getResult(theValue); + aShape = aSelection->getShape(theValue); + myExternalObjectMgr->getGeomSelection(theValue, anObject, aShape, myWorkshop, sketch(), true); + + return anObject; +}