]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
[bos #31549] [EDF] (2023-T1) Sketch Visualization of constrains eksu/31549_VisConstraints master 51/head
authorasozinov <alexey.sozinov@opencascade.com>
Mon, 10 Jul 2023 12:14:58 +0000 (13:14 +0100)
committerEsukhareva <ekaterina.sukhareva@opencascade.com>
Fri, 22 Nov 2024 15:18:08 +0000 (15:18 +0000)
- 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

87 files changed:
src/ModuleBase/ModuleBase_IModule.h
src/ModuleBase/ModuleBase_ISelection.h
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_SketcherMgr.cpp
src/PartSet/PartSet_SketcherMgr.h
src/SketchAPI/SketchAPI_Constraint.cpp
src/SketchAPI/SketchAPI_ConstraintAngle.cpp
src/SketchAPI/SketchAPI_MacroMiddlePoint.cpp
src/SketchAPI/SketchAPI_MacroMiddlePoint.h
src/SketchAPI/SketchAPI_Sketch.cpp
src/SketchAPI/SketchAPI_Sketch.h
src/SketchPlugin/SketchPlugin_Constraint.h
src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp
src/SketchPlugin/SketchPlugin_ConstraintAngle.h
src/SketchPlugin/SketchPlugin_ConstraintCoincidence.cpp
src/SketchPlugin/SketchPlugin_ConstraintCollinear.cpp
src/SketchPlugin/SketchPlugin_ConstraintDistance.cpp
src/SketchPlugin/SketchPlugin_ConstraintDistanceAlongDir.cpp
src/SketchPlugin/SketchPlugin_ConstraintDistanceAlongDir.h
src/SketchPlugin/SketchPlugin_ConstraintEqual.cpp
src/SketchPlugin/SketchPlugin_ConstraintHorizontal.cpp
src/SketchPlugin/SketchPlugin_ConstraintLength.cpp
src/SketchPlugin/SketchPlugin_ConstraintLength.h
src/SketchPlugin/SketchPlugin_ConstraintMiddle.cpp
src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp
src/SketchPlugin/SketchPlugin_ConstraintParallel.cpp
src/SketchPlugin/SketchPlugin_ConstraintPerpendicular.cpp
src/SketchPlugin/SketchPlugin_ConstraintRadius.cpp
src/SketchPlugin/SketchPlugin_ConstraintRigid.cpp
src/SketchPlugin/SketchPlugin_ConstraintTangent.cpp
src/SketchPlugin/SketchPlugin_ConstraintVertical.cpp
src/SketchPlugin/SketchPlugin_MultiRotation.cpp
src/SketchPlugin/SketchPlugin_MultiTranslation.cpp
src/SketchPlugin/SketchPlugin_Offset.cpp
src/SketchPlugin/doc/SketchPlugin.rst
src/SketchPlugin/doc/images/ConstraintsBrowser.png [new file with mode: 0644]
src/SketchPlugin/doc/images/constraints_suppressed.png [new file with mode: 0644]
src/SketchPlugin/doc/images/constraints_suppressed_moved.png [new file with mode: 0644]
src/SketchPlugin/doc/sketchConstraintsBrowser.rst [new file with mode: 0644]
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h
src/SketchSolver/SketchSolver_ConstraintDistance.cpp
src/SketchSolver/SketchSolver_Group.cpp
src/SketchSolver/SketchSolver_Storage.h
src/SketcherPrs/CMakeLists.txt
src/SketcherPrs/SketcherPrs_Angle.cpp
src/SketcherPrs/SketcherPrs_Collinear.h
src/SketcherPrs/SketcherPrs_DimensionStyle.cpp
src/SketcherPrs/SketcherPrs_DimensionStyle.h
src/SketcherPrs/SketcherPrs_Equal.h
src/SketcherPrs/SketcherPrs_HVDirection.h
src/SketcherPrs/SketcherPrs_LengthDimension.cpp
src/SketcherPrs/SketcherPrs_Middle.h
src/SketcherPrs/SketcherPrs_Mirror.h
src/SketcherPrs/SketcherPrs_Offset.h
src/SketcherPrs/SketcherPrs_Parallel.h
src/SketcherPrs/SketcherPrs_Perpendicular.h
src/SketcherPrs/SketcherPrs_Radius.cpp
src/SketcherPrs/SketcherPrs_Rigid.h
src/SketcherPrs/SketcherPrs_SymbolPrs.cpp
src/SketcherPrs/SketcherPrs_SymbolPrs.h
src/SketcherPrs/SketcherPrs_Tangent.h
src/SketcherPrs/SketcherPrs_Transformation.h
src/SketcherPrs/icons/anchor_deactivate.png [new file with mode: 0644]
src/SketcherPrs/icons/collinear_deactivate.png [new file with mode: 0644]
src/SketcherPrs/icons/equal_deactivate.png [new file with mode: 0644]
src/SketcherPrs/icons/horisontal_deactivate.png [new file with mode: 0644]
src/SketcherPrs/icons/middlepoint_deactivate.png [new file with mode: 0644]
src/SketcherPrs/icons/parallel_deactivate.png [new file with mode: 0644]
src/SketcherPrs/icons/perpendicular_deactivate.png [new file with mode: 0644]
src/SketcherPrs/icons/tangent_deactivate.png [new file with mode: 0644]
src/SketcherPrs/icons/vertical_deactivate.png [new file with mode: 0644]
src/XGUI/CMakeLists.txt
src/XGUI/XGUI_ActionsMgr.cpp
src/XGUI/XGUI_ContextMenuMgr.cpp
src/XGUI/XGUI_ContextMenuMgr.h
src/XGUI/XGUI_Displayer.cpp
src/XGUI/XGUI_OperationMgr.cpp
src/XGUI/XGUI_Selection.cpp
src/XGUI/XGUI_Selection.h
src/XGUI/XGUI_SelectionMgr.cpp
src/XGUI/XGUI_SelectionMgr.h
src/XGUI/XGUI_SketchConstraintsBrowser.cpp [new file with mode: 0644]
src/XGUI/XGUI_SketchConstraintsBrowser.h [new file with mode: 0644]
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_Workshop.h
src/XGUI/XGUI_msg_fr.ts

index fc224c006cf4e65cee93861f04907d099c7f9e0a..a3076cc658755628157c44994c402a1c5eadfc29 100644 (file)
@@ -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
index f816f5b7f41f209b0991bdfa21abecf221b12f02..51bda71c6ac8b3e7400ece49973f1505c9bcb01e 100644 (file)
@@ -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() {}
 
index efc79517164858128f90545408d964e51ac29d05..d882dfbb8c7d2decc3a2386e4d9edddb9576ace8 100644 (file)
 #include <XGUI_OperationMgr.h>
 #include <XGUI_PropertyPanel.h>
 #include <XGUI_SelectionMgr.h>
+#include <XGUI_SketchConstraintsBrowser.h>
 #include <XGUI_Tools.h>
 #include <XGUI_Workshop.h>
 
@@ -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
index 1a34c5127dabb1b31c31351558176b5f1ca1ffcc..acc269bef77885c65c523e7fb522f86d13f06a66 100644 (file)
@@ -31,6 +31,7 @@
 #include "PartSet_PreviewSketchPlane.h"
 
 #include <XGUI_ModuleConnector.h>
+#include <XGUI_SketchConstraintsBrowser.h>
 #include <XGUI_Displayer.h>
 #include <XGUI_Workshop.h>
 #include <XGUI_ContextMenuMgr.h>
 #include <ModelAPI_Events.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeRefAttr.h>
+#include <ModelAPI_AttributeDouble.h>
 
 #include <ModelAPI_Validator.h>
 #include <ModelAPI_Tools.h>
 
+#include <Events_InfoMessage.h>
+
 #include <QMouseEvent>
 #include <QApplication>
 #include <QCursor>
@@ -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<SketchPlugin_Constraint>(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<std::pair<FeaturePtr, std::vector<AttributePtr>>> aConstraints;
+
+  CompositeFeaturePtr aComposite =
+    std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(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<FeaturePtr, std::vector<AttributePtr>> 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<FeaturePtr> theFeatures)
+{
+  std::list<ObjectPtr> 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<FeaturePtr>)), this, SLOT(onDeactivate(bool, std::vector<FeaturePtr>)));
+  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<FeaturePtr>)), this, SLOT(onDeactivate(bool, std::vector<FeaturePtr>)));
+
+  workshop()->desktop()->removeDockWidget(myConstraintsBrowser);
+  std::vector<std::pair<FeaturePtr, std::vector<AttributePtr>>> 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<int> 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<int> 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<int> aColor = colorOfObject(theObject, aFeature, isConstruction, isSupressed);
   if (!aColor.empty()) {
     // The code below causes redisplay again
     if (ModelAPI_Session::get()->isOperation()) {
index 12b9f4fce1b1ed8e69b7e931e40e2d64e17c6fc4..236206885e74e5149f07fec1791dbba57b104c94 100644 (file)
@@ -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<FeaturePtr> theFeatures);
+
 private slots:
   /// Toggle show constraints
   void onShowConstraintsToggle(int theType, bool theState);
@@ -485,7 +492,7 @@ private:
   XGUI_OperationMgr* operationMgr() const;
 
   std::vector<int> 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;
 };
 
 
