]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #2206 Avoid the ability to cancel the current sketch when saving,
authornds <nds@opencascade.com>
Mon, 25 Sep 2017 08:56:00 +0000 (11:56 +0300)
committernds <nds@opencascade.com>
Mon, 25 Sep 2017 08:56:00 +0000 (11:56 +0300)
Issue #2204 Avoid the ability to cancel the current sketch when saving,
Issue #2299 Import of edges participating to the result of the sketch
Issue #2205 Ability to customize the arrows and texts of dimensions

37 files changed:
src/ModuleBase/ModuleBase_IModule.h
src/ModuleBase/ModuleBase_ModelWidget.cpp
src/ModuleBase/ModuleBase_ModelWidget.h
src/ModuleBase/ModuleBase_ResultPrs.cpp
src/ModuleBase/ModuleBase_ResultPrs.h
src/ModuleBase/ModuleBase_WidgetChoice.cpp
src/PartSet/CMakeLists.txt
src/PartSet/PartSet_CustomPrs.h
src/PartSet/PartSet_ExternalObjectsMgr.cpp
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_Module.h
src/PartSet/PartSet_PreviewSketchPlane.cpp [new file with mode: 0644]
src/PartSet/PartSet_PreviewSketchPlane.h [new file with mode: 0644]
src/PartSet/PartSet_SketcherMgr.cpp
src/PartSet/PartSet_SketcherMgr.h
src/PartSet/PartSet_Tools.cpp
src/PartSet/PartSet_Tools.h
src/PartSet/PartSet_WidgetChoice.h [deleted file]
src/PartSet/PartSet_WidgetPoint2d.cpp
src/PartSet/PartSet_WidgetShapeSelector.cpp
src/PartSet/PartSet_WidgetSketchLabel.cpp
src/SketchPlugin/SketchPlugin_ConstraintLength.cpp
src/SketchPlugin/SketchPlugin_ConstraintLength.h
src/SketchPlugin/icons/location_automatic.png [new file with mode: 0644]
src/SketchPlugin/icons/location_left.png [new file with mode: 0644]
src/SketchPlugin/icons/location_right.png [new file with mode: 0644]
src/SketchPlugin/plugin-Sketch.xml
src/SketcherPrs/SketcherPrs_LengthDimension.cpp
src/SketcherPrs/SketcherPrs_Radius.cpp
src/SketcherPrs/SketcherPrs_Tools.h
src/XGUI/XGUI_Displayer.cpp
src/XGUI/XGUI_Displayer.h
src/XGUI/XGUI_MenuMgr.cpp
src/XGUI/XGUI_OperationMgr.cpp
src/XGUI/XGUI_OperationMgr.h
src/XGUI/XGUI_Tools.cpp
src/XGUI/XGUI_Workshop.cpp

index 995e21fe825269abddeb9dc26dd58b3356d839d3..8295af76172a7c2f6d3294b2463728ae3da1475a 100755 (executable)
@@ -309,6 +309,9 @@ class MODULEBASE_EXPORT ModuleBase_IModule : public QObject
   /// \param theStdActions - a map of standard actions
   virtual void updateViewerMenu(const QMap<QString, QAction*>& theStdActions) {}
 
+  /// Updates the current operation state after undo/redo actions calling
+  virtual void updateOperationByUndoRedo() {}
+
   /// Returns true if the action should be always enabled
   /// \param theActionId an action index: Accept or Accept All
   /// \return boolean value
index fcba4e0c4b194ca241bfa5dfdd2eee8e9e8897f1..c5ff1104d9862bd365a99ae021ded888ab69bf59 100644 (file)
@@ -406,20 +406,6 @@ void ModuleBase_ModelWidget::updateObject(ObjectPtr theObject)
   }
 }
 
