From: asozinov Date: Mon, 10 Jul 2023 12:14:58 +0000 (+0100) Subject: [bos #31549] [EDF] (2023-T1) Sketch Visualization of constrains X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=refs%2Ftlpr%2F51%2Fhead;p=modules%2Fshaper.git [bos #31549] [EDF] (2023-T1) Sketch Visualization of constrains - Added browser which show all constraints in the active sketch. - This browser provide functionality for Delete, Edit and Suppress constraints - Suppressed constraints can be reactivated - for constraints will be added new attribute ConstraintState. If True - constraint active, otherwise - suppressed. This parameter can be used as optional for python script. Example of using: Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint(), is_active = False) Documentationalso will be added --- diff --git a/src/ModuleBase/ModuleBase_IModule.h b/src/ModuleBase/ModuleBase_IModule.h index fc224c006..a3076cc65 100644 --- a/src/ModuleBase/ModuleBase_IModule.h +++ b/src/ModuleBase/ModuleBase_IModule.h @@ -149,6 +149,10 @@ class MODULEBASE_EXPORT ModuleBase_IModule : public QObject /// \param theMenu a popup menu to be shown in the object browser virtual void addObjectBrowserMenu(QMenu* theMenu) const {}; + /// Add menu items for constraints browser into the given menu + /// \param theMenu a popup menu to be shown in the constraints browser + virtual void addConstraintBrowserMenu(QMenu* theMenu) const {}; + /// Creates custom widgets for property panel /// \param theType a type of widget /// \param theParent the parent object diff --git a/src/ModuleBase/ModuleBase_ISelection.h b/src/ModuleBase/ModuleBase_ISelection.h index f816f5b7f..51bda71c6 100644 --- a/src/ModuleBase/ModuleBase_ISelection.h +++ b/src/ModuleBase/ModuleBase_ISelection.h @@ -44,7 +44,7 @@ class MODULEBASE_EXPORT ModuleBase_ISelection { public: /// Types of the selection place, where the selection is obtained - enum SelectionPlace { Browser, Viewer, AllControls }; + enum SelectionPlace { Browser, Viewer, ConstraintsBrowser, AllControls }; virtual ~ModuleBase_ISelection() {} diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index efc795171..d882dfbb8 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -104,6 +104,7 @@ #include #include #include +#include #include #include @@ -997,6 +998,24 @@ bool PartSet_Module::deleteObjects() // the abort leads to selection lost on constraint objects. It can be corrected after #386 issue ModuleBase_ISelection* aSel = workshop()->selection(); QObjectPtrList aSelectedObj = aSel->selectedPresentations(); + + QObjectPtrList aConstrSelectedObj = getWorkshop()->constraintsBrowser()->selectedConstraints(); + // if list not empty, delete only constraints from list + if (!aConstrSelectedObj.isEmpty()) + { + QString aDescription = aWorkshop->contextMenuMgr()->action("DELETE_CMD")->text(); + ModuleBase_Operation* anOpAction = new ModuleBase_Operation(aDescription, this); + + bool isCommitted; + if (!anOpMgr->canStartOperation(anOpAction->id(), isCommitted)) + return true; + + anOpMgr->startOperation(anOpAction); + aWorkshop->deleteFeatures(aConstrSelectedObj); + anOpMgr->commitOperation(); + return true; + } + // if there are no selected objects in the viewer, that means that the selection in another // place cased this method. It is necessary to return the false value to understande in above // method that delete is not processed diff --git a/src/PartSet/PartSet_SketcherMgr.cpp b/src/PartSet/PartSet_SketcherMgr.cpp index 1a34c5127..acc269bef 100644 --- a/src/PartSet/PartSet_SketcherMgr.cpp +++ b/src/PartSet/PartSet_SketcherMgr.cpp @@ -31,6 +31,7 @@ #include "PartSet_PreviewSketchPlane.h" #include +#include #include #include #include @@ -108,10 +109,14 @@ #include #include #include +#include +#include #include #include +#include + #include #include #include @@ -219,6 +224,11 @@ PartSet_SketcherMgr::~PartSet_SketcherMgr() delete mySketchPlane; } +XGUI_SketchConstraintsBrowser* PartSet_SketcherMgr::constraintsBrowser() +{ + return workshop()->constraintsBrowser(); +} + void PartSet_SketcherMgr::onEnterViewPort() { // 1. if the mouse over window, update the next flag. Do not perform update visibility of @@ -850,6 +860,107 @@ void PartSet_SketcherMgr::onAfterContextMenu() myIsPopupMenuActive = false; } +void PartSet_SketcherMgr::onEditValues() +{ + auto aConstrBrowser = constraintsBrowser(); + + auto anOperMgr = workshop()->operationMgr(); + + ModuleBase_Operation* anOpAction = new ModuleBase_Operation("Edit Constraints value"); + + anOperMgr->startOperation(anOpAction); + int aRow = 0; + QTreeWidgetItemIterator anIter(aConstrBrowser->getViewTree()); + while (*anIter) { + // Change value + auto aData = (*anIter)->data(3, 0); + if (!aData.isNull()) + { + auto aName = (*anIter)->data(1, 0).toString(); + FeaturePtr aConstrFeat; + for (int i = 0; i < myCurrentSketch->numberOfSubs(); ++i) + { + auto aFFeat = myCurrentSketch->subFeature(i); + if (aName == QString::fromStdWString(aFFeat->name())) + { + aConstrFeat = aFFeat; + break; + } + } + + double aNewValue = aData.toDouble(); + ConstraintPtr aConstraint = std::dynamic_pointer_cast(aConstrFeat); + if(aNewValue < 0 || (aNewValue == 0 && !aConstraint->isZeroValueAllowed())) + { + aNewValue = aConstraint->getNumericValue(); + (*anIter)->setData(3, 0, aNewValue); + Events_InfoMessage("PartSet_SketcherMgr", "Some values are not correct and cannot be set").send(); + continue; + } + if(aNewValue != aConstraint->getNumericValue()) + aConstraint->setNumericValue(aNewValue); + } + + ++aRow; + ++anIter; + } + anOperMgr->commitOperation(); + workshop()->viewer()->update(); + delete anOpAction; +} + +void PartSet_SketcherMgr::onUpdateConstraintsList() +{ + auto aConstrBrowser = constraintsBrowser(); + + std::vector>> aConstraints; + + CompositeFeaturePtr aComposite = + std::dynamic_pointer_cast(activeSketch()); + int aNumSubs = aComposite->numberOfSubs(); + for (int i = 0; i < aNumSubs; ++i) + { + auto aFeat = aComposite->subFeature(i); + if (aFeat->refattr(SketchPlugin_Constraint::ENTITY_A()) && + (!aFeat->attribute(SketchPlugin_Constraint::ENTITY_B()) || aFeat->refattr(SketchPlugin_Constraint::ENTITY_B()))) + { + std::pair> anElemContr; + anElemContr.first = aFeat; + + anElemContr.second.push_back(aFeat->refattr(SketchPlugin_Constraint::ENTITY_A())); + if (aFeat->attribute(SketchPlugin_Constraint::ENTITY_B())) + anElemContr.second.push_back(aFeat->refattr(SketchPlugin_Constraint::ENTITY_B())); + + aConstraints.push_back(anElemContr); + } + } + aConstrBrowser->UpdateTree(aConstraints); +} + +void PartSet_SketcherMgr::onDeactivate(bool isNeedDeactivate, std::vector theFeatures) +{ + std::list anUpd; + auto anOperMgr = workshop()->operationMgr(); + + ModuleBase_OperationFeature* anOpAction = new ModuleBase_OperationFeature("Deactivate/Activate"); + anOpAction->setFeature(myCurrentSketch); + startNestedSketch(anOpAction); + anOperMgr->startOperation(anOpAction); + + for (size_t i = 0; i < theFeatures.size(); ++i) + { + theFeatures[i]->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())->setValue(isNeedDeactivate); + + static const Events_ID anEvent = Events_Loop::eventByName(EVENT_VISUAL_ATTRIBUTES); + ModelAPI_EventCreator::get()->sendUpdated(theFeatures[i], anEvent, false); + } + + stopNestedSketch(anOpAction); + anOperMgr->commitOperation(); + workshop()->viewer()->update(); + delete anOpAction; +} + void PartSet_SketcherMgr::get2dPoint(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent, Point& thePoint) { @@ -1200,6 +1311,17 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) PartSet_Fitter* aFitter = new PartSet_Fitter(this); myModule->workshop()->viewer()->setFitter(aFitter); + + auto aDesktop = workshop()->desktop(); + myConstraintsBrowser = workshop()->createConstraintsBrowser(aDesktop); + + // For process edit/delete and deactivate/activate constraints + connect(constraintsBrowser(), SIGNAL(editValues()), this, SLOT(onEditValues())); + connect(constraintsBrowser(), SIGNAL(deleteConstraints()), this, SLOT(onUpdateConstraintsList())); + connect(constraintsBrowser(), SIGNAL(deactivate(bool, std::vector)), this, SLOT(onDeactivate(bool, std::vector))); + aDesktop->addDockWidget(Qt::RightDockWidgetArea, myConstraintsBrowser); + + onUpdateConstraintsList(); } void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation) @@ -1274,6 +1396,17 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation) workshop()->selectionActivate()->updateSelectionFilters(); workshop()->selectionActivate()->updateSelectionModes(); workshop()->viewer()->set2dMode(false); + + disconnect(constraintsBrowser(), SIGNAL(editValues()), this, SLOT(onEditValues())); + disconnect(constraintsBrowser(), SIGNAL(deleteConstraints()), this, SLOT(onUpdateConstraintsList())); + disconnect(constraintsBrowser(), SIGNAL(deactivate(bool, std::vector)), this, SLOT(onDeactivate(bool, std::vector))); + + workshop()->desktop()->removeDockWidget(myConstraintsBrowser); + std::vector>> anEmpty; + constraintsBrowser()->UpdateTree(anEmpty); + workshop()->removeConstrBrowser(); + + myConstraintsBrowser->deleteLater(); } void PartSet_SketcherMgr::startNestedSketch(ModuleBase_Operation* theOperation) @@ -2266,11 +2399,15 @@ bool isIncludeToResult(const ObjectPtr& theObject) //************************************************************************************** std::vector PartSet_SketcherMgr::colorOfObject(const ObjectPtr& theObject, - const FeaturePtr& theFeature, bool isConstruction) const + const FeaturePtr& theFeature, bool isConstruction, bool isSuppressedConstraint) const { PartSet_OverconstraintListener* aOCListener = myModule->overconstraintListener(); std::string aKind = theFeature->getKind(); + // may be Preference Config_PropManager::color("Visualization", "sketch_deactivated_color"); + if (isSuppressedConstraint) + return { 128, 128, 128 }; + if (aOCListener->isConflictingObject(theObject)) { return Config_PropManager::color("Visualization", "sketch_overconstraint_color"); } @@ -2303,7 +2440,11 @@ void PartSet_SketcherMgr::customizeSketchPresentation(const ObjectPtr& theObject aFeature->data()->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID()); bool isConstruction = anAuxiliaryAttr.get() != NULL && anAuxiliaryAttr->value(); - std::vector aColor = colorOfObject(theObject, aFeature, isConstruction); + bool isSupressed = false; + if (aFeature->data()->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())) + isSupressed = !aFeature->data()->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())->value(); + + std::vector aColor = colorOfObject(theObject, aFeature, isConstruction, isSupressed); if (!aColor.empty()) { // The code below causes redisplay again if (ModelAPI_Session::get()->isOperation()) { diff --git a/src/PartSet/PartSet_SketcherMgr.h b/src/PartSet/PartSet_SketcherMgr.h index 12b9f4fce..236206885 100644 --- a/src/PartSet/PartSet_SketcherMgr.h +++ b/src/PartSet/PartSet_SketcherMgr.h @@ -66,6 +66,7 @@ class ModuleBase_Operation; class XGUI_OperationMgr; class XGUI_Workshop; class XGUI_Displayer; +class XGUI_SketchConstraintsBrowser; class PartSet_ExternalPointsMgr; class AIS_InteractiveObject; @@ -387,6 +388,8 @@ public: /// Returns true if current mode of objects creation is by drag mouse bool isDragModeCreation() const; + // Get constraints browser + XGUI_SketchConstraintsBrowser* constraintsBrowser(); public slots: /// Process sketch plane selected event @@ -396,6 +399,10 @@ public slots: /// \param toShow a state of the check box void onShowPoints(bool toShow); + void onEditValues(); + void onUpdateConstraintsList(); + void onDeactivate(bool isNeedDeactivate, std::vector theFeatures); + private slots: /// Toggle show constraints void onShowConstraintsToggle(int theType, bool theState); @@ -485,7 +492,7 @@ private: XGUI_OperationMgr* operationMgr() const; std::vector colorOfObject(const ObjectPtr& theObject, - const FeaturePtr& aFeature, bool isConstruction) const; + const FeaturePtr& aFeature, bool isConstruction, bool isSuppressedConstraint) const; private: PartSet_Module* myModule; @@ -518,6 +525,8 @@ private: bool myNoDragMoving; QPoint myMousePoint; + + QDockWidget* myConstraintsBrowser; }; diff --git a/src/SketchAPI/SketchAPI_Constraint.cpp b/src/SketchAPI/SketchAPI_Constraint.cpp index 95ea7b9fa..df29fd9ef 100644 --- a/src/SketchAPI/SketchAPI_Constraint.cpp +++ b/src/SketchAPI/SketchAPI_Constraint.cpp @@ -224,6 +224,9 @@ void SketchAPI_Constraint::dump(ModelHighAPI_Dumper& theDumper) const if (aRefAttr && aRefAttr->isInitialized()) { theDumper << aRefAttr; } + + bool isActive = aBase->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())->value(); + theDumper << ", " << isActive; theDumper << ")" << std::endl; } else @@ -255,6 +258,10 @@ void SketchAPI_Constraint::dump(ModelHighAPI_Dumper& theDumper) const AttributeBooleanPtr isSigned = aBase->boolean(SketchPlugin_ConstraintDistance::SIGNED()); theDumper << ", " << isSigned->value(); } + + bool isActive = aBase->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())->value(); + theDumper << ", " << isActive; + theDumper << ")" << std::endl; } diff --git a/src/SketchAPI/SketchAPI_ConstraintAngle.cpp b/src/SketchAPI/SketchAPI_ConstraintAngle.cpp index 5ddb665dd..ade1e4e60 100644 --- a/src/SketchAPI/SketchAPI_ConstraintAngle.cpp +++ b/src/SketchAPI/SketchAPI_ConstraintAngle.cpp @@ -148,5 +148,7 @@ void SketchAPI_ConstraintAngle::dump(ModelHighAPI_Dumper& theDumper) const theDumper << ", " << aValueAttr; std::string aType = angleTypeToString(aBase); - theDumper << ", type = \"" << aType << "\")" << std::endl; + theDumper << ", type = \"" << aType << "\""; + bool isActive = aBase->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())->value(); + theDumper << ", is_active = " << isActive << ")" << std::endl; } diff --git a/src/SketchAPI/SketchAPI_MacroMiddlePoint.cpp b/src/SketchAPI/SketchAPI_MacroMiddlePoint.cpp index 3ec3a3610..74846043a 100644 --- a/src/SketchAPI/SketchAPI_MacroMiddlePoint.cpp +++ b/src/SketchAPI/SketchAPI_MacroMiddlePoint.cpp @@ -35,13 +35,14 @@ SketchAPI_MacroMiddlePoint::SketchAPI_MacroMiddlePoint( } SketchAPI_MacroMiddlePoint::SketchAPI_MacroMiddlePoint(const std::shared_ptr& theFeature, - const ModelHighAPI_RefAttr& theLine, const std::shared_ptr& thePoint) + const ModelHighAPI_RefAttr& theLine, const std::shared_ptr& thePoint, const bool is_Active) : SketchAPI_Point(theFeature, thePoint) { - createConstraint(theLine); + createConstraint(theLine, is_Active); } -void SketchAPI_MacroMiddlePoint::createConstraint(const ModelHighAPI_RefAttr& theLine) +void SketchAPI_MacroMiddlePoint::createConstraint(const ModelHighAPI_RefAttr& theLine, + const bool is_Active) { // Find sketch CompositeFeaturePtr aSketch; @@ -62,6 +63,7 @@ void SketchAPI_MacroMiddlePoint::createConstraint(const ModelHighAPI_RefAttr& th aConstrFeature->refattr(SketchPlugin_Constraint::ENTITY_A())->setObject(theLine.object()); aConstrFeature->refattr(SketchPlugin_Constraint::ENTITY_B())->setAttr(coordinates()); std::dynamic_pointer_cast(aConstrFeature->attribute(SketchPlugin_ConstraintMiddle::POINT_REF_ID()))->setValue(coordinates()->x(), coordinates()->y()); + aConstrFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())->setValue(is_Active); aConstrFeature->execute(); diff --git a/src/SketchAPI/SketchAPI_MacroMiddlePoint.h b/src/SketchAPI/SketchAPI_MacroMiddlePoint.h index 2e747dff0..bcd3ec76c 100644 --- a/src/SketchAPI/SketchAPI_MacroMiddlePoint.h +++ b/src/SketchAPI/SketchAPI_MacroMiddlePoint.h @@ -42,7 +42,8 @@ public: SKETCHAPI_EXPORT SketchAPI_MacroMiddlePoint(const std::shared_ptr& theFeature, const ModelHighAPI_RefAttr& theLine, - const std::shared_ptr& thePoint); + const std::shared_ptr& thePoint, + const bool is_Active); static std::string ID() { @@ -52,7 +53,8 @@ public: virtual std::string getID() { return ID(); } protected: - void createConstraint(const ModelHighAPI_RefAttr& theLine); + void createConstraint(const ModelHighAPI_RefAttr& theLine, + const bool is_Active); }; #endif diff --git a/src/SketchAPI/SketchAPI_Sketch.cpp b/src/SketchAPI/SketchAPI_Sketch.cpp index eeacdbb4d..8d695be18 100644 --- a/src/SketchAPI/SketchAPI_Sketch.cpp +++ b/src/SketchAPI/SketchAPI_Sketch.cpp @@ -1243,7 +1243,8 @@ std::shared_ptr SketchAPI_Sketch::setAngle( const ModelHighAPI_RefAttr & theLine1, const ModelHighAPI_RefAttr & theLine2, const ModelHighAPI_Double & theValue, - const std::string& theType) + const std::string& theType, + bool theIsActive) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID()); @@ -1261,6 +1262,7 @@ std::shared_ptr SketchAPI_Sketch::setAngle( fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())); fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B())); + fillAttribute(theIsActive, aFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())); if (aVersion == SketchPlugin_ConstraintAngle::THE_VERSION_1) { std::string aTypeLC = theType; @@ -1282,7 +1284,8 @@ std::shared_ptr SketchAPI_Sketch::setAngle( std::shared_ptr SketchAPI_Sketch::setAngleComplementary( const ModelHighAPI_RefAttr & theLine1, const ModelHighAPI_RefAttr & theLine2, - const ModelHighAPI_Double & theValue) + const ModelHighAPI_Double & theValue, + bool theIsActive) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID()); @@ -1293,6 +1296,7 @@ std::shared_ptr SketchAPI_Sketch::setAngleComplementary( fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID())); fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())); fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B())); + fillAttribute(theIsActive, aFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } @@ -1300,7 +1304,8 @@ std::shared_ptr SketchAPI_Sketch::setAngleComplementary( std::shared_ptr SketchAPI_Sketch::setAngleBackward( const ModelHighAPI_RefAttr & theLine1, const ModelHighAPI_RefAttr & theLine2, - const ModelHighAPI_Double & theValue) + const ModelHighAPI_Double & theValue, + bool theIsActive) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID()); @@ -1311,30 +1316,35 @@ std::shared_ptr SketchAPI_Sketch::setAngleBackward( fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID())); fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())); fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B())); + fillAttribute(theIsActive, aFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } std::shared_ptr SketchAPI_Sketch::setCoincident( const ModelHighAPI_RefAttr & thePoint1, - const ModelHighAPI_RefAttr & thePoint2) + const ModelHighAPI_RefAttr & thePoint2, + bool theIsActive) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_ConstraintCoincidence::ID()); fillAttribute(thePoint1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())); fillAttribute(thePoint2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B())); + fillAttribute(theIsActive, aFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } std::shared_ptr SketchAPI_Sketch::setCollinear( const ModelHighAPI_RefAttr & theLine1, - const ModelHighAPI_RefAttr & theLine2) + const ModelHighAPI_RefAttr & theLine2, + bool theIsActive) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_ConstraintCollinear::ID()); fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())); fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B())); + fillAttribute(theIsActive, aFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } @@ -1343,7 +1353,8 @@ std::shared_ptr SketchAPI_Sketch::setDistance( const ModelHighAPI_RefAttr & thePoint, const ModelHighAPI_RefAttr & thePointOrLine, const ModelHighAPI_Double & theValue, - bool isSigned) + bool isSigned, + bool theIsActive) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_ConstraintDistance::ID()); @@ -1351,6 +1362,7 @@ std::shared_ptr SketchAPI_Sketch::setDistance( fillAttribute(thePointOrLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B())); fillAttribute(theValue, aFeature->real(SketchPlugin_Constraint::VALUE())); fillAttribute(isSigned, aFeature->boolean(SketchPlugin_ConstraintDistance::SIGNED())); + fillAttribute(theIsActive, aFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } @@ -1358,23 +1370,26 @@ std::shared_ptr SketchAPI_Sketch::setDistance( std::shared_ptr SketchAPI_Sketch::setSignedDistance( const ModelHighAPI_RefAttr & thePoint, const ModelHighAPI_RefAttr & thePointOrLine, - const ModelHighAPI_Double & theValue) + const ModelHighAPI_Double & theValue, + bool theIsActive) { - return setDistance(thePoint, thePointOrLine, theValue, true); + return setDistance(thePoint, thePointOrLine, theValue, true, theIsActive); } std::shared_ptr SketchAPI_Sketch::setUnsignedDistance( const ModelHighAPI_RefAttr & thePoint, const ModelHighAPI_RefAttr & thePointOrLine, - const ModelHighAPI_Double & theValue) + const ModelHighAPI_Double & theValue, + bool theIsActive) { - return setDistance(thePoint, thePointOrLine, theValue, false); + return setDistance(thePoint, thePointOrLine, theValue, false, theIsActive); } std::shared_ptr SketchAPI_Sketch::setHorizontalDistance( const ModelHighAPI_RefAttr & thePoint1, const ModelHighAPI_RefAttr & thePoint2, - const ModelHighAPI_Double & theValue) + const ModelHighAPI_Double & theValue, + bool theIsActive) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_ConstraintDistanceHorizontal::ID()); @@ -1382,6 +1397,7 @@ std::shared_ptr SketchAPI_Sketch::setHorizontalDistance( fillAttribute(thePoint2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B())); fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintDistanceAlongDir::DISTANCE_VALUE_ID())); + fillAttribute(theIsActive, aFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } @@ -1389,7 +1405,8 @@ std::shared_ptr SketchAPI_Sketch::setHorizontalDistance( std::shared_ptr SketchAPI_Sketch::setVerticalDistance( const ModelHighAPI_RefAttr & thePoint1, const ModelHighAPI_RefAttr & thePoint2, - const ModelHighAPI_Double & theValue) + const ModelHighAPI_Double & theValue, + bool theIsActive) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_ConstraintDistanceVertical::ID()); @@ -1397,18 +1414,21 @@ std::shared_ptr SketchAPI_Sketch::setVerticalDistance( fillAttribute(thePoint2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B())); fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintDistanceAlongDir::DISTANCE_VALUE_ID())); + fillAttribute(theIsActive, aFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } std::shared_ptr SketchAPI_Sketch::setEqual( const ModelHighAPI_RefAttr & theObject1, - const ModelHighAPI_RefAttr & theObject2) + const ModelHighAPI_RefAttr & theObject2, + bool theIsActive) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_ConstraintEqual::ID()); fillAttribute(theObject1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())); fillAttribute(theObject2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B())); + fillAttribute(theIsActive, aFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } @@ -1442,40 +1462,47 @@ std::shared_ptr SketchAPI_Sketch::setFilletWithRadius( } std::shared_ptr SketchAPI_Sketch::setFixed( - const ModelHighAPI_RefAttr & theObject) + const ModelHighAPI_RefAttr & theObject, + bool theIsActive) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_ConstraintRigid::ID()); fillAttribute(theObject, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())); + fillAttribute(theIsActive, aFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } std::shared_ptr SketchAPI_Sketch::setHorizontal( - const ModelHighAPI_RefAttr & theLine) + const ModelHighAPI_RefAttr & theLine, + bool theIsActive) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_ConstraintHorizontal::ID()); fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())); + fillAttribute(theIsActive, aFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } std::shared_ptr SketchAPI_Sketch::setLength( const ModelHighAPI_RefAttr & theLine, - const ModelHighAPI_Double & theValue) + const ModelHighAPI_Double & theValue, + bool theIsActive) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_ConstraintLength::ID()); fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())); fillAttribute(theValue, aFeature->real(SketchPlugin_Constraint::VALUE())); + fillAttribute(theIsActive, aFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } std::shared_ptr SketchAPI_Sketch::setMiddlePoint( const ModelHighAPI_RefAttr & thePoint, - const ModelHighAPI_RefAttr & theLine) + const ModelHighAPI_RefAttr & theLine, + bool theIsActive) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_ConstraintMiddle::ID()); @@ -1485,12 +1512,14 @@ std::shared_ptr SketchAPI_Sketch::setMiddlePoint( fillAttribute(thePoint, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())); fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B())); + fillAttribute(theIsActive, aFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } std::shared_ptr SketchAPI_Sketch::setMiddlePoint( - const ModelHighAPI_RefAttr& theLine) + const ModelHighAPI_RefAttr& theLine, + bool is_active) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_Point::ID()); @@ -1499,63 +1528,73 @@ std::shared_ptr SketchAPI_Sketch::setMiddlePoint( auto aPoint = middlePoint(anObj, this); return std::shared_ptr - (new SketchAPI_MacroMiddlePoint(aFeature, theLine, aPoint)); + (new SketchAPI_MacroMiddlePoint(aFeature, theLine, aPoint, is_active)); } std::shared_ptr SketchAPI_Sketch::setParallel( const ModelHighAPI_RefAttr & theLine1, - const ModelHighAPI_RefAttr & theLine2) + const ModelHighAPI_RefAttr & theLine2, + bool theIsActive) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_ConstraintParallel::ID()); fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())); fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B())); + fillAttribute(theIsActive, aFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } std::shared_ptr SketchAPI_Sketch::setPerpendicular( const ModelHighAPI_RefAttr & theLine1, - const ModelHighAPI_RefAttr & theLine2) + const ModelHighAPI_RefAttr & theLine2, + bool theIsActive) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_ConstraintPerpendicular::ID()); fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())); fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B())); + fillAttribute(theIsActive, aFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } std::shared_ptr SketchAPI_Sketch::setRadius( const ModelHighAPI_RefAttr & theCircleOrArc, - const ModelHighAPI_Double & theValue) + const ModelHighAPI_Double & theValue, + bool theIsActive) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_ConstraintRadius::ID()); fillAttribute(theCircleOrArc, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())); fillAttribute(theValue, aFeature->real(SketchPlugin_Constraint::VALUE())); + fillAttribute(theIsActive, aFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } std::shared_ptr SketchAPI_Sketch::setTangent( const ModelHighAPI_RefAttr & theLine, - const ModelHighAPI_RefAttr & theCircle) + const ModelHighAPI_RefAttr & theCircle, + bool theIsActive) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_ConstraintTangent::ID()); fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())); fillAttribute(theCircle, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B())); + fillAttribute(theIsActive, aFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } std::shared_ptr SketchAPI_Sketch::setVertical( - const ModelHighAPI_RefAttr & theLine) + const ModelHighAPI_RefAttr & theLine, + bool theIsActive) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_ConstraintVertical::ID()); fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())); + fillAttribute(theIsActive, aFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } diff --git a/src/SketchAPI/SketchAPI_Sketch.h b/src/SketchAPI/SketchAPI_Sketch.h index fba36db2c..85ec175e7 100644 --- a/src/SketchAPI/SketchAPI_Sketch.h +++ b/src/SketchAPI/SketchAPI_Sketch.h @@ -471,33 +471,38 @@ public: const ModelHighAPI_RefAttr & theLine1, const ModelHighAPI_RefAttr & theLine2, const ModelHighAPI_Double & theValue, - const std::string& type = std::string()); + const std::string& type = std::string(), + bool is_active = true); /// Set complementary angle SKETCHAPI_EXPORT std::shared_ptr setAngleComplementary( const ModelHighAPI_RefAttr & theLine1, const ModelHighAPI_RefAttr & theLine2, - const ModelHighAPI_Double & theValue); + const ModelHighAPI_Double & theValue, + bool is_active = true); /// Set backward angle (= 360 - angle) SKETCHAPI_EXPORT std::shared_ptr setAngleBackward( const ModelHighAPI_RefAttr & theLine1, const ModelHighAPI_RefAttr & theLine2, - const ModelHighAPI_Double & theValue); + const ModelHighAPI_Double & theValue, + bool is_active = true); /// Set coincident SKETCHAPI_EXPORT std::shared_ptr setCoincident( const ModelHighAPI_RefAttr & thePoint1, - const ModelHighAPI_RefAttr & thePoint2); + const ModelHighAPI_RefAttr & thePoint2, + bool is_active = true); /// Set collinear SKETCHAPI_EXPORT std::shared_ptr setCollinear( const ModelHighAPI_RefAttr & theLine1, - const ModelHighAPI_RefAttr & theLine2); + const ModelHighAPI_RefAttr & theLine2, + bool is_active = true); /// Set distance SKETCHAPI_EXPORT @@ -505,41 +510,47 @@ public: const ModelHighAPI_RefAttr & thePoint, const ModelHighAPI_RefAttr & thePointOrLine, const ModelHighAPI_Double & theValue, - bool isSigned = false); + bool isSigned = false, + bool is_active = true); /// Set signed distance SKETCHAPI_EXPORT std::shared_ptr setSignedDistance( const ModelHighAPI_RefAttr & thePoint, const ModelHighAPI_RefAttr & thePointOrLine, - const ModelHighAPI_Double & theValue); + const ModelHighAPI_Double & theValue, + bool is_active = true); /// Set unsigned distance SKETCHAPI_EXPORT std::shared_ptr setUnsignedDistance( const ModelHighAPI_RefAttr & thePoint, const ModelHighAPI_RefAttr & thePointOrLine, - const ModelHighAPI_Double & theValue); + const ModelHighAPI_Double & theValue, + bool is_active = true); /// Set horizontal distance SKETCHAPI_EXPORT std::shared_ptr setHorizontalDistance( const ModelHighAPI_RefAttr & thePoint1, const ModelHighAPI_RefAttr & thePoint2, - const ModelHighAPI_Double & theValue); + const ModelHighAPI_Double & theValue, + bool is_active = true); /// Set vertical distance SKETCHAPI_EXPORT std::shared_ptr setVerticalDistance( const ModelHighAPI_RefAttr & thePoint1, const ModelHighAPI_RefAttr & thePoint2, - const ModelHighAPI_Double & theValue); + const ModelHighAPI_Double & theValue, + bool is_active = true); /// Set equal SKETCHAPI_EXPORT std::shared_ptr setEqual( const ModelHighAPI_RefAttr & theObject1, - const ModelHighAPI_RefAttr & theObject2); + const ModelHighAPI_RefAttr & theObject2, + bool is_active = true); /// Set fillet SKETCHAPI_EXPORT @@ -555,58 +566,68 @@ public: /// Set fixed SKETCHAPI_EXPORT std::shared_ptr setFixed( - const ModelHighAPI_RefAttr & theObject); + const ModelHighAPI_RefAttr & theObject, + bool is_active = true); /// Set horizontal SKETCHAPI_EXPORT std::shared_ptr setHorizontal( - const ModelHighAPI_RefAttr & theLine); + const ModelHighAPI_RefAttr & theLine, + bool is_active = true); /// Set length SKETCHAPI_EXPORT std::shared_ptr setLength( const ModelHighAPI_RefAttr & theLine, - const ModelHighAPI_Double & theValue); + const ModelHighAPI_Double & theValue, + bool is_active = true); /// Set middle SKETCHAPI_EXPORT std::shared_ptr setMiddlePoint( const ModelHighAPI_RefAttr & thePoint, - const ModelHighAPI_RefAttr & theLine); + const ModelHighAPI_RefAttr & theLine, + bool is_active = true); /// Set middle SKETCHAPI_EXPORT - std::shared_ptr setMiddlePoint( - const ModelHighAPI_RefAttr& theLine); + std::shared_ptr setMiddlePoint( + const ModelHighAPI_RefAttr& theLine, + bool is_active = true); /// Set parallel SKETCHAPI_EXPORT std::shared_ptr setParallel( const ModelHighAPI_RefAttr & theLine1, - const ModelHighAPI_RefAttr & theLine2); + const ModelHighAPI_RefAttr & theLine2, + bool is_active = true); /// Set perpendicular SKETCHAPI_EXPORT std::shared_ptr setPerpendicular( const ModelHighAPI_RefAttr & theLine1, - const ModelHighAPI_RefAttr & theLine2); + const ModelHighAPI_RefAttr & theLine2, + bool is_active = true); /// Set radius SKETCHAPI_EXPORT std::shared_ptr setRadius( const ModelHighAPI_RefAttr & theCircleOrArc, - const ModelHighAPI_Double & theValue); + const ModelHighAPI_Double & theValue, + bool is_active = true); /// Set tangent SKETCHAPI_EXPORT std::shared_ptr setTangent( const ModelHighAPI_RefAttr & theLine, - const ModelHighAPI_RefAttr & theCircle); + const ModelHighAPI_RefAttr & theCircle, + bool is_active = true); /// Set vertical SKETCHAPI_EXPORT std::shared_ptr setVertical( - const ModelHighAPI_RefAttr & theLine); + const ModelHighAPI_RefAttr & theLine, + bool is_active = true); /// Set constraint value SKETCHAPI_EXPORT diff --git a/src/SketchPlugin/SketchPlugin_Constraint.h b/src/SketchPlugin/SketchPlugin_Constraint.h index 2cc8555f9..bfeec45af 100644 --- a/src/SketchPlugin/SketchPlugin_Constraint.h +++ b/src/SketchPlugin/SketchPlugin_Constraint.h @@ -21,8 +21,10 @@ #define SketchPlugin_Constraint_H_ #include +#include #include +#include /// Size of the list of constraint attributes const int CONSTRAINT_ATTR_SIZE = 4; @@ -46,6 +48,12 @@ class SketchPlugin_Constraint : public SketchPlugin_Feature static const std::string MY_FLYOUT_VALUE_PNT("ConstraintFlyoutValuePnt"); return MY_FLYOUT_VALUE_PNT; } + /// State of constraint - Active - true, Suppressed - false + inline static const std::string& CONSTRAINT_ACTIVE() + { + static const std::string MY_STATE("ConstraintState"); + return MY_STATE; + } /// First entity for the constraint inline static const std::string& ENTITY_A() { @@ -90,6 +98,25 @@ class SketchPlugin_Constraint : public SketchPlugin_Feature return EMPTY_STRING; } + /// Get if a constraint is able to have a zero numeric value + virtual inline bool isZeroValueAllowed() + { + return true; + } + + /// Set numeric value to atribute VALUE() + /// \param theValue new set value + virtual inline void setNumericValue(const double theValue) + { + real(VALUE())->setValue(theValue); + } + + /// Get numeric value of atribute VALUE() + virtual inline double getNumericValue() + { + return real(VALUE())? real(VALUE())->value(): std::numeric_limits::lowest(); + } + protected: /// \brief Use plugin manager for features creation SketchPlugin_Constraint(); diff --git a/src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp b/src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp index a653e62cb..84371f335 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp @@ -105,12 +105,18 @@ void SketchPlugin_ConstraintAngle::initAttributes() AttributeIntegerPtr aVerAttr = std::dynamic_pointer_cast( data()->addAttribute(VERSION_ID(), ModelAPI_AttributeInteger::typeId())); aVerAttr->setIsArgument(false); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), VERSION_ID()); if (!aVerAttr->isInitialized()) { // this is a newly created feature (not read from file), // so, initialize the latest version aVerAttr->setValue(THE_VERSION_1); } + + AttributeBooleanPtr anActiveAttr = std::dynamic_pointer_cast( + data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId())); + if (!anActiveAttr->isInitialized()) + anActiveAttr->setValue(true); } void SketchPlugin_ConstraintAngle::colorConfigInfo(std::string& theSection, std::string& theName, @@ -160,6 +166,12 @@ AISObjectPtr SketchPlugin_ConstraintAngle::getAISObject(AISObjectPtr thePrevious return anAIS; } +void SketchPlugin_ConstraintAngle::setNumericValue(const double theValue) +{ + SketchPlugin_Constraint::setNumericValue(theValue); + real(ANGLE_VALUE_ID())->setValue(theValue); +} + // LCOV_EXCL_START std::string SketchPlugin_ConstraintAngle::processEvent( const std::shared_ptr& theMessage) diff --git a/src/SketchPlugin/SketchPlugin_ConstraintAngle.h b/src/SketchPlugin/SketchPlugin_ConstraintAngle.h index bc71c6304..b277321f4 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintAngle.h +++ b/src/SketchPlugin/SketchPlugin_ConstraintAngle.h @@ -26,6 +26,8 @@ #include +#include + /** \class SketchPlugin_ConstraintAngle * \ingroup Plugins * \brief Feature for creation of a new constraint fix angle between two lines @@ -138,6 +140,16 @@ public: /// Returns the AIS preview SKETCHPLUGIN_EXPORT virtual AISObjectPtr getAISObject(AISObjectPtr thePrevious); + /// Set numeric value to atribute ANGLE_VALUE_ID() + /// \param theValue new set value + void setNumericValue(const double theValue) override; + + /// Get numeric value of atribute MY_ANGLE_VALUE_ID() + inline double getNumericValue() override + { + return real(ANGLE_VALUE_ID())? real(ANGLE_VALUE_ID())->value() : std::numeric_limits::lowest(); + } + /// Apply information of the message to current object. /// It fills selected point and the first object. virtual std::string processEvent(const std::shared_ptr& theMessage); diff --git a/src/SketchPlugin/SketchPlugin_ConstraintCoincidence.cpp b/src/SketchPlugin/SketchPlugin_ConstraintCoincidence.cpp index 5220ac304..101b7e80f 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintCoincidence.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintCoincidence.cpp @@ -40,6 +40,11 @@ void SketchPlugin_ConstraintCoincidence::initAttributes() { data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId()); data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId()); + + AttributeBooleanPtr anActiveAttr = std::dynamic_pointer_cast( + data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId())); + if (!anActiveAttr->isInitialized()) + anActiveAttr->setValue(true); } void SketchPlugin_ConstraintCoincidence::execute() diff --git a/src/SketchPlugin/SketchPlugin_ConstraintCollinear.cpp b/src/SketchPlugin/SketchPlugin_ConstraintCollinear.cpp index c9aee84e5..f7eebabb0 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintCollinear.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintCollinear.cpp @@ -29,6 +29,11 @@ void SketchPlugin_ConstraintCollinear::initAttributes() { data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId()); data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId()); + + AttributeBooleanPtr anActiveAttr = std::dynamic_pointer_cast( + data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId())); + if (!anActiveAttr->isInitialized()) + anActiveAttr->setValue(true); } void SketchPlugin_ConstraintCollinear::execute() diff --git a/src/SketchPlugin/SketchPlugin_ConstraintDistance.cpp b/src/SketchPlugin/SketchPlugin_ConstraintDistance.cpp index 27d48101f..b0707d48d 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintDistance.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintDistance.cpp @@ -68,6 +68,11 @@ void SketchPlugin_ConstraintDistance::initAttributes() GeomDataAPI_Dir::typeId()); anAttr->setIsArgument(false); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), DIRECTION_ID()); + + AttributeBooleanPtr anActiveAttr = std::dynamic_pointer_cast( + data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId())); + if (!anActiveAttr->isInitialized()) + anActiveAttr->setValue(true); } void SketchPlugin_ConstraintDistance::colorConfigInfo(std::string& theSection, std::string& theName, diff --git a/src/SketchPlugin/SketchPlugin_ConstraintDistanceAlongDir.cpp b/src/SketchPlugin/SketchPlugin_ConstraintDistanceAlongDir.cpp index 3d0ce5cd2..13819ac11 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintDistanceAlongDir.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintDistanceAlongDir.cpp @@ -63,6 +63,12 @@ void SketchPlugin_ConstraintDistanceAlongDir::initAttributes() data()->addAttribute(NEGATIVE_TYPE_ID(), ModelAPI_AttributeBoolean::typeId()); boolean(NEGATIVE_TYPE_ID())->setValue(false); + + AttributeBooleanPtr anActiveAttr = std::dynamic_pointer_cast( + data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId())); + if (!anActiveAttr->isInitialized()) + anActiveAttr->setValue(true); + } //************************************************************************************* @@ -90,6 +96,7 @@ AISObjectPtr SketchPlugin_ConstraintDistanceAlongDir::getAISObject(AISObjectPtr return anAIS; } +//************************************************************************************* void SketchPlugin_ConstraintDistanceAlongDir::attributeChanged(const std::string& theID) { if (theID == SketchPlugin_Constraint::ENTITY_A() || @@ -146,3 +153,10 @@ void SketchPlugin_ConstraintDistanceAlongDir::attributeChanged(const std::string myFlyoutUpdate = false; } } + +//************************************************************************************* +void SketchPlugin_ConstraintDistanceAlongDir::setNumericValue(const double theValue) +{ + SketchPlugin_Constraint::setNumericValue(theValue); + real(DISTANCE_VALUE_ID())->setValue(theValue); +} diff --git a/src/SketchPlugin/SketchPlugin_ConstraintDistanceAlongDir.h b/src/SketchPlugin/SketchPlugin_ConstraintDistanceAlongDir.h index 851a74a69..5b86a96f0 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintDistanceAlongDir.h +++ b/src/SketchPlugin/SketchPlugin_ConstraintDistanceAlongDir.h @@ -27,6 +27,8 @@ #include #include +#include + /** \class SketchPlugin_ConstraintDistanceAlongDir * \ingroup Plugins * \brief Feature for creation of a new constraint which defines a distance along direction. @@ -72,6 +74,16 @@ public: /// \param theID identifier of changed attribute SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID); + /// Set numeric value to atribute DISTANCE_VALUE_ID() + /// \param theValue new set value + void setNumericValue(const double theValue) override; + + /// Get numeric value of atribute DISTANCE_VALUE_ID() + inline double getNumericValue() override + { + return real(DISTANCE_VALUE_ID())? real(DISTANCE_VALUE_ID())->value(): std::numeric_limits::lowest(); + } + /// \brief Use plugin manager for features creation SketchPlugin_ConstraintDistanceAlongDir(); diff --git a/src/SketchPlugin/SketchPlugin_ConstraintEqual.cpp b/src/SketchPlugin/SketchPlugin_ConstraintEqual.cpp index 15b650931..2c2f88d7b 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintEqual.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintEqual.cpp @@ -38,6 +38,11 @@ void SketchPlugin_ConstraintEqual::initAttributes() { data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId()); data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId()); + + AttributeBooleanPtr anActiveAttr = std::dynamic_pointer_cast( + data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId())); + if (!anActiveAttr->isInitialized()) + anActiveAttr->setValue(true); } void SketchPlugin_ConstraintEqual::execute() diff --git a/src/SketchPlugin/SketchPlugin_ConstraintHorizontal.cpp b/src/SketchPlugin/SketchPlugin_ConstraintHorizontal.cpp index db64bf260..069a24061 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintHorizontal.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintHorizontal.cpp @@ -38,6 +38,11 @@ SketchPlugin_ConstraintHorizontal::SketchPlugin_ConstraintHorizontal() void SketchPlugin_ConstraintHorizontal::initAttributes() { data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId()); + + AttributeBooleanPtr anActiveAttr = std::dynamic_pointer_cast( + data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId())); + if (!anActiveAttr->isInitialized()) + anActiveAttr->setValue(true); } void SketchPlugin_ConstraintHorizontal::execute() diff --git a/src/SketchPlugin/SketchPlugin_ConstraintLength.cpp b/src/SketchPlugin/SketchPlugin_ConstraintLength.cpp index 96e5b4894..92eb30697 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintLength.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintLength.cpp @@ -60,6 +60,11 @@ void SketchPlugin_ConstraintLength::initAttributes() data()->addAttribute(SketchPlugin_ConstraintLength::LOCATION_TYPE_ID(), ModelAPI_AttributeInteger::typeId()); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), LOCATION_TYPE_ID()); + + AttributeBooleanPtr anActiveAttr = std::dynamic_pointer_cast( + data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId())); + if (!anActiveAttr->isInitialized()) + anActiveAttr->setValue(true); } void SketchPlugin_ConstraintLength::colorConfigInfo(std::string& theSection, std::string& theName, diff --git a/src/SketchPlugin/SketchPlugin_ConstraintLength.h b/src/SketchPlugin/SketchPlugin_ConstraintLength.h index 37de8b939..c1712f25f 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintLength.h +++ b/src/SketchPlugin/SketchPlugin_ConstraintLength.h @@ -93,6 +93,12 @@ class SketchPlugin_ConstraintLength : public SketchPlugin_ConstraintBase /// \return boolean value if distance is computed bool computeLenghtValue(double& theValue); + /// Get if a constraint is able to have a zero numeric value + inline bool isZeroValueAllowed() override + { + return false; + } + private: /// retrns the points-base of length, returns false if it is not possible bool getPoints( diff --git a/src/SketchPlugin/SketchPlugin_ConstraintMiddle.cpp b/src/SketchPlugin/SketchPlugin_ConstraintMiddle.cpp index ecb882bbc..876b0ba0e 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintMiddle.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintMiddle.cpp @@ -121,8 +121,12 @@ void SketchPlugin_ConstraintMiddle::initAttributes() } data()->addAttribute(POINT_REF_ID(), GeomDataAPI_Point2D::typeId()); - ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), POINT_REF_ID()); + + AttributeBooleanPtr anActiveAttr = std::dynamic_pointer_cast( + data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId())); + if (!anActiveAttr->isInitialized()) + anActiveAttr->setValue(true); } void SketchPlugin_ConstraintMiddle::execute() diff --git a/src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp b/src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp index 468b28012..42131b15d 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp @@ -50,6 +50,11 @@ void SketchPlugin_ConstraintMirror::initAttributes() registerNotObligatory(getKind(), SketchPlugin_Constraint::ENTITY_B()); ModelAPI_Session::get()->validators()-> registerNotObligatory(getKind(), SketchPlugin_Constraint::ENTITY_C()); + + AttributeBooleanPtr anActiveAttr = std::dynamic_pointer_cast( + data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId())); + if (!anActiveAttr->isInitialized()) + anActiveAttr->setValue(true); } void SketchPlugin_ConstraintMirror::execute() diff --git a/src/SketchPlugin/SketchPlugin_ConstraintParallel.cpp b/src/SketchPlugin/SketchPlugin_ConstraintParallel.cpp index 9008189d6..fde442d8f 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintParallel.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintParallel.cpp @@ -44,6 +44,11 @@ void SketchPlugin_ConstraintParallel::initAttributes() { data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId()); data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId()); + + AttributeBooleanPtr anActiveAttr = std::dynamic_pointer_cast( + data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId())); + if (!anActiveAttr->isInitialized()) + anActiveAttr->setValue(true); } void SketchPlugin_ConstraintParallel::execute() diff --git a/src/SketchPlugin/SketchPlugin_ConstraintPerpendicular.cpp b/src/SketchPlugin/SketchPlugin_ConstraintPerpendicular.cpp index 934674b30..ed2a3bc21 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintPerpendicular.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintPerpendicular.cpp @@ -43,6 +43,11 @@ void SketchPlugin_ConstraintPerpendicular::initAttributes() { data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId()); data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId()); + + AttributeBooleanPtr anActiveAttr = std::dynamic_pointer_cast( + data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId())); + if (!anActiveAttr->isInitialized()) + anActiveAttr->setValue(true); } void SketchPlugin_ConstraintPerpendicular::execute() diff --git a/src/SketchPlugin/SketchPlugin_ConstraintRadius.cpp b/src/SketchPlugin/SketchPlugin_ConstraintRadius.cpp index 906802732..9afede5aa 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintRadius.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintRadius.cpp @@ -60,6 +60,11 @@ void SketchPlugin_ConstraintRadius::initAttributes() data()->addAttribute(SketchPlugin_ConstraintRadius::LOCATION_TYPE_ID(), ModelAPI_AttributeInteger::typeId()); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), LOCATION_TYPE_ID()); + + AttributeBooleanPtr anActiveAttr = std::dynamic_pointer_cast( + data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId())); + if (!anActiveAttr->isInitialized()) + anActiveAttr->setValue(true); } void SketchPlugin_ConstraintRadius::colorConfigInfo(std::string& theSection, std::string& theName, diff --git a/src/SketchPlugin/SketchPlugin_ConstraintRigid.cpp b/src/SketchPlugin/SketchPlugin_ConstraintRigid.cpp index f693756c6..2ebfbaa56 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintRigid.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintRigid.cpp @@ -36,6 +36,11 @@ SketchPlugin_ConstraintRigid::SketchPlugin_ConstraintRigid() void SketchPlugin_ConstraintRigid::initAttributes() { data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId()); + + AttributeBooleanPtr anActiveAttr = std::dynamic_pointer_cast( + data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId())); + if (!anActiveAttr->isInitialized()) + anActiveAttr->setValue(true); } void SketchPlugin_ConstraintRigid::execute() diff --git a/src/SketchPlugin/SketchPlugin_ConstraintTangent.cpp b/src/SketchPlugin/SketchPlugin_ConstraintTangent.cpp index 0e8ec34e3..40c712e4c 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintTangent.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintTangent.cpp @@ -38,6 +38,11 @@ void SketchPlugin_ConstraintTangent::initAttributes() { data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId()); data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId()); + + AttributeBooleanPtr anActiveAttr = std::dynamic_pointer_cast( + data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId())); + if (!anActiveAttr->isInitialized()) + anActiveAttr->setValue(true); } void SketchPlugin_ConstraintTangent::execute() diff --git a/src/SketchPlugin/SketchPlugin_ConstraintVertical.cpp b/src/SketchPlugin/SketchPlugin_ConstraintVertical.cpp index bdbdf711e..76bf23395 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintVertical.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintVertical.cpp @@ -37,6 +37,11 @@ SketchPlugin_ConstraintVertical::SketchPlugin_ConstraintVertical() void SketchPlugin_ConstraintVertical::initAttributes() { data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId()); + + AttributeBooleanPtr anActiveAttr = std::dynamic_pointer_cast( + data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId())); + if (!anActiveAttr->isInitialized()) + anActiveAttr->setValue(true); } void SketchPlugin_ConstraintVertical::execute() diff --git a/src/SketchPlugin/SketchPlugin_MultiRotation.cpp b/src/SketchPlugin/SketchPlugin_MultiRotation.cpp index 66463e83c..24cca8f12 100644 --- a/src/SketchPlugin/SketchPlugin_MultiRotation.cpp +++ b/src/SketchPlugin/SketchPlugin_MultiRotation.cpp @@ -68,6 +68,11 @@ void SketchPlugin_MultiRotation::initAttributes() registerNotObligatory(getKind(), SketchPlugin_Constraint::ENTITY_A()); ModelAPI_Session::get()->validators()-> registerNotObligatory(getKind(), SketchPlugin_Constraint::ENTITY_B()); + + AttributeBooleanPtr anActiveAttr = std::dynamic_pointer_cast( + data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId())); + if (!anActiveAttr->isInitialized()) + anActiveAttr->setValue(true); } void SketchPlugin_MultiRotation::execute() diff --git a/src/SketchPlugin/SketchPlugin_MultiTranslation.cpp b/src/SketchPlugin/SketchPlugin_MultiTranslation.cpp index 5091d98d6..60b50b28f 100644 --- a/src/SketchPlugin/SketchPlugin_MultiTranslation.cpp +++ b/src/SketchPlugin/SketchPlugin_MultiTranslation.cpp @@ -56,6 +56,11 @@ void SketchPlugin_MultiTranslation::initAttributes() registerNotObligatory(getKind(), SketchPlugin_Constraint::ENTITY_A()); ModelAPI_Session::get()->validators()-> registerNotObligatory(getKind(), SketchPlugin_Constraint::ENTITY_B()); + + AttributeBooleanPtr anActiveAttr = std::dynamic_pointer_cast( + data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId())); + if (!anActiveAttr->isInitialized()) + anActiveAttr->setValue(true); } void SketchPlugin_MultiTranslation::execute() diff --git a/src/SketchPlugin/SketchPlugin_Offset.cpp b/src/SketchPlugin/SketchPlugin_Offset.cpp index 402a9f57b..68461c60c 100644 --- a/src/SketchPlugin/SketchPlugin_Offset.cpp +++ b/src/SketchPlugin/SketchPlugin_Offset.cpp @@ -135,6 +135,11 @@ void SketchPlugin_Offset::initAttributes() // Initialize approximation to false by default for backward compatibility if (!approxAttr->isInitialized()) approxAttr->setValue(false); + + AttributeBooleanPtr anActiveAttr = std::dynamic_pointer_cast( + data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId())); + if (!anActiveAttr->isInitialized()) + anActiveAttr->setValue(true); } void SketchPlugin_Offset::execute() diff --git a/src/SketchPlugin/doc/SketchPlugin.rst b/src/SketchPlugin/doc/SketchPlugin.rst index d1c47eb22..cd146e687 100644 --- a/src/SketchPlugin/doc/SketchPlugin.rst +++ b/src/SketchPlugin/doc/SketchPlugin.rst @@ -53,6 +53,15 @@ After the plane for sketch is selected, the following property panel will be ope - **Change sketch plane** button - allows to change working plane of the current sketch. - **Show remaining DoFs** button - highlights all sketch edges which are not fully constrained. +A window containing the specified constraints will also appear: + +.. figure:: images/ConstraintsBrowser.png + :align: center + + Sketch constraints browser + +**See** :ref:`sketchConstraintsBrowsers` + Now it is possible to: - create :ref:`sketch objects ` diff --git a/src/SketchPlugin/doc/images/ConstraintsBrowser.png b/src/SketchPlugin/doc/images/ConstraintsBrowser.png new file mode 100644 index 000000000..47f40ab97 Binary files /dev/null and b/src/SketchPlugin/doc/images/ConstraintsBrowser.png differ diff --git a/src/SketchPlugin/doc/images/constraints_suppressed.png b/src/SketchPlugin/doc/images/constraints_suppressed.png new file mode 100644 index 000000000..66ea1de97 Binary files /dev/null and b/src/SketchPlugin/doc/images/constraints_suppressed.png differ diff --git a/src/SketchPlugin/doc/images/constraints_suppressed_moved.png b/src/SketchPlugin/doc/images/constraints_suppressed_moved.png new file mode 100644 index 000000000..1809edee5 Binary files /dev/null and b/src/SketchPlugin/doc/images/constraints_suppressed_moved.png differ diff --git a/src/SketchPlugin/doc/sketchConstraintsBrowser.rst b/src/SketchPlugin/doc/sketchConstraintsBrowser.rst new file mode 100644 index 000000000..1ba6ad4b9 --- /dev/null +++ b/src/SketchPlugin/doc/sketchConstraintsBrowser.rst @@ -0,0 +1,52 @@ + +.. _sketchConstraintsBrowsers: + +Sketch Constraints Browser +================ +.. figure:: images/ConstraintsBrowser.png + :align: center + + Sketch constraints browser + +- **Extended Information** check box - show/hide **Primitives** and **Parameter** columns + +Right click on any constraint opens context menu: + +- **Edit...** - edit value of constraint's numeric parameter, if it exists +- **Delete** - delete constraints +- **Deactivate/Activate** - (de)activate constraints + +Edit +================ + +For constraints with a numeric parameter (Angle, Length, Radius e.t.c.), values can be changed in the following ways: + +1. Select one/multiple constraint(s) -> right click -> Edit... -> hit Enter to apply; + +2. Double click on a constraint value. + +**Limitations:** + +1. It is not possible to set negative values to all constraints with a numeric parameter + +2. It is not possible to set zero value to "Length constraint" + +Delete +================ + +Select one/multiple constraint(s) -> rightg click -> Delete. + +Deactivate +================ + +.. figure:: images/constraints_suppressed.png + :align: center + + Suppressed constraints + +.. figure:: images/constraints_suppressed_moved.png + :align: center + + Suppressed constraints moved + +Activates/deactivates applied constraints. Deactivating the constraint allows to examine and manipulate the sketch or shape as if the constraint wasn't there. diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp index aecba9754..d4813735b 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp @@ -66,7 +66,8 @@ void PlaneGCSSolver_Storage::addConstraint( { SketchSolver_Storage::addConstraint(theConstraint, theSolverConstraint); - theSolverConstraint->setId(++myConstraintLastID); + if (theSolverConstraint->id() == 0) + theSolverConstraint->setId(++myConstraintLastID); constraintsToSolver(theSolverConstraint, mySketchSolver); } @@ -523,6 +524,59 @@ bool PlaneGCSSolver_Storage::removeConstraint(ConstraintPtr theConstraint) return true; } +bool PlaneGCSSolver_Storage::changeActiveStatus(ConstraintPtr theConstraint, bool theNewState) +{ + if (theNewState) + { + // activate + auto aPair = myDeactivatedConstraintMap.find(theConstraint); + if (aPair == myDeactivatedConstraintMap.end()) + return false; + + addConstraint(theConstraint, aPair->second); + } + else + { + // suppress + auto aPair = myConstraintMap.find(theConstraint); + if (aPair == myConstraintMap.end()) + return false; + myDeactivatedConstraintMap.insert((*aPair)); + + ConstraintWrapperPtr aCW = aPair->second; + ConstraintID anID = aCW->id(); + mySketchSolver->removeConstraint(anID); + myConstraintMap.erase(theConstraint); + } + myNeedToResolve = true; + notify(theConstraint); + + return true; +} + +bool PlaneGCSSolver_Storage::UpdateDeactivateList() +{ + std::list toRemove; + for (auto& aDeactMap : myDeactivatedConstraintMap) + { + if (!aDeactMap.first->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())) + { + toRemove.push_back(aDeactMap.first); + } + else if(aDeactMap.first->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())->value()) + { + changeActiveStatus(aDeactMap.first, true); + toRemove.push_back(aDeactMap.first); + } + } + for (auto& aRemove : toRemove) + { + myDeactivatedConstraintMap.erase(aRemove); + } + + return true; +} + void PlaneGCSSolver_Storage::removeInvalidEntities() { PlaneGCSSolver_EntityDestroyer aDestroyer; diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h index 9f67d498a..2ebfebb10 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h @@ -70,6 +70,11 @@ public: /// \return \c true if the constraint and all its parameters are removed successfully virtual bool removeConstraint(ConstraintPtr theConstraint); + // Change status of constraints. + virtual bool changeActiveStatus(ConstraintPtr theConstraint, bool theNewState); + + virtual bool UpdateDeactivateList(); + /// \brief Verify, the sketch contains degenerated geometry /// after resolving the set of constraints /// \return STATUS_OK if the geometry is valid, STATUS_DEGENERATED otherwise. diff --git a/src/SketchSolver/SketchSolver_ConstraintDistance.cpp b/src/SketchSolver/SketchSolver_ConstraintDistance.cpp index 4ecb036e5..44acce9bf 100644 --- a/src/SketchSolver/SketchSolver_ConstraintDistance.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintDistance.cpp @@ -215,6 +215,10 @@ void SketchSolver_ConstraintDistance::adjustConstraint() void SketchSolver_ConstraintDistance::update() { ConstraintWrapperPtr aConstraint = myStorage->constraint(myBaseConstraint); + + if (!aConstraint) + return; + myPrevValue = aConstraint->value(); bool isDistanceAlognDir = diff --git a/src/SketchSolver/SketchSolver_Group.cpp b/src/SketchSolver/SketchSolver_Group.cpp index 83fafe3b1..6bcf0c542 100644 --- a/src/SketchSolver/SketchSolver_Group.cpp +++ b/src/SketchSolver/SketchSolver_Group.cpp @@ -231,6 +231,21 @@ bool SketchSolver_Group::movePoint(AttributePtr theAttribute, // ============================================================================ bool SketchSolver_Group::resolveConstraints() { + auto aNb = mySketch->numberOfSubs(); + std::list aList; + for (int i = 0; i < aNb; ++i) + if (mySketch->subFeature(i)->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE()) && !mySketch->subFeature(i)->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())->value()) + aList.push_back(std::dynamic_pointer_cast(mySketch->subFeature(i))); + + while (aList.size() > 0) + { + auto aConstr = aList.front(); + aList.pop_front(); + myStorage->changeActiveStatus(aConstr, false); + } + + myStorage->UpdateDeactivateList(); + static const int MAX_STACK_SIZE = 5; // check the "Multi" constraints do not drop sketch into infinite loop if (myMultiConstraintUpdateStack > MAX_STACK_SIZE) { diff --git a/src/SketchSolver/SketchSolver_Storage.h b/src/SketchSolver/SketchSolver_Storage.h index a5e773f4a..1755c19b1 100644 --- a/src/SketchSolver/SketchSolver_Storage.h +++ b/src/SketchSolver/SketchSolver_Storage.h @@ -103,6 +103,11 @@ public: /// \brief Removes constraint from the storage /// \return \c true if the constraint and all its parameters are removed successfully virtual bool removeConstraint(ConstraintPtr theConstraint) = 0; + + virtual bool changeActiveStatus(ConstraintPtr theConstraint, bool theNewState) = 0; + + virtual bool UpdateDeactivateList() = 0; + /// \brief Removes feature from the storage void removeFeature(FeaturePtr theFeature); /// \brief Removes attribute from the storage @@ -177,6 +182,7 @@ protected: std::map myAttributeMap; UpdaterPtr myUpdaters; + std::map myDeactivatedConstraintMap; }; typedef std::shared_ptr StoragePtr; diff --git a/src/SketcherPrs/CMakeLists.txt b/src/SketcherPrs/CMakeLists.txt index 288babe53..b5e622d60 100644 --- a/src/SketcherPrs/CMakeLists.txt +++ b/src/SketcherPrs/CMakeLists.txt @@ -94,14 +94,23 @@ ENDIF() SET(PROJECT_PICTURES icons/collinear.png + icons/collinear_deactivate.png icons/parallel.png + icons/parallel_deactivate.png icons/perpendicular.png + icons/perpendicular_deactivate.png icons/anchor.png + icons/anchor_deactivate.png icons/horisontal.png + icons/horisontal_deactivate.png icons/vertical.png + icons/vertical_deactivate.png icons/equal.png + icons/equal_deactivate.png icons/tangent.png + icons/tangent_deactivate.png icons/middlepoint.png + icons/middlepoint_deactivate.png icons/mirror.png icons/rotate.png icons/translate.png diff --git a/src/SketcherPrs/SketcherPrs_Angle.cpp b/src/SketcherPrs/SketcherPrs_Angle.cpp index 444f8d69d..1136c19ea 100644 --- a/src/SketcherPrs/SketcherPrs_Angle.cpp +++ b/src/SketcherPrs/SketcherPrs_Angle.cpp @@ -48,6 +48,7 @@ /// \param theDimAspect an aspect to be changed /// \param theDimValue an arrow value /// \param theTextSize an arrow value +/// \param theIsActivated state of constraint extern void updateArrows(Handle(Prs3d_DimensionAspect) theDimAspect, double theDimValue, double theTextSize, SketcherPrs_Tools::LocationType theLocationType); @@ -247,7 +248,7 @@ void SketcherPrs_Angle::Compute(const Handle(PrsMgr_PresentationManager3d)& theP SetFlyout(aDist); // Update text visualization: parameter value or parameter text - myStyleListener->updateDimensions(this, myValue); + myStyleListener->updateDimensions(this, myValue, !aData->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())->value()); double aTextSize = 0.0; GetValueString(aTextSize); diff --git a/src/SketcherPrs/SketcherPrs_Collinear.h b/src/SketcherPrs/SketcherPrs_Collinear.h index 88dc318d6..b75cabf93 100644 --- a/src/SketcherPrs/SketcherPrs_Collinear.h +++ b/src/SketcherPrs/SketcherPrs_Collinear.h @@ -49,7 +49,7 @@ public: const std::shared_ptr& thePlane); protected: - virtual const char* iconName() const { return "collinear.png"; } + virtual const char* iconName(bool isActiveIcon = true) const { return isActiveIcon ? "collinear.png" : "collinear_deactivate.png"; } virtual void drawLines(const Handle(Prs3d_Presentation)& thePrs, Quantity_Color theColor) const; diff --git a/src/SketcherPrs/SketcherPrs_DimensionStyle.cpp b/src/SketcherPrs/SketcherPrs_DimensionStyle.cpp index fa3073713..b76fc48aa 100644 --- a/src/SketcherPrs/SketcherPrs_DimensionStyle.cpp +++ b/src/SketcherPrs/SketcherPrs_DimensionStyle.cpp @@ -64,18 +64,18 @@ SketcherPrs_DimensionStyle::~SketcherPrs_DimensionStyle() } void SketcherPrs_DimensionStyle::updateDimensions(PrsDim_Dimension* theDimension, - const SketcherPrs_DimensionStyle::DimensionValue& theDimensionValue) + const SketcherPrs_DimensionStyle::DimensionValue& theDimensionValue, bool theIsSuppress) { if (!theDimension) return; updateDimensions(theDimension, theDimensionValue.myHasParameters, - theDimensionValue.myTextValue, theDimensionValue.myDoubleValue); + theDimensionValue.myTextValue, theDimensionValue.myDoubleValue, theIsSuppress); } void SketcherPrs_DimensionStyle::updateDimensions(PrsDim_Dimension* theDimension, const bool theHasParameters, const std::string& theTextValue, - const double theDoubleValue) + const double theDoubleValue, bool theIsSuppress) { if (!theDimension) return; @@ -90,13 +90,31 @@ void SketcherPrs_DimensionStyle::updateDimensions(PrsDim_Dimension* theDimension #endif TCollection_ExtendedString aCustomValue; - if (theHasParameters) { - //bool isParameterTextStyle = myStyle == SketcherPrs_ParameterStyleMessage::ParameterText; - bool isParameterTextStyle = - SketcherPrs_Tools::parameterStyle() == SketcherPrs_Tools::ParameterText; - - if (isParameterTextStyle) - aCustomValue = theTextValue.c_str(); + if (theIsSuppress) + { + // for suppressed constraints not need show value + aCustomValue = TCollection_ExtendedString(MyEmptySymbol); + } + else + { + if (theHasParameters) { + //bool isParameterTextStyle = myStyle == SketcherPrs_ParameterStyleMessage::ParameterText; + bool isParameterTextStyle = + SketcherPrs_Tools::parameterStyle() == SketcherPrs_Tools::ParameterText; + + if (isParameterTextStyle) + aCustomValue = theTextValue.c_str(); + else { + // format value string using "sprintf" + TCollection_AsciiString aFormatStr = + theDimension->Attributes()->DimensionAspect()->ValueStringFormat(); + char aFmtBuffer[256]; + sprintf(aFmtBuffer, aFormatStr.ToCString(), theDoubleValue); + aCustomValue = TCollection_ExtendedString(aFmtBuffer); + + aCustomValue.Insert(1, MySigmaSymbol); + } + } else { // format value string using "sprintf" TCollection_AsciiString aFormatStr = @@ -104,18 +122,8 @@ void SketcherPrs_DimensionStyle::updateDimensions(PrsDim_Dimension* theDimension char aFmtBuffer[256]; sprintf (aFmtBuffer, aFormatStr.ToCString(), theDoubleValue); aCustomValue = TCollection_ExtendedString (aFmtBuffer); - - aCustomValue.Insert (1, MySigmaSymbol); } } - else { - // format value string using "sprintf" - TCollection_AsciiString aFormatStr = - theDimension->Attributes()->DimensionAspect()->ValueStringFormat(); - char aFmtBuffer[256]; - sprintf (aFmtBuffer, aFormatStr.ToCString(), theDoubleValue); - aCustomValue = TCollection_ExtendedString (aFmtBuffer); - } #ifdef COMPILATION_CORRECTION theDimension->SetCustomValue(theDoubleValue); #else diff --git a/src/SketcherPrs/SketcherPrs_DimensionStyle.h b/src/SketcherPrs/SketcherPrs_DimensionStyle.h index 817155885..76487f07e 100644 --- a/src/SketcherPrs/SketcherPrs_DimensionStyle.h +++ b/src/SketcherPrs/SketcherPrs_DimensionStyle.h @@ -64,7 +64,7 @@ public: /// \param theDimension a modified dimension /// \param theDimensionValue container filled by the model double attribute Standard_EXPORT void updateDimensions(PrsDim_Dimension* theDimension, - const DimensionValue& theDimensionValue); + const DimensionValue& theDimensionValue, bool theIsSuppress/* = false*/); private: /// Visualizes the dimension text or dimension value depending on the has parameters state @@ -72,10 +72,11 @@ private: /// \param theHasParameters if true, the text is shown, else digit /// \param theTextValue a dimension text value /// \param theDoubleValue a dimension digit value + /// \param theIsSuppress a state of constraint (active or not) void updateDimensions(PrsDim_Dimension* theDimension, const bool theHasParameters, const std::string& theTextValue, - const double theDoubleValue); + const double theDoubleValue, bool theIsSuppress/* = false*/); }; #endif \ No newline at end of file diff --git a/src/SketcherPrs/SketcherPrs_Equal.h b/src/SketcherPrs/SketcherPrs_Equal.h index 2e75f77bd..ce285dca7 100644 --- a/src/SketcherPrs/SketcherPrs_Equal.h +++ b/src/SketcherPrs/SketcherPrs_Equal.h @@ -48,7 +48,7 @@ public: const std::shared_ptr& thePlane); protected: - virtual const char* iconName() const { return "equal.png"; } + virtual const char* iconName(bool isActiveIcon = true) const { return isActiveIcon ? "equal.png" : "equal_deactivate.png"; } virtual void drawLines(const Handle(Prs3d_Presentation)& thePrs, Quantity_Color theColor) const; diff --git a/src/SketcherPrs/SketcherPrs_HVDirection.h b/src/SketcherPrs/SketcherPrs_HVDirection.h index caeef2731..9a09e11c7 100644 --- a/src/SketcherPrs/SketcherPrs_HVDirection.h +++ b/src/SketcherPrs/SketcherPrs_HVDirection.h @@ -51,7 +51,12 @@ public: const std::shared_ptr& thePlane); protected: - virtual const char* iconName() const { return myIsHorisontal? "horisontal.png" : "vertical.png"; } + virtual const char* iconName(bool isActiveIcon = true) const { + if (isActiveIcon) + return myIsHorisontal? "horisontal.png" : "vertical.png"; + else + return myIsHorisontal ? "horisontal_deactivate.png" : "vertical_deactivate.png"; + } /// Redefine this function in order to add additiona lines of constraint base /// \param thePrs a presentation diff --git a/src/SketcherPrs/SketcherPrs_LengthDimension.cpp b/src/SketcherPrs/SketcherPrs_LengthDimension.cpp index 3567a212a..355d9bc0c 100644 --- a/src/SketcherPrs/SketcherPrs_LengthDimension.cpp +++ b/src/SketcherPrs/SketcherPrs_LengthDimension.cpp @@ -225,7 +225,7 @@ void SketcherPrs_LengthDimension::Compute( updateArrows(DimensionAspect(), GetValue(), aTextSize, aLocationType); // Update text visualization: parameter value or parameter text - myStyleListener->updateDimensions(this, myValue); + myStyleListener->updateDimensions(this, myValue, !myConstraint->data()->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())->value()); PrsDim_LengthDimension::Compute(thePresentationManager, thePresentation, theMode); diff --git a/src/SketcherPrs/SketcherPrs_Middle.h b/src/SketcherPrs/SketcherPrs_Middle.h index b49284fdb..553613211 100644 --- a/src/SketcherPrs/SketcherPrs_Middle.h +++ b/src/SketcherPrs/SketcherPrs_Middle.h @@ -48,7 +48,7 @@ public: const std::shared_ptr& thePlane); protected: - virtual const char* iconName() const { return "middlepoint.png"; } + virtual const char* iconName(bool isActiveIcon = true) const { return isActiveIcon ? "middlepoint.png" : "middlepoint_deactivate.png"; } virtual void drawLines(const Handle(Prs3d_Presentation)& thePrs, Quantity_Color theColor) const; diff --git a/src/SketcherPrs/SketcherPrs_Mirror.h b/src/SketcherPrs/SketcherPrs_Mirror.h index 6a5200fce..a24e8f364 100644 --- a/src/SketcherPrs/SketcherPrs_Mirror.h +++ b/src/SketcherPrs/SketcherPrs_Mirror.h @@ -47,7 +47,7 @@ public: static bool IsReadyToDisplay(ModelAPI_Feature* theConstraint, const std::shared_ptr& thePlane); protected: - virtual const char* iconName() const { return "mirror.png"; } + virtual const char* iconName(bool /*isActiveIcon*/) const { return "mirror.png"; } virtual void drawLines(const Handle(Prs3d_Presentation)& thePrs, Quantity_Color theColor) const; diff --git a/src/SketcherPrs/SketcherPrs_Offset.h b/src/SketcherPrs/SketcherPrs_Offset.h index 246dc6c35..5e11e28e3 100644 --- a/src/SketcherPrs/SketcherPrs_Offset.h +++ b/src/SketcherPrs/SketcherPrs_Offset.h @@ -49,7 +49,7 @@ public: const std::shared_ptr& thePlane); protected: - virtual const char* iconName() const { return "offset.png"; } + virtual const char* iconName(bool /*isActiveIcon*/) const { return "offset.png"; } virtual void drawLines(const Handle(Prs3d_Presentation)& thePrs, Quantity_Color theColor) const; diff --git a/src/SketcherPrs/SketcherPrs_Parallel.h b/src/SketcherPrs/SketcherPrs_Parallel.h index 27e0e6fd9..a4cfa017b 100644 --- a/src/SketcherPrs/SketcherPrs_Parallel.h +++ b/src/SketcherPrs/SketcherPrs_Parallel.h @@ -48,7 +48,7 @@ public: const std::shared_ptr& thePlane); protected: - virtual const char* iconName() const { return "parallel.png"; } + virtual const char* iconName(bool isActiveIcon = true) const { return isActiveIcon ? "parallel.png" : "parallel_deactivate.png"; } virtual void drawLines(const Handle(Prs3d_Presentation)& thePrs, Quantity_Color theColor) const; diff --git a/src/SketcherPrs/SketcherPrs_Perpendicular.h b/src/SketcherPrs/SketcherPrs_Perpendicular.h index e5a740544..aae490ceb 100644 --- a/src/SketcherPrs/SketcherPrs_Perpendicular.h +++ b/src/SketcherPrs/SketcherPrs_Perpendicular.h @@ -50,7 +50,7 @@ public: static bool IsReadyToDisplay(ModelAPI_Feature* theConstraint, const std::shared_ptr& thePlane); protected: - virtual const char* iconName() const { return "perpendicular.png"; } + virtual const char* iconName(bool isActiveIcon = true) const { return isActiveIcon ? "perpendicular.png" : "perpendicular_deactivate.png"; } /// Redefine this function in order to add additiona lines of constraint base /// \param thePrs a presentation diff --git a/src/SketcherPrs/SketcherPrs_Radius.cpp b/src/SketcherPrs/SketcherPrs_Radius.cpp index 3a1771ea8..6b2713de6 100644 --- a/src/SketcherPrs/SketcherPrs_Radius.cpp +++ b/src/SketcherPrs/SketcherPrs_Radius.cpp @@ -160,7 +160,7 @@ void SketcherPrs_Radius::Compute( } SetMeasuredGeometry(myCircle, myAnchorPoint); - myStyleListener->updateDimensions(this, myValue); + myStyleListener->updateDimensions(this, myValue, !myConstraint->data()->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())->value()); // Update variable aspect parameters (depending on viewer scale) double aTextSize = 0.0; diff --git a/src/SketcherPrs/SketcherPrs_Rigid.h b/src/SketcherPrs/SketcherPrs_Rigid.h index ceee0ce02..36e9219a6 100644 --- a/src/SketcherPrs/SketcherPrs_Rigid.h +++ b/src/SketcherPrs/SketcherPrs_Rigid.h @@ -51,7 +51,7 @@ public: static bool IsReadyToDisplay(ModelAPI_Feature* theConstraint, const std::shared_ptr& thePlane); protected: - virtual const char* iconName() const { return "anchor.png"; } + virtual const char* iconName(bool isActiveIcon = true) const { return isActiveIcon ? "anchor.png" : "anchor_deactivate.png"; } /// Redefine this function in order to add additiona lines of constraint base /// \param thePrs a presentation diff --git a/src/SketcherPrs/SketcherPrs_SymbolPrs.cpp b/src/SketcherPrs/SketcherPrs_SymbolPrs.cpp index de2569009..81dd5cc2b 100644 --- a/src/SketcherPrs/SketcherPrs_SymbolPrs.cpp +++ b/src/SketcherPrs/SketcherPrs_SymbolPrs.cpp @@ -159,8 +159,9 @@ SketcherPrs_SymbolPrs::~SketcherPrs_SymbolPrs() //********************************************************************************* Handle(Image_AlienPixMap) SketcherPrs_SymbolPrs::icon() { - if (myIconsMap.count(iconName()) == 1) { - return myIconsMap[iconName()]; + auto isIconType = myConstraint->boolean("ConstraintState")->value(); + if (myIconsMap.count(iconName(isIconType)) == 1) { + return myIconsMap[iconName(isIconType)]; } // Load icon for the presentation std::string aFile; @@ -175,7 +176,7 @@ Handle(Image_AlienPixMap) SketcherPrs_SymbolPrs::icon() } aFile += FSEP; - aFile += iconName(); + aFile += iconName(isIconType); Handle(Image_AlienPixMap) aPixMap = new Image_AlienPixMap(); if (aPixMap->Load(aFile.c_str())) { const double aRatio = SketcherPrs_Tools::pixelRatio(); @@ -192,14 +193,14 @@ Handle(Image_AlienPixMap) SketcherPrs_SymbolPrs::icon() } aPixMap = aSizedMap; } - myIconsMap[iconName()] = aPixMap; + myIconsMap[iconName(isIconType)] = aPixMap; return aPixMap; } // The icon for constraint is not found static const char aMsg[] = "Error! constraint images are not found"; std::cout<SetColor(myCustomColor); - } + Handle(Image_AlienPixMap) aIcon = icon(); + if (aIcon.IsNull()) + myAspect = new Graphic3d_AspectMarker3d(); + else + myAspect = new Graphic3d_AspectMarker3d(aIcon); } //********************************************************************************* diff --git a/src/SketcherPrs/SketcherPrs_SymbolPrs.h b/src/SketcherPrs/SketcherPrs_SymbolPrs.h index 70bfd7305..5561b3864 100644 --- a/src/SketcherPrs/SketcherPrs_SymbolPrs.h +++ b/src/SketcherPrs/SketcherPrs_SymbolPrs.h @@ -109,7 +109,7 @@ protected: const Standard_Integer aMode); /// Returns an icon file name. Has to be redefined in successors - virtual const char* iconName() const = 0; + virtual const char* iconName(bool isActiveIcon = true) const = 0; /// Check and creates if it is necessary myAspect member. /// It has to be called before the object computation diff --git a/src/SketcherPrs/SketcherPrs_Tangent.h b/src/SketcherPrs/SketcherPrs_Tangent.h index 083287aec..cff9c8474 100644 --- a/src/SketcherPrs/SketcherPrs_Tangent.h +++ b/src/SketcherPrs/SketcherPrs_Tangent.h @@ -50,7 +50,7 @@ public: const std::shared_ptr& thePlane); protected: - virtual const char* iconName() const { return "tangent.png"; } + virtual const char* iconName(bool isActiveIcon = true) const { return isActiveIcon ? "tangent.png" : "tangent_deactivate.png"; } virtual void drawLines(const Handle(Prs3d_Presentation)& thePrs, Quantity_Color theColor) const; diff --git a/src/SketcherPrs/SketcherPrs_Transformation.h b/src/SketcherPrs/SketcherPrs_Transformation.h index b924b970a..5c213b60d 100644 --- a/src/SketcherPrs/SketcherPrs_Transformation.h +++ b/src/SketcherPrs/SketcherPrs_Transformation.h @@ -50,7 +50,7 @@ public: static bool IsReadyToDisplay(ModelAPI_Feature* theConstraint, const std::shared_ptr& thePlane); protected: - virtual const char* iconName() const { return myIsTranslation? "translate.png" : "rotate.png"; } + virtual const char* iconName(bool /*isActiveIcon*/ ) const { return myIsTranslation ? "translate.png" : "rotate.png"; } /// Redefine this function in order to add additiona lines of constraint base /// \param thePrs a presentation diff --git a/src/SketcherPrs/icons/anchor_deactivate.png b/src/SketcherPrs/icons/anchor_deactivate.png new file mode 100644 index 000000000..c03591e15 Binary files /dev/null and b/src/SketcherPrs/icons/anchor_deactivate.png differ diff --git a/src/SketcherPrs/icons/collinear_deactivate.png b/src/SketcherPrs/icons/collinear_deactivate.png new file mode 100644 index 000000000..19c401385 Binary files /dev/null and b/src/SketcherPrs/icons/collinear_deactivate.png differ diff --git a/src/SketcherPrs/icons/equal_deactivate.png b/src/SketcherPrs/icons/equal_deactivate.png new file mode 100644 index 000000000..f865127fc Binary files /dev/null and b/src/SketcherPrs/icons/equal_deactivate.png differ diff --git a/src/SketcherPrs/icons/horisontal_deactivate.png b/src/SketcherPrs/icons/horisontal_deactivate.png new file mode 100644 index 000000000..c11988aea Binary files /dev/null and b/src/SketcherPrs/icons/horisontal_deactivate.png differ diff --git a/src/SketcherPrs/icons/middlepoint_deactivate.png b/src/SketcherPrs/icons/middlepoint_deactivate.png new file mode 100644 index 000000000..bd0ef350d Binary files /dev/null and b/src/SketcherPrs/icons/middlepoint_deactivate.png differ diff --git a/src/SketcherPrs/icons/parallel_deactivate.png b/src/SketcherPrs/icons/parallel_deactivate.png new file mode 100644 index 000000000..49cb518ed Binary files /dev/null and b/src/SketcherPrs/icons/parallel_deactivate.png differ diff --git a/src/SketcherPrs/icons/perpendicular_deactivate.png b/src/SketcherPrs/icons/perpendicular_deactivate.png new file mode 100644 index 000000000..31c1f6dbe Binary files /dev/null and b/src/SketcherPrs/icons/perpendicular_deactivate.png differ diff --git a/src/SketcherPrs/icons/tangent_deactivate.png b/src/SketcherPrs/icons/tangent_deactivate.png new file mode 100644 index 000000000..90bffe48b Binary files /dev/null and b/src/SketcherPrs/icons/tangent_deactivate.png differ diff --git a/src/SketcherPrs/icons/vertical_deactivate.png b/src/SketcherPrs/icons/vertical_deactivate.png new file mode 100644 index 000000000..201f281c7 Binary files /dev/null and b/src/SketcherPrs/icons/vertical_deactivate.png differ diff --git a/src/XGUI/CMakeLists.txt b/src/XGUI/CMakeLists.txt index dd690533e..a8c103fac 100644 --- a/src/XGUI/CMakeLists.txt +++ b/src/XGUI/CMakeLists.txt @@ -58,13 +58,14 @@ SET(PROJECT_HEADERS XGUI_Selection.h XGUI_SelectionActivate.h XGUI_SelectionMgr.h + XGUI_SketchConstraintsBrowser.h XGUI_Tools.h XGUI_TransparencyWidget.h XGUI_ViewerProxy.h XGUI_Workshop.h XGUI_WorkshopListener.h - XGUI_InspectionPanel.h - XGUI_CompressFiles.h + XGUI_InspectionPanel.h + XGUI_CompressFiles.h ) SET(PROJECT_MOC_HEADERS @@ -88,11 +89,12 @@ SET(PROJECT_MOC_HEADERS XGUI_PropertyPanel.h XGUI_PropertyPanelSelector.h XGUI_SelectionMgr.h + XGUI_SketchConstraintsBrowser.h XGUI_TransparencyWidget.h XGUI_ViewerProxy.h XGUI_Workshop.h XGUI_WorkshopListener.h - XGUI_InspectionPanel.h + XGUI_InspectionPanel.h ) # sources / moc wrappings @@ -125,13 +127,14 @@ SET(PROJECT_SOURCES XGUI_Selection.cpp XGUI_SelectionActivate.cpp XGUI_SelectionMgr.cpp + XGUI_SketchConstraintsBrowser.cpp XGUI_Tools.cpp XGUI_TransparencyWidget.cpp XGUI_ViewerProxy.cpp XGUI_Workshop.cpp XGUI_WorkshopListener.cpp - XGUI_InspectionPanel.cpp - XGUI_CompressFiles.cpp + XGUI_InspectionPanel.cpp + XGUI_CompressFiles.cpp ) SET(PROJECT_RESOURCES diff --git a/src/XGUI/XGUI_ActionsMgr.cpp b/src/XGUI/XGUI_ActionsMgr.cpp index aa05544af..49de8deb1 100644 --- a/src/XGUI/XGUI_ActionsMgr.cpp +++ b/src/XGUI/XGUI_ActionsMgr.cpp @@ -121,7 +121,9 @@ void XGUI_ActionsMgr::updateCommandsStatus() { setAllEnabled(); XGUI_Selection* aSelection = myWorkshop->selector()->selection(); - if (aSelection->getSelected(ModuleBase_ISelection::AllControls).size() > 0) + // If ::ConstraintsBrowser and has Coincodence deleted - fail!!! + if (aSelection->getSelected(ModuleBase_ISelection::AllControls).size() > 0 + && aSelection->getSelected(ModuleBase_ISelection::ConstraintsBrowser).size() == 0) updateOnViewSelection(); FeaturePtr anActiveFeature = FeaturePtr(); diff --git a/src/XGUI/XGUI_ContextMenuMgr.cpp b/src/XGUI/XGUI_ContextMenuMgr.cpp index 5b4365658..7e23b10d7 100644 --- a/src/XGUI/XGUI_ContextMenuMgr.cpp +++ b/src/XGUI/XGUI_ContextMenuMgr.cpp @@ -20,6 +20,7 @@ #include "XGUI_ContextMenuMgr.h" #include "XGUI_Workshop.h" #include "XGUI_ObjectsBrowser.h" +#include "XGUI_SketchConstraintsBrowser.h" #include "XGUI_SelectionMgr.h" #include "XGUI_Displayer.h" #include "XGUI_ViewerProxy.h" @@ -101,6 +102,10 @@ void XGUI_ContextMenuMgr::createActions() anAction->setShortcut(Qt::Key_F2); addAction("RENAME_CMD", anAction); + anAction = ModuleBase_Tools::createAction(QIcon(":pictures/part_ico.png"), tr("Deactivate/Activate"), + aDesktop, this); + addAction("DEACTIVATE_CONSTRAINT_CMD", anAction); + #ifdef HAVE_SALOME anAction = ModuleBase_Tools::createAction(QIcon(":pictures/move_to_end.png"), XGUI_Workshop::MOVE_TO_END_COMMAND, this); @@ -166,6 +171,10 @@ void XGUI_ContextMenuMgr::createActions() aDesktop); addAction("ISOLINES_CMD", anAction); + anAction = ModuleBase_Tools::createAction(QIcon(":pictures/rename_edit.png"), tr("Edit..."), + aDesktop); + addAction("EDIT_CONSTR_CMD", anAction); + anAction = ModuleBase_Tools::createAction(QIcon(), tr("Show Isos"), aDesktop); anAction->setCheckable(true); addAction("SHOW_ISOLINES_CMD", anAction); @@ -251,6 +260,7 @@ void XGUI_ContextMenuMgr::createActions() addAction("SET_VIEW_NORMAL_CMD", anAction); buildObjBrowserMenu(); + buildConstrBrowserMenu(); buildViewerMenu(); } @@ -304,6 +314,8 @@ void XGUI_ContextMenuMgr::onContextMenuRequest(QContextMenuEvent* theEvent) } else if (sender() == myWorkshop->viewer()) { updateViewerMenu(); addViewerMenu(aMenu); + } else if (sender() == myWorkshop->constraintsBrowser()) { + addConstrBrowserMenu(aMenu); } if (aMenu && (aMenu->actions().size() > 0)) { @@ -699,6 +711,11 @@ void XGUI_ContextMenuMgr::connectViewer() SLOT(onContextMenuRequest(QContextMenuEvent*))); } +void XGUI_ContextMenuMgr::connectConstraintsBrowser() +{ + connect(myWorkshop->constraintsBrowser(), SIGNAL(contextMenuRequested(QContextMenuEvent*)), this, + SLOT(onContextMenuRequest(QContextMenuEvent*))); +} void XGUI_ContextMenuMgr::buildObjBrowserMenu() { @@ -820,6 +837,18 @@ void XGUI_ContextMenuMgr::buildObjBrowserMenu() myObjBrowserMenus[ModelAPI_ResultField::ModelAPI_FieldStep::group()] = aList; } +void XGUI_ContextMenuMgr::buildConstrBrowserMenu() +{ + QAction* aSeparator = ModuleBase_Tools::createAction(QIcon(), "", myWorkshop->desktop()); + aSeparator->setSeparator(true); + + QActionsList aList; + + aList.append(action("HIDE_CMD")); + aList.append(action("DELETE_CMD")); + aList.append(action("DEACTIVATE_CONSTRAINT_CMD")); +} + void XGUI_ContextMenuMgr::buildViewerMenu() { QActionsList aList; @@ -886,6 +915,48 @@ void XGUI_ContextMenuMgr::buildViewerMenu() myViewerMenu[ModelAPI_ResultField::ModelAPI_FieldStep::group()] = aList; } +void XGUI_ContextMenuMgr::addConstrBrowserMenu(QMenu* theMenu) const +{ + QActionsList anActions; + QObjectPtrList aObjects = myWorkshop->constraintsBrowser()->selectedObjects(); + + // Check that state foreach constraint. + // If at least 1 is Activa - show Deactivate + // otherwise - show Activate + // + if (aObjects.size() > 0) + { + // It's update START + + // Enable edit only if exist at least 1 dimensional constraint + bool isEditEnabled = false; + foreach(ObjectPtr anObject, aObjects) + { + if (auto aFeat = ModelAPI_Feature::feature(anObject)) + { + if (aFeat->real("ConstraintValue")) + { + isEditEnabled = true; + break; + } + } + } + + action("EDIT_CONSTR_CMD")->setEnabled(isEditEnabled); + action("DELETE_CMD")->setEnabled(true); + action("DEACTIVATE_CONSTRAINT_CMD")->setEnabled(true); + // It's update END + + anActions.append(action("EDIT_CONSTR_CMD")); + anActions.append(action("DELETE_CMD")); + anActions.append(action("DEACTIVATE_CONSTRAINT_CMD")); + } + + + theMenu->addActions(anActions); + addFeatures(theMenu); + +} void XGUI_ContextMenuMgr::addObjBrowserMenu(QMenu* theMenu) const { diff --git a/src/XGUI/XGUI_ContextMenuMgr.h b/src/XGUI/XGUI_ContextMenuMgr.h index 3e9e97a38..455b5ee28 100644 --- a/src/XGUI/XGUI_ContextMenuMgr.h +++ b/src/XGUI/XGUI_ContextMenuMgr.h @@ -67,9 +67,15 @@ Q_OBJECT /// Connect to viewer from workshop. Has to called at creation of viewer. void connectViewer(); + /// Connect to viewer from workshop. Has to called at creation of viewer. + void connectConstraintsBrowser(); + /// Add menu items for Object browser pop-up void addObjBrowserMenu(QMenu*) const; + /// Add menu items for Object browser pop-up + void addConstrBrowserMenu(QMenu*) const; + /// Add menu items for Viewer pop-up void addViewerMenu(QMenu*) const; @@ -126,6 +132,9 @@ signals: /// Creates menu for object browser void buildObjBrowserMenu(); + /// Creates menu for object browser + void buildConstrBrowserMenu(); + /// Creates menu for viewer void buildViewerMenu(); diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index 477544490..3d294afd4 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -562,6 +562,23 @@ void XGUI_Displayer::setSelected(const QList& theValue #endif } } + else + { + auto aConstrFeature = ModelAPI_Feature::feature(anObject); + if (!aConstrFeature) + continue; + + AISObjectPtr aAisPtr = myWorkshop->displayer()->getAISObject(aConstrFeature); + if (!aAisPtr) + { + aAisPtr = myResult2AISObjectMap.value(aConstrFeature->lastResult()); + if (!aAisPtr) + continue; + } + Handle(AIS_InteractiveObject) aAisObj = aAisPtr->impl(); + + aContext->AddOrRemoveSelected(aAisObj, false); + } } } if (!aShapesToBeSelected.IsEmpty()) diff --git a/src/XGUI/XGUI_OperationMgr.cpp b/src/XGUI/XGUI_OperationMgr.cpp index 04d12eabc..55efe02e1 100644 --- a/src/XGUI/XGUI_OperationMgr.cpp +++ b/src/XGUI/XGUI_OperationMgr.cpp @@ -28,6 +28,7 @@ #include "XGUI_FacesPanel.h" #include "XGUI_Tools.h" #include "XGUI_ObjectsBrowser.h" +#include "XGUI_SketchConstraintsBrowser.h" #include "XGUI_ContextMenuMgr.h" #include "XGUI_Selection.h" #include "XGUI_SelectionMgr.h" @@ -701,7 +702,16 @@ bool XGUI_OperationMgr::onKeyReleased(QObject *theObject, QKeyEvent* theEvent) break; case Qt::Key_Return: case Qt::Key_Enter: { - isAccepted = onProcessEnter(theObject); + if(xworkshop()->constraintsBrowser() && + xworkshop()->constraintsBrowser()->IsInEditMode()) + { + xworkshop()->constraintsBrowser()->CloseEditor(); + isAccepted = true; + } + else + { + isAccepted = onProcessEnter(theObject); + } } break; case Qt::Key_N: diff --git a/src/XGUI/XGUI_Selection.cpp b/src/XGUI/XGUI_Selection.cpp index 7a80eb0a9..9aafff1ed 100644 --- a/src/XGUI/XGUI_Selection.cpp +++ b/src/XGUI/XGUI_Selection.cpp @@ -22,6 +22,7 @@ #include "XGUI_Displayer.h" #include "XGUI_ViewerProxy.h" #include "XGUI_ObjectsBrowser.h" +#include "XGUI_SketchConstraintsBrowser.h" #ifndef HAVE_SALOME #include @@ -79,6 +80,10 @@ QList XGUI_Selection::getSelected(const SelectionPlace& case Viewer: getSelectedInViewer(aPresentations); break; + case ConstraintsBrowser: + getSelectedInSketchConstraintsBrowser(aPresentations); + break; + case AllControls: // Get selection from object browser getSelectedInBrowser(aPresentations); @@ -201,6 +206,34 @@ void XGUI_Selection::getSelectedInBrowser(QList& thePre } } +void XGUI_Selection::getSelectedInSketchConstraintsBrowser(QList>& thePresentations) const +{ + QObjectPtrList anObjects; + if (myWorkshop->constraintsBrowser()) + anObjects = myWorkshop->constraintsBrowser()->selectedObjects(); + + if (anObjects.isEmpty()) + return; + + QObjectPtrList::const_iterator anIt = anObjects.begin(), aLast = anObjects.end(); + for (; anIt != aLast; anIt++) { + ObjectPtr anObject = *anIt; + if (anObject.get() != NULL) { + auto aConstrFeature = ModelAPI_Feature::feature(anObject); + thePresentations.append(std::shared_ptr( + new ModuleBase_ViewerPrs(anObject, GeomShapePtr(), NULL))); + + /* AISObjectPtr aAisPtr = myWorkshop->displayer()->getAISObject(aConstrFeature); + if (!aAisPtr) + continue; + Handle(AIS_InteractiveObject) aAisObj = aAisPtr->impl(); + auto aPrs = std::shared_ptr( + new ModuleBase_ViewerPrs(anObject, GeomShapePtr(), NULL)); + aPrs->setInteractive(aAisObj); + thePresentations.append(aPrs);*/ + } + } +} void XGUI_Selection::fillPresentation(ModuleBase_ViewerPrsPtr& thePrs, const Handle(SelectMgr_EntityOwner)& theOwner) const { @@ -381,6 +414,8 @@ QObjectPtrList XGUI_Selection::selectedObjects() const { if (myWorkshop->objectBrowser()) return myWorkshop->objectBrowser()->selectedObjects(); + if (myWorkshop->constraintsBrowser()) //probably this code can be deleted, because first condition is always true + return myWorkshop->constraintsBrowser()->selectedObjects(); return QObjectPtrList(); } diff --git a/src/XGUI/XGUI_Selection.h b/src/XGUI/XGUI_Selection.h index 9cf5ea963..29eeffa61 100644 --- a/src/XGUI/XGUI_Selection.h +++ b/src/XGUI/XGUI_Selection.h @@ -103,6 +103,13 @@ protected: /// \param thePresentations an output list of presentation void getSelectedInBrowser(QList>& thePresentations) const; + /// Fills the list of presentations by objects selected in the object browser. + /// ViewerPrs contains only object parameter not empty. + /// If the given list of presentations already has a viewer presentation with the same object + /// as selected in the browser, a new item is not appended to the list of presentations. + /// \param thePresentations an output list of presentation + void getSelectedInSketchConstraintsBrowser(QList>& thePresentations) const; + /// Generates a vertex or edge by the give IO if it is an AIS created on trihedron /// \param theIO a selected object /// \return created shape or empty shape diff --git a/src/XGUI/XGUI_SelectionMgr.cpp b/src/XGUI/XGUI_SelectionMgr.cpp index 00ebe2234..339a22bc8 100644 --- a/src/XGUI/XGUI_SelectionMgr.cpp +++ b/src/XGUI/XGUI_SelectionMgr.cpp @@ -21,6 +21,7 @@ #include "XGUI_Workshop.h" #include "XGUI_ObjectsBrowser.h" +#include "XGUI_SketchConstraintsBrowser.h" #include "XGUI_SalomeConnector.h" #include "XGUI_ViewerProxy.h" #include "XGUI_Displayer.h" @@ -83,6 +84,8 @@ void XGUI_SelectionMgr::connectViewers() //Connect to other viewers connect(myWorkshop->viewer(), SIGNAL(selectionChanged()), this, SLOT(onViewerSelection())); + connect(myWorkshop->constraintsBrowser(), SIGNAL(selectionChanged()), this, + SLOT(onSketchConstraintsBrowserSelection())); } //************************************************************** @@ -140,6 +143,23 @@ void XGUI_SelectionMgr::onObjectBrowserSelection() emit selectionChanged(); } +//************************************************************** +void XGUI_SelectionMgr::onSketchConstraintsBrowserSelection() +{ + ModuleBase_Operation* aCurOperation = myWorkshop->operationMgr()->currentOperation(); + + //prevent selection while child sketch-operation is active + if (myWorkshop->operationMgr()->previousOperation(aCurOperation) == NULL) { + myLastSelectionPlace = ModuleBase_ISelection::ConstraintsBrowser; + QList aSelectedPrs = + myWorkshop->selector()->selection()->getSelected(ModuleBase_ISelection::ConstraintsBrowser); + XGUI_Displayer* aDisplayer = myWorkshop->displayer(); + aDisplayer->setSelected(aSelectedPrs); + myWorkshop->updateColorScaleVisibility(); + emit selectionChanged(); + } +} + //************************************************************** void XGUI_SelectionMgr::onViewerSelection() { diff --git a/src/XGUI/XGUI_SelectionMgr.h b/src/XGUI/XGUI_SelectionMgr.h index ce9a47d31..be5e31065 100644 --- a/src/XGUI/XGUI_SelectionMgr.h +++ b/src/XGUI/XGUI_SelectionMgr.h @@ -94,9 +94,12 @@ signals: void selectionChanged(); public slots: - /// Reaction on selectio0n in Object browser + /// Reaction on selection in Object browser void onObjectBrowserSelection(); + /// Reaction on selection in Constraints Browser + void onSketchConstraintsBrowserSelection(); + /// Reaction on selectio0n in Viewer void onViewerSelection(); diff --git a/src/XGUI/XGUI_SketchConstraintsBrowser.cpp b/src/XGUI/XGUI_SketchConstraintsBrowser.cpp new file mode 100644 index 000000000..576caaeb7 --- /dev/null +++ b/src/XGUI/XGUI_SketchConstraintsBrowser.cpp @@ -0,0 +1,760 @@ +// Copyright (C) 2014-2022 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 "XGUI_SketchConstraintsBrowser.h" +#include "XGUI_Tools.h" +#include "XGUI_DataModel.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#ifdef DEBUG_INDXES +#include +#endif + + +#ifdef WIN32 +# define FSEP "\\" +#else +# define FSEP "/" +#endif + +// Type of columns +enum ColumnType { + Col_Icon, + Col_Constraint, + Col_Primitive, + Col_Value +}; + +namespace +{ + QModelIndex GetIndex(QModelIndex theChildIndex) + { + auto aParent = theChildIndex.parent(); + if (aParent.isValid()) + return aParent.model()->index(aParent.row(), 1); + else + return QModelIndex(); + } + + // Retrurn name for constraint attribute + QString GetName(const AttributePtr& theAttribute) + { + QString aName; + + if (theAttribute->attributeType() != ModelAPI_AttributeRefAttr::typeId()) + return aName; + + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(theAttribute); + + auto anObj = aRefAttr->object(); + auto anAttr = aRefAttr->attr(); + if (anAttr) + { + FeaturePtr anAttrA = ModelAPI_Feature::feature(anAttr->owner()); + aName += QString::fromStdWString(anAttrA->name()); + aName += "/"; + aName += QString::fromStdString(anAttr->id()); + } + else if (anObj) + { + FeaturePtr anAttrA = ModelAPI_Feature::feature(anObj); + aName += QString::fromStdWString(anAttrA->name()); + } + + return aName; + } + + std::pair FromSketchKindToName(const std::string& theKind) + { + const std::string& aType = theKind; + if (aType == "SketchConstraintCoincidence" || + aType == "SketchConstraintCoincidenceInternal") + return { "Coincidence", "coincedence.png" }; + else if (aType == "SketchConstraintRigid") + return { "Fixed", "fixed.png" }; + else if (aType == "SketchConstraintHorizontal") + return { "Horizontal", "horisontal.png" }; + else if (aType == "SketchConstraintVertical") + return { "Vertical", "vertical.png" }; + else if (aType == "SketchConstraintAngle") + return { "Angle", "angle_constr.png" }; + else if (aType == "SketchConstraintDistance") + return { "Distance", "distance.png" }; + else if (aType == "SketchConstraintDistanceHorizontal") + return { "Horizontal distance", "distance_h.png" }; + else if (aType == "SketchConstraintDistanceVertical") + return { "Vertical distance", "distance_v.png" }; + else if (aType == "SketchConstraintEqual") + return { "Equal", "equal.png" }; + else if (aType == "SketchConstraintLength") + return { "Length", "length.png" }; + else if (aType == "SketchConstraintMiddle") + return { "Middle point", "middlepoint.png" }; + else if (aType == "SketchConstraintMirror") + return { "Mirror objects", "mirror.png" }; + else if (aType == "SketchConstraintParallel") + return { "Parallel", "parallel.png" }; + else if (aType == "SketchConstraintPerpendicular") + return { "Perpendicular", "perpendicular.png" }; + else if (aType == "SketchConstraintRadius") + return { "Radius", "radius_constr.png" }; + else if (aType == "SketchConstraintCollinear") + return { "Collinear", "collinear.png" }; + else if (aType == "SketchConstraintTangent") + return { "Tangent", "tangent.png" }; + return { "", "" }; + } + + std::string GetIconPath(const std::string& theKind) + { + std::string aFile; + char* anEnv = getenv("SHAPER_ROOT_DIR"); + if (anEnv) { + aFile = std::string(anEnv) + + FSEP + "share" + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper" + FSEP + "icons" + FSEP + "Sketch"; + } + else { + anEnv = getenv("CADBUILDER_ROOT_DIR"); + if (anEnv) + aFile = std::string(anEnv) + FSEP + "plugins" + FSEP + "icons" + FSEP + "Sketch"; + } + + aFile += FSEP; + aFile += FromSketchKindToName(theKind).second; + return aFile; + } +} + +/*! + * \ingroup GUI + * ItemDelegate object in order to redefine items behavior + */ +class XGUI_ConstraintsItemDelegate : public QStyledItemDelegate +{ +public: + /// Constructor + /// \param theParent a parent + XGUI_ConstraintsItemDelegate(QObject* theParent) : + QStyledItemDelegate(theParent) {} + + /// Redefinition of virtual method + /// \param parent a parent widget + /// \param option the item options + /// \param index the current index + virtual QWidget* createEditor(QWidget* parent, + const QStyleOptionViewItem& option, + const QModelIndex& index) const; + + /// Returns True if the given index is editable item + /// \param theIndex an item index + bool isEditable(const QModelIndex& theIndex) const; + + // Return current state for TreeItem + bool GetIsActive(const QModelIndex& index) const; + + // Modify state item + void SetIsActive(QModelIndex& theIndex, bool theIsActive); + + /// Returns currently editing index + QModelIndex editIndex() const { return myEditingIdx; } + +protected: + /// Redefinition of virtual method + /// \param option the item options + /// \param index the current index + virtual void initStyleOption(QStyleOptionViewItem* option, + const QModelIndex& index) const; + +private: + mutable QModelIndex myEditingIdx; +}; + +// Implement + +bool XGUI_ConstraintsItemDelegate::GetIsActive(const QModelIndex& index) const +{ + if (!index.parent().isValid()) + return true; + + auto aModel = index.model(); + auto anIndexForCheck = aModel->index(index.row(), 1); + bool myIsActive = index.parent().child(index.row(), 1).data(Qt::UserRole + 1).toBool(); + return myIsActive; +} + +void XGUI_ConstraintsItemDelegate::initStyleOption(QStyleOptionViewItem* option, const QModelIndex& index) const +{ + if (index.parent().isValid()) + { + bool myIsActive = GetIsActive(index); + QPalette palette = QApplication::palette(); + QColor textColor = palette.color(QPalette::WindowText); + option->palette.setBrush(QPalette::ColorRole::Text, myIsActive ? textColor : Qt::darkGray); + } + + QStyledItemDelegate::initStyleOption(option, index); +} + +void XGUI_ConstraintsItemDelegate::SetIsActive(QModelIndex& theIndex, bool theIsActive) +{ + bool aBool = theIndex.model()->data(theIndex, Qt::UserRole + 1).toBool(); + theIndex.model()->data(theIndex, Qt::UserRole + 1).setValue(!aBool); +} + +QWidget* XGUI_ConstraintsItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + myEditingIdx = index; + return QStyledItemDelegate::createEditor(parent, option, index); +} + +bool XGUI_ConstraintsItemDelegate::isEditable(const QModelIndex& theIndex) const +{ + QModelIndex aParent = theIndex.parent(); + if (aParent.isValid() && !theIndex.data(0).isNull() && theIndex.column() == 3) + return true; + + return false; +} + +void XGUI_ConstraintsViewTree::closeEditor(QWidget* theEditor, + QAbstractItemDelegate::EndEditHint theHint) +{ + if (theHint == QAbstractItemDelegate::EditNextItem) { + QModelIndex aCurrent = currentIndex(); + QModelIndex aParent = model()->index(0, 0); + int aNbRows = model()->rowCount(aParent); + QModelIndex aIdx; + if (aCurrent.column() == 3) { + QTreeWidget::closeEditor(theEditor, theHint); + return; + } + if (aIdx.isValid()) { + QTreeWidget::closeEditor(theEditor, QAbstractItemDelegate::NoHint); + setCurrentIndex(aIdx); + edit(aIdx); + return; + } + } + QTreeWidget::closeEditor(theEditor, theHint); +} + +//******************************************************************** +XGUI_SketchConstraintsBrowser::XGUI_SketchConstraintsBrowser(QWidget* theParent, XGUI_Workshop* theWorkshop) + : QWidget(theParent), myWorkshop(theWorkshop) +{ + // Attempt create Tree View + myViewTree = new XGUI_ConstraintsViewTree(this); + myViewTree->setColumnCount(4); + QStringList aHeaders; + aHeaders << "" << tr("Constraint") << tr("Primitives") + << tr("Parameter"); + + myViewTree->setHeaderLabels(aHeaders); + myViewTree->setColumnWidth(Col_Icon, 40); + myViewTree->setColumnWidth(Col_Constraint, 160); + myViewTree->setColumnWidth(Col_Primitive, 140); + myViewTree->setColumnWidth(Col_Value, 40); + + myViewTree->setEditTriggers(QAbstractItemView::NoEditTriggers); + myViewTree->setSelectionBehavior(QAbstractItemView::SelectRows); + myViewTree->setSelectionMode(QAbstractItemView::ExtendedSelection); + + connect(myViewTree, SIGNAL(doubleClicked(const QModelIndex&)), + SLOT(onDoubleClick(const QModelIndex&))); + connect(myViewTree, SIGNAL(itemSelectionChanged()), SLOT(onSelectionChanged())); + + myDelegate = new XGUI_ConstraintsItemDelegate(myViewTree); + + myViewTree->setItemDelegate(myDelegate); + + QPalette aTreePalet = myViewTree->palette(); + QColor aTreeBack = aTreePalet.color(QPalette::Base); + + QPalette aPalet; + aPalet.setColor(QPalette::Base, aTreeBack); + aPalet.setColor(QPalette::Window, aTreeBack); + myViewTree->setPalette(aTreePalet); + + connect(myViewTree, SIGNAL(contextMenuRequested(QContextMenuEvent*)), this, + SLOT(onContextMenuRequested(QContextMenuEvent*))); + + myExtInfo = new QCheckBox(tr("Extended Information")); + myExtInfo->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + myExtInfo->setChecked(true); + + // Connect for show/hide extended information + connect(myExtInfo, SIGNAL(toggled(bool)), this, SLOT(SelectStateChanged(bool))); + ModuleBase_Tools::adjustMargins(myExtInfo); + + myLayout = new QVBoxLayout(this); + ModuleBase_Tools::zeroMargins(myLayout); + myLayout->setSpacing(0); + + myLayout->addWidget(myExtInfo); + myLayout->addWidget(myViewTree); + + Events_Loop* aLoop = Events_Loop::loop(); + aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_CREATED)); + aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); +} + +XGUI_SketchConstraintsBrowser::~XGUI_SketchConstraintsBrowser() +{ + // For avoid crashes after reopen sketch + Events_Loop* aLoop = Events_Loop::loop(); + aLoop->removeListener(this); +} + +void XGUI_SketchConstraintsBrowser::SelectStateChanged(bool /*theState*/) +{ + // Add process for show columns in edit mode + bool isShowExtInfo = !myExtInfo->isChecked(); + myViewTree->setColumnHidden(Col_Primitive, isShowExtInfo); + myViewTree->setColumnHidden(Col_Value, isShowExtInfo); +} + +// bad first param! Make more easy +bool XGUI_SketchConstraintsBrowser::UpdateTree(const std::vector>>& theList) +{ + // Save the expand state so that after the update, all the items will retain their previous expand/collapse state. + std::unordered_map aPrevExpandState; + QTreeWidgetItemIterator anIter(myViewTree); + while (*anIter) + { + QTreeWidgetItem *item = *anIter; + if (item->parent() == nullptr) + { + auto aName = (item)->data(1, 0).toString(); + aPrevExpandState[aName.toStdString()] = myViewTree->isItemExpanded(item); + } + ++anIter; + } + myViewTree->clear(); + myConstrs.clear(); + + // Prepare all groups of constraints + for (const auto& anElemConstr : theList) + { + myConstrs[FromSketchKindToName(anElemConstr.first->getKind()).first].push_back({ anElemConstr.first, anElemConstr.second }); + } + + int aRow = 0; + for (const auto& line : myConstrs) + { + //Get icon for group + std::string aFile = GetIconPath(line.second.front().Feature->getKind()); + + if (line.second[0].Attributes.size() == 0) + continue; + + QTreeWidgetItem* anElem = new QTreeWidgetItem(myViewTree); + anElem->setFlags(Qt::ItemIsEnabled); + anElem->setText(Col_Constraint, QString::fromStdString(line.first)); + anElem->setIcon(Col_Icon, QIcon(QString::fromStdString(aFile))); + + //set expand + bool isToExpand{true}; + if(aPrevExpandState.find(line.first) != aPrevExpandState.end()) + { + isToExpand = aPrevExpandState[line.first]; + } + anElem->setExpanded(isToExpand); + + auto aStart = line.second.begin(); + for (; aStart != line.second.end(); ++aStart) + { + FeatStruct aFeatStruct; + // + for (const auto& anElemConstr : theList) + { + if (anElemConstr.first == (*aStart).Feature) + { + aFeatStruct.Feature = anElemConstr.first; + aFeatStruct.Attributes = anElemConstr.second; + ++aRow; + break; + } + } + // + QTreeWidgetItem* aSubElem = new QTreeWidgetItem(anElem); + aSubElem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled); + aSubElem->setText(Col_Constraint, QString::fromStdWString((*aStart).Feature->name())); + aSubElem->setData(Col_Constraint, Qt::UserRole + 1, (*aStart).Feature->boolean("ConstraintState")->value()); // Store state of constraints true - activated, false - supressed + + QString aPrimitives; + aPrimitives = GetName(aFeatStruct.Attributes[0]); + if (aFeatStruct.Attributes.size() == 2) + { + aPrimitives += "\n"; + aPrimitives += GetName(aFeatStruct.Attributes[1]); + } + + aSubElem->setText(Col_Primitive, aPrimitives); + if ((*aStart).Feature->real("ConstraintValue")) + { + if ((*aStart).Feature->real("AngleValue")) + aSubElem->setData(Col_Value, Qt::EditRole, QString::number((*aStart).Feature->real("AngleValue")->value(),'f', 4)); + else if ((*aStart).Feature->real("DistanceValue")) + aSubElem->setData(Col_Value, Qt::EditRole, QString::number((*aStart).Feature->real("DistanceValue")->value(),'f', 4)); + else + aSubElem->setData(Col_Value, Qt::EditRole, QString::number((*aStart).Feature->real("ConstraintValue")->value(),'f', 4)); + } + anElem->addChild(aSubElem); + } + + myViewTree->addTopLevelItem(anElem); + } + return true; +} + +//****************************************************** +void XGUI_SketchConstraintsBrowser::processEvent(const std::shared_ptr& theMessage) +{ + if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED) + || theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED)) + { + std::shared_ptr aUpdMsg = + std::dynamic_pointer_cast(theMessage); + std::set aObjects = aUpdMsg->objects(); + + foreach(ObjectPtr anObjectC, aObjects) + { + auto aCreatedFeature = ModelAPI_Feature::feature(anObjectC); + if (aCreatedFeature && aCreatedFeature->getKind() == "Sketch") + { + // It's for update constraints after creating or updating + emit deleteConstraints(); + break; + } + } + } +} + +//*************************************************** +void XGUI_SketchConstraintsBrowser::initialize(ModuleBase_ITreeNode* theRoot) +{ + QItemSelectionModel* aSelMod = myViewTree->selectionModel(); + connect(aSelMod, SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + this, SLOT(onSelectionChanged(const QItemSelection&, const QItemSelection&))); +} + +//*************************************************** +void XGUI_SketchConstraintsBrowser::onContextMenuRequested(QContextMenuEvent* theEvent) +{ + ModuleBase_Operation* aCurOperation = myWorkshop->operationMgr()->currentOperation(); + //allow appear of context menu only if no child sketch-operation is active + bool isAllowContextMenu{myWorkshop->operationMgr()->previousOperation(aCurOperation) == NULL}; + if(isAllowContextMenu) + { + //close editor if it was activated + if(IsInEditMode()) + { + CloseEditor(); + } + QModelIndexList aIndexes; + QObjectPtrList aSelectedData = selectedObjects(&aIndexes); + bool toEnable = true; + + foreach(QAction* aCmd, actions()) { + aCmd->setEnabled(toEnable); + } + emit contextMenuRequested(theEvent); + } +} + +//*************************************************** +bool XGUI_SketchConstraintsBrowser::IsInEditMode() +{ + QTreeWidgetItemIterator anIter(myViewTree); + while (*anIter) { + if(myViewTree->isPersistentEditorOpen((*anIter), Col_Value)){ + return true; + } + ++anIter; + } + return false; +} + +//*************************************************** +void XGUI_SketchConstraintsBrowser::CloseEditor() +{ + if(IsInEditMode()) + { + // Close editor + QTreeWidgetItemIterator anIter(myViewTree); + while (*anIter) { + myViewTree->closePersistentEditor((*anIter), Col_Value); + ++anIter; + } + myExtInfo->setChecked(myLastState); + + // Send signals for apply updates + emit editValues(); + } +} + +//*************************************************** +void XGUI_SketchConstraintsBrowser::onEditItem() +{ + myLastState = myExtInfo->isChecked(); + myExtInfo->setChecked(true); + + QObjectPtrList aSelectedData = selectedObjects(); + if (aSelectedData.size() > 0) { + ObjectPtr anObject = aSelectedData.first(); + if (anObject.get()) { // Selection happens in TreeView + // check whether the object can be renamed. There should not be parts which are not loaded + std::set aFeatures; + aFeatures.insert(ModelAPI_Feature::feature(anObject)); + if (!XGUI_Tools::canRemoveOrRename((QWidget*)parent(), aFeatures)) + return; + + // Find index which corresponds the feature + QModelIndex aIndex; + foreach(QModelIndex aIdx, selectedIndexes()) { + if (aIdx.column() == Col_Value) { + aIndex = aIdx; + if (aIndex.isValid()) { + myViewTree->setCurrentIndex(aIndex); + auto aData = aIndex.data(0); + if (!aData.isNull()) + myViewTree->openPersistentEditor(myViewTree->currentItem(), Col_Value); + } + } + } + } + } + else + { + QTreeWidgetItemIterator anIter(myViewTree); + while (*anIter) { + auto aData = (*anIter)->data(Col_Value, 0); + if (!aData.isNull()) + myViewTree->openPersistentEditor((*anIter), Col_Value); + ++anIter; + } + } +} + +void XGUI_SketchConstraintsBrowser::onDeactivateItems() +{ + bool isActivate = true; + std::vector aFeaturesMod; + // This Check need on request COntext Menu step! + foreach(QModelIndex aIdx, selectedIndexes()) + { + if (aIdx.isValid() && aIdx.column() == Col_Constraint) { + auto aBool = aIdx.data(Qt::UserRole + 1).toBool(); + if (aBool) + { + isActivate = false; + break; + } + } + } + + QObjectPtrList aSelectedData = selectedObjects(); + if (aSelectedData.size() > 0) { + ObjectPtr anObject = aSelectedData.first(); + if (anObject.get()) { // Selection happens in TreeView + // check whether the object can be renamed. There should not be parts which are not loaded + std::set aFeatures; + aFeatures.insert(ModelAPI_Feature::feature(anObject)); + if (!XGUI_Tools::canRemoveOrRename((QWidget*)parent(), aFeatures)) + return; + + // Find index which corresponds the feature + foreach(QModelIndex aIdx, selectedIndexes()) { + auto aParent = GetIndex(aIdx); + if (aParent.isValid() && aIdx.isValid() && aIdx.column() == Col_Constraint) { + myViewTree->setCurrentIndex(aIdx); + myViewTree->currentItem()->setData(Col_Constraint, Qt::UserRole + 1, isActivate); + + auto aFeat = myConstrs[aParent.data().toString().toStdString()].at(aIdx.row()).Feature; + aFeaturesMod.push_back(aFeat); + } + } + } + } + + emit deactivate(isActivate, aFeaturesMod); +} + +//*************************************************** +void XGUI_SketchConstraintsBrowser::setObjectsSelected(const QObjectPtrList& theObjects) +{ + QItemSelectionModel* aSelectModel = myViewTree->selectionModel(); + QModelIndexList aIndexes = aSelectModel->selectedIndexes(); + if (theObjects.size() == 0) { + bool aIsBlock = aSelectModel->blockSignals(true); + aSelectModel->clear(); + aSelectModel->blockSignals(aIsBlock); + foreach(QModelIndex aIdx, aIndexes) { + myViewTree->update(aIdx); + } + return; + } +} + +//*************************************************** +void XGUI_SketchConstraintsBrowser::onSelectionChanged(const QItemSelection& theSelected, + const QItemSelection& theDeselected) +{ + onSelectionChanged(); +} + +//*************************************************** +void XGUI_SketchConstraintsBrowser::onSelectionChanged() +{ + emit selectionChanged(); +} + +//*************************************************** +QObjectPtrList XGUI_SketchConstraintsBrowser::selectedObjects(QModelIndexList* theIndexes) const +{ + QObjectPtrList aList; + QModelIndexList aIndexes = selectedIndexes(); + + foreach(QModelIndex aIdx, aIndexes) { + if (aIdx.column() == Col_Constraint) { + QModelIndex aParentData = GetIndex(aIdx); + if (!aParentData.isValid()) + continue; + + std::string aData = aParentData.data().toString().toStdString(); + ObjectPtr aObject = myConstrs.at(aData).at(aIdx.row()).Feature; + + auto anAttrs = myConstrs.at(aParentData.data().toString().toStdString()).at(aIdx.row()).Attributes; + if (aObject) { + if (!aList.contains(aObject)) + { + aList.append(aObject); + + // Add related primitives to list + for (int anIndex = 0; anIndex < anAttrs.size(); ++anIndex) + { + if (anAttrs[anIndex]->attributeType() == ModelAPI_AttributeRefAttr::typeId()) + { + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(anAttrs[anIndex]); + if (!aRefAttr->attr()) + { + auto aFObj = aRefAttr->object(); + + if (!aList.contains(aFObj)) + { + aList.append(aFObj); + } + } + else + { + aList.append(aRefAttr->attr()->owner()); + } + } + } + + if (theIndexes) + theIndexes->append(aIdx); + } + } + } + } + return aList; +} + +//*************************************************** +QObjectPtrList XGUI_SketchConstraintsBrowser::selectedConstraints(QModelIndexList* theIndexes) const +{ + QObjectPtrList aList; + QModelIndexList aIndexes = selectedIndexes(); + + foreach(QModelIndex aIdx, aIndexes) { + if (aIdx.column() == Col_Constraint) { + QModelIndex aParentData = GetIndex(aIdx); + if (!aParentData.isValid()) + continue; + + std::string aData = aParentData.data().toString().toStdString(); + ObjectPtr aObject = myConstrs.at(aData).at(aIdx.row()).Feature; + if (aObject) { + if (!aList.contains(aObject)) + { + aList.append(aObject); + + if (theIndexes) + theIndexes->append(aIdx); + } + } + } + } + return aList; +} + +//*************************************************** +void XGUI_SketchConstraintsBrowser::onDoubleClick(const QModelIndex& theIndex) +{ + ModuleBase_Operation* aCurOperation = myWorkshop->operationMgr()->currentOperation(); + //allow edit only if no child sketch-operation is active + bool isAllowEdit{myWorkshop->operationMgr()->previousOperation(aCurOperation) == NULL}; + if (isAllowEdit && myDelegate->isEditable(theIndex)) { + myViewTree->setCurrentIndex(theIndex); + myViewTree->openPersistentEditor(myViewTree->currentItem(), Col_Value); + onEditItem(); + } +} + +void XGUI_SketchConstraintsBrowser::resizeEvent(QResizeEvent* theEvent) +{ + QWidget::resizeEvent(theEvent); + emit sizeChanged(); +} diff --git a/src/XGUI/XGUI_SketchConstraintsBrowser.h b/src/XGUI/XGUI_SketchConstraintsBrowser.h new file mode 100644 index 000000000..44e852926 --- /dev/null +++ b/src/XGUI/XGUI_SketchConstraintsBrowser.h @@ -0,0 +1,198 @@ +// Copyright (C) 2014-2022 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 +// + +#ifndef XGUI_SketchConstraintsBrowser_H +#define XGUI_SketchConstraintsBrowser_H + +#include "XGUI.h" +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class ModuleBase_IDocumentDataModel; +class XGUI_DataModel; +class Config_DataModelReader; +class XGUI_Workshop; +class XGUI_ConstraintsItemDelegate; +class ModuleBase_ITreeNode; + +//#define DEBUG_INDXES + +struct FeatStruct +{ + FeaturePtr Feature; + std::vector Attributes; +}; + + +class XGUI_EXPORT XGUI_ConstraintsViewTree : public QTreeWidget +{ + Q_OBJECT +public: + /// Constructor + /// \param theParent a parent widget + XGUI_ConstraintsViewTree(QWidget* theParent = 0) : QTreeWidget(theParent) {} + + /// Returns current data model + XGUI_DataModel* dataModel() const + { + return static_cast(model()); + } + +signals: + //! Emited on context menu request + void contextMenuRequested(QContextMenuEvent* theEvent); + +protected slots: + /// Redefinition of virtual method + virtual void contextMenuEvent(QContextMenuEvent* theEvent) + { + emit contextMenuRequested(theEvent); + } + + void closeEditor(QWidget* theEditor, QAbstractItemDelegate::EndEditHint theHint); + +}; + +/**\class XGUI_SketchConstraintsBrowser + * \ingroup GUI + * \brief Object browser window object. Represents data tree of current data structure + */ +class XGUI_EXPORT XGUI_SketchConstraintsBrowser : public QWidget, public Events_Listener +{ +Q_OBJECT + public: + + // Temporary for more simple modification + XGUI_ConstraintsViewTree* getViewTree() { return myViewTree; } + + bool IsInEditMode(); + + // Make more good option + bool UpdateTree(const std::vector>>& theList); + + void CloseEditor(); + + /// Constructor + /// \param theParent a parent widget + XGUI_SketchConstraintsBrowser(QWidget* theParent, XGUI_Workshop* theWorkshop); + virtual ~XGUI_SketchConstraintsBrowser(); + + /// Event Listener method + /// \param theMessage an event message + virtual void processEvent(const std::shared_ptr& theMessage); + + //! Returns list of currently selected constraints and geometries + //! \param theIndexes - output list of corresponded indexes (can be NULL) + QObjectPtrList selectedObjects(QModelIndexList* theIndexes = 0) const; + + //! Returns list of currently selected constraints in browser + //! \param theIndexes - output list of corresponded indexes (can be NULL) + QObjectPtrList selectedConstraints(QModelIndexList* theIndexes = 0) const; + + /// Set selected list of objects + /// \param theObjects list of objects to select + void setObjectsSelected(const QObjectPtrList& theObjects); + + //! Returns currently selected indexes + QModelIndexList selectedIndexes() const + { + if (myViewTree->selectionModel()) + return myViewTree->selectionModel()->selectedIndexes(); + else + return QModelIndexList(); + } + + /// Initialize the Object browser + void initialize(ModuleBase_ITreeNode* theRoot); + + /// Returns current workshop + XGUI_Workshop* workshop() const { return myWorkshop; } + + void onSelectionChanged(); + +public slots: + //! Called on Edit command request + void onEditItem(); + + //! Change state of constraints + void onDeactivateItems(); + +private slots: + void SelectStateChanged(bool theState); + +signals: + //! Emited when selection is changed + void selectionChanged(); + + //! Emited on context menu request + void contextMenuRequested(QContextMenuEvent* theEvent); + + //! An signal emitted on resize of the Object Browser + void sizeChanged(); + + void editValues(); + void deleteConstraints(); + void deactivate(bool, std::vector); + +protected: + //! redefinition of a virtual method + void resizeEvent(QResizeEvent* theEvent); + + private slots: + /// Show context menu + /// \param theEvent a context menu event + void onContextMenuRequested(QContextMenuEvent* theEvent); + + //! Called when selection in Data Tree is changed + void onSelectionChanged(const QItemSelection& theSelected, const QItemSelection& theDeselected); + + /// Slot for reaction on double click in the table (start editing) + /// \param theIndex the clicked index + void onDoubleClick(const QModelIndex& theIndex); + + private: + XGUI_Workshop* myWorkshop; + + XGUI_ConstraintsViewTree* myViewTree; + QVBoxLayout* myLayout; + QHBoxLayout* myButtons; + + bool myLastState; //Store state of Extended Information CheckBox (need for correct reset after edit constraints) + QCheckBox* myExtInfo; + XGUI_ConstraintsItemDelegate* myDelegate; + + std::map> myConstrs; // string - name of group, vector - constraints from group +}; + +#endif diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index c40ea021c..5e0a1018c 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -51,6 +51,8 @@ #include #include +#include + #ifdef HAVE_SALOME #include #include @@ -207,6 +209,7 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector) : QObject(), myModule(NULL), myObjectBrowser(0), + mySkConstBrwsr(0), myPropertyPanel(0), myFacesPanel(0), myDisplayer(0), @@ -1624,6 +1627,29 @@ QDockWidget* XGUI_Workshop::createObjectBrowser(QWidget* theParent) return aObjDock; } +//****************************************************** +QDockWidget* XGUI_Workshop::createConstraintsBrowser(QWidget* theParent) +{ + QDockWidget* aSkDock = new QDockWidget(theParent); + aSkDock->setAllowedAreas(Qt::LeftDockWidgetArea | + Qt::RightDockWidgetArea); + aSkDock->setWindowTitle(tr("Sketch Constraints Browser")); + aSkDock->setStyleSheet( + "::title { position: relative; padding-left: 5px; text-align: left center }"); + + mySkConstBrwsr = new XGUI_SketchConstraintsBrowser(aSkDock, this); + mySkConstBrwsr->initialize(myModule->rootNode()); + //myModule->customizeObjectBrowser(mySkConstBrwsr); + aSkDock->setWidget(mySkConstBrwsr); + aSkDock->setObjectName("Constraints browser"); + + connect(mySkConstBrwsr, SIGNAL(sizeChanged()), SLOT(onDockSizeChanged())); + + mySelector->connectViewers(); + myContextMenuMgr->connectConstraintsBrowser(); + return aSkDock; +} + //****************************************************** /* * Creates dock widgets, places them in corresponding area @@ -1769,6 +1795,20 @@ void XGUI_Workshop::hideObjectBrowser() myObjectBrowser->parentWidget()->hide(); } +//****************************************************** +void XGUI_Workshop::showConstraintsBrowser() +{ + if (!isSalomeMode()) + mySkConstBrwsr->parentWidget()->show(); +} + +//****************************************************** +void XGUI_Workshop::hideConstraintsBrowser() +{ + if (!isSalomeMode()) + mySkConstBrwsr->parentWidget()->hide(); +} + //****************************************************** void XGUI_Workshop::salomeViewerSelectionChanged() { @@ -1789,6 +1829,10 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked) deleteObjects(); else if (theId == "CLEAN_HISTORY_CMD") cleanHistory(); + else if (theId == "EDIT_CONSTR_CMD") + editConstraints(); + else if (theId == "DEACTIVATE_CONSTRAINT_CMD") + deactivateCosntraint(); else if (theId == "MOVE_CMD" || theId == "MOVE_SPLIT_CMD") moveObjects(theId == "MOVE_SPLIT_CMD"); else if (theId == "RECOVER_CMD") @@ -2121,6 +2165,23 @@ void XGUI_Workshop::deleteObjects() myDisplayer->updateViewer(); } +void XGUI_Workshop::deactivateCosntraint() +{ + QObjectPtrList anObjects = constraintsBrowser()->selectedObjects(); + + constraintsBrowser()->setObjectsSelected(anObjects); + constraintsBrowser()->onDeactivateItems(); +} + +void XGUI_Workshop::editConstraints() +{ + QObjectPtrList anObjects = constraintsBrowser()->selectedObjects(); + + // restore selection in case if dialog box was shown + constraintsBrowser()->setObjectsSelected(anObjects); + constraintsBrowser()->onEditItem(); +} + //************************************************************** void addRefsToFeature(const FeaturePtr& theFeature, const std::map >& theMainList, diff --git a/src/XGUI/XGUI_Workshop.h b/src/XGUI/XGUI_Workshop.h index e0d97cbae..fc3fa4a41 100644 --- a/src/XGUI/XGUI_Workshop.h +++ b/src/XGUI/XGUI_Workshop.h @@ -65,6 +65,7 @@ class XGUI_SelectionMgr; class XGUI_ViewerProxy; class XGUI_WorkshopListener; class XGUI_InspectionPanel; +class XGUI_SketchConstraintsBrowser; class ModuleBase_IModule; class ModuleBase_IViewer; @@ -88,6 +89,12 @@ Q_OBJECT XGUI_Workshop(XGUI_SalomeConnector* theConnector = 0); virtual ~XGUI_Workshop(); + /// Create Sketch constraints browser widget + /// \param theParent a parent of widget + QDockWidget* createConstraintsBrowser(QWidget* theParent); + + void removeConstrBrowser() { mySkConstBrwsr = NULL; } + /// Starting of the application void startApplication(); @@ -153,6 +160,9 @@ Q_OBJECT /// Returns Object browser XGUI_ObjectsBrowser* objectBrowser() const { return myObjectBrowser; } + /// Returns Sketch constraints browser + XGUI_SketchConstraintsBrowser* constraintsBrowser() const { return mySkConstBrwsr; } + /// This method is called by Salome module when selection is changed void salomeViewerSelectionChanged(); @@ -176,6 +186,11 @@ Q_OBJECT /// Delete features void deleteObjects(); + /// Eit constraints + void editConstraints(); + + void deactivateCosntraint(); + /// Searches for selected features unused in other (not selected) features. If one or several /// selected features are found, a warning message proposes to delete them. It contains /// the list of features to be deleted. @@ -412,6 +427,12 @@ signals: /// Hide object Browser void hideObjectBrowser(); + /// Show Sketch constraints Browser + void showConstraintsBrowser(); + + /// Hide Sketch constraints Browser + void hideConstraintsBrowser(); + /// Close document void closeDocument(); @@ -569,6 +590,7 @@ private: AppElements_MainWindow* myMainWindow; ///< desktop window #endif + XGUI_SketchConstraintsBrowser* mySkConstBrwsr; // ~~!!!!~~ ModuleBase_IModule* myModule; ///< current module XGUI_ErrorMgr* myErrorMgr; ///< updator of error message XGUI_ObjectsBrowser* myObjectBrowser; ///< data tree widget diff --git a/src/XGUI/XGUI_msg_fr.ts b/src/XGUI/XGUI_msg_fr.ts index 9d89050d2..db4f19255 100644 --- a/src/XGUI/XGUI_msg_fr.ts +++ b/src/XGUI/XGUI_msg_fr.ts @@ -552,6 +552,13 @@ Panneau de propriété + + XGUI_SketchConstraintsBrowser + + Extended Information + Informations étendues + + XGUI_TransparencyWidget