index 95ea7b9faac9b0c523e882fe953741a779417ee2..df29fd9eff204172c7303f3f1a28fd2249cbf7dc 100644 (file)
@@ -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;
   }
 
index 5ddb665dd7805d7f64de714a40583896d0c6e13b..ade1e4e60a2b133790b7d8da163375409258a224 100644 (file)
@@ -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;
 }
index 3ec3a36102c9bd25e661dcc9a634e0aaa71c48f3..74846043a45333211b127dd85c882e0a9cd89d0f 100644 (file)
@@ -35,13 +35,14 @@ SketchAPI_MacroMiddlePoint::SketchAPI_MacroMiddlePoint(
 }
 
 SketchAPI_MacroMiddlePoint::SketchAPI_MacroMiddlePoint(const std::shared_ptr<ModelAPI_Feature>& theFeature,
-  const ModelHighAPI_RefAttr& theLine, const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
+  const ModelHighAPI_RefAttr& theLine, const std::shared_ptr<GeomAPI_Pnt2d>& 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<GeomDataAPI_Point2D>(aConstrFeature->attribute(SketchPlugin_ConstraintMiddle::POINT_REF_ID()))->setValue(coordinates()->x(), coordinates()->y());
+  aConstrFeature->boolean(SketchPlugin_Constraint::CONSTRAINT_ACTIVE())->setValue(is_Active);
 
   aConstrFeature->execute();
 
index 2e747dff018cb77a53504307f9546820d56b6823..bcd3ec76c959627e002c4dda1b96325717fea246 100644 (file)
@@ -42,7 +42,8 @@ public:
   SKETCHAPI_EXPORT
     SketchAPI_MacroMiddlePoint(const std::shared_ptr<ModelAPI_Feature>& theFeature,
       const ModelHighAPI_RefAttr& theLine,
-      const std::shared_ptr<GeomAPI_Pnt2d>& thePoint);
+      const std::shared_ptr<GeomAPI_Pnt2d>& 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
index eeacdbb4de6a1b1a00d4577ac98e7b476dedc972..8d695be1814b86ddfb21b9a6c14fcaebc1635a7f 100644 (file)
@@ -1243,7 +1243,8 @@ std::shared_ptr<ModelHighAPI_Interface> 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<ModelAPI_Feature> aFeature =
       compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID());
@@ -1261,6 +1262,7 @@ std::shared_ptr<ModelHighAPI_Interface> 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<ModelHighAPI_Interface> SketchAPI_Sketch::setAngle(
 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setAngleComplementary(
     const ModelHighAPI_RefAttr & theLine1,
     const ModelHighAPI_RefAttr & theLine2,
-    const ModelHighAPI_Double & theValue)
+    const ModelHighAPI_Double & theValue,
+    bool theIsActive)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
       compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID());