-void ModuleBase_ModelWidget::moveObject(ObjectPtr theObj)
-{
-  //blockUpdateViewer(true);
-#ifdef DEBUG_WIDGET_INSTANCE
-  qDebug("ModuleBase_ModelWidget::moveObject");
-#endif
-
-  static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED);
-  ModelAPI_EventCreator::get()->sendUpdated(theObj, anEvent);
-  Events_Loop::loop()->flush(anEvent);
-
-  //blockUpdateViewer(false);
-}
-
 bool ModuleBase_ModelWidget::processEnter()
 {
   return false;
index 29dc34733703637174f7e38f1a32ced3624fb384..a1e753fd71c9afd9c9275c75b45ae4123ddc1849 100644 (file)
@@ -250,10 +250,6 @@ Q_OBJECT
   /// \param theObj is updating object
   void updateObject(ObjectPtr theObj);
 
-  /// Sends Move event for the given object
-  /// \param theObj is object for moving
-  static void moveObject(ObjectPtr theObj);
-
   /// Translate passed string with widget context()
   virtual QString translate(const std::string& theStr) const;
 
index 0dd37b3550efc2c532da7bdea5a515390075ffdf..907fd6a6098ffb50752defe12d7ff04ddbc2d987 100755 (executable)
@@ -105,11 +105,14 @@ void ModuleBase_ResultPrs::Compute(
 }
 
 void ModuleBase_ResultPrs::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
-                                            const Standard_Integer aMode)
+                                            const Standard_Integer theMode)
 {
-  if (aMode > TopAbs_SHAPE) {
+  if (appendVertexSelection(aSelection, theMode))
+    return;
+
+  if (theMode > TopAbs_SHAPE) {
     // In order to avoid using custom selection modes
-    if (aMode == ModuleBase_ResultPrs::Sel_Result) {
+    if (theMode == ModuleBase_ResultPrs::Sel_Result) {
       AIS_Shape::ComputeSelection(aSelection, TopAbs_COMPOUND);
     }
     return;
@@ -117,7 +120,7 @@ void ModuleBase_ResultPrs::ComputeSelection(const Handle(SelectMgr_Selection)& a
 
   // 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)) {
+  if (theMode == 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
@@ -125,7 +128,7 @@ void ModuleBase_ResultPrs::ComputeSelection(const Handle(SelectMgr_Selection)& a
       return;
   }
 
-  if (aMode == AIS_Shape::SelectionMode(TopAbs_COMPSOLID)) {
+  if (theMode == AIS_Shape::SelectionMode(TopAbs_COMPSOLID)) {
     // Limit selection area only by actual object (Shape)
     ResultCompSolidPtr aCompSolid = ModelAPI_Tools::compSolidOwner(myResult);
     if (aCompSolid.get()) {
@@ -154,7 +157,7 @@ void ModuleBase_ResultPrs::ComputeSelection(const Handle(SelectMgr_Selection)& a
     }
     //AIS_Shape::ComputeSelection(aSelection, 0);
   }
-  AIS_Shape::ComputeSelection(aSelection, aMode);
+  AIS_Shape::ComputeSelection(aSelection, theMode);
 
   if (myAdditionalSelectionPriority > 0) {
     for (aSelection->Init(); aSelection->More(); aSelection->Next()) {
@@ -166,23 +169,31 @@ void ModuleBase_ResultPrs::ComputeSelection(const Handle(SelectMgr_Selection)& a
   }
 }
 
-void ModuleBase_ResultPrs::appendWiresSelection(const Handle(SelectMgr_Selection)& theSelection,
-                                                const TopoDS_Shape& theShape)
+bool ModuleBase_ResultPrs::appendVertexSelection(const Handle(SelectMgr_Selection)& aSelection,
+                                                 const Standard_Integer theMode)
 {
-  static TopAbs_ShapeEnum TypOfSel
-          = AIS_Shape::SelectionType(AIS_Shape::SelectionMode(TopAbs_WIRE));
-  // POP protection against crash in low layers
-  Standard_Real aDeflection = Prs3d::GetDeflection(theShape, myDrawer);
-  try {
-    StdSelect_BRepSelectionTool::Load(theSelection,
-                                      this,
-                                      theShape,
-                                      TypOfSel,
-                                      aDeflection,
-                                      myDrawer->HLRAngle(),
-                                      myDrawer->IsAutoTriangulation());
-  } catch ( Standard_Failure ) {
+  if (Shape().ShapeType() == TopAbs_VERTEX) {
+    const TopoDS_Shape& aShape = Shape();
+
+    int aPriority = StdSelect_BRepSelectionTool::GetStandardPriority(aShape, TopAbs_VERTEX);
+    double aDeflection = Prs3d::GetDeflection(aShape, myDrawer);
+
+    /// The cause of this method is the last parameter of BRep owner setting into True.
+    /// That means that owner should behave like it comes from decomposition. (In this case, OCCT
+    /// visualizes it in Ring style) OCCT version is 7.0.0 with path for SHAPER module.
+    Handle(StdSelect_BRepOwner) aOwner = new StdSelect_BRepOwner(aShape, aPriority, Standard_True);
+    StdSelect_BRepSelectionTool::ComputeSensitive(aShape, aOwner, aSelection,
+                                                  aDeflection, myDrawer->HLRAngle(), 9, 500);
+
+    for (aSelection->Init(); aSelection->More(); aSelection->Next()) {
+      Handle(SelectMgr_EntityOwner) anOwner =
+        Handle(SelectMgr_EntityOwner)
+        ::DownCast(aSelection->Sensitive()->BaseSensitive()->OwnerId());
+      anOwner->Set(this);
+    }
+    return true;
   }
+  return false;
 }
 
 void ModuleBase_ResultPrs::HilightSelected(const Handle(PrsMgr_PresentationManager3d)& thePM,
index 6d46e4ef5c7b85cbef8be991b096f676bbb5b105..d9a0da37c2f1ad9d9916fb74eba139b389fcc8f8 100644 (file)
@@ -53,9 +53,9 @@ public:
   /// Highlight the presentation with the given color
   /// \param aPM a presentations manager
   /// \param theStyle a style of presentation
-  /// \param aMode a drawing mode
+  /// \param theMode a drawing mode
   virtual void HilightWithColor (const Handle(PrsMgr_PresentationManager3d)& aPM,
-    const Handle(Graphic3d_HighlightStyle)& theStyle, const Standard_Integer aMode = 0)
+    const Handle(Graphic3d_HighlightStyle)& theStyle, const Standard_Integer theMode = 0)
   {
     Selectable()->HilightOwnerWithColor(aPM, theStyle, this);
   }
@@ -119,14 +119,17 @@ protected:
 
   /// Redefinition of virtual function
   Standard_EXPORT virtual void ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
-    const Standard_Integer aMode) ;
+                                                const Standard_Integer theMode) ;
 
 private:
-  /// Appens sensitive and owners for wires of the given shape into selection
+  /// If the shape of this presentation is Vertex, it appends custom sensitive and owners for it.
+  /// Owner is a usual Brep owner with "isDecomposite" in true. It is necessary to have "Ring"
+  /// highlight/selected marker.
   /// \param theSelection a current filled selection
-  /// \param theShape a shape
-  void appendWiresSelection(const Handle(SelectMgr_Selection)& theSelection,
-                            const TopoDS_Shape& theShape);
+  /// \param theMode a selection mode
+  /// \return true if the owner is created
+  bool appendVertexSelection(const Handle(SelectMgr_Selection)& aSelection,
+                             const Standard_Integer theMode);
 
   /// Reference to result object
   ResultPtr myResult;
index ce664179fb40611472f9037f2c24d1cee49827a6..74e8b12aa335a3b3e39fa68fb910bdc9ca7f8086 100644 (file)
@@ -55,6 +55,8 @@ ModuleBase_WidgetChoice::ModuleBase_WidgetChoice(QWidget* theParent,
   if (theData->getBooleanAttribute("use_in_title", false))
     myButtonTitles = aList;
 
+  bool aHasDefaultValue;
+  int aDefaultVal = QString::fromStdString(getDefaultValue()).toInt(&aHasDefaultValue);
   // Widget type can be combobox or radiobuttons
   std::string aWgtType = theData->getProperty("widget_type");
   if ((aWgtType.length() > 0) && (aWgtType == "radiobuttons")) {
@@ -97,7 +99,8 @@ ModuleBase_WidgetChoice::ModuleBase_WidgetChoice(QWidget* theParent,
         myButtons->addButton(aBtn, aId++);
       }
     }
-    myButtons->button(0)->setChecked(true);
+    int aCheckedId = aHasDefaultValue ? aDefaultVal : 0;
+    myButtons->button(aDefaultVal)->setChecked(true);
     connect(myButtons, SIGNAL(buttonClicked(int)), this, SLOT(onCurrentIndexChanged(int)));
   } else {
     myLabel = new QLabel(aLabelText, this);
@@ -115,6 +118,9 @@ ModuleBase_WidgetChoice::ModuleBase_WidgetChoice(QWidget* theParent,
 
     myCombo->addItems(aList);
 
+    if (aHasDefaultValue && aDefaultVal < aList.size())
+      myCombo->setCurrentIndex(aDefaultVal);
+
     connect(myCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int)));
   }
 }
index 37575cf725c28525a1f7541c0224ba880c0130a6..8bb95e123773e96885c16eb3ffa570cad42b2c95 100644 (file)
@@ -41,12 +41,12 @@ SET(PROJECT_HEADERS
     PartSet_OperationPrs.h
     PartSet_OverconstraintListener.h
     PartSet_PreviewPlanes.h
+    PartSet_PreviewSketchPlane.h
     PartSet_ResultSketchPrs.h
     PartSet_SketcherMgr.h
     PartSet_SketcherReentrantMgr.h
     PartSet_Tools.h
     PartSet_Validators.h
-    PartSet_WidgetChoice.h
     PartSet_WidgetEditor.h
     PartSet_WidgetFeaturePointSelector.h
     PartSet_WidgetFileSelector.h
@@ -66,7 +66,6 @@ SET(PROJECT_MOC_HEADERS
     PartSet_Module.h
     PartSet_SketcherMgr.h
     PartSet_SketcherReentrantMgr.h
-    PartSet_WidgetChoice.h
     PartSet_WidgetEditor.h
     PartSet_WidgetFeaturePointSelector.h
     PartSet_WidgetFileSelector.h
@@ -90,6 +89,7 @@ SET(PROJECT_SOURCES
     PartSet_OperationPrs.cpp
     PartSet_OverconstraintListener.cpp
     PartSet_PreviewPlanes.cpp
+    PartSet_PreviewSketchPlane.cpp
     PartSet_ResultSketchPrs.cpp
     PartSet_SketcherMgr.cpp
     PartSet_SketcherReentrantMgr.cpp
index c0254161111fea1d36aa296b316c4d9694953bef..fc83596816a6f0fb2331a165b1cc352f92f73c7a 100755 (executable)
@@ -55,6 +55,9 @@ public:
 
   /// Returns color lighter than sketch feature entity : pink
   static const std::string OPERATION_REMOVE_FEATURE_COLOR() { return "255, 174, 201"; }
+
+  /// Returns color equal to default color of construction plugin : gray
+  static const std::string OPERATION_SKETCH_PLANE() { return "150,150,180"; }
 public:
   /// Constructor
   /// \param theWorkshop a reference to workshop
index 85c9ce0ddcc01961d86a89cea52b2f741ba9dc65..a33d6c39168c31af1885e267f36d7d9930e9ef39 100755 (executable)
@@ -72,22 +72,13 @@ ObjectPtr PartSet_ExternalObjectsMgr::externalObject(const ObjectPtr& theSelecte
 {
   ObjectPtr aSelectedObject = PartSet_Tools::findFixedObjectByExternal(
                                   theShape->impl<TopoDS_Shape>(), theSelectedObject, theSketch);
-  FeaturePtr aFeature = ModelAPI_Feature::feature(aSelectedObject);
-  if (aFeature.get()) {
-    std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
-                            std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
-    /// some sketch entities should be never shown, e.g. projection feature
-    /// such external features should not be used in selection
-    if (aSketchFeature.get() && !aSketchFeature->canBeDisplayed())
-      return ObjectPtr();
-  }
-
   if (!aSelectedObject.get()) {
     // Processing of external (non-sketch) object
-    aSelectedObject = PartSet_Tools::createFixedObjectByExternal(theShape->impl<TopoDS_Shape>(),
-                                                    theSelectedObject, theSketch, theTemporary);
+    FeaturePtr aCreatedFeature;
+    aSelectedObject = PartSet_Tools::createFixedObjectByExternal(theShape,
+      theSelectedObject, theSketch, theTemporary, aCreatedFeature);
     if (aSelectedObject.get() && theTemporary)
-        myExternalObjectValidated = aSelectedObject;
+        myExternalObjectValidated = aCreatedFeature;
   }
   return aSelectedObject;
 }
index 5dc11364e32d6cd5496a910e7d54dbd0ecd92df3..078b18236f5a8c41be1d78d75f7890ca4e176f0d 100755 (executable)
@@ -37,7 +37,6 @@
 #include "PartSet_MenuMgr.h"
 #include "PartSet_CustomPrs.h"
 #include "PartSet_IconFactory.h"
-#include "PartSet_WidgetChoice.h"
 #include "PartSet_OverconstraintListener.h"
 
 #include "PartSet_Filters.h"
@@ -52,6 +51,7 @@
 #include <ModuleBase_IViewer.h>
 #include <ModuleBase_IViewWindow.h>
 #include <ModuleBase_IPropertyPanel.h>
+#include <ModuleBase_WidgetChoice.h>
 #include <ModuleBase_WidgetEditor.h>
 #include <ModuleBase_WidgetValidated.h>
 #include <ModuleBase_Tools.h>
@@ -185,6 +185,9 @@ PartSet_Module::PartSet_Module(ModuleBase_IWorkshop* theWshop)
   Config_PropManager::registerProp("Visualization", "operation_remove_feature_color",
                           "Color of removed feature in operation", Config_Prop::Color,
                           PartSet_CustomPrs::OPERATION_REMOVE_FEATURE_COLOR());
+  Config_PropManager::registerProp("Visualization", "sketch_preview_plane",
+                          "Color of sketch plane", Config_Prop::Color,
+                          PartSet_CustomPrs::OPERATION_SKETCH_PLANE());
 }
 
 PartSet_Module::~PartSet_Module()
@@ -547,6 +550,12 @@ void PartSet_Module::updateViewerMenu(const QMap<QString, QAction*>& theStdActio
   myMenuMgr->updateViewerMenu(theStdActions);
 }
 
+void PartSet_Module::updateOperationByUndoRedo()
+{
+  PartSet_SketcherMgr* aSketchMgr = sketchMgr();
+  aSketchMgr->previewSketchPlane()->updatePlaneSize(aSketchMgr->activeSketch(), workshop());
+}
+
 bool PartSet_Module::isActionEnableStateFixed(const int theActionId) const
 {
   bool isEnabledFixed = false;
@@ -789,7 +798,7 @@ ModuleBase_ModelWidget* PartSet_Module::createWidgetByType(const std::string& th
   } else if (theType == "sketch_launcher") {
     aWgt = new PartSet_WidgetSketchCreator(theParent, this, theWidgetApi);
   } else if (theType == "module_choice") {
-    aWgt = new PartSet_WidgetChoice(theParent, theWidgetApi);
+    aWgt = new ModuleBase_WidgetChoice(theParent, theWidgetApi);
     connect(aWgt, SIGNAL(itemSelected(ModuleBase_ModelWidget*, int)),
             this, SLOT(onChoiceChanged(ModuleBase_ModelWidget*, int)));
   }
@@ -1472,7 +1481,7 @@ void PartSet_Module::setReentrantPreSelection(const std::shared_ptr<Events_Messa
 void PartSet_Module::onChoiceChanged(ModuleBase_ModelWidget* theWidget,
                                      int theIndex)
 {
-  PartSet_WidgetChoice* aChoiceWidget = dynamic_cast<PartSet_WidgetChoice*>(theWidget);
+  ModuleBase_WidgetChoice* aChoiceWidget = dynamic_cast<ModuleBase_WidgetChoice*>(theWidget);
   if (!aChoiceWidget)
     return;
 
index 4a70c942f511760ce05a93907663a9707df3424b..cc9bd9ed52e97e0b31e06b426f3ac15b72df542c 100755 (executable)
@@ -331,6 +331,9 @@ public:
   /// \param theStdActions - a map of standard actions
   virtual void updateViewerMenu(const QMap<QString, QAction*>& theStdActions);
 
+  /// Updates the current operation state after undo/redo actions calling
+  virtual void updateOperationByUndoRedo();
+
   /// Returns true if the action should be always enabled
   /// \param theActionId an action index: Accept or Accept All
   /// \return boolean value
diff --git a/src/PartSet/PartSet_PreviewSketchPlane.cpp b/src/PartSet/PartSet_PreviewSketchPlane.cpp
new file mode 100644 (file)
index 0000000..1ee9856
--- /dev/null
@@ -0,0 +1,239 @@
+// Copyright (C) 2014-2017  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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "PartSet_PreviewSketchPlane.h"
+#include "PartSet_Tools.h"
+
+#include <ModuleBase_IWorkshop.h>
+
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_CompositeFeature.h>
+#include <ModelAPI_Tools.h>
+
+#include <GeomAlgoAPI_ShapeTools.h>
+
+#include <XGUI_Tools.h>
+#include <XGUI_Displayer.h>
+#include <XGUI_Workshop.h>
+
+#include <Config_PropManager.h>
+#include <GeomAlgoAPI_FaceBuilder.h>
+
+#include <SketchPlugin_Sketch.h>
+#include <SketchPlugin_SketchEntity.h>
+
+#include <BRepBndLib.hxx>
+
+double maximumSize(double theXmin, double theYmin, double theZmin,
+                   double theXmax, double theYmax, double theZmax)
+{
+  double aSize = fabs(theXmax - theXmin);
+  double aSizeToCompare = fabs(theYmax - theYmin);
+  if (aSizeToCompare > aSize)
+    aSize = aSizeToCompare;
+  aSizeToCompare = fabs(theZmax - theZmin);
+  if (aSizeToCompare > aSize)
+    aSize = aSizeToCompare;
+
+  return aSize;
+}
+
+PartSet_PreviewSketchPlane::PartSet_PreviewSketchPlane()
+ : mySketchDisplayed(false), myOtherSketchSize(0)
+{
+}
+
+void PartSet_PreviewSketchPlane::setOtherSketchParameters(const GeomShapePtr& theOtherSketchFace)
+{
+  myOtherSketchOrigin = std::shared_ptr<GeomAPI_Pnt>();
+  myOtherSketchSize = 0;
+  if (!theOtherSketchFace)
+    return;
+
+  getShapeParameters(theOtherSketchFace, myOtherSketchOrigin, myOtherSketchSize);
+}
+
+void PartSet_PreviewSketchPlane::eraseSketchPlane(ModuleBase_IWorkshop* theWorkshop,
+                                                  const bool isClearPlane)
+{
+  if (mySketchDisplayed) {
+    XGUI_Displayer* aDisp = XGUI_Tools::workshop(theWorkshop)->displayer();
+    aDisp->eraseAIS(myPlane, false);
+    if (isClearPlane) {
+      myPlane = NULL;
+      myOrigin = NULL;
+      myNormal = NULL;
+    }
+    mySketchDisplayed = false;
+  }
+}
+
+void PartSet_PreviewSketchPlane::createSketchPlane(const CompositeFeaturePtr& theSketch,
+                                                   ModuleBase_IWorkshop* theWorkshop)
+{
+  if (mySketchDisplayed)
+    return;
+
+  // plane is visualized only if sketch plane is filled
+  std::shared_ptr<GeomAPI_Pln> aPlane = PartSet_Tools::sketchPlane(theSketch);
+  if (!aPlane.get())
+    return;
+
+  if (!myPlane) { // If planes are not created
+    std::shared_ptr<GeomDataAPI_Point> anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
+        theSketch->data()->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
+    std::shared_ptr<GeomDataAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+        theSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
+
+    // Create Preview
+    // default planes parameters
+    std::shared_ptr<GeomAPI_Pnt> anOriginPnt = anOrigin->pnt();
+    double aSize = 10;//Config_PropManager::integer(SKETCH_TAB_NAME, "planes_size");
+    // another sketch parameters
+    if (myOtherSketchOrigin) {
+      anOriginPnt = myOtherSketchOrigin;
+      aSize = myOtherSketchSize;
+      setOtherSketchParameters(GeomShapePtr());
+    }
+    else {
+      // selected linear face parameters
+      AttributeSelectionPtr aSelAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
+                                (theSketch->data()->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
+      if (aSelAttr) {
+        std::shared_ptr<GeomAPI_Shape> aSketchExternalFace = aSelAttr->value();
+        if (aSketchExternalFace)
+          getShapeParameters(aSketchExternalFace, anOriginPnt, aSize);
+      }
+    }
+    double aSketchSize = getSketchBoundingBoxSize(theSketch, anOriginPnt);
+    if (aSketchSize > 0)
+      aSize = aSketchSize;
+
+    myOrigin = anOriginPnt;
+    myNormal = aNormal->dir();
+    myPlane = createPreviewPlane(aSize);
+  }
+
+  XGUI_Displayer* aDisp = XGUI_Tools::workshop(theWorkshop)->displayer();
+  aDisp->displayAIS(myPlane, true, 1/*shaded*/, false);
+  mySketchDisplayed = true;
+}
+
+void PartSet_PreviewSketchPlane::updatePlaneSize(const CompositeFeaturePtr& theSketch,
+                                                 ModuleBase_IWorkshop* theWorkshop)
+{
+  std::shared_ptr<GeomAPI_Pnt> anOriginPnt;
+  double aSize = getSketchBoundingBoxSize(theSketch, anOriginPnt);
+  if (aSize <= 0)
+    return;
+  myOrigin = anOriginPnt;
+  createPreviewPlane(aSize);
+}
+
+AISObjectPtr PartSet_PreviewSketchPlane::createPreviewPlane(double theSize)
+{
+  std::vector<int> aYZRGB(3, 0);
+#ifdef SET_PLANES_COLOR_IN_PREFERENCES
+    aYZRGB = Config_PropManager::color("Visualization", "yz_plane_color");
+#else
+    aYZRGB[0] = 225;
+#endif
+    int aR[] = {aYZRGB[0], aYZRGB[1], aYZRGB[2]};
+
+  std::shared_ptr<GeomAPI_Shape> aFace =
+    GeomAlgoAPI_FaceBuilder::squareFace(myOrigin, myNormal, theSize);
+
+  if (myPlane.get()) {
+    myPlane->createShape(aFace);
+    return myPlane;
+  }
+  else {
+    AISObjectPtr aAIS = AISObjectPtr(new GeomAPI_AISObject());
+    aAIS->createShape(aFace);
+    std::vector<int> aColor = Config_PropManager::color("Visualization", "sketch_preview_plane");
+    if (aColor.size() == 3)
+      aAIS->setColor(aColor[0], aColor[1], aColor[2]);
+    aAIS->setTransparensy(0.8);
+
+    int aDispMode = 1; // shading
+    Handle(AIS_InteractiveObject) anAISIO = aAIS->impl<Handle(AIS_InteractiveObject)>();
+    if (!anAISIO.IsNull()) {
+      anAISIO->Attributes()->SetFaceBoundaryDraw( Standard_True );
+      anAISIO->SetDisplayMode(aDispMode);
+    }
+    return aAIS;
+  }
+}
+
+void PartSet_PreviewSketchPlane::getShapeParameters(const GeomShapePtr& theShape,
+                                                    std::shared_ptr<GeomAPI_Pnt>& theOrigin,
+                                                    double& theSize)
+{
+  theOrigin = GeomAlgoAPI_ShapeTools::centreOfMass(theShape);
+
+  // Create rectangular face close to the selected
+  double aXmin, anYmin, aZmin, aXmax, anYmax, aZmax;
+  theShape->computeSize(aXmin, anYmin, aZmin, aXmax, anYmax, aZmax);
+
+  theSize = maximumSize(aXmin, anYmin, aZmin, aXmax, anYmax, aZmax);
+}
+
+double PartSet_PreviewSketchPlane::getSketchBoundingBoxSize(
+                                 const std::shared_ptr<ModelAPI_CompositeFeature>& theSketch,
+                                 std::shared_ptr<GeomAPI_Pnt>& theCentralPnt)
+{
+  if (!theSketch.get() || theSketch->numberOfSubs() == 0)
+    return 0;
+
+  Bnd_Box aBox;
+  for (int aSubFeatureId = 0; aSubFeatureId < theSketch->numberOfSubs(); aSubFeatureId++) {
+    FeaturePtr aFeature = theSketch->subFeature(aSubFeatureId);
+    if (!aFeature.get())
+      continue;
+
+    std::list<ResultPtr> aResults = aFeature->results();
+    std::list<ResultPtr>::const_iterator aResultIt;
+    for (aResultIt = aResults.begin(); aResultIt != aResults.end(); ++aResultIt) {
+      ResultPtr aResult = *aResultIt;
+      std::shared_ptr<GeomAPI_Shape> aShapePtr = aResult->shape();
+      if (aShapePtr.get()) {
+        TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
+        if (aShape.IsNull())
+          continue;
+        BRepBndLib::Add(aShape, aBox);
+      }
+    }
+  }
+  if (aBox.IsVoid())
+    return 0;
+
+  double aXmin, aXmax, anYmin, anYmax, aZmin, aZmax;
+  aBox.Get(aXmin, anYmin, aZmin, aXmax, anYmax, aZmax);
+
+  double aSize = maximumSize(aXmin, anYmin, aZmin, aXmax, anYmax, aZmax);
+  if (aSize > 0) {
+    gp_Pnt aCentre(aXmax-fabs(aXmax-aXmin)/2., anYmax-fabs(anYmax-anYmin)/2.,
+                   aZmax - fabs(aZmax-aZmin)/2.);
+    theCentralPnt = std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aCentre.X(), aCentre.Y(),
+                                                                 aCentre.Z()));
+  }
+  return aSize;
+}
\ No newline at end of file
diff --git a/src/PartSet/PartSet_PreviewSketchPlane.h b/src/PartSet/PartSet_PreviewSketchPlane.h
new file mode 100644 (file)
index 0000000..b2d32c8
--- /dev/null
@@ -0,0 +1,101 @@
+// Copyright (C) 2014-2017  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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef PartSet_PreviewSketchPlane_H
+#define PartSet_PreviewSketchPlane_H
+
+#include <GeomAPI_AISObject.h>
+
+#include <GeomAPI_Pnt.h>
+#include <GeomAPI_Dir.h>
+#include <GeomAPI_AISObject.h>
+
+class ModuleBase_IWorkshop;
+class ModelAPI_CompositeFeature;
+
+/**
+* \class PartSet_PreviewSketchPlane
+* \ingroup Modules
+* A class to show/hide sketch preview plane
+*/
+class PartSet_PreviewSketchPlane
+{
+public:
+  /// Constructor
+  PartSet_PreviewSketchPlane();
+
+  ~PartSet_PreviewSketchPlane() {};
+
+  /// Returns if the sketch plane was displayed
+  /// \return boolean value
+  bool isSketchDisplayed() const { return mySketchDisplayed; }
+
+  /// Sets parameters of another sketch to be used in createSketchPlane().
+  /// \param theOtherSketchFace a shape of other selected sketch. It is a planar face.
+  void setOtherSketchParameters(const std::shared_ptr<GeomAPI_Shape>& theOtherSketchFace);
+
+  /// Erase preview planes
+  /// \param theWorkshop the application workshop
+  /// \param isClearPlane flag whether the plane, origin and normal should be nullified
+  void eraseSketchPlane(ModuleBase_IWorkshop* theWorkshop, const bool isClearPlane = true);
+
+  /// Show preview planes
+  /// \param theSketch source sketch to initialize plane
+  /// \param theWorkshop the application workshop
+  void createSketchPlane(const std::shared_ptr<ModelAPI_CompositeFeature>& theSketch,
+                         ModuleBase_IWorkshop* theWorkshop);
+
+  /// Resize plane size by sketch content
+  /// \param theSketch source sketch to build sketch sub features bounding box
+  /// \param theWorkshop the application workshop
+  void updatePlaneSize(const std::shared_ptr<ModelAPI_CompositeFeature>& theSketch,
+                       ModuleBase_IWorkshop* theWorkshop);
+
+private:
+  /// Create a square face by parameters
+  /// \param theSize a size of created square
+  AISObjectPtr createPreviewPlane(double theSize);
+
+  /// Finds origin and maximum size of the shape
+  /// \param theShape source shape
+  /// \param theOrigin a shape center of mass
+  /// \param theSize maximum of delta X, Y or Z
+  void getShapeParameters(const std::shared_ptr<GeomAPI_Shape>& theShape,
+                          std::shared_ptr<GeomAPI_Pnt>& theOrigin,
+                          double& theSize);
+
+  /// Calculate maximum bounding box size of sketch sub features
+  /// \param theSketch source sketch to build sketch sub features bounding box
+  /// \param theCentralPoint central point of the sketch sub features
+  /// \return double value
+  double getSketchBoundingBoxSize(const std::shared_ptr<ModelAPI_CompositeFeature>& theSketch,
+                                  std::shared_ptr<GeomAPI_Pnt>& theCentralPnt);
+
+private:
+  bool mySketchDisplayed;
+  AISObjectPtr myPlane;
+  std::shared_ptr<GeomAPI_Pnt> myOrigin; //! an origin of the plane
+  std::shared_ptr<GeomAPI_Dir> myNormal; //! a normal vector of the plane
+
+  std::shared_ptr<GeomAPI_Pnt> myOtherSketchOrigin;
+  double myOtherSketchSize;
+};
+
+#endif
\ No newline at end of file
index eab2a165ce2f8de27adcd3d4ac2f3b665b6fb99d..88334e9ee5b4eee569cb3c1b624283e4cf63e653 100755 (executable)
@@ -27,6 +27,7 @@
 #include "PartSet_WidgetEditor.h"
 #include "PartSet_ResultSketchPrs.h"
 #include "PartSet_ExternalPointsMgr.h"
+#include "PartSet_PreviewSketchPlane.h"
 
 #include <XGUI_ModuleConnector.h>
 #include <XGUI_Displayer.h>
@@ -83,6 +84,7 @@
 #include <SketchPlugin_MultiRotation.h>
 #include <SketchPlugin_MultiTranslation.h>
 #include <SketchPlugin_IntersectionPoint.h>
+#include <SketchPlugin_Projection.h>
 
 #include <SketcherPrs_Tools.h>
 
@@ -179,6 +181,8 @@ PartSet_SketcherMgr::PartSet_SketcherMgr(PartSet_Module* theModule)
   myIsConstraintsShown[PartSet_Tools::Geometrical] = true;
   myIsConstraintsShown[PartSet_Tools::Dimensional] = true;
   myIsConstraintsShown[PartSet_Tools::Expressions] = false;
+
+  mySketchPlane = new PartSet_PreviewSketchPlane();
 }
 
 PartSet_SketcherMgr::~PartSet_SketcherMgr()
@@ -719,8 +723,15 @@ void PartSet_SketcherMgr::launchEditing()
     FeaturePtr aFeature = myCurrentSelection.begin().key();
     std::shared_ptr<SketchPlugin_Feature> aSPFeature =
               std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
-    if (aSPFeature && (!aSPFeature->isExternal())) {
-      myModule->editFeature(aSPFeature);
+    if (aSPFeature) {
+      if (!aSPFeature->isExternal())
+        myModule->editFeature(aSPFeature);
+      else {
+        FeaturePtr aProjectionFeature = PartSet_Tools::findRefsToMeFeature(aFeature,
+                                                        SketchPlugin_Projection::ID());
+        if (aProjectionFeature.get())
+          myModule->editFeature(aProjectionFeature);
+      }
     }
   }
 }
@@ -915,6 +926,7 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation)
 
   // Display all sketcher sub-Objects
   myCurrentSketch = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFOperation->feature());
+  mySketchPlane->createSketchPlane(myCurrentSketch, myModule->workshop());
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
 
   // Hide sketcher result
@@ -1036,6 +1048,7 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation)
     XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();
     // The sketch was aborted
     myCurrentSketch = CompositeFeaturePtr();
+    mySketchPlane->eraseSketchPlane(myModule->workshop());
     // TODO: move this outside of if-else
     myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter);
     myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);
@@ -1079,6 +1092,7 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation)
       myCurrentSketch->setDisplayed(true);
 
     myCurrentSketch = CompositeFeaturePtr();
+    mySketchPlane->eraseSketchPlane(myModule->workshop());
 
     myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter);
     myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);
@@ -1104,6 +1118,7 @@ void PartSet_SketcherMgr::startNestedSketch(ModuleBase_Operation* theOperation)
 
 void PartSet_SketcherMgr::stopNestedSketch(ModuleBase_Operation* theOperation)
 {
+  previewSketchPlane()->updatePlaneSize(activeSketch(), myModule->workshop());
   myIsMouseOverViewProcessed = true;
   operationMgr()->onValidateOperation();
   // when sketch nested operation is stopped the cursor should be restored unconditionally
index 92c74ef8c5dbaa65bd410f1e4a94b118c7ce13c6..7f76b48c03be26b130aa164e1ea20fa3902f08dd 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "PartSet_Filters.h"
 #include "PartSet_Tools.h"
+#include "PartSet_PreviewSketchPlane.h"
 
 #include <ModelAPI_Feature.h>
 #include <ModelAPI_Attribute.h>
@@ -171,6 +172,10 @@ public:
   /// Returns current Sketch feature/ Returns NULL if there is no launched sketch operation
   CompositeFeaturePtr activeSketch() const { return myCurrentSketch; }
 
+  /// Returns help class to visualize sketcher plane
+  /// \return a preview plane
+  PartSet_PreviewSketchPlane* previewSketchPlane() const { return mySketchPlane; }
+
   /// Starts sketch operation
   void startSketch(ModuleBase_Operation* );
 
@@ -413,6 +418,7 @@ private:
 
 private:
   PartSet_Module* myModule;
+  PartSet_PreviewSketchPlane* mySketchPlane; // display/erase sketch plane on start/stop sketch operation
 
   bool myPreviousDrawModeEnabled; // the previous selection enabled state in the viewer
   bool myIsEditLaunching;
index 2a5f0f08d0ee6ed45326ecb64c9e6f68b10cfce3..61a05c9d2d8e9686a16964766ea5bc179dc2b503 100755 (executable)
@@ -70,6 +70,7 @@
 #include <SketchPlugin_Arc.h>
 #include <SketchPlugin_Line.h>
 #include <SketchPlugin_Point.h>
+#include <SketchPlugin_Projection.h>
 
 #include <ModuleBase_IWorkshop.h>
 #include <ModuleBase_ViewerPrs.h>
@@ -331,26 +332,54 @@ ResultPtr PartSet_Tools::findFixedObjectByExternal(const TopoDS_Shape& theShape,
                                                    const ObjectPtr& theObject,
                                                    CompositeFeaturePtr theSketch)
 {
-  ResultPtr aResult;
-  if (theShape.ShapeType() == TopAbs_EDGE) {
-    // Check that we already have such external edge
-    std::shared_ptr<GeomAPI_Edge> aInEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge());
-    aInEdge->setImpl(new TopoDS_Shape(theShape));
-    aResult = findExternalEdge(theSketch, aInEdge);
-  }
-  if (theShape.ShapeType() == TopAbs_VERTEX) {
-    std::shared_ptr<GeomAPI_Vertex> aInVert = std::shared_ptr<GeomAPI_Vertex>(new GeomAPI_Vertex());
-    aInVert->setImpl(new TopoDS_Shape(theShape));
-    aResult = findExternalVertex(theSketch, aInVert);
+  ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
+  if (!aResult.get())
+    return ResultPtr();
+
+  for (int i = 0, aNbSubs = theSketch->numberOfSubs(); i < aNbSubs; i++) {
+    FeaturePtr aFeature = theSketch->subFeature(i);
+    if (aFeature->getKind() != SketchPlugin_Projection::PROJECTED_FEATURE_ID())
+      continue;
+    if (aFeature->lastResult() == aResult)
+      return aResult;
   }
-  return aResult;
+  return ResultPtr();
 }
 
-ResultPtr PartSet_Tools::createFixedObjectByExternal(const TopoDS_Shape& theShape,
-                                                     const ObjectPtr& theObject,
-                                                     CompositeFeaturePtr theSketch,
-                                                     const bool theTemporary)
+ResultPtr PartSet_Tools::createFixedObjectByExternal(
+                                   const std::shared_ptr<GeomAPI_Shape>& theShape,
+                                   const ObjectPtr& theObject,
+                                   CompositeFeaturePtr theSketch,
+                                   const bool theTemporary,
+                                   FeaturePtr& theCreatedFeature)
 {
+  ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
+
+  if (!aResult.get())
+    return ResultPtr();
+
+  FeaturePtr aProjectionFeature = theSketch->addFeature(SketchPlugin_Projection::ID());
+  theCreatedFeature = aProjectionFeature;
+  AttributeSelectionPtr anExternalAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(
+                 aProjectionFeature->attribute(SketchPlugin_Projection::EXTERNAL_FEATURE_ID()));
+  anExternalAttr->setValue(aResult, theShape);
+  AttributeBooleanPtr anIntoResult = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>
+    (aProjectionFeature->data()->attribute(SketchPlugin_Projection::INCLUDE_INTO_RESULT()));
+  anIntoResult->setValue(false);
+
+  aProjectionFeature->execute();
+
+  AttributeRefAttrPtr aRefAttr = aProjectionFeature->data()->refattr(
+    SketchPlugin_Projection::PROJECTED_FEATURE_ID());
+  if (!aRefAttr || !aRefAttr->isInitialized())
+    return ResultPtr();
+
+  FeaturePtr aProjection = ModelAPI_Feature::feature(aRefAttr->object());
+  if (aProjection.get() && aProjection->lastResult().get())
+    return aProjection->lastResult();
+
+  //return aProjectionFeature->lastResult();//ResultPtr();//aFeature->attribute(;
+  /*
   if (theShape.ShapeType() == TopAbs_EDGE) {
     Standard_Real aStart, aEnd;
     Handle(V3d_View) aNullView;
@@ -525,7 +554,7 @@ ResultPtr PartSet_Tools::createFixedObjectByExternal(const TopoDS_Shape& theShap
         return aMyFeature->lastResult();
       }
     }
-  }
+  }*/
   return ResultPtr();
 }
 
@@ -539,86 +568,6 @@ bool PartSet_Tools::isContainPresentation(const QList<ModuleBase_ViewerPrsPtr>&
   return false;
 }
 
-ResultPtr PartSet_Tools::findExternalEdge(CompositeFeaturePtr theSketch,
-                                          std::shared_ptr<GeomAPI_Edge> theEdge)
-{
-  for (int i = 0; i < theSketch->numberOfSubs(); i++) {
-    FeaturePtr aFeature = theSketch->subFeature(i);
-    std::shared_ptr<SketchPlugin_Feature> aSketchFea =
-      std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
-    // not displayed result of feature projection should not be returned as external edge
-    if (aSketchFea && aSketchFea->canBeDisplayed()) {
-      if (aSketchFea->isExternal()) {
-        std::list<ResultPtr> aResults = aSketchFea->results();
-        std::list<ResultPtr>::const_iterator aIt;
-        for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) {
-          ResultConstructionPtr aRes =
-            std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aIt);
-          if (aRes) {
-            std::shared_ptr<GeomAPI_Shape> aShape = aRes->shape();
-            if (aShape) {
-              if (theEdge->isEqual(aShape))
-                return aRes;
-            }
-          }
-        }
-      }
-    }
-  }
-  return ResultPtr();
-}
-
-
-ResultPtr PartSet_Tools::findExternalVertex(CompositeFeaturePtr theSketch,
-                                            std::shared_ptr<GeomAPI_Vertex> theVert)
-{
-  for (int i = 0; i < theSketch->numberOfSubs(); i++) {
-    FeaturePtr aFeature = theSketch->subFeature(i);
-    std::shared_ptr<SketchPlugin_Feature> aSketchFea =
-      std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
-    if (aSketchFea) {
-      if (aSketchFea->isExternal()) {
-        std::list<ResultPtr> aResults = aSketchFea->results();
-        std::list<ResultPtr>::const_iterator aIt;
-        for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) {
-          ResultConstructionPtr aRes =
-            std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aIt);
-          if (aRes) {
-            std::shared_ptr<GeomAPI_Shape> aShape = aRes->shape();
-            if (aShape) {
-              if (theVert->isEqual(aShape))
-                return aRes;
-            }
-          }
-        }
-      }
-    }
-  }
-  return ResultPtr();
-}
-
-
-bool PartSet_Tools::hasVertexShape(const ModuleBase_ViewerPrsPtr& thePrs, FeaturePtr theSketch,
-                                   Handle(V3d_View) theView, double& theX, double& theY)
-{
-  bool aHasVertex = false;
-
-  const GeomShapePtr& aShape = thePrs->shape();
-  if (aShape.get() && !aShape->isNull() && aShape->shapeType() == GeomAPI_Shape::VERTEX)
-  {
-    const TopoDS_Shape& aTDShape = aShape->impl<TopoDS_Shape>();
-    const TopoDS_Vertex& aVertex = TopoDS::Vertex(aTDShape);
-    if (!aVertex.IsNull())
-    {
-      gp_Pnt aPoint = BRep_Tool::Pnt(aVertex);
-      PartSet_Tools::convertTo2D(aPoint, theSketch, theView, theX, theY);
-      aHasVertex = true;
-    }
-  }
-
-  return aHasVertex;
-}
-
 GeomShapePtr PartSet_Tools::findShapeBy2DPoint(const AttributePtr& theAttribute,
                                                        ModuleBase_IWorkshop* theWorkshop)
 {
index b7c0a22c921efec6e030b73f6af513d872cd62cb..486d361e01cdb6d30461f5fd587858973c176306 100755 (executable)
@@ -167,12 +167,14 @@ public:
   /// \param theObject a selected result object
   /// \param theSketch a sketch feature
   /// \param theTemporary the created external object is temporary, execute is not performed for it
+  /// \param theCreatedFeature a new projection feature
   /// \return result of created feature
   static std::shared_ptr<ModelAPI_Result> createFixedObjectByExternal(
-                                               const TopoDS_Shape& theShape,
+                                               const std::shared_ptr<GeomAPI_Shape>& theShape,
                                                const ObjectPtr& theObject,
                                                CompositeFeaturePtr theSketch,
-                                               const bool theTemporary = false);
+                                               const bool theTemporary,
+                                               FeaturePtr& theCreatedFeature);
 
     /// Checks whether the list of selected presentations contains the given one
   /// \param theSelected a list of presentations
