Salome HOME
Selection priority in Sketch, clear selection when sketch goes from entity to neutral...
authornds <nds@opencascade.com>
Tue, 21 Jun 2016 13:32:01 +0000 (16:32 +0300)
committernds <nds@opencascade.com>
Tue, 21 Jun 2016 13:32:35 +0000 (16:32 +0300)
23 files changed:
src/ModuleBase/CMakeLists.txt
src/ModuleBase/ModuleBase_Events.h [new file with mode: 0755]
src/ModuleBase/ModuleBase_OperationFeature.cpp
src/ModuleBase/ModuleBase_ResultPrs.cpp
src/ModuleBase/ModuleBase_ResultPrs.h
src/ModuleBase/ModuleBase_Tools.cpp
src/ModuleBase/ModuleBase_Tools.h
src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp
src/ModuleBase/ModuleBase_WidgetSelector.cpp
src/ModuleBase/ModuleBase_WidgetSelector.h
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_OperationPrs.cpp
src/PartSet/PartSet_SketcherMgr.cpp
src/PartSet/PartSet_SketcherMgr.h
src/PartSet/PartSet_WidgetSketchCreator.h
src/SketchPlugin/SketchPlugin_SketchEntity.h
src/SketcherPrs/SketcherPrs_Tools.h
src/XGUI/XGUI_CustomPrs.cpp
src/XGUI/XGUI_Displayer.cpp
src/XGUI/XGUI_Displayer.h
src/XGUI/XGUI_PropertyPanel.cpp
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_WorkshopListener.cpp

index c4fc1a27659b647728e65899f565f8190490cc83..c4fe31943fd2fab04a5925cc7e793c10ce1f391d 100644 (file)
@@ -8,6 +8,7 @@ SET(PROJECT_HEADERS
   ModuleBase_ActionInfo.h
   ModuleBase_Definitions.h
   ModuleBase_DoubleSpinBox.h
+  ModuleBase_Events.h
   ModuleBase_Filter.h
   ModuleBase_FilterFactory.h
   ModuleBase_FilterValidated.h
diff --git a/src/ModuleBase/ModuleBase_Events.h b/src/ModuleBase/ModuleBase_Events.h
new file mode 100755 (executable)
index 0000000..f6f4c7e
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        ModuleBase_Events.h
+// Created:     21 June 2016
+// Author:      Natalia Ermolaeva
+
+#ifndef ModuleBase_Events_H
+#define ModuleBase_Events_H
+
+#include "ModuleBase.h"
+
+static const char * EVENT_UPDATE_BY_WIDGET_SELECTION = "SelectionUpdatedByWidget";
+
+#endif
index ea72d23076a387e66377043d0d122d6ad1b1409a..6066fa00aad09503d83ac9e08e6a51ab03402075 100755 (executable)
@@ -117,7 +117,8 @@ void ModuleBase_OperationFeature::startOperation()
 
   myVisualizedObjects.clear();
   // store hidden result features
-  std::list<ResultPtr> aResults = aFeature->results();
+  std::list<ResultPtr> aResults;
+  ModelAPI_Tools::allResults(aFeature, aResults);
   std::list<ResultPtr>::const_iterator aIt;
   for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
     ObjectPtr anObject = *aIt;
@@ -140,7 +141,8 @@ void ModuleBase_OperationFeature::stopOperation()
     return;
 
   // store hidden result features
-  std::list<ResultPtr> aResults = aFeature->results();
+  std::list<ResultPtr> aResults;
+  ModelAPI_Tools::allResults(aFeature, aResults);
   std::list<ResultPtr>::const_iterator aIt;
   for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
     ObjectPtr anObject = *aIt;
@@ -194,11 +196,13 @@ bool ModuleBase_OperationFeature::hasObject(ObjectPtr theObj) const
   if (aFeature) {
     if (aFeature == theObj)
       return true;
-    std::list<ResultPtr> aResults = aFeature->results();
+    std::list<ResultPtr> aResults;
+    ModelAPI_Tools::allResults(aFeature, aResults);
     std::list<ResultPtr>::const_iterator aIt;
     for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) {
-      if (theObj == (*aIt))
-        return true;
+      ResultPtr aResult = *aIt;
+      if (theObj == aResult)
+         return true;
     }
 #ifdef DEBUG_DO_NOT_ACTIVATE_SUB_FEATURE
     if (aFeature->isMacro()) {
@@ -453,7 +457,8 @@ void ModuleBase_OperationFeature::initSelection(ModuleBase_ISelection* theSelect
   if (aFeature) {
     QList<ModuleBase_ViewerPrsPtr> aSelected = theSelection->getSelected(ModuleBase_ISelection::AllControls);
 
-    std::list<ResultPtr> aResults = aFeature->results();
+    std::list<ResultPtr> aResults;
+    ModelAPI_Tools::allResults(aFeature, aResults);
     QObjectPtrList aResList;
     std::list<ResultPtr>::const_iterator aIt;
     for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt)
index 128770c2f7f8db6e86c8ba14972e748ec7a16341..d9460ce72b20da44fd6db842e46e20a2e42edddc 100755 (executable)
@@ -31,6 +31,7 @@
 #include <AIS_Selection.hxx>
 #include <TColStd_ListIteratorOfListOfInteger.hxx>
 #include <Graphic3d_AspectMarker3d.hxx>
+#include <TopExp_Explorer.hxx>
 
 IMPLEMENT_STANDARD_HANDLE(ModuleBase_BRepOwner, StdSelect_BRepOwner);
 IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_BRepOwner, StdSelect_BRepOwner);
@@ -45,7 +46,7 @@ IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_ResultPrs, ViewerData_AISShape);
 
 
 ModuleBase_ResultPrs::ModuleBase_ResultPrs(ResultPtr theResult)
-  : ViewerData_AISShape(TopoDS_Shape()), myResult(theResult)
+  : ViewerData_AISShape(TopoDS_Shape()), myResult(theResult), myAdditionalSelectionPriority(0)
 {
   std::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(theResult);
   TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
@@ -63,6 +64,11 @@ ModuleBase_ResultPrs::ModuleBase_ResultPrs(ResultPtr theResult)
   ModuleBase_Tools::setPointBallHighlighting(this);
 }
 
+void ModuleBase_ResultPrs::setAdditionalSelectionPriority(const int thePriority)
+{
+  myAdditionalSelectionPriority = thePriority;
+}
+
 void ModuleBase_ResultPrs::Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
                                    const Handle(Prs3d_Presentation)& thePresentation, 
                                    const Standard_Integer theMode)