@@ -1293,6 +1296,7 @@ std::shared_ptr<ModelHighAPI_Interface> 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<ModelHighAPI_Interface> SketchAPI_Sketch::setAngleComplementary(
 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setAngleBackward(
     const ModelHighAPI_RefAttr & theLine1,
     const ModelHighAPI_RefAttr & theLine2,
-    const ModelHighAPI_Double & theValue)
+    const ModelHighAPI_Double & theValue,
+    bool theIsActive)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
       compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID());
@@ -1311,30 +1316,35 @@ std::shared_ptr<ModelHighAPI_Interface> 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<ModelHighAPI_Interface> SketchAPI_Sketch::setCoincident(
     const ModelHighAPI_RefAttr & thePoint1,
-    const ModelHighAPI_RefAttr & thePoint2)
+    const ModelHighAPI_RefAttr & thePoint2,
+    bool theIsActive)
 {
   std::shared_ptr<ModelAPI_Feature> 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<ModelHighAPI_Interface> SketchAPI_Sketch::setCollinear(
     const ModelHighAPI_RefAttr & theLine1,
-    const ModelHighAPI_RefAttr & theLine2)
+    const ModelHighAPI_RefAttr & theLine2,
+    bool theIsActive)
 {
   std::shared_ptr<ModelAPI_Feature> 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<ModelHighAPI_Interface> SketchAPI_Sketch::setDistance(
     const ModelHighAPI_RefAttr & thePoint,
     const ModelHighAPI_RefAttr & thePointOrLine,
     const ModelHighAPI_Double & theValue,
-    bool isSigned)
+    bool isSigned,
+    bool theIsActive)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
       compositeFeature()->addFeature(SketchPlugin_ConstraintDistance::ID());
@@ -1351,6 +1362,7 @@ std::shared_ptr<ModelHighAPI_Interface> 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<ModelHighAPI_Interface> SketchAPI_Sketch::setDistance(
 std::shared_ptr<ModelHighAPI_Interface> 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<ModelHighAPI_Interface> 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<ModelHighAPI_Interface> SketchAPI_Sketch::setHorizontalDistance(
     const ModelHighAPI_RefAttr & thePoint1,
     const ModelHighAPI_RefAttr & thePoint2,
-    const ModelHighAPI_Double & theValue)
+    const ModelHighAPI_Double & theValue,
+    bool theIsActive)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
       compositeFeature()->addFeature(SketchPlugin_ConstraintDistanceHorizontal::ID());
@@ -1382,6 +1397,7 @@ std::shared_ptr<ModelHighAPI_Interface> 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<ModelHighAPI_Interface> SketchAPI_Sketch::setHorizontalDistance(
 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setVerticalDistance(
     const ModelHighAPI_RefAttr & thePoint1,
     const ModelHighAPI_RefAttr & thePoint2,
-    const ModelHighAPI_Double & theValue)
+    const ModelHighAPI_Double & theValue,
+    bool theIsActive)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
       compositeFeature()->addFeature(SketchPlugin_ConstraintDistanceVertical::ID());
@@ -1397,18 +1414,21 @@ std::shared_ptr<ModelHighAPI_Interface> 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<ModelHighAPI_Interface> SketchAPI_Sketch::setEqual(
     const ModelHighAPI_RefAttr & theObject1,
-    const ModelHighAPI_RefAttr & theObject2)
+    const ModelHighAPI_RefAttr & theObject2,
+    bool theIsActive)
 {
   std::shared_ptr<ModelAPI_Feature> 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<ModelHighAPI_Interface> SketchAPI_Sketch::setFilletWithRadius(
 }
 
 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setFixed(
-    const ModelHighAPI_RefAttr & theObject)
+    const ModelHighAPI_RefAttr & theObject,
+    bool theIsActive)
 {
   std::shared_ptr<ModelAPI_Feature> 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<ModelHighAPI_Interface> SketchAPI_Sketch::setHorizontal(
-    const ModelHighAPI_RefAttr & theLine)
+    const ModelHighAPI_RefAttr & theLine,
+    bool theIsActive)
 {
   std::shared_ptr<ModelAPI_Feature> 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<ModelHighAPI_Interface> SketchAPI_Sketch::setLength(
     const ModelHighAPI_RefAttr & theLine,
-    const ModelHighAPI_Double & theValue)
+    const ModelHighAPI_Double & theValue,
+    bool theIsActive)
 {
   std::shared_ptr<ModelAPI_Feature> 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<ModelHighAPI_Interface> SketchAPI_Sketch::setMiddlePoint(
     const ModelHighAPI_RefAttr & thePoint,
-    const ModelHighAPI_RefAttr & theLine)
+    const ModelHighAPI_RefAttr & theLine,
+    bool theIsActive)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
       compositeFeature()->addFeature(SketchPlugin_ConstraintMiddle::ID());
@@ -1485,12 +1512,14 @@ std::shared_ptr<ModelHighAPI_Interface> 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_MacroMiddlePoint> SketchAPI_Sketch::setMiddlePoint(
-  const ModelHighAPI_RefAttr& theLine)
+    const ModelHighAPI_RefAttr& theLine,
+    bool is_active)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
     compositeFeature()->addFeature(SketchPlugin_Point::ID());