@@ -181,31 +183,6 @@ public:
   static bool isContainPresentation(const QList<std::shared_ptr<ModuleBase_ViewerPrs>>& theSelected,
                                     const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);
 
-  /// Returns Result object if the given skietch contains external edge equal to the given
-  /// \param theSketch - the sketch feature
-  /// \param theEdge - the edge
-  /// \return result object with external edge if it is found
-  static std::shared_ptr<ModelAPI_Result> findExternalEdge(CompositeFeaturePtr theSketch,
-                                                           std::shared_ptr<GeomAPI_Edge> theEdge);
-
-  /// Returns Result object if the given sketch contains external vertex equal to the given
-  /// \param theSketch - the sketch feature
-  /// \param theVert - the vertex
-  /// \return result object with external vertex if it is found
-  static std::shared_ptr<ModelAPI_Result> findExternalVertex(CompositeFeaturePtr theSketch,
-                                                        std::shared_ptr<GeomAPI_Vertex> theVert);
-
-  /// Returns whether the selected presentation has a shape with the vertex type
-  /// \param thePrs a selected presentation
-  /// \param theSketch the sketch feature
-  /// \param theView a 3D view
-  /// \param theX the output horizontal coordinate of the point
-  /// \param theY the output vertical coordinate of the point
-  static bool hasVertexShape(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs,
-                             FeaturePtr theSketch,
-                             Handle(V3d_View) theView, double& theX, double& theY);
-
-
   /**
   * Find attribute of object which corresponds to the given shape
   * \param theObj - an object
@@ -264,6 +241,27 @@ public:
                                QList<FeaturePtr>& theCoincidencies,
                                std::string theAttr, QList<bool>& theIsAttributes);
 
+  /*
+  * Finds and returns feature reerenced to the paramenter feature with the given name if found
+  * \param theFeature a source feature where refsToMe is obtained
+  * \param theFeatureId an indentifier of the searched feature
+  */
+  static FeaturePtr findRefsToMeFeature(FeaturePtr theFeature, const std::string& theFeatureId)
+  {
+    if (!theFeature.get())
+      return FeaturePtr();
+
+    // find first projected feature and edit it
+    const std::set<AttributePtr>& aRefsList = theFeature->data()->refsToMe();
+    std::set<AttributePtr>::const_iterator anIt;
+    for (anIt = aRefsList.cbegin(); anIt != aRefsList.cend(); ++anIt) {
+      FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>((*anIt)->owner());
+      if (aRefFeature->getKind() == theFeatureId)
+        return aRefFeature;
+    }
+    return FeaturePtr();
+  }
+
   /**
   * Returns point of a coincedence
   * \param theStartCoin the coincedence feature
diff --git a/src/PartSet/PartSet_WidgetChoice.h b/src/PartSet/PartSet_WidgetChoice.h
deleted file mode 100644 (file)
index 071e06f..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (C) 2014-2017  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<mailto:webmaster.salome@opencascade.com>
-//
-
-#ifndef PartSet_WidgetChoice_H
-#define PartSet_WidgetChoice_H
-
-#include "PartSet.h"
-#include <ModuleBase_WidgetChoice.h>
-
-/**
-* \ingroup GUI
-* Implementation of a proxy of choice widget in order to geat access to it on moment 
-* of creation in module
-*/
-class PARTSET_EXPORT PartSet_WidgetChoice : public ModuleBase_WidgetChoice
-{
-Q_OBJECT
- public:
-  /// Constructor
-  /// \param theParent the parent object
-  /// \param theData the widget configuation. The attribute of the model widget is obtained from
-  PartSet_WidgetChoice(QWidget* theParent, const Config_WidgetAPI* theData)
-    : ModuleBase_WidgetChoice(theParent, theData) {}
-};
-
-#endif
\ No newline at end of file
index 3d9d933e95e927ce3457820dfc1b48c90fe9e886..37d9fb01599b1bef5cfcb10f85d3e9520247a064 100644 (file)
@@ -362,7 +362,8 @@ bool PartSet_WidgetPoint2D::storeValueCustom()
   if (myFeature->isMacro()) {
     // Moving points of macro-features has been processed directly (without solver)
     aPoint->setValue(myXSpin->value(), myYSpin->value());
-    moveObject(myFeature);
+    updateObject(myFeature);
+
   } else {
     if (!aPoint->isInitialized())
       aPoint->setValue(0., 0.);
@@ -593,6 +594,7 @@ void PartSet_WidgetPoint2D::mouseReleased(ModuleBase_IViewWindow* theWindow, QMo
   if (!aFirstValue.get() && myPreSelected.get()) {
     aFirstValue = myPreSelected;
   }
+
   // if we have selection and use it
   if (aFirstValue.get() && isValidSelectionCustom(aFirstValue) &&
       aFirstValue->shape().get()) { /// Trihedron Axis may be selected, but shape is empty
@@ -616,7 +618,11 @@ void PartSet_WidgetPoint2D::mouseReleased(ModuleBase_IViewWindow* theWindow, QMo
       else {
         anExternal = true;
         if (!aFixedObject.get())
-          aFixedObject = PartSet_Tools::createFixedObjectByExternal(aShape, aObject, mySketch);
+        {
+          FeaturePtr aCreatedFeature;
+          aFixedObject = PartSet_Tools::createFixedObjectByExternal(aGeomShape, aObject, mySketch,
+            false, aCreatedFeature);
+        }
       }
     }
     if (anExternal) {
index 6b70c7eaa434a92be6e7f959f71520589a92f19d..ead2a719aab71e133fe8ea75ac919d9eeca000c6 100755 (executable)
@@ -90,38 +90,6 @@ void PartSet_WidgetShapeSelector::getGeomSelection(const ModuleBase_ViewerPrsPtr
 
   myExternalObjectMgr->getGeomSelection(thePrs, theObject, theShape,
                                         myWorkshop, sketch(), myIsInValidate);
-  /*
-  FeaturePtr aSelectedFeature = ModelAPI_Feature::feature(theObject);
-  std::shared_ptr<SketchPlugin_Feature> aSPFeature =
-          std::dynamic_pointer_cast<SketchPlugin_Feature>(aSelectedFeature);
-  // there is no a sketch feature is selected, but the shape exists,
-  // try to create an exernal object
-  // TODO: unite with the same functionality in PartSet_WidgetShapeSelector
-  if (aSPFeature.get() == NULL) {
-    ObjectPtr anExternalObject = ObjectPtr();
-    GeomShapePtr anExternalShape = GeomShapePtr();
-    if (myExternalObjectMgr->useExternal()) {
-      if (myExternalObjectMgr->canCreateExternal()) {
-        GeomShapePtr aShape = theShape;
-        if (!aShape.get()) {
-          ResultPtr aResult = myWorkshop->selection()->getResult(thePrs);
-          if (aResult.get())
-            aShape = aResult->shape();
-        }
-        if (aShape.get() != NULL && !aShape->isNull())
-          anExternalObject =
-            myExternalObjectMgr->externalObject(theObject, aShape, sketch(), myIsInValidate);
-      }
-      else { /// use objects of found selection
-        anExternalObject = theObject;
-        anExternalShape = theShape;
-      }
-    }
-    /// the object is null if the selected feature is "external"(not sketch entity feature of the
-    /// current sketch) and it is not created by object manager
-    theObject = anExternalObject;
-    theShape = anExternalShape;
-  }*/
 }
 
 //********************************************************************
index aa209656b328a61230ef0ff4e5efe3eacce1a881..8485a1b495d8923e36fa9636769f40f3df259a21 100644 (file)
@@ -272,8 +272,28 @@ bool PartSet_WidgetSketchLabel::setSelectionInternal(
 
 void PartSet_WidgetSketchLabel::updateByPlaneSelected(const ModuleBase_ViewerPrsPtr& thePrs)
 {
-  // 1. hide main planes if they have been displayed
+  // 1. hide main planes if they have been displayed and display sketch preview plane
   myPreviewPlanes->erasePreviewPlanes(myWorkshop);
+
+  PartSet_Module* aModule = dynamic_cast<PartSet_Module*>(myWorkshop->module());
+  if (aModule) {
+    // if selected object is a shape of another sketch, the origin of selected shape does not stored
+    // in argument, so we need to find parameters of selected shape on the sketch
+    if (thePrs->object() && (feature() != thePrs->object())) {
+      FeaturePtr aFeature = ModelAPI_Feature::feature(thePrs->object());
+      if (aFeature.get() && (aFeature != feature())) {
+        if (aFeature->getKind() == SketchPlugin_Sketch::ID()) {
+          CompositeFeaturePtr aSketch =
+            std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFeature);
+          std::shared_ptr<GeomAPI_Pln> aPlane = PartSet_Tools::sketchPlane(aSketch);
+          if (aPlane.get())
+            aModule->sketchMgr()->previewSketchPlane()->setOtherSketchParameters(thePrs->shape());
+        }
+      }
+    }
+    CompositeFeaturePtr aSketch = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
+    aModule->sketchMgr()->previewSketchPlane()->createSketchPlane(aSketch, myWorkshop);
+  }
   // 2. if the planes were displayed, change the view projection
   const GeomShapePtr& aShape = thePrs->shape();
   std::shared_ptr<GeomAPI_Shape> aGShape;
index 504314fbd293b7a98c91b1b684c681d9b2ed0427..6eda688a8da5422a87f9b4de2e07526ff0195c4e 100644 (file)
@@ -26,6 +26,7 @@
 #include <SketcherPrs_Factory.h>
 
 #include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeInteger.h>
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Result.h>
 
@@ -52,6 +53,9 @@ void SketchPlugin_ConstraintLength::initAttributes()
   data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::typeId());
   data()->addAttribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT(), GeomDataAPI_Point2D::typeId());
   data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
+
+  data()->addAttribute(SketchPlugin_ConstraintLength::LOCATION_TYPE_ID(),
+                       ModelAPI_AttributeInteger::typeId());
 }
 
 void SketchPlugin_ConstraintLength::colorConfigInfo(std::string& theSection, std::string& theName,
index 50e9ebb9b5c10654b0b39d3c11b89a552cd20ad4..13666de04bf6efd46050783c41435192782e5373 100644 (file)
@@ -49,6 +49,7 @@ class SketchPlugin_ConstraintLength : public SketchPlugin_ConstraintBase
     static const std::string MY_CONSTRAINT_LENGTH_ID("SketchConstraintLength");
     return MY_CONSTRAINT_LENGTH_ID;
   }
+
   /// \brief Returns the kind of a feature
   SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
   {
@@ -56,6 +57,13 @@ class SketchPlugin_ConstraintLength : public SketchPlugin_ConstraintBase
     return MY_KIND;
   }
 
+  /// attribute name of dimension location type
+  inline static const std::string& LOCATION_TYPE_ID()
+  {
+    static const std::string MY_LOCATION_TYPE_ID("LocationType");
+    return MY_LOCATION_TYPE_ID;
+  }
+
   /// \brief Creates a new part document if needed
   SKETCHPLUGIN_EXPORT virtual void execute();
 
diff --git a/src/SketchPlugin/icons/location_automatic.png b/src/SketchPlugin/icons/location_automatic.png
new file mode 100644 (file)
index 0000000..88730b3
Binary files /dev/null and b/src/SketchPlugin/icons/location_automatic.png differ
diff --git a/src/SketchPlugin/icons/location_left.png b/src/SketchPlugin/icons/location_left.png
new file mode 100644 (file)
index 0000000..e963b8d
Binary files /dev/null and b/src/SketchPlugin/icons/location_left.png differ
diff --git a/src/SketchPlugin/icons/location_right.png b/src/SketchPlugin/icons/location_right.png
new file mode 100644 (file)
index 0000000..cdb8551
Binary files /dev/null and b/src/SketchPlugin/icons/location_right.png differ
index 9bc2d8b7280e738f93b2b82159ff54fb3a920c54..30f03a352431e974b98c6984df3c243aa2f9a523 100644 (file)
@@ -734,6 +734,15 @@ email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com
         <doublevalue_editor label="Value" tooltip="Length" id="ConstraintValue" default="computed">
           <validator id="GeomValidators_Positive"/>
         </doublevalue_editor>
+        <module_choice id="LocationType"
+          widget_type="radiobuttons"
+          buttons_dir="horizontal"
+          label="Location type"
+          tooltip="Type of location"
+          string_list="Left Automatic Right"
+          icons_list="icons/Sketch/location_left.png icons/Sketch/location_automatic.png icons/Sketch/location_right.png"
+          default="1"
+          />
         <validator id="PartSet_LengthSelection"/>
       </feature>
 
index 34fb6a6eed108e69660e376bb0a35e19eec050a9..3aeebbc2b4b15bb58b8da98086628df605382bf3 100644 (file)
@@ -39,6 +39,7 @@
 
 #include <ModelAPI_Data.h>
 #include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeInteger.h>
 
 #include <AIS_DisplaySpecialSymbol.hxx>
 
@@ -64,21 +65,30 @@ Handle(Prs3d_DimensionAspect) createDimensionAspect()
 /// \param theDimValue an arrow value
 /// \param theTextSize an arrow value
 void updateArrows(Handle(Prs3d_DimensionAspect) theDimAspect,
-                  double theDimValue, double theTextSize)
+  double theDimValue, double theTextSize, SketcherPrs_Tools::LocationType theLocationType)
 {
-  double anArrowLength = theDimAspect->ArrowAspect()->Length();
-   // This is not realy correct way to get viewer scale.
-  double aViewerScale = (double) SketcherPrs_Tools::getDefaultArrowSize() / anArrowLength;
-
-  if(theTextSize > ((theDimValue - 3 * SketcherPrs_Tools::getArrowSize()) * aViewerScale)) {
+  if (theLocationType == SketcherPrs_Tools::LOCATION_AUTOMATIC) {
+    double anArrowLength = theDimAspect->ArrowAspect()->Length();
+     // This is not realy correct way to get viewer scale.
+    double aViewerScale = (double) SketcherPrs_Tools::getDefaultArrowSize() / anArrowLength;
+
+    if(theTextSize > ((theDimValue - 3 * SketcherPrs_Tools::getArrowSize()) * aViewerScale)) {
+      theDimAspect->SetTextHorizontalPosition(Prs3d_DTHP_Left);
+      theDimAspect->SetArrowOrientation(Prs3d_DAO_External);
+      theDimAspect->SetExtensionSize(
+        (theTextSize / aViewerScale + SketcherPrs_Tools::getArrowSize()) / 2.0);
+    } else {
+      theDimAspect->SetTextHorizontalPosition(Prs3d_DTHP_Center);
+      theDimAspect->SetArrowOrientation(Prs3d_DAO_Internal);
+    }
+  }
+  else if (theLocationType == SketcherPrs_Tools::LOCATION_RIGHT ||
+           theLocationType == SketcherPrs_Tools::LOCATION_LEFT) {
     theDimAspect->SetTextHorizontalPosition(Prs3d_DTHP_Left);
+    //theDimAspect->SetTextHorizontalPosition(Prs3d_DTHP_Right);
     theDimAspect->SetArrowOrientation(Prs3d_DAO_External);
-    theDimAspect->SetExtensionSize(
-      (theTextSize / aViewerScale + SketcherPrs_Tools::getArrowSize()) / 2.0);
-  } else {
-    theDimAspect->SetTextHorizontalPosition(Prs3d_DTHP_Center);
-    theDimAspect->SetArrowOrientation(Prs3d_DAO_Internal);
   }
+
   theDimAspect->SetArrowTailSize(theDimAspect->ArrowAspect()->Length());
   // The value of vertical aligment is sometimes changed
   theDimAspect->TextAspect()->SetVerticalJustification(Graphic3d_VTA_CENTER);
@@ -152,7 +162,17 @@ void SketcherPrs_LengthDimension::Compute(
   double aTextSize = 0.0;
   GetValueString(aTextSize);
 
-  updateArrows(DimensionAspect(), GetValue(), aTextSize);
+  SketcherPrs_Tools::LocationType aLocationType = SketcherPrs_Tools::LOCATION_AUTOMATIC;
+  std::string aLocationAttribute;
+  if (myConstraint->getKind() == SketchPlugin_ConstraintLength::ID())
+    aLocationAttribute = SketchPlugin_ConstraintLength::LOCATION_TYPE_ID();
+  if (!aLocationAttribute.empty())
+  {
+    std::shared_ptr<ModelAPI_AttributeInteger> aTypeAttr = std::dynamic_pointer_cast<
+      ModelAPI_AttributeInteger>(myConstraint->data()->attribute(aLocationAttribute));
+    aLocationType = (SketcherPrs_Tools::LocationType)(aTypeAttr->value());
+  }
+  updateArrows(DimensionAspect(), GetValue(), aTextSize, aLocationType);
 
   // Update text visualization: parameter value or parameter text
   myStyleListener->updateDimensions(this, myValue);
index fe5fbaa999ebcec224303b6b79872877da1e9ded..bc784cb38bae61cce5fe03bce358da9eab450438 100644 (file)
@@ -44,7 +44,7 @@ extern Handle(Prs3d_DimensionAspect) createDimensionAspect();
 /// \param theDimValue an arrow value
 /// \param theTextSize an arrow value
 extern void updateArrows(Handle_Prs3d_DimensionAspect theDimAspect,
-                         double theDimValue, double theTextSize);
+  double theDimValue, double theTextSize, SketcherPrs_Tools::LocationType theLocationType);
 
 
 static const gp_Circ MyDefCirc(gp_Ax2(gp_Pnt(0,0,0), gp_Dir(0,0,1)), 1);
@@ -163,7 +163,7 @@ void SketcherPrs_Radius::Compute(
   // Update variable aspect parameters (depending on viewer scale)
   double aTextSize = 0.0;
   GetValueString(aTextSize);
-  updateArrows(DimensionAspect(), GetValue(), aTextSize);
+  updateArrows(DimensionAspect(), GetValue(), aTextSize, SketcherPrs_Tools::LOCATION_AUTOMATIC);
 
 
   AIS_RadiusDimension::Compute(thePresentationManager, thePresentation, theMode);
index 550edad50071b631a0ca5f48235d91e9feeea026..bdb0c5737524dd2f7e86ab7a58c4b99e6daf4962 100644 (file)
@@ -103,6 +103,13 @@ namespace SketcherPrs_Tools {
     ANGLE_BACKWARD ///< Angle from the second line to the first line
   };
 
+  /// Type of dimension location
+  enum LocationType{
+    LOCATION_RIGHT,   ///< Position is marked by right arrow placed on the left
+    LOCATION_AUTOMATIC,  ///< Position is marked by two arrow placed on the both sides
+    LOCATION_LEFT ///< Position is marked by left arrow placed on the left
+  };
+
   /// Event ID about expression visual state has been changed, the symbol with a digit
   /// or parameter text is shown
 
index b735f2a51accd2ae8fc1a4993f1d90dae80f2b80..4a9582d29d38ed7ba2c964a79f6ae7f605a3e54d 100644 (file)
@@ -1071,13 +1071,13 @@ Handle(SelectMgr_AndFilter) XGUI_Displayer::GetFilter()
 }
 
 bool XGUI_Displayer::displayAIS(AISObjectPtr theAIS, const bool toActivateInSelectionModes,
-                                bool theUpdateViewer)
+                                const Standard_Integer theDisplayMode, bool theUpdateViewer)
 {
   bool aDisplayed = false;
   Handle(AIS_InteractiveContext) aContext = AISContext();
   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
   if (!aContext.IsNull() && !anAISIO.IsNull()) {
-    aContext->Display(anAISIO, 0/*wireframe*/, 0, false/*update viewer*/, true, AIS_DS_Displayed);
+    aContext->Display(anAISIO, theDisplayMode, 0, false/*update viewer*/, true, AIS_DS_Displayed);
     #ifdef TINSPECTOR
     if (getCallBack()) getCallBack()->Display(anAISIO);
     #endif
index 71e50a7fdc489fd36134ac32de94825bd4f4fafb..9b606dab3b55c0877694e1fe5033e150b8df9d77 100644 (file)
@@ -93,10 +93,11 @@ class XGUI_EXPORT XGUI_Displayer: public QObject
   /// \param theAIS AIOS object to display
   /// \param toActivateInSelectionModes boolean value whether the presentation should be
   /// activated in the current selection modes
+  /// \param theDisplayMode mode how the presentation should be displayed
   /// \param theUpdateViewer the parameter whether the viewer should be update immediatelly
   /// \return true if the object visibility state is changed
   bool displayAIS(AISObjectPtr theAIS, const bool toActivateInSelectionModes,
-                  bool theUpdateViewer = true);
+                  const Standard_Integer theDisplayMode = 0, bool theUpdateViewer = true);
 
   /// Redisplay the shape if it was displayed
   /// \param theObject an object instance
index fdb129faa151144ab62b56f27fda7406159d83d4..76ca0417f8e568f0bfca8c6e597e07421234a84c 100755 (executable)
@@ -99,7 +99,7 @@ void XGUI_MenuMgr::addFeature(const std::shared_ptr<Config_FeatureMessage>& theM
     }
     if (aNestedActions.contains(FEATURE_WHEN_NESTED_ABORT)) {
       QAction* anAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AbortAll);
-      QObject::connect(anAction, SIGNAL(triggered()), anOperationMgr, SLOT(abortAllOperations()));
+      QObject::connect(anAction, SIGNAL(triggered()), anOperationMgr, SLOT(onAbortAllOperation()));
       aNestedActList << anAction;
     }
   }
@@ -209,7 +209,7 @@ QAction* XGUI_MenuMgr::buildAction(const std::shared_ptr<Config_FeatureMessage>&
     }
     if (aNestedActions.contains(FEATURE_WHEN_NESTED_ABORT)) {
       QAction* anAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AbortAll);
-      QObject::connect(anAction, SIGNAL(triggered()), anOperationMgr, SLOT(abortAllOperations()));
+      QObject::connect(anAction, SIGNAL(triggered()), anOperationMgr, SLOT(onAbortAllOperation()));
       aNestedActList << anAction;
     }
     anAction = aSalomeConnector->addFeatureOfNested(theWchName.c_str(), aFeatureInfo,
index 42f892d212103f2d37bebefb575461c1d6c767d5..3c6073c7fd68bdff0969fcb490fadb99fafa6112 100644 (file)
@@ -218,7 +218,7 @@ bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation)
   return isStarted;
 }
 
