X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_SketcherReentrantMgr.cpp;h=5dfd5a26ffdcead2416ca5dab32e7c9a41104dff;hb=06e7f5859095193fc7f498bd89a7d28009794f53;hp=b9c92f940c6a08d417f4ea475cb1d873f8698882;hpb=42394362cfec9b39f7def70c83e99c77a48fdfe5;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_SketcherReentrantMgr.cpp b/src/PartSet/PartSet_SketcherReentrantMgr.cpp index b9c92f940..5dfd5a26f 100644 --- a/src/PartSet/PartSet_SketcherReentrantMgr.cpp +++ b/src/PartSet/PartSet_SketcherReentrantMgr.cpp @@ -1,6 +1,24 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D +// Copyright (C) 2014-2023 CEA, EDF +// +// 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_SketcherReentrantMgr.h" +#include "PartSet_ExternalObjectsMgr.h" #include "PartSet_Module.h" #include "PartSet_SketcherMgr.h" #include "PartSet_WidgetPoint2d.h" @@ -8,11 +26,16 @@ #include "ModelAPI_Session.h" #include "ModelAPI_AttributeString.h" #include "ModelAPI_AttributeRefAttr.h" +#include "ModelAPI_AttributeReference.h" #include "ModelAPI_EventReentrantMessage.h" #include "GeomDataAPI_Point2D.h" +#include "GeomAPI_Lin2d.h" +#include "GeomAPI_Dir2d.h" + #include +#include #include #include #include @@ -30,6 +53,9 @@ #include #include #include +#include +#include +#include #include #include @@ -48,8 +74,9 @@ PartSet_SketcherReentrantMgr::PartSet_SketcherReentrantMgr(ModuleBase_IWorkshop* myRestartingMode(RM_None), myIsFlagsBlocked(false), myIsInternalEditOperation(false), - myInternalActiveWidget(0), - myNoMoreWidgetsAttribute("") + myNoMoreWidgetsAttribute(""), + myIsAutoConstraints(true), + myLastAutoConstraint(0) { } @@ -57,24 +84,6 @@ PartSet_SketcherReentrantMgr::~PartSet_SketcherReentrantMgr() { } -ModuleBase_ModelWidget* PartSet_SketcherReentrantMgr::internalActiveWidget() const -{ - ModuleBase_ModelWidget* aWidget = 0; - if (!isActiveMgr()) - return aWidget; - - ModuleBase_Operation* anOperation = myWorkshop->currentOperation(); - if (anOperation) { - ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel(); - if (aPanel) { // check for case when the operation is started but property panel is not filled - ModuleBase_ModelWidget* anActiveWidget = aPanel->activeWidget(); - if (myIsInternalEditOperation && (!anActiveWidget || !anActiveWidget->isViewerSelector())) - aWidget = myInternalActiveWidget; - } - } - return aWidget; -} - bool PartSet_SketcherReentrantMgr::isInternalEditActive() const { return myIsInternalEditOperation; @@ -117,13 +126,13 @@ void PartSet_SketcherReentrantMgr::operationStarted(ModuleBase_Operation* theOpe if (!isActiveMgr()) return; - if (myPreviousFeature.get() && myRestartingMode == RM_LastFeatureUsed) { - ModuleBase_OperationFeature* aCurrentOperation = dynamic_cast( - myWorkshop->currentOperation()); - CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch(); - if (myPreviousFeature.get() && myPreviousFeature->data()->isValid()) // it is not removed - copyReetntrantAttributes(myPreviousFeature, aCurrentOperation->feature(), aSketch); - } + //if (myPreviousFeature.get() && myRestartingMode == RM_LastFeatureUsed) { + //ModuleBase_OperationFeature* aCurrentOperation = dynamic_cast( + // myWorkshop->currentOperation()); + //CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch(); + //if (myPreviousFeature.get() && myPreviousFeature->data()->isValid()) // it is not removed + //copyReetntrantAttributes(myPreviousFeature, aCurrentOperation->feature(), aSketch); + //} resetFlags(); } @@ -152,17 +161,16 @@ bool PartSet_SketcherReentrantMgr::processMouseMoved(ModuleBase_IViewWindow* the ModuleBase_IPropertyPanel* aPanel = myWorkshop->currentOperation()->propertyPanel(); FeaturePtr aCurrentFeature = aFOperation->feature(); - bool isLineFeature = false, isArcFeature = false; + bool isLineFeature = false, isReentrantArcFeature = false; std::string anAttributeOnStart; if (aCurrentFeature->getKind() == SketchPlugin_Line::ID()) { anAttributeOnStart = SketchPlugin_Line::START_ID(); isLineFeature = anActiveWidget->attributeID() == anAttributeOnStart; } else if (isTangentArc(aFOperation, module()->sketchMgr()->activeSketch())) { - anAttributeOnStart = SketchPlugin_MacroArc::TANGENT_POINT_ID(); - isArcFeature = anActiveWidget->attributeID() == anAttributeOnStart; + isReentrantArcFeature = true; } - bool aCanBeActivatedByMove = isLineFeature || isArcFeature; + bool aCanBeActivatedByMove = isLineFeature || isReentrantArcFeature; if (aCanBeActivatedByMove) { /// before restarting of operation we need to clear selection, as it may take part in /// new feature creation, e.g. tangent arc. But it is not necessary as it was processed @@ -174,16 +182,15 @@ bool PartSet_SketcherReentrantMgr::processMouseMoved(ModuleBase_IViewWindow* the myPreviousFeature = FeaturePtr(); anActiveWidget = module()->activeWidget(); - aCurrentFeature = anActiveWidget->feature(); aProcessed = true; - if (anActiveWidget->attributeID() == anAttributeOnStart) { + if (anActiveWidget && anActiveWidget->attributeID() == anAttributeOnStart) { // it was not deactivated by preselection processing aPanel->activateNextWidget(anActiveWidget); } } else { // processing mouse move in active widget of restarted operation - ModuleBase_ModelWidget* anActiveWidget = module()->activeWidget(); - PartSet_MouseProcessor* aProcessor = dynamic_cast(anActiveWidget); + ModuleBase_ModelWidget* anActiveWdg = module()->activeWidget(); + PartSet_MouseProcessor* aProcessor = dynamic_cast(anActiveWdg); if (aProcessor) aProcessor->mouseMoved(theWnd, theEvent); } @@ -234,10 +241,32 @@ bool PartSet_SketcherReentrantMgr::processMouseReleased(ModuleBase_IViewWindow* myClickedSketchPoint = PartSet_Tools::getPnt2d(theEvent, theWindow, module()->sketchMgr()->activeSketch()); - if (!aPreSelected.empty()) - module()->getGeomSelection(aPreSelected.first(), mySelectedObject, mySelectedAttribute); + FeaturePtr anExternalCreatedFeature; + if (!aPreSelected.empty()) { + ModuleBase_ViewerPrsPtr aValue = aPreSelected.first(); + module()->getGeomSelection(aValue, mySelectedObject, mySelectedAttribute); + + PartSet_WidgetPoint2D* aPointWidget = dynamic_cast(anActiveWidget); + if (aPointWidget) { + GeomShapePtr aShape; + aPointWidget->getGeomSelection_(aValue, mySelectedObject, aShape); + ObjectPtr anExternalObject = + aPointWidget->getExternalObjectMgr()->getExternalObjectValidated(); + // if external object is during reentrant operation and is used as a parameter of feature + // it should be removed after the operation is restarted. (Circle feature, Projection) + if (anExternalObject.get()) + anExternalCreatedFeature = ModelAPI_Feature::feature(anExternalObject); + } + } restartOperation(); + // remove created external feature + if (anExternalCreatedFeature.get()) { + QObjectPtrList anObjects; + anObjects.append(anExternalCreatedFeature); + workshop()->deleteFeatures(anObjects); + } + myClickedSketchPoint = std::shared_ptr(); mySelectedObject = ObjectPtr(); mySelectedAttribute = AttributePtr(); @@ -263,7 +292,7 @@ bool PartSet_SketcherReentrantMgr::processMouseReleased(ModuleBase_IViewWindow* && !aSelectedPrs->object()->data()->isValid()) { // the selected object was removed diring restart, e.g. presentable macro feature // there are created objects to replace the object depending on created feature kind - aSelectedPrs = generatePreSelection(); + aSelectedPrs = std::shared_ptr(); } aMouseProcessor->setPreSelection(aSelectedPrs, theWindow, theEvent); //aPoint2DWdg->mouseReleased(theWindow, theEvent); @@ -294,22 +323,24 @@ void PartSet_SketcherReentrantMgr::setReentrantPreSelection( aReentrantMessage->setClickedPoint(myClickedSketchPoint); } -void PartSet_SketcherReentrantMgr::onWidgetActivated() -{ - if (!isActiveMgr()) - return; - if (!myIsInternalEditOperation) - return; - - PartSet_Module* aModule = module(); - ModuleBase_ModelWidget* aFirstWidget = aModule->activeWidget(); - ModuleBase_IPropertyPanel* aPanel = aModule->currentOperation()->propertyPanel(); - if (aFirstWidget != aPanel->activeWidget()) { - ModuleBase_WidgetSelector* aWSelector = dynamic_cast(aFirstWidget); - if (aWSelector) - aWSelector->activateSelectionAndFilters(true); - } -} +//void PartSet_SketcherReentrantMgr::onWidgetActivated() +//{ +// if (!isActiveMgr()) +// return; +// if (!myIsInternalEditOperation) +// return; +// +// PartSet_Module* aModule = module(); +// ModuleBase_ModelWidget* aFirstWidget = aModule->activeWidget(); +// ModuleBase_IPropertyPanel* aPanel = aModule->currentOperation()->propertyPanel(); +// if (aFirstWidget != aPanel->activeWidget()) { +// ModuleBase_WidgetSelector* aWSelector = dynamic_cast +// (aFirstWidget); +// if (aWSelector) { +// myWorkshop->selectionActivate()->updateSelectionModesAndFilters(aWSelector); +// } +// } +//} void PartSet_SketcherReentrantMgr::onNoMoreWidgets(const std::string& thePreviousAttributeID) { @@ -331,19 +362,32 @@ void PartSet_SketcherReentrantMgr::onNoMoreWidgets(const std::string& thePreviou ModuleBase_OperationFeature* aFOperation = dynamic_cast (myWorkshop->currentOperation()); + if (module()->sketchMgr()->isDragModeCreation()) { + if (aFOperation && myIsAutoConstraints) + addConstraints(aFOperation->feature()); + return; + } if (!myWorkshop->module()->getFeatureError(aFOperation->feature()).isEmpty()) return; if (aFOperation && module()->sketchMgr()->isNestedSketchOperation(aFOperation)) { - bool isStarted = false; - if (!module()->sketchMgr()->sketchSolverError()) { - if (myRestartingMode != RM_Forbided) { - myRestartingMode = RM_LastFeatureUsed; - isStarted = startInternalEdit(thePreviousAttributeID); + if (aFOperation->isNeedToBeAborted()) { + aFOperation->abort(); + } + else { + bool isStarted = false; + if (!module()->sketchMgr()->sketchSolverError()) { + if (myRestartingMode != RM_Forbided) { + myRestartingMode = RM_LastFeatureUsed; + isStarted = startInternalEdit(thePreviousAttributeID); + } + } + if (!isStarted) { + if (myIsAutoConstraints) + addConstraints(aFOperation->feature()); + aFOperation->commit(); } } - if (!isStarted) - aFOperation->commit(); } } @@ -368,7 +412,9 @@ bool PartSet_SketcherReentrantMgr::processEnter(const std::string& thePreviousAt if (!isSketchSolverError) { myRestartingMode = RM_EmptyFeatureUsed; - isDone = startInternalEdit(thePreviousAttributeID); + // It seems that the call is obsolete for Enter key processing + // It prevent finalysing of the current operation by Enter key + //isDone = startInternalEdit(thePreviousAttributeID); } return isDone; @@ -403,10 +449,7 @@ void PartSet_SketcherReentrantMgr::onVertexSelected() void PartSet_SketcherReentrantMgr::onAfterValuesChangedInPropertyPanel() { - if (isInternalEditActive()) { - ModuleBase_OperationFeature* aFOperation = dynamic_cast - (myWorkshop->currentOperation()); ModuleBase_ModelWidget* aWidget = (ModuleBase_ModelWidget*)sender(); if (!aWidget->isModifiedInEdit().empty()) restartOperation(); @@ -460,6 +503,13 @@ bool PartSet_SketcherReentrantMgr::startInternalEdit(const std::string& thePrevi (myWorkshop->currentOperation()); if (aFOperation && module()->sketchMgr()->isNestedSketchOperation(aFOperation)) { + /// improvement to deselect automatically all eventual selected objects, when + // returning to the neutral point of the Sketcher or start internal edit + workshop()->selector()->clearSelection(); + + if (myIsAutoConstraints) + addConstraints(aFOperation->feature()); + aFOperation->setEditOperation(true/*, false*/); createInternalFeature(); @@ -471,7 +521,7 @@ bool PartSet_SketcherReentrantMgr::startInternalEdit(const std::string& thePrevi connect(aFOperation, SIGNAL(beforeAborted()), this, SLOT(onBeforeStopped())); // activate selection filters of the first widget in the viewer - onWidgetActivated(); + //onWidgetActivated(); // activate the last active widget in the Property Panel if (!thePreviousAttributeID.empty()) { @@ -482,9 +532,9 @@ bool PartSet_SketcherReentrantMgr::startInternalEdit(const std::string& thePrevi QList aWidgets = aPanel->modelWidgets(); for (int i = 0, aNb = aWidgets.size(); i < aNb && !aPreviousAttributeWidget; i++) { if (aWidgets[i]->attributeID() == thePreviousAttributeID) { - /// workaround for the same attributes used in different stacked widgets(attribute types) - if (ModuleBase_ToolBox::isOffToolBoxParent(aWidgets[i])) - continue; + // workaround for the same attributes used in different stacked widgets(attribute types) + if (ModuleBase_ToolBox::isOffToolBoxParent(aWidgets[i])) + continue; aPreviousAttributeWidget = aWidgets[i]; } } @@ -492,6 +542,7 @@ bool PartSet_SketcherReentrantMgr::startInternalEdit(const std::string& thePrevi if (aPreviousAttributeWidget) { if (!aPreviousAttributeWidget->isViewerSelector()) { aPreviousAttributeWidget->focusTo(); + aPreviousAttributeWidget->emitFocusInWidget(); aPreviousAttributeWidget->selectContent(); } else { @@ -508,7 +559,7 @@ bool PartSet_SketcherReentrantMgr::startInternalEdit(const std::string& thePrevi QToolButton* anOkBtn = dynamic_cast(aPanel)->findButton(PROP_PANEL_OK); if (anOkBtn) - anOkBtn->setFocus(Qt::TabFocusReason); + ModuleBase_Tools::setFocus(anOkBtn, "XGUI_PropertyPanel::activateNextWidget"); } } } @@ -548,7 +599,7 @@ void PartSet_SketcherReentrantMgr::restartOperation() if (myInternalFeature.get()) copyReetntrantAttributes(myInternalFeature, aFOperation->feature(), - module()->sketchMgr()->activeSketch()); + module()->sketchMgr()->activeSketch()); myNoMoreWidgetsAttribute = ""; myIsFlagsBlocked = true; @@ -615,7 +666,7 @@ void PartSet_SketcherReentrantMgr::createInternalFeature() ModuleBase_ModelWidget* aFirstWidget = ModuleBase_IPropertyPanel::findFirstAcceptingValueWidget (aWidgets); if (aFirstWidget) - myInternalActiveWidget = aFirstWidget; + setInternalActiveWidget(aFirstWidget); } } @@ -625,13 +676,7 @@ void PartSet_SketcherReentrantMgr::deleteInternalFeature() std::cout << "PartSet_SketcherReentrantMgr::deleteInternalFeature: " << myInternalFeature->data()->name() << std::endl; #endif - if (myInternalActiveWidget) { - ModuleBase_WidgetSelector* aWSelector = - dynamic_cast(myInternalActiveWidget); - if (aWSelector) - aWSelector->activateSelectionAndFilters(false); - myInternalActiveWidget = 0; - } + setInternalActiveWidget(0); delete myInternalWidget; myInternalWidget = 0; @@ -690,16 +735,16 @@ bool PartSet_SketcherReentrantMgr::copyReetntrantAttributes(const FeaturePtr& th AttributeStringPtr aNewFeatureTypeAttr = theNewFeature->data()->string(aTypeAttributeId); if (aNewFeatureTypeAttr->value() != aTypeAttributeId) // do nothing if there is no changes aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value()); - //ModuleBase_Tools::flushUpdated(theNewFeature); - aChanged = true;*/ + //ModuleBase_Tools::flushUpdated(theNewFeature);*/ + //aChanged = true; } else if (aFeatureKind == SketchPlugin_MacroArc::ID()) { // set arc type - std::string aTypeAttributeId = SketchPlugin_MacroArc::ARC_TYPE(); + /*std::string aTypeAttributeId = SketchPlugin_MacroArc::ARC_TYPE(); AttributeStringPtr aSourceFeatureTypeAttr = theSourceFeature->data()->string(aTypeAttributeId); AttributeStringPtr aNewFeatureTypeAttr = theNewFeature->data()->string(aTypeAttributeId); if (aNewFeatureTypeAttr->value() != aTypeAttributeId) // do nothing if there is no changes - aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value()); + aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value());*/ //// if the arc is tangent, set coincidence to end point of the previous arc //std::string anArcType = aSourceFeatureTypeAttr->value(); //if (anArcType == SketchPlugin_Arc::ARC_TYPE_TANGENT()) { @@ -720,42 +765,28 @@ bool PartSet_SketcherReentrantMgr::copyReetntrantAttributes(const FeaturePtr& th //} //ModuleBase_Tools::flushUpdated(theNewFeature); - aChanged = true; + //aChanged = true; } - else if (aFeatureKind == SketchPlugin_Trim::ID()) { - /*std::shared_ptr aRefSelectedAttr = - std::dynamic_pointer_cast( - theSourceFeature->data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT())); - std::shared_ptr aNRefSelectedAttr = - std::dynamic_pointer_cast( - theNewFeature->data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT())); - aNRefSelectedAttr->setValue(aRefSelectedAttr->value());*/ - + else if (aFeatureKind == SketchPlugin_Trim::ID() || + aFeatureKind == SketchPlugin_Split::ID()) { + std::string aPreviewObjectAttribute = aFeatureKind == SketchPlugin_Trim::ID() ? + SketchPlugin_Trim::PREVIEW_OBJECT(): SketchPlugin_Split::PREVIEW_OBJECT(); + std::string aPreviewPointAttribute = aFeatureKind == SketchPlugin_Trim::ID() ? + SketchPlugin_Trim::PREVIEW_POINT(): SketchPlugin_Split::PREVIEW_POINT(); std::shared_ptr aRefPreviewAttr = std::dynamic_pointer_cast( - theSourceFeature->data()->attribute(SketchPlugin_Trim::PREVIEW_OBJECT())); + theSourceFeature->data()->attribute(aPreviewObjectAttribute)); std::shared_ptr aNRefPreviewAttr = std::dynamic_pointer_cast( - theNewFeature->data()->attribute(SketchPlugin_Trim::PREVIEW_OBJECT())); + theNewFeature->data()->attribute(aPreviewObjectAttribute)); aNRefPreviewAttr->setValue(aRefPreviewAttr->value()); - - /*std::shared_ptr aPointSelectedAttr = - std::dynamic_pointer_cast( - theSourceFeature->data()->attribute(SketchPlugin_Trim::SELECTED_POINT())); - std::shared_ptr aNPointSelectedAttr = - std::dynamic_pointer_cast( - theNewFeature->data()->attribute(SketchPlugin_Trim::SELECTED_POINT())); - aNPointSelectedAttr->setValue(aPointSelectedAttr->x(), aPointSelectedAttr->y()); - */ std::shared_ptr aPointPreviewAttr = std::dynamic_pointer_cast( - theSourceFeature->data()->attribute(SketchPlugin_Trim::PREVIEW_POINT())); + theSourceFeature->data()->attribute(aPreviewPointAttribute)); std::shared_ptr aNPointPreviewAttr = std::dynamic_pointer_cast( - theNewFeature->data()->attribute(SketchPlugin_Trim::PREVIEW_POINT())); + theNewFeature->data()->attribute(aPreviewPointAttribute)); aNPointPreviewAttr->setValue(aPointPreviewAttr->x(), aPointPreviewAttr->y()); - - aChanged = true; } return aChanged; } @@ -777,13 +808,6 @@ bool PartSet_SketcherReentrantMgr::isTangentArc(ModuleBase_Operation* theOperati return aTangentArc; } -std::shared_ptr PartSet_SketcherReentrantMgr::generatePreSelection() -{ - std::shared_ptr aPrs; - - return aPrs; -} - void PartSet_SketcherReentrantMgr::updateAcceptAllAction() { CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch(); @@ -801,3 +825,69 @@ PartSet_Module* PartSet_SketcherReentrantMgr::module() const { return dynamic_cast(myWorkshop->module()); } + +void PartSet_SketcherReentrantMgr::setInternalActiveWidget(ModuleBase_ModelWidget* theWidget) +{ + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (myWorkshop->currentOperation()); + if (aFOperation) + { + XGUI_PropertyPanel* aPropertyPanel = dynamic_cast + (aFOperation->propertyPanel()); + if (aPropertyPanel) + aPropertyPanel->setInternalActiveWidget(theWidget); + } +} + +void PartSet_SketcherReentrantMgr::onAutoConstraints(bool isOn) +{ + myIsAutoConstraints = isOn; +} + +void PartSet_SketcherReentrantMgr::addConstraints(const FeaturePtr& theFeature) +{ + if (theFeature->getKind() != SketchPlugin_Line::ID()) + return; + + static GeomDir2dPtr myHorDir(new GeomAPI_Dir2d(1, 0)); + static GeomDir2dPtr myVertDir(new GeomAPI_Dir2d(0, 1)); + + std::shared_ptr aData = theFeature->data(); + std::shared_ptr aPoint1 = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Line::START_ID())); + std::shared_ptr aPoint2 = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Line::END_ID())); + if (aPoint1.get() && aPoint2.get()) { + GeomLine2dPtr aLine(new GeomAPI_Lin2d(aPoint1->pnt(), aPoint2->pnt())); + GeomDir2dPtr aDir = aLine->direction(); + double aHorAngle = fabs(myHorDir->angle(aDir)); + double aVertAngle = fabs(myVertDir->angle(aDir)); + if (aHorAngle > M_PI/2.) + aHorAngle = M_PI - aHorAngle; + if (aVertAngle > M_PI/2.) + aVertAngle = M_PI - aVertAngle; + + double aTolerance = Config_PropManager::real(SKETCH_TAB_NAME, "angular_tolerance"); + CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch(); + FeaturePtr aFeature; + if (aHorAngle < aTolerance) { + // Add horizontal constraint + aFeature = aSketch->addFeature(SketchPlugin_ConstraintHorizontal::ID()); + } + else if (aVertAngle < aTolerance) { + // Add vertical constraint + aFeature = aSketch->addFeature(SketchPlugin_ConstraintVertical::ID()); + } + if (aFeature.get()) { + aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())->setObject( + theFeature->firstResult()); + myLastAutoConstraint = aFeature.get(); + } + } +} + + +bool PartSet_SketcherReentrantMgr::isLastAutoConstraint(const ObjectPtr& theObj) const +{ + return theObj.get() == myLastAutoConstraint; +}