@@ -1499,63 +1528,73 @@ std::shared_ptr<SketchAPI_MacroMiddlePoint> SketchAPI_Sketch::setMiddlePoint(
   auto aPoint = middlePoint(anObj, this);
 
   return std::shared_ptr<SketchAPI_MacroMiddlePoint>
-    (new SketchAPI_MacroMiddlePoint(aFeature, theLine, aPoint));
+    (new SketchAPI_MacroMiddlePoint(aFeature, theLine, aPoint, is_active));
 }
 
 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setParallel(
     const ModelHighAPI_RefAttr & theLine1,
-    const ModelHighAPI_RefAttr & theLine2)
+    const ModelHighAPI_RefAttr & theLine2,
+    bool theIsActive)
 {
   std::shared_ptr<ModelAPI_Feature> 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<ModelHighAPI_Interface> SketchAPI_Sketch::setPerpendicular(
     const ModelHighAPI_RefAttr & theLine1,
-    const ModelHighAPI_RefAttr & theLine2)
+    const ModelHighAPI_RefAttr & theLine2,
+    bool theIsActive)
 {
   std::shared_ptr<ModelAPI_Feature> 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<ModelHighAPI_Interface> SketchAPI_Sketch::setRadius(
     const ModelHighAPI_RefAttr & theCircleOrArc,
-    const ModelHighAPI_Double & theValue)
+    const ModelHighAPI_Double & theValue,
+    bool theIsActive)
 {
   std::shared_ptr<ModelAPI_Feature> 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<ModelHighAPI_Interface> SketchAPI_Sketch::setTangent(
     const ModelHighAPI_RefAttr & theLine,
-    const ModelHighAPI_RefAttr & theCircle)
+    const ModelHighAPI_RefAttr & theCircle,
+    bool theIsActive)
 {
   std::shared_ptr<ModelAPI_Feature> 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<ModelHighAPI_Interface> SketchAPI_Sketch::setVertical(
-    const ModelHighAPI_RefAttr & theLine)
+    const ModelHighAPI_RefAttr & theLine,
+    bool theIsActive)
 {
   std::shared_ptr<ModelAPI_Feature> 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));
 }
index fba36db2c079550a44325ccd57bd9efa5e314af2..85ec175e7f819139d106fefb10a89342f66f28d1 100644 (file)
@@ -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<ModelHighAPI_Interface> 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<ModelHighAPI_Interface> 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<ModelHighAPI_Interface> setCoincident(
       const ModelHighAPI_RefAttr & thePoint1,
-      const ModelHighAPI_RefAttr & thePoint2);
+      const ModelHighAPI_RefAttr & thePoint2,
+      bool is_active = true);
 
   /// Set collinear
   SKETCHAPI_EXPORT
   std::shared_ptr<ModelHighAPI_Interface> 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<ModelHighAPI_Interface> 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<ModelHighAPI_Interface> 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<ModelHighAPI_Interface> 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<ModelHighAPI_Interface> 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<ModelHighAPI_Interface> 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<ModelHighAPI_Interface> setFixed(
-      const ModelHighAPI_RefAttr & theObject);
+      const ModelHighAPI_RefAttr & theObject,
+      bool is_active = true);
 
   /// Set horizontal
   SKETCHAPI_EXPORT
   std::shared_ptr<ModelHighAPI_Interface> setHorizontal(
-      const ModelHighAPI_RefAttr & theLine);
+      const ModelHighAPI_RefAttr & theLine,
+      bool is_active = true);
 
   /// Set length
   SKETCHAPI_EXPORT
   std::shared_ptr<ModelHighAPI_Interface> setLength(
       const ModelHighAPI_RefAttr & theLine,
-      const ModelHighAPI_Double & theValue);
+      const ModelHighAPI_Double & theValue,
+      bool is_active = true);
 
   /// Set middle
   SKETCHAPI_EXPORT
   std::shared_ptr<ModelHighAPI_Interface> setMiddlePoint(
       const ModelHighAPI_RefAttr & thePoint,
-      const ModelHighAPI_RefAttr & theLine);
+      const ModelHighAPI_RefAttr & theLine,
+      bool is_active = true);
 
   /// Set middle
   SKETCHAPI_EXPORT
-    std::shared_ptr<SketchAPI_MacroMiddlePoint> setMiddlePoint(
-      const ModelHighAPI_RefAttr& theLine);
+  std::shared_ptr<SketchAPI_MacroMiddlePoint> setMiddlePoint(
+      const ModelHighAPI_RefAttr& theLine,
+      bool is_active = true);
 
   /// Set parallel
   SKETCHAPI_EXPORT
   std::shared_ptr<ModelHighAPI_Interface> setParallel(
       const ModelHighAPI_RefAttr & theLine1,
-      const ModelHighAPI_RefAttr & theLine2);
+      const ModelHighAPI_RefAttr & theLine2,
+      bool is_active = true);
 
   /// Set perpendicular
   SKETCHAPI_EXPORT
   std::shared_ptr<ModelHighAPI_Interface> setPerpendicular(
       const ModelHighAPI_RefAttr & theLine1,
-      const ModelHighAPI_RefAttr & theLine2);
+      const ModelHighAPI_RefAttr & theLine2,
+      bool is_active = true);
 
   /// Set radius
   SKETCHAPI_EXPORT
   std::shared_ptr<ModelHighAPI_Interface> setRadius(
       const ModelHighAPI_RefAttr & theCircleOrArc,
-      const ModelHighAPI_Double & theValue);
+      const ModelHighAPI_Double & theValue,
+      bool is_active = true);
 
   /// Set tangent
   SKETCHAPI_EXPORT
   std::shared_ptr<ModelHighAPI_Interface> setTangent(
       const ModelHighAPI_RefAttr & theLine,
-      const ModelHighAPI_RefAttr & theCircle);
+      const ModelHighAPI_RefAttr & theCircle,
+      bool is_active = true);
 
   /// Set vertical
   SKETCHAPI_EXPORT
   std::shared_ptr<ModelHighAPI_Interface> setVertical(
-      const ModelHighAPI_RefAttr & theLine);
+      const ModelHighAPI_RefAttr & theLine,
+      bool is_active = true);
 
   /// Set constraint value
   SKETCHAPI_EXPORT
index 2cc8555f9bb2c720064e383aeeb5f68a33d60319..bfeec45af7d0bc38428959e5163ff4069a5e7b72 100644 (file)
 #define SketchPlugin_Constraint_H_
 
 #include <SketchPlugin_Feature.h>
+#include <ModelAPI_AttributeDouble.h>
 
 #include <string>
+#include <limits>
 
 /// 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<double>::lowest();
+  }
+
  protected:
   /// \brief Use plugin manager for features creation
   SketchPlugin_Constraint();