@@ -92,6 +98,16 @@ void ModuleBase_ResultPrs::ComputeSelection(const Handle(SelectMgr_Selection)& a
     // In order to avoid using custom selection modes
     return;
 
+  // TODO: OCCT issue should be created for the COMPOUND processing
+  // before it is fixed, the next workaround in necessary
+  if (aMode == AIS_Shape::SelectionMode(TopAbs_COMPOUND)) {
+    const TopoDS_Shape& aShape = Shape();
+    TopExp_Explorer aCompExp(aShape, TopAbs_COMPOUND);
+    // do not activate in compound mode shapes which do not contain compounds
+    if (!aCompExp.More())
+      return;
+  }
+
   if (aMode == AIS_Shape::SelectionMode(TopAbs_COMPSOLID)) {
     // Limit selection area only by actual object (Shape)
     ResultCompSolidPtr aCompSolid = ModelAPI_Tools::compSolidOwner(myResult);
@@ -117,6 +133,14 @@ void ModuleBase_ResultPrs::ComputeSelection(const Handle(SelectMgr_Selection)& a
     //AIS_Shape::ComputeSelection(aSelection, 0);
   } 
   AIS_Shape::ComputeSelection(aSelection, aMode);
+
+  if (myAdditionalSelectionPriority > 0) {
+    for (aSelection->Init(); aSelection->More(); aSelection->Next()) {
+      Handle(SelectBasics_EntityOwner) aBasicsOwner = aSelection->Sensitive()->BaseSensitive()->OwnerId();
+      if (!aBasicsOwner.IsNull())
+        aBasicsOwner->Set(aBasicsOwner->Priority() + myAdditionalSelectionPriority);
+    }
+  }
 }
 
 void ModuleBase_ResultPrs::appendWiresSelection(const Handle(SelectMgr_Selection)& theSelection,
index 240d64eafd18e2c84a2789d880bdaeafd0e64c3f..e1143734ca13e70b0925bbac148525bea447ef82 100644 (file)
@@ -15,6 +15,8 @@
 #include <Standard_DefineHandle.hxx>
 #include <StdSelect_BRepOwner.hxx>
 
+#include <QMap>
+
 DEFINE_STANDARD_HANDLE(ModuleBase_BRepOwner, StdSelect_BRepOwner)
 
 /**
@@ -73,6 +75,15 @@ public:
   /// Returns result object
   Standard_EXPORT ResultPtr getResult() const { return myResult; }
 
+  /// Returns selection priorities that will be added to created selection owner
+  /// \return integer value
+  Standard_EXPORT int getAdditionalSelectionPriority() const { return myAdditionalSelectionPriority; }
+
+  /// Appends a special priority for the mode of selection
+  /// \param theSelectionMode a mode of selection, used in ComputeSelection
+  /// \param thePriority a new priority value
+  Standard_EXPORT void setAdditionalSelectionPriority(const int thePriority);
+
   DEFINE_STANDARD_RTTI(ModuleBase_ResultPrs)
 protected:
   /// Redefinition of virtual function
@@ -95,6 +106,8 @@ private:
 
   /// Original shape of the result object
   TopoDS_Shape myOriginalShape;
+  /// selection priority that will be added to the standard selection priority of the selection entity
+  int myAdditionalSelectionPriority;
 };
 
 
index 986d22d18a5f707545ee2f583f80e4f58037504c..9e77f06503b7250a8814eb7689c8dd9483b46c0e 100755 (executable)
@@ -390,8 +390,9 @@ QString displayedInteractiveObjects(Handle(AIS_InteractiveContext)& theContext,
 
     if (!aShapePrs.IsNull()) {
       const TopoDS_Shape& aShape = aShapePrs->Shape();
-      if (aShape.IsNull())
-        Events_Error::throwException("An empty AIS presentation");
+      if (aShape.IsNull()) {
+        //Events_Error::throwException("An empty AIS presentation");
+      }
       else
         anInfo += QString(", shape type: %1").arg(getShapeTypeInfo(aShape.ShapeType()));
     }
@@ -451,8 +452,9 @@ QString activeOwners(Handle(AIS_InteractiveContext)& theContext, const bool theS
 
     if (!BROwnr.IsNull() && BROwnr->HasShape()) {
       const TopoDS_Shape& aShape = BROwnr->Shape();
-      if (aShape.IsNull())
-        Events_Error::throwException("An empty AIS presentation");
+      if (aShape.IsNull()) {
+        //Events_Error::throwException("An empty AIS presentation");
+      }
       else
         anInfo += QString(", shape type: %1").arg(getShapeTypeInfo(aShape.ShapeType()));
     }
@@ -851,6 +853,8 @@ GeomShapePtr getShape(const AttributePtr& theAttribute, ModuleBase_IWorkshop* th
                                                                                  (theAttribute);
     aShape = aSelectAttr->value();
   }
+  else // Geom2D point processing
+    aShape = theWorkshop->module()->findShape(theAttribute);
   return aShape;
 }
 
@@ -934,7 +938,7 @@ void refsToFeatureInFeatureDocument(const ObjectPtr& theObject, std::set<Feature
 
 
 //**************************************************************
-bool isSubOfComposite(const ObjectPtr& theObject)
+/*bool isSubOfComposite(const ObjectPtr& theObject)
 {
   bool isSub = false;
   std::set<FeaturePtr> aRefFeatures;
@@ -945,10 +949,10 @@ bool isSubOfComposite(const ObjectPtr& theObject)
     isSub = isSubOfComposite(theObject, *anIt);
   }
   return isSub;
-}
+}*/
 
 //**************************************************************
-bool isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature)
+/*bool isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature)
 {
   bool isSub = false;
   CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
@@ -964,7 +968,7 @@ bool isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature)
     }
   }
   return isSub;
-}
+}*/
 
 //**************************************************************
 ResultPtr firstResult(const ObjectPtr& theObject)
index 376337dc4f0b3e62d82e5b57492c5d2e0ea14a85..4fb4146b02bf2268a942b08883730bc075b70f8e 100755 (executable)
@@ -264,13 +264,13 @@ void MODULEBASE_EXPORT refsToFeatureInFeatureDocument(const ObjectPtr& theObject
 /// \param theObject a candidate to be a sub object
 /// \param theFeature a candidate to be a composite feature
 /// \return a boolean value
-bool MODULEBASE_EXPORT isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature);
+//bool MODULEBASE_EXPORT isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature);
 
 
 /// Returns true if the result is a sub object of some composite object
 /// \param theObject a result object
 /// \returns boolean value
-bool MODULEBASE_EXPORT isSubOfComposite(const ObjectPtr& theObject);
+//bool MODULEBASE_EXPORT isSubOfComposite(const ObjectPtr& theObject);
 
 
 /// Returns first result of the feature: the object itself if it is a result of
index 932b3d5af2a227d0e84ec96c4072489f2cc1f390..378aa4a6229ed16f18e9578249bc27b21abc568b 100755 (executable)
@@ -17,6 +17,7 @@
 #include <ModuleBase_IModule.h>
 #include <ModuleBase_ViewerPrs.h>
 #include <ModuleBase_IconFactory.h>
+#include <ModuleBase_Events.h>
 
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Object.h>
@@ -24,6 +25,7 @@
 #include <ModelAPI_AttributeRefList.h>
 #include <ModelAPI_AttributeRefAttrList.h>
 #include <ModelAPI_Tools.h>
+#include <ModelAPI_Events.h>
 
 #include <Config_WidgetAPI.h>
 
@@ -302,10 +304,11 @@ bool ModuleBase_WidgetMultiSelector::isValidSelectionCustom(const ModuleBase_Vie
     if (aValid) {
       if (myFeature) {
         // We can not select a result of our feature
-        const std::list<ResultPtr>& aResList = myFeature->results();
+        std::list<ResultPtr> aResults;
+        ModelAPI_Tools::allResults(myFeature, aResults);
         std::list<ResultPtr>::const_iterator aIt;
         bool isSkipSelf = false;
-        for (aIt = aResList.cbegin(); aIt != aResList.cend(); ++aIt) {
+        for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) {
           if ((*aIt) == aResult) {
             isSkipSelf = true;
             break;
@@ -402,8 +405,15 @@ void ModuleBase_WidgetMultiSelector::onSelectionChanged()
 {
   if (!myIsNeutralPointClear) {
     QList<ModuleBase_ViewerPrsPtr> aSelected = getFilteredSelected();
-    if (aSelected.size() == 0)
-      return;
+    // do not clear selected object
+    if (aSelected.size() == 0) {
+      if (!getAttributeSelection().empty()) {
+        // Restore selection in the viewer by the attribute selection list
+        // it should be postponed to exit from the selectionChanged processing
+        static Events_ID anEvent = Events_Loop::eventByName(EVENT_UPDATE_BY_WIDGET_SELECTION);
+        ModelAPI_EventCreator::get()->sendUpdated(myFeature, anEvent);
+      }
+    }
   }
   ModuleBase_WidgetSelector::onSelectionChanged();
 }
index ce06eb4a63673f628a4fd1cab95b20e5bf4b9160..caa9c798b476182f4e98df1cda537e894cfcca93 100755 (executable)
 #include <ModuleBase_IModule.h>
 #include <ModuleBase_ResultPrs.h>
 #include <ModuleBase_ViewerPrs.h>
+#include <ModuleBase_Events.h>
 
 #include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_Events.h>
 
 #include <TopoDS_Iterator.hxx>
 
@@ -163,7 +165,9 @@ void ModuleBase_WidgetSelector::activateCustom()
   activateSelectionAndFilters(true);
 
   // Restore selection in the viewer by the attribute selection list
-  myWorkshop->setSelected(getAttributeSelection());
+  // it should be postponed to have current widget as active to validate restored selection
+  static Events_ID anEvent = Events_Loop::eventByName(EVENT_UPDATE_BY_WIDGET_SELECTION);
+  ModelAPI_EventCreator::get()->sendUpdated(myFeature, anEvent);
 }
 
 //********************************************************************
index 9db264010e91e3813143ea69043288440aae20ca..3a309beb06e5fbc9850a8d083abdf859ce40c776 100755 (executable)
@@ -59,6 +59,11 @@ Q_OBJECT
   /// The methiod called when widget is deactivated
   virtual void deactivate();
 
+  /// Return the attribute values wrapped in a list of viewer presentations
+  /// \return a list of viewer presentations, which contains an attribute result and
+  /// a shape. If the attribute do not uses the shape, it is empty
+  virtual QList<std::shared_ptr<ModuleBase_ViewerPrs>> getAttributeSelection() const;
+
 protected slots:
   /// Slot which is called on selection event
   virtual void onSelectionChanged();
@@ -72,12 +77,6 @@ protected:
   // NDS: has body is temporary
    virtual void updateFocus() {};
 
-  /// Return the attribute values wrapped in a list of viewer presentations
-  /// \return a list of viewer presentations, which contains an attribute result and
-  /// a shape. If the attribute do not uses the shape, it is empty
-  // NDS: has body is temporary
-  virtual QList<std::shared_ptr<ModuleBase_ViewerPrs>> getAttributeSelection() const;
-
   /// Retunrs a list of possible shape types
   /// \return a list of shapes
   QIntList getShapeTypes() const;
index 37754a8b16c9009df7e7ec62425097164df1c62f..d3eb60aa144bfcca3d313c82f3b293e5c475a8b7 100755 (executable)
@@ -51,6 +51,7 @@
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_AttributeString.h>
 #include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_Tools.h>
 
 #include <GeomDataAPI_Point2D.h>
 #include <GeomDataAPI_Point.h>
@@ -332,7 +333,8 @@ void PartSet_Module::operationStarted(ModuleBase_Operation* theOperation)
         // the objects of the current operation should be deactivated
         QObjectPtrList anObjects;
         anObjects.append(aFeature);
-        std::list<ResultPtr> aResults = aFeature->results();
+        std::list<ResultPtr> aResults;
+        ModelAPI_Tools::allResults(aFeature, aResults);
         std::list<ResultPtr>::const_iterator aIt;
         for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
           anObjects.append(*aIt);
@@ -949,13 +951,13 @@ bool PartSet_Module::customisePresentation(ResultPtr theResult, AISObjectPtr the
 {
   bool aCustomized = false;
 
-  if (theResult.get())
-    return aCustomized;
-
   XGUI_Workshop* aWorkshop = getWorkshop();
   XGUI_Displayer* aDisplayer = aWorkshop->displayer();
   ObjectPtr anObject = aDisplayer->getObject(thePrs);
-  if (anObject.get()) {
+  if (!anObject)
+    return aCustomized;
+
+  if (!theResult.get()) {
     bool isConflicting = myOverconstraintListener->isConflictingObject(anObject);
     // customize sketch symbol presentation
     if (thePrs.get()) {
@@ -992,10 +994,9 @@ bool PartSet_Module::customisePresentation(ResultPtr theResult, AISObjectPtr the
         aCustomized = thePrs->setColor(aColor[0], aColor[1], aColor[2]);
       }
     }
-
-    // customize dimentional constrains
-    sketchMgr()->customizePresentation(anObject);
   }
+  // customize dimentional constrains
+  sketchMgr()->customizePresentation(anObject);
 
   return aCustomized;
 }
index 1f8d0c5606ed6349bc40c2236b9effb03db15400..d5e81272352a1ff9f17727c7227f32e4b31a9869 100755 (executable)
@@ -29,6 +29,7 @@
 #include <ModelAPI_Validator.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_ResultCompSolid.h>
+#include <ModelAPI_Tools.h>
 
 #include <Events_InfoMessage.h>
 #include <Events_Loop.h>
@@ -331,9 +332,10 @@ void PartSet_OperationPrs::getResultShapes(const FeaturePtr& theFeature,
 
   XGUI_Displayer* aDisplayer = XGUI_Tools::workshop(theWorkshop)->displayer();
 
-  std::list<ResultPtr> aFeatureResults = theFeature->results();
-  std::list<ResultPtr>::const_iterator aRIt = aFeatureResults.begin(),
-                                       aRLast = aFeatureResults.end();
+  std::list<ResultPtr> aResults;
+  ModelAPI_Tools::allResults(theFeature, aResults);
+  std::list<ResultPtr>::const_iterator aRIt = aResults.begin(),
+                                       aRLast = aResults.end();
   for (; aRIt != aRLast; aRIt++) {
     ResultPtr aResult = *aRIt;
     GeomShapePtr aGeomShape = aResult->shape();
index beb3206c7e83bb674612a6af929206f5da2cbdfb..b95786c36a8bc0f131faa6b752663a545ee25e8e 100755 (executable)
@@ -38,6 +38,7 @@
 #include <ModuleBase_WidgetEditor.h>
 #include <ModuleBase_ViewerPrs.h>
 #include <ModuleBase_Tools.h>
+#include <ModuleBase_ResultPrs.h>
 
 #include <GeomDataAPI_Point2D.h>
 
@@ -384,11 +385,6 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
       return;
 
     Handle(AIS_InteractiveContext) aContext = aViewer->AISContext();
-    if (!aContext.IsNull()) {
-      // MoveTo in order to highlight current object
-      aContext->MoveTo(theEvent->x(), theEvent->y(), theWnd->v3dView());
-      ModuleBase_Tools::selectionInfo(aContext, "PartSet_SketcherMgr::onMousePressed -- MoveTo");
-    }
     // Remember highlighted objects for editing
     ModuleBase_ISelection* aSelect = aWorkshop->selection();
 
@@ -433,13 +429,8 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
 
       myPreviousDrawModeEnabled = aViewer->enableDrawMode(false);
 
-      // this is temporary commented in order to avoid the following wrong case:
-      // Distance constraint is under edition, double click on the digit -> nothing happens
-      // because QApplication::processEvents() calls onMouseDoubleClick, which try to show editor
-      // but as the prev edit is commited an new one is not started, editor is not shown.
-      // This is necessary in order to finalize previous operation
-      //QApplication::processEvents();
       launchEditing();
+      restoreSelection();
     }
   }
 }
@@ -1003,6 +994,9 @@ void PartSet_SketcherMgr::stopNestedSketch(ModuleBase_Operation* theOperation)
     qDebug("stopNestedSketch() : None");
 #endif
   }
+  /// improvement to deselect automatically all eventual selected objects, when
+  // returning to the neutral point of the Sketcher
+  workshop()->selector()->clearSelection();
 }
 
 void PartSet_SketcherMgr::commitNestedSketch(ModuleBase_Operation* theOperation)
@@ -1576,6 +1570,18 @@ void PartSet_SketcherMgr::customizePresentation(const ObjectPtr& theObject)
   if (aFOperation && (PartSet_SketcherMgr::isSketchOperation(aFOperation) ||
                       PartSet_SketcherMgr::isNestedSketchOperation(aFOperation)))
     SketcherPrs_Tools::sendExpressionShownEvent(myIsConstraintsShown[PartSet_Tools::Expressions]);
+
+  // update entities selection priorities
+  FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
+  if (aFeature.get() && PartSet_SketcherMgr::isEntity(aFeature->getKind())) {
+    // update priority for feature
+    updateSelectionPriority(aFeature, aFeature);
+    // update priority for results of the feature
+    std::list<ResultPtr> aResults = aFeature->results();
+    std::list<ResultPtr>::const_iterator anIt = aResults.begin(), aLastIt = aResults.end();
+    for (; anIt != aLastIt; anIt++)
+      updateSelectionPriority(*anIt, aFeature);
+  }
 }
 
 ModuleBase_Operation* PartSet_SketcherMgr::getCurrentOperation() const
@@ -1728,6 +1734,53 @@ void PartSet_SketcherMgr::updateBySketchParameters(
   }
 }
 
+void PartSet_SketcherMgr::updateSelectionPriority(ObjectPtr theObject,
+                                                  FeaturePtr theFeature)
+{
+  if (!theObject.get() || !theFeature.get())
+    return;
+
+  AISObjectPtr anAIS = workshop()->displayer()->getAISObject(theObject);
+  Handle(AIS_InteractiveObject) anAISIO;
+  if (anAIS.get() != NULL) {
+    anAISIO = anAIS->impl<Handle(AIS_InteractiveObject)>();
+  }
+
+  if (!anAISIO.IsNull()) { // the presentation for the object is visualized
+    int anAdditionalPriority = 0;
+    // current feature
+    std::shared_ptr<SketchPlugin_Feature> aSPFeature =
+            std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
+    if (aSPFeature.get() != NULL) {
+      // 1. Vertices
+      // 2. Simple segments
+      // 3. External objects (violet color)
+      // 4. Auxiliary segments (dotted)
+      // StdSelect_BRepSelectionTool::Load uses priority calculating:
+      // Standard_Integer aPriority = (thePriority == -1) ? GetStandardPriority (theShape, theType) : thePriority;
+      // Priority of Vertex is 8, edge(segment) is 7.
+      // It might be not corrected as provides the condition above.
+      bool isExternal = aSPFeature->isExternal();
+      bool isAuxiliary = PartSet_Tools::isAuxiliarySketchEntity(aSPFeature);
+      // current feature
+      if (!isExternal && !isAuxiliary)
+        anAdditionalPriority = 30;
+      // external feature
+      if (isExternal)
+        anAdditionalPriority = 20;
+      // auxiliary feature
+      if (isAuxiliary) {
+        anAdditionalPriority = 10; /// auxiliary objects should have less priority that
+        // edges/vertices of local selection on not-sketch objects
+      }
+      Handle(ModuleBase_ResultPrs) aResult = Handle(ModuleBase_ResultPrs)::DownCast(anAISIO);
+      if (!aResult.IsNull()) {
+        aResult->setAdditionalSelectionPriority(anAdditionalPriority);
+      }
+    }
+  }
+}
+
 XGUI_Workshop* PartSet_SketcherMgr::workshop() const
 {
   ModuleBase_IWorkshop* anIWorkshop = myModule->workshop();
index ec9ea8f82d3be2e20df29a2f0540807d549c1e44..f8e85809b1ecb0596c7cdb1fda862a4afcab0092 100644 (file)
@@ -366,6 +366,10 @@ private:
                         const bool isToDisplay, const bool isFlushRedisplay = true);
 
 private:
+  /// Updates selection priority of the presentation
+  /// \param theObject object to find a presentation which will be corrected
+  /// \param theFeature a feature of the presentation
+  void updateSelectionPriority(ObjectPtr theObject, FeaturePtr theFeature);
   /// Returns current workshop
   XGUI_Workshop* workshop() const;
   /// Returns operation manager
index 5290cef0a66139cf1be68c05591bffc2493e0ebd..60a3cf30ea04b00a3775d2830107640fc556d1d9 100644 (file)
@@ -13,7 +13,6 @@
 
 class QLabel;
 class PartSet_Module;
-class ModelAPI_Tools;
 class ModuleBase_Operation;
 class ModuleBase_IWorkshop;
 class PartSet_PreviewPlanes;
index f0fb440204471b617f01cff76094a904d33d5e56..3174d09ea94c4c964263fcfaf395a72f4c93b371 100644 (file)
@@ -104,7 +104,9 @@ class SketchPlugin_SketchEntity : public SketchPlugin_Feature, public GeomAPI_IC
   virtual bool customisePresentation(ResultPtr theResult, AISObjectPtr thePrs,
                                      std::shared_ptr<GeomAPI_ICustomPrs> theDefaultPrs)
   {
-    bool isCustomized = false;
+    //bool isCustomized = false;
+    bool isCustomized = theDefaultPrs.get() != NULL &&
+                        theDefaultPrs->customisePresentation(theResult, thePrs, theDefaultPrs);
     int aShapeType = thePrs->getShapeType();
     // a compound is processed like the edge because the arc feature uses the compound for presentable AIS
     if (aShapeType != 6/*an edge*/ && aShapeType != 7/*a vertex*/ && aShapeType != 0/*compound*/)
index cfc15dbfc6c06cb1dcc2c4cc9be00870963739e6..04db3704c09cbbd153c8aa07dcecb58a432e1245 100644 (file)
@@ -25,7 +25,7 @@ class Handle_Prs3d_DimensionAspect;
 
 //#define MyTextHeight 20
 
-/// Message that document (Part, PartSet) was created
+/// Message that style of visualization of parameter is changed. It will be shown as expression or value
 class SketcherPrs_ParameterStyleMessage : public Events_Message
 {
 public:
index f07582125e0a09dfb500ff2993be9c606d371892..5878f463599e57b687319f861460fbeb8e39d851 100644 (file)
@@ -85,11 +85,7 @@ bool XGUI_CustomPrs::customisePresentation(ResultPtr theResult, AISObjectPtr the
     }
     aCustomized = !aColor.empty() && thePrs->setColor(aColor[0], aColor[1], aColor[2]);
   }
-  else {
-   if (!aCustomized) {
-      ModuleBase_IModule* aModule = myWorkshop->module();
-      aCustomized = aModule->customisePresentation(theResult, thePrs, theCustomPrs);
-    }
-  }
+  ModuleBase_IModule* aModule = myWorkshop->module();
+  aCustomized = aModule->customisePresentation(theResult, thePrs, theCustomPrs) || aCustomized;
   return aCustomized;
 }
index 83e738a05b04660c16fda6890e6d7b17fc37552d..b35bd80c8a5ae4e00a3ab473ae18c0e7a4cb3cea 100644 (file)
@@ -79,7 +79,7 @@ const int MOUSE_SENSITIVITY_IN_PIXEL = 10;  ///< defines the local context mouse
 
 //#define DEBUG_OCCT_SHAPE_SELECTION
 
-#define WORKAROUND_UNTIL_27523_IS_FIXED
+//#define WORKAROUND_UNTIL_27523_IS_FIXED
 
 void displayedObjects(const Handle(AIS_InteractiveContext)& theAIS, AIS_ListOfInteractive& theList)
 {
@@ -476,7 +476,8 @@ bool XGUI_Displayer::isVisible(XGUI_Displayer* theDisplayer, const ObjectPtr& th
   if (!aVisible) {
     // check if all results of the feature are visible
     FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
-    std::list<ResultPtr> aResults = aFeature->results();
+    std::list<ResultPtr> aResults;
+    ModelAPI_Tools::allResults(aFeature, aResults);
     std::list<ResultPtr>::const_iterator aIt;
     aVisible = !aResults.empty();
     for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
@@ -601,6 +602,8 @@ bool XGUI_Displayer::isActive(ObjectPtr theObject) const
   aContext->ActivatedModes(anAIS, aModes);
   return aModes.Extent() > 0;
 }
+
+
 void XGUI_Displayer::setSelected(const  QList<ModuleBase_ViewerPrsPtr>& theValues, bool theUpdateViewer)
 {
   Handle(AIS_InteractiveContext) aContext = AISContext();
@@ -609,16 +612,25 @@ void XGUI_Displayer::setSelected(const  QList<ModuleBase_ViewerPrsPtr>& theValue
   if (aContext->HasOpenedContext()) {
     aContext->UnhilightSelected(false);
     aContext->ClearSelected(false);
-    NCollection_Map<TopoDS_Shape> aShapesToBeSelected;
+    NCollection_DataMap<TopoDS_Shape, NCollection_Map<Handle(AIS_InteractiveObject)>> aShapesToBeSelected;
 
     foreach (ModuleBase_ViewerPrsPtr aPrs, theValues) {
       const GeomShapePtr& aGeomShape = aPrs->shape();
       if (aGeomShape.get() && !aGeomShape->isNull()) {
         const TopoDS_Shape& aShape = aGeomShape->impl<TopoDS_Shape>();
 #ifdef DEBUG_OCCT_SHAPE_SELECTION
+        // problem 1: performance
+        // problem 2: IO is not specified, so the first found owner is selected, as a result
+        // it might belong to another result
         aContext->AddOrRemoveSelected(aShape, false);
 #else
-        aShapesToBeSelected.Add(aShape);
+        NCollection_Map<Handle(AIS_InteractiveObject)> aPresentations;
+        if (aShapesToBeSelected.IsBound(aShape))
+          aPresentations = aShapesToBeSelected.Find(aShape);
+        ObjectPtr anObject = aPrs->object();
+        getPresentations(anObject, aPresentations);
+
+        aShapesToBeSelected.Bind(aShape, aPresentations);
 #endif
       } else {
         ObjectPtr anObject = aPrs->object();
@@ -1297,6 +1309,42 @@ std::string XGUI_Displayer::getResult2AISObjectMapInfo() const
                                             arg(aContent.join("\n")).toStdString().c_str();
 }
 
+void XGUI_Displayer::getPresentations(const ObjectPtr& theObject,
+                                  NCollection_Map<Handle(AIS_InteractiveObject)>& thePresentations)
+{
+  ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
+  if (aResult.get()) {
+    AISObjectPtr aAISObj = getAISObject(aResult);
+    if (aAISObj.get() != NULL) {
+      Handle(AIS_InteractiveObject) anAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
+      if (!anAIS.IsNull() && !thePresentations.Contains(anAIS))
+        thePresentations.Add(anAIS);
+    }
+  }
+  else {
+    FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
+    // find presentation of the feature
+    AISObjectPtr aAISObj = getAISObject(aFeature);
+    if (aAISObj.get() != NULL) {
+      Handle(AIS_InteractiveObject) anAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
+      if (!anAIS.IsNull() && !thePresentations.Contains(anAIS))
+        thePresentations.Add(anAIS);
+    }
+    // find presentations of the feature results
+    std::list<ResultPtr> aResults;
+    ModelAPI_Tools::allResults(aFeature, aResults);
+    std::list<ResultPtr>::const_iterator anIt = aResults.begin(), aLast = aResults.end();
+    for (; anIt != aLast; ++anIt) {
+      AISObjectPtr aAISObj = getAISObject(*anIt);
+      if (aAISObj.get() != NULL) {
+        Handle(AIS_InteractiveObject) anAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
+        if (!anAIS.IsNull() && !thePresentations.Contains(anAIS))
+          thePresentations.Add(anAIS);
+      }
+    }
+  }
+}
+
 void XGUI_Displayer::activateTrihedron(bool theIsActive) 
 {  
   myIsTrihedronActive = theIsActive; 
@@ -1348,14 +1396,13 @@ QIntList XGUI_Displayer::activeSelectionModes() const
 }
 
 void XGUI_Displayer::AddOrRemoveSelectedShapes(Handle(AIS_InteractiveContext) theContext,
-                                      const NCollection_Map<TopoDS_Shape>& theShapesToBeSelected)
+ const NCollection_DataMap<TopoDS_Shape,
+                           NCollection_Map<Handle(AIS_InteractiveObject)>>& theShapesToBeSelected)
 {
   Handle(AIS_LocalContext) aLContext = theContext->LocalContext();
   TCollection_AsciiString aSelectionName = aLContext->SelectionName();
   aLContext->UnhilightPicked(Standard_False);
 
-  NCollection_Map<TopoDS_Shape> aShapesSelected;
-
   NCollection_List<Handle(SelectBasics_EntityOwner)> anActiveOwners;
   aLContext->MainSelector()->ActiveOwners(anActiveOwners);
   NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (anActiveOwners);
@@ -1363,12 +1410,18 @@ void XGUI_Displayer::AddOrRemoveSelectedShapes(Handle(AIS_InteractiveContext) th
   for (; anOwnersIt.More(); anOwnersIt.Next()) {
     anOwner = Handle(SelectMgr_EntityOwner)::DownCast (anOwnersIt.Value());
     Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(anOwner);
-    if (!BROwnr.IsNull() && BROwnr->HasShape() && theShapesToBeSelected.Contains(BROwnr->Shape())) {
-      if (aShapesSelected.Contains(BROwnr->Shape()))
-        continue;
-      AIS_Selection::Selection(aSelectionName.ToCString())->Select(anOwner);
-      anOwner->SetSelected (Standard_True);
-      aShapesSelected.Add(BROwnr->Shape());
+    if (!BROwnr.IsNull() && BROwnr->HasShape()) {
+      const TopoDS_Shape& aShape = BROwnr->Shape();
+      if (!aShape.IsNull() && theShapesToBeSelected.IsBound(aShape)) {
+        Handle(AIS_InteractiveObject) anOwnerPresentation =
+                                    Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable());
+        NCollection_Map<Handle(AIS_InteractiveObject)> aPresentations =
+                                    theShapesToBeSelected.Find(aShape);
+        if (aPresentations.Contains(anOwnerPresentation)) {
+          AIS_Selection::Selection(aSelectionName.ToCString())->Select(anOwner);
+          anOwner->SetSelected (Standard_True);
+        }
+      }
     }
   }
   aLContext->HilightPicked(Standard_False);
index b80165b6903a11c5b96cd37203aa7f7b54a17302..529aab5ef9a03c6fe135764c26c0997b744a6757 100644 (file)
@@ -13,7 +13,8 @@
 #include <TopoDS_Shape.hxx>
 #include <AIS_InteractiveObject.hxx>
 #include <AIS_InteractiveContext.hxx>
-#include <NCollection_List.hxx>
+#include <NCollection_Map.hxx>
+#include <NCollection_DataMap.hxx>
 
 #include <ModelAPI_Result.h>
 
@@ -322,6 +323,13 @@ private:
   /// \return a string representation
   std::string getResult2AISObjectMapInfo() const;
 
+  /// Returns container of visible presentations for the object. For a feature object,
+  /// the feature results are processed also. The presentations map is not cleared inside.
+  /// \param theObject a feature or result
+  /// \param thePresentations result map of presentations
+  void getPresentations(const ObjectPtr& theObject,
+                        NCollection_Map<Handle(AIS_InteractiveObject)>& thePresentations);
+
   /// Sets the shapes selected in the context. It contains logic of the similar method
   /// in OCCT but improved for performance. The modification is to iterates by a list
   /// of owners in the context only once.
@@ -329,7 +337,10 @@ private:
   /// \param theShapesToBeSelected a map of shapes. Owner's shape is searched in the map and the owner
   /// is selected if it is found there. Only first owner is processed(according to OCCT logic)
   static void AddOrRemoveSelectedShapes(Handle(AIS_InteractiveContext) theContext,
-                                        const NCollection_Map<TopoDS_Shape>& theShapesToBeSelected);
+          const NCollection_DataMap<TopoDS_Shape,
+                          NCollection_Map<Handle(AIS_InteractiveObject)>>& theShapesToBeSelected);
+
+                                        //const NCollection_Map<TopoDS_Shape>& theShapesToBeSelected);
 
  protected:
    /// Reference to workshop
index 10d39b798efacf2a7c4317a8b471de97580f74d7..e37d69f9132f077dba252ba81d4d94f5ecd2c3f4 100755 (executable)
@@ -17,6 +17,9 @@
 #include <ModuleBase_PageWidget.h>
 #include <ModuleBase_WidgetFactory.h>
 #include <ModuleBase_OperationDescription.h>
+#include <ModuleBase_Events.h>
+
+#include <Events_Loop.h>
 
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Validator.h>
@@ -436,6 +439,9 @@ bool XGUI_PropertyPanel::setActiveWidget(ModuleBase_ModelWidget* theWidget)
     theWidget->activate();
   }
   myActiveWidget = theWidget;
+  static Events_ID anEvent = Events_Loop::eventByName(EVENT_UPDATE_BY_WIDGET_SELECTION);
+  Events_Loop::loop()->flush(anEvent);
+
   return true;
 }
 
index f36f9353eab2fd50b598b8d988e7a64f83255cb9..cffb0d4b088296aba150e06c0c990a2c4b02f5cc 100755 (executable)
@@ -627,7 +627,8 @@ void XGUI_Workshop::onOperationStopped(ModuleBase_Operation* theOperation)
   if (aFeature.get()) { // feature may be not created (plugin load fail)
     if (myDisplayer->isVisible(aFeature) && !myDisplayer->isActive(aFeature))
       anObjects.append(aFeature);
-    std::list<ResultPtr> aResults = aFeature->results();
+    std::list<ResultPtr> aResults;
+    ModelAPI_Tools::allResults(aFeature, aResults);
     std::list<ResultPtr>::const_iterator aIt;
     for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
       ResultPtr anObject = *aIt;
@@ -1552,7 +1553,9 @@ std::list<FeaturePtr> allFeatures(const DocumentPtr& theDocument)
     // The order of appending features of the part and the part itself is important
 
     // Append features from a part feature
-    foreach (const ResultPtr& aResult, aFeature->results()) {
+    std::list<ResultPtr> aResults;
+    ModelAPI_Tools::allResults(aFeature, aResults);
+    foreach (const ResultPtr& aResult, aResults) {
       ResultPartPtr aResultPart =
           std::dynamic_pointer_cast<ModelAPI_ResultPart>(aResult);
       if (aResultPart.get() && aResultPart->partDoc().get()) {
@@ -1957,7 +1960,8 @@ void XGUI_Workshop::highlightResults(const QObjectPtrList& theObjects)
   foreach(ObjectPtr aObj, theObjects) {
     aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
     if (aFeature.get()) {
-      aResList = aFeature->results();
+      std::list<ResultPtr> aResults;
+      ModelAPI_Tools::allResults(aFeature, aResults);
       std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aIt;
       for(aIt = aResList.cbegin(); aIt != aResList.cend(); aIt++) {
         aHasHidden |= (*aIt)->isConcealed();
index 366336a1f4307ed65b504699ec1c7dfbf52af5bc..984388b5c6ac4b3d9850fa71431ec906c0da51c4 100755 (executable)
@@ -16,6 +16,7 @@
 #endif
 
 #include <ModuleBase_IModule.h>
+#include <ModuleBase_Events.h>
 
 #include <ModelAPI_Object.h>
 #include <ModelAPI_Events.h>
@@ -39,6 +40,7 @@
 #include <ModuleBase_Tools.h>
 #include <ModuleBase_IViewer.h>
 #include <ModuleBase_FilterFactory.h>
+#include <ModuleBase_WidgetSelector.h>
 
 #include <Config_FeatureMessage.h>
 #include <Config_PointerMessage.h>
@@ -94,6 +96,7 @@ void XGUI_WorkshopListener::initializeEventListening()
   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED));
   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED));
   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_EMPTY_AIS_PRESENTATION));
+  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_UPDATE_BY_WIDGET_SELECTION));
 }
 
 //******************************************************
@@ -133,7 +136,15 @@ void XGUI_WorkshopListener::processEvent(const std::shared_ptr<Events_Message>&
     std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg =
         std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
     onFeatureEmptyPresentationMsg(aUpdMsg);
+  } else if (theMessage->eventID() == Events_Loop::eventByName(EVENT_UPDATE_BY_WIDGET_SELECTION)) {
+    ModuleBase_ModelWidget* aWidget = workshop()->propertyPanel()->activeWidget();
+    if (aWidget) {
+      ModuleBase_WidgetSelector* aWidgetSelector = dynamic_cast<ModuleBase_WidgetSelector*>(aWidget);
+      if (aWidgetSelector)
+        myWorkshop->setSelected(aWidgetSelector->getAttributeSelection());
+    }
   }
+
   //Update property panel on corresponding message. If there is no current operation (no
   //property panel), or received message has different feature to the current - do nothing.
   else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED)) {