From e020f9c3646f7b40639c498b1504078b122bd983 Mon Sep 17 00:00:00 2001 From: vsv Date: Tue, 2 Jun 2020 12:06:07 +0300 Subject: [PATCH] Issue #3232: Delete automatic constraints if they cause conflicts --- src/PartSet/PartSet_Module.cpp | 25 +++++++++++++++++++ src/PartSet/PartSet_Module.h | 2 ++ .../PartSet_OverconstraintListener.cpp | 19 +++++++++++++- src/PartSet/PartSet_OverconstraintListener.h | 5 ++++ src/PartSet/PartSet_SketcherReentrantMgr.cpp | 17 ++++++++++--- src/PartSet/PartSet_SketcherReentrantMgr.h | 3 +++ 6 files changed, 66 insertions(+), 5 deletions(-) diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 7ac26dd9c..623083bae 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -1854,3 +1854,28 @@ void PartSet_Module::disableCustomMode(ModuleBase_CustomizeFlag theMode) { void PartSet_Module::enableCustomModes() { myCustomPrs->enableCustomModes(); } + +//****************************************************** +void PartSet_Module::onConflictingConstraints() +{ + const std::set& aConstraints = myOverconstraintListener->conflictingObjects(); + if (aConstraints.size() == 1) { + QObjectPtrList aObjectsList; + std::set::const_iterator aIt; + for (aIt = aConstraints.cbegin(); aIt != aConstraints.cend(); aIt++) { + if (mySketchReentrantMgr->isLastAutoConstraint(*aIt)) + aObjectsList.append(*aIt); + } + if (aObjectsList.size() > 0) { + XGUI_Workshop* aWorkshop = getWorkshop(); + QString aDescription = aWorkshop->contextMenuMgr()->action("DELETE_CMD")->text(); + ModuleBase_Operation* anOpAction = new ModuleBase_Operation(aDescription); + XGUI_OperationMgr* anOpMgr = aWorkshop->operationMgr(); + + anOpMgr->startOperation(anOpAction); + aWorkshop->deleteFeatures(aObjectsList); + anOpMgr->commitOperation(); + ModuleBase_Tools::flushUpdated(sketchMgr()->activeSketch()); + } + } +} diff --git a/src/PartSet/PartSet_Module.h b/src/PartSet/PartSet_Module.h index 7567f40a2..e9481244e 100644 --- a/src/PartSet/PartSet_Module.h +++ b/src/PartSet/PartSet_Module.h @@ -414,6 +414,8 @@ public slots: /// \param theTrsfType type of tranformation virtual void onViewTransformed(int theTrsfType = 2); + void onConflictingConstraints(); + protected slots: /// Called when previous operation is finished virtual void onSelectionChanged(); diff --git a/src/PartSet/PartSet_OverconstraintListener.cpp b/src/PartSet/PartSet_OverconstraintListener.cpp index 70c19725c..a0eff2c34 100644 --- a/src/PartSet/PartSet_OverconstraintListener.cpp +++ b/src/PartSet/PartSet_OverconstraintListener.cpp @@ -35,6 +35,8 @@ #include "SketchPlugin_SketchEntity.h" #include "SketchPlugin_MacroArcReentrantMessage.h" #include "SketchPlugin_Sketch.h" +#include "SketchPlugin_ConstraintHorizontal.h" +#include "SketchPlugin_ConstraintVertical.h" #include "Events_Loop.h" @@ -44,6 +46,7 @@ #include #include +#include //#define DEBUG_FEATURE_OVERCONSTRAINT_LISTENER @@ -253,6 +256,21 @@ bool PartSet_OverconstraintListener::appendConflictingObjects( if (isUpdated) redisplayObjects(aModifiedObjects); + if (myConflictingObjects.size() == 1) { + // If the conflicting object is an automatic constraint caused the conflict + // then it has to be deleted + ObjectPtr aObj = *theConflictingObjects.cbegin(); + FeaturePtr aFeature = std::dynamic_pointer_cast(aObj); + if (aFeature) { + std::string aType = aFeature->getKind(); + if ((aType == SketchPlugin_ConstraintHorizontal::ID()) || + (aType == SketchPlugin_ConstraintVertical::ID())) { + PartSet_Module* aModule = dynamic_cast(myWorkshop->module()); + QTimer::singleShot(5, aModule, SLOT(onConflictingConstraints())); + } + } + } + return isUpdated; } @@ -267,7 +285,6 @@ bool PartSet_OverconstraintListener::repairConflictingObjects( ObjectPtr anObject = *anIt; if (theConflictingObjects.find(anObject) != theConflictingObjects.end()) { // it is found myConflictingObjects.erase(anObject); - aModifiedObjects.insert(anObject); } } diff --git a/src/PartSet/PartSet_OverconstraintListener.h b/src/PartSet/PartSet_OverconstraintListener.h index a02dee98e..551fb50ea 100644 --- a/src/PartSet/PartSet_OverconstraintListener.h +++ b/src/PartSet/PartSet_OverconstraintListener.h @@ -64,6 +64,11 @@ public: return (myConflictingObjects.find(theObject) != myConflictingObjects.end()); } + const std::set& conflictingObjects() const + { + return myConflictingObjects; + } + bool isFullyConstrained() const { return myIsFullyConstrained; } protected: diff --git a/src/PartSet/PartSet_SketcherReentrantMgr.cpp b/src/PartSet/PartSet_SketcherReentrantMgr.cpp index ff241a141..f61252974 100644 --- a/src/PartSet/PartSet_SketcherReentrantMgr.cpp +++ b/src/PartSet/PartSet_SketcherReentrantMgr.cpp @@ -75,7 +75,8 @@ PartSet_SketcherReentrantMgr::PartSet_SketcherReentrantMgr(ModuleBase_IWorkshop* myIsFlagsBlocked(false), myIsInternalEditOperation(false), myNoMoreWidgetsAttribute(""), - myIsAutoConstraints(true) + myIsAutoConstraints(true), + myLastAutoConstraint(0) { } @@ -872,16 +873,24 @@ void PartSet_SketcherReentrantMgr::addConstraints(const FeaturePtr& theFeature) double aTolerance = Config_PropManager::real(SKETCH_TAB_NAME, "angular_tolerance"); CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch(); FeaturePtr aFeature; - if (aHorAngle < aTolerance) + if (aHorAngle < aTolerance) { // Add horizontal constraint aFeature = aSketch->addFeature(SketchPlugin_ConstraintHorizontal::ID()); - else if (aVertAngle < aTolerance) + } + 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; +} diff --git a/src/PartSet/PartSet_SketcherReentrantMgr.h b/src/PartSet/PartSet_SketcherReentrantMgr.h index 046f45dba..c11f56bcf 100644 --- a/src/PartSet/PartSet_SketcherReentrantMgr.h +++ b/src/PartSet/PartSet_SketcherReentrantMgr.h @@ -134,6 +134,8 @@ public: bool isAutoConstraints() const { return myIsAutoConstraints; } + bool isLastAutoConstraint(const ObjectPtr& theObj) const; + public slots: /// The slot is called when user checks "Automatic constraints" button /// \param isOn a state of the check box @@ -240,6 +242,7 @@ private: std::shared_ptr myClickedSketchPoint; /// cashed clicked point bool myIsAutoConstraints; + void* myLastAutoConstraint; //< Stores address of last automatic constraint. Connot be used as a pointer!!! }; #endif -- 2.39.2