index a653e62cb310c3d225970d4ba50fde6c9c2e6b88..84371f335f3540a40ca015de93a7d2bcf697daef 100644 (file)
@@ -105,12 +105,18 @@ void SketchPlugin_ConstraintAngle::initAttributes()
   AttributeIntegerPtr aVerAttr = std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(
       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<ModelAPI_AttributeBoolean>(
+    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<Events_Message>& theMessage)
index bc71c6304d3d426d11030106f3054c7cc9f69869..b277321f4ffe1d47458b854bc9e046f538422f12 100644 (file)
@@ -26,6 +26,8 @@
 
 #include <ModelAPI_IReentrant.h>
 
+#include <limits>
+
 /** \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<double>::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<Events_Message>& theMessage);
index 5220ac304e67070ed0533a24458b02eb9ab72db9..101b7e80f351dc3298bb420c6fb8b649199c21dd 100644 (file)
@@ -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<ModelAPI_AttributeBoolean>(
+    data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId()));
+  if (!anActiveAttr->isInitialized())
+    anActiveAttr->setValue(true);
 }
 
 void SketchPlugin_ConstraintCoincidence::execute()
index c9aee84e5b6054a8a6461245b826b72dfb4d2c8b..f7eebabb05f073ddf1356b3f4c18f1b5699a080c 100644 (file)
@@ -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<ModelAPI_AttributeBoolean>(
+    data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId()));
+  if (!anActiveAttr->isInitialized())
+    anActiveAttr->setValue(true);
 }
 
 void SketchPlugin_ConstraintCollinear::execute()
index 27d48101fe4747da063a1b545caffc41e09ba47c..b0707d48dea5c7433a5255c7a5293538ca7e9f9e 100644 (file)
@@ -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<ModelAPI_AttributeBoolean>(
+    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,
index 3d0ce5cd2d07edcf4d2a5398207f8c4bdd37e4ae..13819ac110507122cd2d20a83ce2d6f7e0ac0476 100644 (file)
@@ -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<ModelAPI_AttributeBoolean>(
+    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);
+}
index 851a74a69803b6006d951bb55a1f14019666b3bc..5b86a96f02b57dc6804a8be56fb18b94f313c20e 100644 (file)
@@ -27,6 +27,8 @@
 #include <SketchPlugin.h>
 #include <SketchPlugin_ConstraintDistance.h>
 
+#include <limits>
+
 /** \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<double>::lowest();
+  }
+
   /// \brief Use plugin manager for features creation
   SketchPlugin_ConstraintDistanceAlongDir();
 
index 15b6509317901922dae23ac0eb62cb5b74f8d564..2c2f88d7bc4f358fac8603b32c4471165ba4f897 100644 (file)
@@ -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<ModelAPI_AttributeBoolean>(
+    data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId()));
+  if (!anActiveAttr->isInitialized())
+    anActiveAttr->setValue(true);
 }
 
 void SketchPlugin_ConstraintEqual::execute()
index db64bf2605d447b8e7b3b5c6c3916dcd1e9566bc..069a2406167f506dd0df57884e55b84baa6b9fc7 100644 (file)
@@ -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<ModelAPI_AttributeBoolean>(
+    data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId()));
+  if (!anActiveAttr->isInitialized())
+    anActiveAttr->setValue(true);
 }
 
 void SketchPlugin_ConstraintHorizontal::execute()
index 96e5b4894f1e36dd367f15343aab34ff89ff0489..92eb306971e7dbfdd8d0af1b3c1b77170429a36b 100644 (file)
@@ -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<ModelAPI_AttributeBoolean>(
+    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,
index 37de8b9394950b4968a24051edb5d2c13db31e40..c1712f25f6e0a48dc2cd41e2bd7edca7e6419d69 100644 (file)
@@ -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(
index ecb882bbc4ddf64240e7c0118fb7d39d3ac729cf..876b0ba0e1d3123e4bcbe662499c78ebb3ad351f 100644 (file)
@@ -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<ModelAPI_AttributeBoolean>(
+    data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId()));
+  if (!anActiveAttr->isInitialized())
+    anActiveAttr->setValue(true);
 }
 
 void SketchPlugin_ConstraintMiddle::execute()
index 468b28012d84c96b228ffff45461c3d5f38260f8..42131b15df843618407f151505f32690376953f9 100644 (file)
@@ -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<ModelAPI_AttributeBoolean>(
+    data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId()));
+  if (!anActiveAttr->isInitialized())
+    anActiveAttr->setValue(true);
 }
 
 void SketchPlugin_ConstraintMirror::execute()
index 9008189d67387def1ace1e2c1c227590a6a629cc..fde442d8fd57892fb6bcca72be93aecd5ae7e6c9 100644 (file)
@@ -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<ModelAPI_AttributeBoolean>(
+    data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId()));
+  if (!anActiveAttr->isInitialized())
+    anActiveAttr->setValue(true);
 }
 
 void SketchPlugin_ConstraintParallel::execute()
index 934674b3004a1c8eb22d76b4868b6f57e95f2d7f..ed2a3bc21c10727cdf1bbd2a554058de4124f461 100644 (file)
@@ -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<ModelAPI_AttributeBoolean>(
+    data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId()));
+  if (!anActiveAttr->isInitialized())
+    anActiveAttr->setValue(true);
 }
 
 void SketchPlugin_ConstraintPerpendicular::execute()
index 906802732176716dfe7d9d7def0879547d2078f4..9afede5aa87afd2801473ce030474867532ba915 100644 (file)
@@ -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<ModelAPI_AttributeBoolean>(
+    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,
index f693756c638349be4ba5dd78eb0b3d4f4ff4826f..2ebfbaa5637b0c09b38387b60da3bd8fa00a9316 100644 (file)
@@ -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<ModelAPI_AttributeBoolean>(
+    data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId()));
+  if (!anActiveAttr->isInitialized())
+    anActiveAttr->setValue(true);
 }
 
 void SketchPlugin_ConstraintRigid::execute()
index 0e8ec34e3d1661d878215af78f611bd7651b1ae5..40c712e4c20fa654cb106fc0336f215249731c2f 100644 (file)
@@ -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<ModelAPI_AttributeBoolean>(
+    data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId()));
+  if (!anActiveAttr->isInitialized())
+    anActiveAttr->setValue(true);
 }
 
 void SketchPlugin_ConstraintTangent::execute()
index bdbdf711ef49bcdd50548e9c149871c1a48063ea..76bf23395a3d1e8f11463b8b7d4144d65d081abd 100644 (file)
@@ -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<ModelAPI_AttributeBoolean>(
+    data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId()));
+  if (!anActiveAttr->isInitialized())
+    anActiveAttr->setValue(true);
 }
 
 void SketchPlugin_ConstraintVertical::execute()
index 66463e83cefa6df1b058e7c53037040c79172aff..24cca8f12f605d2545fd2cd883e77b616deb80ee 100644 (file)
@@ -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<ModelAPI_AttributeBoolean>(
+    data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId()));
+  if (!anActiveAttr->isInitialized())
+    anActiveAttr->setValue(true);
 }
 
 void SketchPlugin_MultiRotation::execute()
index 5091d98d6e68dc62dc19a109e24fb6aa9a9e93af..60b50b28fbd04200528a8e1fe9adddb98049d0d5 100644 (file)
@@ -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<ModelAPI_AttributeBoolean>(
+    data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId()));
+  if (!anActiveAttr->isInitialized())
+    anActiveAttr->setValue(true);
 }
 
 void SketchPlugin_MultiTranslation::execute()
index 402a9f57b223f7893c14081ba482c4274e7b15a1..68461c60cd4b723990ed2e9a087fb2d935665541 100644 (file)
@@ -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<ModelAPI_AttributeBoolean>(
+    data()->addAttribute(SketchPlugin_Constraint::CONSTRAINT_ACTIVE(), ModelAPI_AttributeBoolean::typeId()));
+  if (!anActiveAttr->isInitialized())
+    anActiveAttr->setValue(true);
 }
 
 void SketchPlugin_Offset::execute()
index d1c47eb22e9a7de66ca19fb79c34f3bd14543a47..cd146e687704b4ddf5772de203076fd35d7d0b4d 100644 (file)
@@ -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 <sketch_objects>`
diff --git a/src/SketchPlugin/doc/images/ConstraintsBrowser.png b/src/SketchPlugin/doc/images/ConstraintsBrowser.png
new file mode 100644 (file)
index 0000000..47f40ab
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 (file)
index 0000000..66ea1de
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 (file)
index 0000000..1809ede
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 (file)
index 0000000..1ba6ad4
--- /dev/null
@@ -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.
index aecba9754987f43a7145b98660d1222c502e5ae1..d4813735b1b4c31e996bfae1e9cd659779845131 100644 (file)
@@ -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<ConstraintPtr> 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;
index 9f67d498acb3cc308ea9af10a35ae4eecfd95c50..2ebfebb107bb508968b049206ff100859f073a75 100644 (file)
@@ -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.
index 4ecb036e56d0f43c2188b2a4268194bf4b6d8195..44acce9bfc76cac6da99cc16a57ca5f70dcb2187 100644 (file)
@@ -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 =
index 83fafe3b10c22706628056877dc76e4135f86e59..6bcf0c542566bd2d3cdcc1d49b2588168df74717 100644 (file)
@@ -231,6 +231,21 @@ bool SketchSolver_Group::movePoint(AttributePtr theAttribute,
 // ============================================================================
 bool SketchSolver_Group::resolveConstraints()
 {
+  auto aNb = mySketch->numberOfSubs();
+  std::list<ConstraintPtr> 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<SketchPlugin_Constraint>(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) {
index a5e773f4adfb8923306895b5fc12c493a896da1d..1755c19b113ab2cb7d412164f46e6c7056ce61c6 100644 (file)
@@ -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<AttributePtr, EntityWrapperPtr>      myAttributeMap;
 
   UpdaterPtr myUpdaters;
+  std::map<ConstraintPtr, ConstraintWrapperPtr> myDeactivatedConstraintMap;
 };
 
 typedef std::shared_ptr<SketchSolver_Storage> StoragePtr;
index 288babe53c31408abd2b57de15c7307d1e15d631..b5e622d60c259b79d4b1794ed0dd0c54af2cd0d0 100644 (file)
@@ -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
index 444f8d69d1a2c8dc1b78a3cd2b7a4011e8d16921..1136c19eadd40361b0d8f63ec48b422d5ed5ff1a 100644 (file)
@@ -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);
index 88dc318d6f5b4600f742431032e8a02f3ca38a15..b75cabf93a2a7cc21fda646bf55e136e5cb070e3 100644 (file)
@@ -49,7 +49,7 @@ public:
                                const std::shared_ptr<GeomAPI_Ax3>& 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;
 
index fa307371325843b2b8de77f43de3167b1efe526e..b76fc48aafa7b5c2ab2952e2fd30c73713aea018 100644 (file)
@@ -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
index 8171558854b7f6e4b03d6c35ae70fbd69338e699..76487f07ebd1273fa9b135075b7a8178195f06f0 100644 (file)
@@ -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
index 2e75f77bd6cf39532281f3d0220fc77c338e1b1d..ce285dca7f05dc2bddfc2f6fdab4dd6a99c57c59 100644 (file)
@@ -48,7 +48,7 @@ public:
                                const std::shared_ptr<GeomAPI_Ax3>& 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;
 
index caeef273180e6a026b93ca1a7f8b7a6f116bb687..9a09e11c72c7dd696e52494b7c6a0c3f1cc7629d 100644 (file)
@@ -51,7 +51,12 @@ public:
                                const std::shared_ptr<GeomAPI_Ax3>& 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
index 3567a212a8f739cf82e6baf89f074bc18d629041..355d9bc0c333d82b9c1c31891eba252dbe09ad0a 100644 (file)
@@ -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);
 
index b49284fdb7a0417d10a31ca50d694354528426ee..5536132115015179a82de7f9633f389e0833834a 100644 (file)
@@ -48,7 +48,7 @@ public:
                                const std::shared_ptr<GeomAPI_Ax3>& 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;
 
index 6a5200fce92d70243b0f58bb14112d7ca621daa5..a24e8f364f338077113ac751e068e03dceb60097 100644 (file)
@@ -47,7 +47,7 @@ public:
   static bool IsReadyToDisplay(ModelAPI_Feature* theConstraint,
                                const std::shared_ptr<GeomAPI_Ax3>& 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;
 
index 246dc6c35cd4d1e57173f635e112efbc67a8f1e5..5e11e28e3921f47cb69c971f43019988dd197eef 100644 (file)
@@ -49,7 +49,7 @@ public:
       const std::shared_ptr<GeomAPI_Ax3>& 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;
 
index 27e0e6fd9fc1b8bf2e86e873efae96f66f304d82..a4cfa017b355213c2ebf8c243f92cea65bb4d53e 100644 (file)
@@ -48,7 +48,7 @@ public:
                                const std::shared_ptr<GeomAPI_Ax3>& 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;
 
index e5a7405443fcbebe3937f4c722a807ed6c7a32f4..aae490cebb094179fd72cc12bdff9808bac9dbd3 100644 (file)
@@ -50,7 +50,7 @@ public:
   static bool IsReadyToDisplay(ModelAPI_Feature* theConstraint,
                                const std::shared_ptr<GeomAPI_Ax3>& 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
index 3a1771ea87b47b1c982ea302c7480eafe7e9fe1f..6b2713de6587343126f3c5c87bfe36b5c270cbbb 100644 (file)
@@ -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;
index ceee0ce02b8f3186033e1cf7a47eab2d174e8c74..36e9219a6c18065cc0767088208e2b73b683522a 100644 (file)
@@ -51,7 +51,7 @@ public:
   static bool IsReadyToDisplay(ModelAPI_Feature* theConstraint,
                                const std::shared_ptr<GeomAPI_Ax3>& 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
index de2569009fbabd56088368c8b54beac231768830..81dd5cc2b03f1f285548f7e5cd6b73b856bc0aac 100644 (file)
@@ -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<<aMsg<<std::endl;
   Events_InfoMessage("SketcherPrs_SymbolPrs", aMsg).send();
-  myIconsMap[iconName()] = Handle(Image_AlienPixMap)();
+  myIconsMap[iconName(isIconType)] = Handle(Image_AlienPixMap)();
   return Handle(Image_AlienPixMap)();
 }
 
@@ -207,15 +208,11 @@ Handle(Image_AlienPixMap) SketcherPrs_SymbolPrs::icon()
 void SketcherPrs_SymbolPrs::prepareAspect()
 {
   // Create an aspect with the icon
-  if (myAspect.IsNull()) {
-    Handle(Image_AlienPixMap) aIcon = icon();
-    if (aIcon.IsNull())
-      myAspect = new Graphic3d_AspectMarker3d();
-    else
-      myAspect = new Graphic3d_AspectMarker3d(aIcon);
-
-    myAspect->SetColor(myCustomColor);
-  }
+  Handle(Image_AlienPixMap) aIcon = icon();
+  if (aIcon.IsNull())
+    myAspect = new Graphic3d_AspectMarker3d();
+  else
+    myAspect = new Graphic3d_AspectMarker3d(aIcon);
 }
 
 //*********************************************************************************
index 70bfd7305882050ea62a686ed47c7227bbda979b..5561b386457a7302943fc4c589c39302aab50ddd 100644 (file)
@@ -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
index 083287aecdfa2f2f9e5851d0d59a38aad333b7a1..cff9c8474db19f97cceb22d7536566ac6055bb64 100644 (file)
@@ -50,7 +50,7 @@ public:
                                const std::shared_ptr<GeomAPI_Ax3>& 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;
 
index b924b970acd7b4af343808816370c97cbf80ca61..5c213b60dc2bafda9cbb80813e71bf3283552026 100644 (file)
@@ -50,7 +50,7 @@ public:
   static bool IsReadyToDisplay(ModelAPI_Feature* theConstraint,
                                const std::shared_ptr<GeomAPI_Ax3>& 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 (file)
index 0000000..c03591e
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 (file)
index 0000000..19c4013
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 (file)
index 0000000..f865127
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 (file)
index 0000000..c11988a
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 (file)
index 0000000..bd0ef35
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 (file)
index 0000000..49cb518
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 (file)
index 0000000..31c1f6d
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 (file)
index 0000000..90bffe4
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 (file)
index 0000000..201f281
Binary files /dev/null and b/src/SketcherPrs/icons/vertical_deactivate.png differ
index dd690533ec0779ab317de4850a475a3edb703344..a8c103fac56585345c617ed945e7db8e6d0fd9ff 100644 (file)
@@ -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
index aa05544afe020c19395efa03ecdb88e0cc9a999e..49de8deb1ca37baad1c0517d3be871a7dad59949 100644 (file)
@@ -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();
index 5b43656584e52835956c83072522196be2309908..7e23b10d7b6a7514f65102a9cd5358bc301cacb0 100644 (file)
@@ -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
 {
index 3e9e97a383a1debf7f07b5eb74f596de3907f620..455b5ee288e4524ade5c449f0c548d8f1b972551 100644 (file)
@@ -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();
 
index 4775444902facde04b55b7dd5a36b7b2d05f59af..3d294afd4621189e403d24b98f42262c39444c71 100644 (file)
@@ -562,6 +562,23 @@ void XGUI_Displayer::setSelected(const  QList<ModuleBase_ViewerPrsPtr>& 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<Handle(AIS_InteractiveObject)>();
+
+        aContext->AddOrRemoveSelected(aAisObj, false);
+      }
     }
   }
   if (!aShapesToBeSelected.IsEmpty())
index 04d12eabc39aa04e328d778a9a1d02f323a91685..55efe02e119e793178a49fc091116a6e9d64e61c 100644 (file)
@@ -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:
index 7a80eb0a9c8bcf3b5017ac250aa91fe19333591d..9aafff1ed5f80d07e765d7cc55fee534a1b2d7cb 100644 (file)
@@ -22,6 +22,7 @@
 #include "XGUI_Displayer.h"
 #include "XGUI_ViewerProxy.h"
 #include "XGUI_ObjectsBrowser.h"
+#include "XGUI_SketchConstraintsBrowser.h"
 
 #ifndef HAVE_SALOME
 #include <AIS_ViewCube.hxx>
@@ -79,6 +80,10 @@ QList<ModuleBase_ViewerPrsPtr> 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<ModuleBase_ViewerPrsPtr>& thePre
   }
 }
 
+void XGUI_Selection::getSelectedInSketchConstraintsBrowser(QList<std::shared_ptr<ModuleBase_ViewerPrs>>& 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<ModuleBase_ViewerPrs>(
+        new ModuleBase_ViewerPrs(anObject, GeomShapePtr(), NULL)));
+
+     /* AISObjectPtr aAisPtr = myWorkshop->displayer()->getAISObject(aConstrFeature);
+      if (!aAisPtr)
+        continue;
+      Handle(AIS_InteractiveObject) aAisObj = aAisPtr->impl<Handle(AIS_InteractiveObject)>();
+      auto aPrs = std::shared_ptr<ModuleBase_ViewerPrs>(
+        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();
 }
 
index 9cf5ea963e68670632a3c326082643c7706cb5d0..29eeffa615ef1cf0a530657223fd21f94e71aae8 100644 (file)
@@ -103,6 +103,13 @@ protected:
   /// \param thePresentations an output list of presentation
   void getSelectedInBrowser(QList<std::shared_ptr<ModuleBase_ViewerPrs>>& 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<std::shared_ptr<ModuleBase_ViewerPrs>>& 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
index 00ebe2234d32a54caa06dded0c7a4d5fc56869eb..339a22bc8ca66bb0f0a37daa594171f4fed9a306 100644 (file)
@@ -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<ModuleBase_ViewerPrsPtr> aSelectedPrs =
+      myWorkshop->selector()->selection()->getSelected(ModuleBase_ISelection::ConstraintsBrowser);
+    XGUI_Displayer* aDisplayer = myWorkshop->displayer();
+    aDisplayer->setSelected(aSelectedPrs);
+    myWorkshop->updateColorScaleVisibility();
+    emit selectionChanged();
+  }
+}
+
 //**************************************************************
 void XGUI_SelectionMgr::onViewerSelection()
 {
index ce9a47d3111e48481b509edd122f23b3d454a22f..be5e31065b905af34ac3cbdb1fed1eaadcb93e15 100644 (file)
@@ -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 (file)
index 0000000..576caae
--- /dev/null
@@ -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 <ModelAPI_Data.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Tools.h>
+#include <ModelAPI_ResultField.h>
+
+#include <ModuleBase_Tools.h>
+#include <ModuleBase_ITreeNode.h>
+#include <ModuleBase_Operation.h>
+#include <ModuleBase_IModule.h>
+#include <XGUI_OperationMgr.h>
+#include <XGUI_Workshop.h>
+#include <ModuleBase_WidgetFactory.h>
+#include <XGUI_Displayer.h>
+
+#include <QLayout>
+#include <QLineEdit>
+#include <QHBoxLayout>
+#include <QPushButton>
+#include <QPixmap>
+#include <QEvent>
+#include <QMouseEvent>
+#include <QAction>
+#include <QStyledItemDelegate>
+#include <QMessageBox>
+#include <QApplication>
+#include <QGroupBox>
+#include <QPainter>
+
+#include <ModelAPI_CompositeFeature.h>
+#include <ModelAPI_AttributeRefAttr.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeBoolean.h>
+
+#include <unordered_map>
+
+#ifdef DEBUG_INDXES
+#include <QToolTip>
+#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<ModelAPI_AttributeRefAttr>(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<std::string, std::string> 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<std::pair<FeaturePtr, std::vector<AttributePtr>>>& theList)
+{
+  // Save the expand state so that after the update, all the items will retain their previous expand/collapse state.
+  std::unordered_map<std::string, bool> 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<Events_Message>& theMessage)
+{
+  if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED)
+    || theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED))
+  {
+    std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg =
+      std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
+    std::set<ObjectPtr> 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<FeaturePtr> 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<FeaturePtr> 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<FeaturePtr> 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<ModelAPI_AttributeRefAttr>(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 (file)
index 0000000..44e8529
--- /dev/null
@@ -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 <ModuleBase_Definitions.h>
+#include <ModelAPI_Object.h>
+#include <ModelAPI_ResultPart.h>
+#include <ModelAPI_Events.h>
+#include <ModelAPI_Folder.h>
+#include <XGUI_DataModel.h>
+#include <ModelAPI_Attribute.h>
+
+#include <QWidget>
+#include <QTreeView>
+#include <QLabel>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QMap>
+#include <QCheckBox>
+#include <QScrollArea>
+#include <QTreeWidget>
+
+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<AttributePtr> 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<XGUI_DataModel*>(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<std::pair<FeaturePtr, std::vector<AttributePtr>>>& 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<Events_Message>& 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<FeaturePtr>);
+
+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<std::string, std::vector<FeatStruct>> myConstrs; // string - name of group, vector - constraints from group
+};
+
+#endif
index c40ea021c354806a695d2199bc995154fa1ca0b4..5e0a1018c40cbb8ea8b0a14ec430a7533ffeb7b7 100644 (file)
@@ -51,6 +51,8 @@
 #include <XGUI_InspectionPanel.h>
 #include <XGUI_CompressFiles.h>
 
+#include <XGUI_SketchConstraintsBrowser.h>
+
 #ifdef HAVE_SALOME
 #include <SUIT_Application.h>
 #include <SUIT_Session.h>
@@ -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<FeaturePtr, std::set<FeaturePtr> >& theMainList,
index e0d97cbae43f2f3d1d32645c17366114efe949d4..fc3fa4a4161394584d07c8db363f4bb892c1ed07 100644 (file)
@@ -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
index 9d89050d2aa3121ffd3d50b36e79987094369d23..db4f19255794f190ddd1d8948245400d97543c16 100644 (file)
         <translation>Panneau de propriété</translation>
     </message>
 </context>
+<context>
+    <name>XGUI_SketchConstraintsBrowser</name>
+    <message>
+        <source>Extended Information</source>
+        <translation>Informations étendues</translation>
+    </message>
+</context>
 <context>
     <name>XGUI_TransparencyWidget</name>
     <message>