-bool XGUI_OperationMgr::abortAllOperations()
+bool XGUI_OperationMgr::abortAllOperations(const XGUI_MessageKind& theMessageKind)
 {
   bool aResult = true;
   if(!hasOperation())
@@ -226,18 +226,29 @@ bool XGUI_OperationMgr::abortAllOperations()
 
   if (operationsCount() == 1) {
     ModuleBase_Operation* aCurrentOperation = currentOperation();
-    if (canStopOperation(aCurrentOperation)) {
+    if (canStopOperation(aCurrentOperation, theMessageKind)) {
       abortOperation(aCurrentOperation);
     }
     else
       aResult = false;
   }
   else {
-    aResult = QMessageBox::question(qApp->activeWindow(),
-                                    tr("Abort operation"),
-                                    tr("All active operations will be aborted."),
-                                    QMessageBox::Ok | QMessageBox::Cancel,
-                                    QMessageBox::Cancel) == QMessageBox::Ok;
+    if (theMessageKind == XGUI_AbortOperationMessage) {
+      aResult = QMessageBox::question(qApp->activeWindow(),
+                                      tr("Abort operation"),
+                                      tr("All active operations will be aborted."),
+                                      QMessageBox::Ok | QMessageBox::Cancel,
+                                      QMessageBox::Cancel) == QMessageBox::Ok;
+    }
+    else if (theMessageKind == XGUI_InformationMessage) {
+      QString aMessage = tr("Please validate all your active operations before saving.");
+      QMessageBox::question(qApp->activeWindow(),
+                            tr("Validate operation"),
+                            aMessage,
+                            QMessageBox::Ok,
+                            QMessageBox::Ok);
+      aResult = false; // do not perform abort
+    }
     while(aResult && hasOperation()) {
       abortOperation(currentOperation());
     }
@@ -251,7 +262,7 @@ bool XGUI_OperationMgr::commitAllOperations()
   while (hasOperation()) {
     ModuleBase_Operation* anOperation = currentOperation();
     if (XGUI_Tools::workshop(myWorkshop)->errorMgr()->isApplyEnabled()) {
-      anOperationProcessed = onCommitOperation();
+      anOperationProcessed = commitOperation();
     } else {
       abortOperation(anOperation);
       anOperationProcessed = true;
@@ -305,33 +316,42 @@ void XGUI_OperationMgr::updateApplyOfOperations(ModuleBase_Operation* theOperati
   onValidateOperation();
 }
 
-bool XGUI_OperationMgr::canStopOperation(ModuleBase_Operation* theOperation)
+void XGUI_OperationMgr::updateOperationByUndoRedo()
+{
+  ModuleBase_IModule* aModule = myWorkshop->module();
+  if (aModule)
+    aModule->updateOperationByUndoRedo();
+}
+
+bool XGUI_OperationMgr::canStopOperation(ModuleBase_Operation* theOperation,
+                                         const XGUI_OperationMgr::XGUI_MessageKind& theMessageKind)
 {
   //in case of nested (sketch) operation no confirmation needed
   if (isGrantedOperation(theOperation->id()))
     return true;
   if (theOperation && theOperation->isModified()) {
-    QString aMessage = tr("%1 operation will be aborted.").arg(theOperation->id());
-    int anAnswer = QMessageBox::question(qApp->activeWindow(),
-                                         tr("Abort operation"),
-                                         aMessage,
-                                         QMessageBox::Ok | QMessageBox::Cancel,
-                                         QMessageBox::Cancel);
-    return anAnswer == QMessageBox::Ok;
+    if (theMessageKind == XGUI_AbortOperationMessage) {
+      QString aMessage = tr("%1 operation will be aborted.").arg(theOperation->id());
+      int anAnswer = QMessageBox::question(qApp->activeWindow(),
+                                           tr("Abort operation"),
+                                           aMessage,
+                                           QMessageBox::Ok | QMessageBox::Cancel,
+                                           QMessageBox::Cancel);
+      return anAnswer == QMessageBox::Ok;
+    }
+    else if (theMessageKind == XGUI_InformationMessage) {
+      QString aMessage = tr("Please validate your %1 before saving.").arg(theOperation->id());
+      QMessageBox::question(qApp->activeWindow(),
+                            tr("Validate operation"),
+                            aMessage,
+                            QMessageBox::Ok,
+                            QMessageBox::Ok);
+      return false;
+    }
   }
   return true;
 }
 
-bool XGUI_OperationMgr::commitOperation()
-{
-  //if (hasOperation() && currentOperation()->isValid()) {
-  //  onCommitOperation();
-  //  return true;
-  //}
-  //return false;
-  return onCommitOperation();
-}
-
 void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation)
 {
   theOperation->resume();
@@ -429,7 +449,7 @@ void XGUI_OperationMgr::abortOperation(ModuleBase_Operation* theOperation)
   }
 }
 
-bool XGUI_OperationMgr::onCommitOperation()
+bool XGUI_OperationMgr::commitOperation()
 {
   bool isCommitted = false;
   ModuleBase_Operation* anOperation = currentOperation();
@@ -446,6 +466,11 @@ void XGUI_OperationMgr::onAbortOperation()
   }
 }
 
+void XGUI_OperationMgr::onAbortAllOperation()
+{
+  abortAllOperations();
+}
+
 void XGUI_OperationMgr::onBeforeOperationStarted()
 {
   ModuleBase_Operation* aCurrentOperation = dynamic_cast<ModuleBase_Operation*>(sender());
index 3e6f3b099a86378a1d7250d9b24f7ee59adc0c73..b180436b3c53ab4fce86064f119c3864a4fab889 100755 (executable)
@@ -48,7 +48,15 @@ class XGUI_ShortCutListener;
 class XGUI_EXPORT XGUI_OperationMgr : public QObject
 {
 Q_OBJECT
- public:
+public:
+  /// Enumeration of kind of message that is used when trying to stop the active operation
+  enum XGUI_MessageKind
+  {
+    XGUI_AbortOperationMessage, //< warns and give possibility to abort current operation
+    XGUI_InformationMessage //< ask to apply the current operation before performing something
+  };
+
+public:
   /// Constructor
   /// \param theParent the parent
   /// \param theWorkshop a reference to workshop
@@ -87,7 +95,9 @@ Q_OBJECT
   /// Returns true if the operation can be aborted. If the operation is modified,
   /// the warning message box is shown.
   /// \param theOperation an operation which is checked on stop
-  bool canStopOperation(ModuleBase_Operation* theOperation);
+  /// \param theMessageKind a kind of message in warning message box
+  bool canStopOperation(ModuleBase_Operation* theOperation,
+                        const XGUI_MessageKind& theMessageKind = XGUI_AbortOperationMessage);
 
   /// Find and return operation by its Id.
   ModuleBase_Operation* findOperation(const QString& theId) const;
@@ -124,8 +134,12 @@ Q_OBJECT
   /// \param theOperation an aborted operation
   void abortOperation(ModuleBase_Operation* theOperation);
 
-  /// Slot that commits the current operation.
-  bool onCommitOperation();
+  /// Abort all operations
+  /// \param theMessageKind kind of shown warning message
+  bool abortAllOperations(const XGUI_MessageKind& theMessageKind = XGUI_AbortOperationMessage);
+
+  /// Commits the current operation.
+  bool commitOperation();
 
   /// Returns true if SHIFT is pressed
   /// \param thePressed new boolean state
@@ -138,12 +152,12 @@ Q_OBJECT
 public slots:
   /// Slot that aborts the current operation.
   void onAbortOperation();
+  /// Slot that aborts all operations. It shows aborting message
+  void onAbortAllOperation();
   /// Slot that validates the current operation using the validateOperation method.
   void onValidateOperation();
   /// Commit all operations
   bool commitAllOperations();
-  /// Abort all operations
-  bool abortAllOperations();
 
 signals:
   /// Signal about an operation is stopped. It is emitted after the stop() of operation is done.
@@ -167,8 +181,8 @@ public: // TEMPORARY, it should be protected and be performed automatically
   /// \param theOperation the sent operation. If it is NULL, all operations in the stack are sent.
   void updateApplyOfOperations(ModuleBase_Operation* theOperation = 0);
 
-  /// Commits the current operatin if it is valid
-  bool commitOperation();
+  /// Updates the current operation state after undo/redo actions calling
+  void updateOperationByUndoRedo();
 
 protected: // TEMPORARY
   /// Sets the current operation or NULL
index 0c5fcd7cf7bdc598ff054a3567b8041a4d4731fc..b52be827ea67d9ce23d0112942fb36c1b75eeab2 100644 (file)
@@ -169,7 +169,7 @@ bool canRename(const ObjectPtr& theObject, const QString& theName)
 XGUI_Workshop* workshop(ModuleBase_IWorkshop* theWorkshop)
 {
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(theWorkshop);
-  return aConnector->workshop();
+  return aConnector ? aConnector->workshop() : 0;
 }
 
 }
index 0ab1b602c030fa1f7308db8e4bdd260aee1a2311..72d45256248c607b0fbdad945fc4e984fe9ee925 100755 (executable)
@@ -508,7 +508,7 @@ void XGUI_Workshop::onAcceptActionClicked()
                                                     (anOperationMgr->currentOperation());
     if (aFOperation) {
       //if (errorMgr()->canProcessClick(anAction, aFOperation->feature()))
-      myOperationMgr->onCommitOperation();
+      myOperationMgr->commitOperation();
     }
   }
 }
@@ -927,7 +927,7 @@ void XGUI_Workshop::onTrihedronVisibilityChanged(bool theState)
 //******************************************************
 bool XGUI_Workshop::onSave()
 {
-  if(!abortAllOperations())
+  if(!myOperationMgr->abortAllOperations(XGUI_OperationMgr::XGUI_InformationMessage))
     return false;
   if (myCurrentDir.isEmpty()) {
     return onSaveAs();
@@ -944,7 +944,7 @@ bool XGUI_Workshop::onSave()
 //******************************************************
 bool XGUI_Workshop::onSaveAs()
 {
-  if(!abortAllOperations())
+  if(!myOperationMgr->abortAllOperations(XGUI_OperationMgr::XGUI_InformationMessage))
     return false;
   QFileDialog dialog(desktop());
   dialog.setWindowTitle(tr("Select directory to save files..."));
@@ -999,6 +999,7 @@ void XGUI_Workshop::onUndo(int theTimes)
   }
 
   operationMgr()->updateApplyOfOperations();
+  operationMgr()->updateOperationByUndoRedo();
   updateCommandStatus();
 }
 
@@ -1027,6 +1028,7 @@ void XGUI_Workshop::onRedo(int theTimes)
       myObjectBrowser->rebuildDataTree();
   }
   operationMgr()->updateApplyOfOperations();
+  operationMgr()->updateOperationByUndoRedo();
   updateCommandStatus();
 
   // unblock the viewer update functionality and make update on purpose
@@ -1430,10 +1432,10 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked)
         MyTCommunicator->RegisterPlugin("TKDFBrowser");
         MyTCommunicator->RegisterPlugin("TKShapeView");
         MyTCommunicator->RegisterPlugin("TKVInspector");
-        MyTCommunicator->RegisterPlugin("SMBrowser"); // custom plugin to view ModelAPI
+        MyTCommunicator->RegisterPlugin("TKSMBrowser"); // custom plugin to view ModelAPI
 
         MyTCommunicator->Init(aParameters);
-        MyTCommunicator->Activate("SMBrowser"); // to have button in TInspector
+        MyTCommunicator->Activate("TKSMBrowser"); // to have button in TInspector
         MyTCommunicator->Activate("TKVInspector"); // to have filled callback by model
         MyTCommunicator->Activate("TKDFBrowser");
       }