From b4fa4c082ef0d0e75ee8bf7f3f440b3f9c86e63c Mon Sep 17 00:00:00 2001 From: nds Date: Mon, 25 Sep 2017 11:56:00 +0300 Subject: [PATCH] Issue #2206 Avoid the ability to cancel the current sketch when saving, 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 --- src/ModuleBase/ModuleBase_IModule.h | 3 + src/ModuleBase/ModuleBase_ModelWidget.cpp | 14 - src/ModuleBase/ModuleBase_ModelWidget.h | 4 - src/ModuleBase/ModuleBase_ResultPrs.cpp | 53 ++-- src/ModuleBase/ModuleBase_ResultPrs.h | 17 +- src/ModuleBase/ModuleBase_WidgetChoice.cpp | 8 +- src/PartSet/CMakeLists.txt | 4 +- src/PartSet/PartSet_CustomPrs.h | 3 + src/PartSet/PartSet_ExternalObjectsMgr.cpp | 17 +- src/PartSet/PartSet_Module.cpp | 15 +- src/PartSet/PartSet_Module.h | 3 + src/PartSet/PartSet_PreviewSketchPlane.cpp | 239 ++++++++++++++++++ src/PartSet/PartSet_PreviewSketchPlane.h | 101 ++++++++ src/PartSet/PartSet_SketcherMgr.cpp | 19 +- src/PartSet/PartSet_SketcherMgr.h | 6 + src/PartSet/PartSet_Tools.cpp | 143 ++++------- src/PartSet/PartSet_Tools.h | 52 ++-- src/PartSet/PartSet_WidgetChoice.h | 43 ---- src/PartSet/PartSet_WidgetPoint2d.cpp | 10 +- src/PartSet/PartSet_WidgetShapeSelector.cpp | 32 --- src/PartSet/PartSet_WidgetSketchLabel.cpp | 22 +- .../SketchPlugin_ConstraintLength.cpp | 4 + .../SketchPlugin_ConstraintLength.h | 8 + src/SketchPlugin/icons/location_automatic.png | Bin 0 -> 584 bytes src/SketchPlugin/icons/location_left.png | Bin 0 -> 581 bytes src/SketchPlugin/icons/location_right.png | Bin 0 -> 602 bytes src/SketchPlugin/plugin-Sketch.xml | 9 + .../SketcherPrs_LengthDimension.cpp | 44 +++- src/SketcherPrs/SketcherPrs_Radius.cpp | 4 +- src/SketcherPrs/SketcherPrs_Tools.h | 7 + src/XGUI/XGUI_Displayer.cpp | 4 +- src/XGUI/XGUI_Displayer.h | 3 +- src/XGUI/XGUI_MenuMgr.cpp | 4 +- src/XGUI/XGUI_OperationMgr.cpp | 79 ++++-- src/XGUI/XGUI_OperationMgr.h | 30 ++- src/XGUI/XGUI_Tools.cpp | 2 +- src/XGUI/XGUI_Workshop.cpp | 12 +- 37 files changed, 689 insertions(+), 329 deletions(-) create mode 100644 src/PartSet/PartSet_PreviewSketchPlane.cpp create mode 100644 src/PartSet/PartSet_PreviewSketchPlane.h delete mode 100644 src/PartSet/PartSet_WidgetChoice.h create mode 100644 src/SketchPlugin/icons/location_automatic.png create mode 100644 src/SketchPlugin/icons/location_left.png create mode 100644 src/SketchPlugin/icons/location_right.png diff --git a/src/ModuleBase/ModuleBase_IModule.h b/src/ModuleBase/ModuleBase_IModule.h index 995e21fe8..8295af761 100755 --- a/src/ModuleBase/ModuleBase_IModule.h +++ b/src/ModuleBase/ModuleBase_IModule.h @@ -309,6 +309,9 @@ class MODULEBASE_EXPORT ModuleBase_IModule : public QObject /// \param theStdActions - a map of standard actions virtual void updateViewerMenu(const QMap& 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/ModuleBase/ModuleBase_ModelWidget.cpp b/src/ModuleBase/ModuleBase_ModelWidget.cpp index fcba4e0c4..c5ff1104d 100644 --- a/src/ModuleBase/ModuleBase_ModelWidget.cpp +++ b/src/ModuleBase/ModuleBase_ModelWidget.cpp @@ -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; diff --git a/src/ModuleBase/ModuleBase_ModelWidget.h b/src/ModuleBase/ModuleBase_ModelWidget.h index 29dc34733..a1e753fd7 100644 --- a/src/ModuleBase/ModuleBase_ModelWidget.h +++ b/src/ModuleBase/ModuleBase_ModelWidget.h @@ -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; diff --git a/src/ModuleBase/ModuleBase_ResultPrs.cpp b/src/ModuleBase/ModuleBase_ResultPrs.cpp index 0dd37b355..907fd6a60 100755 --- a/src/ModuleBase/ModuleBase_ResultPrs.cpp +++ b/src/ModuleBase/ModuleBase_ResultPrs.cpp @@ -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, diff --git a/src/ModuleBase/ModuleBase_ResultPrs.h b/src/ModuleBase/ModuleBase_ResultPrs.h index 6d46e4ef5..d9a0da37c 100644 --- a/src/ModuleBase/ModuleBase_ResultPrs.h +++ b/src/ModuleBase/ModuleBase_ResultPrs.h @@ -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; diff --git a/src/ModuleBase/ModuleBase_WidgetChoice.cpp b/src/ModuleBase/ModuleBase_WidgetChoice.cpp index ce664179f..74e8b12aa 100644 --- a/src/ModuleBase/ModuleBase_WidgetChoice.cpp +++ b/src/ModuleBase/ModuleBase_WidgetChoice.cpp @@ -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))); } } diff --git a/src/PartSet/CMakeLists.txt b/src/PartSet/CMakeLists.txt index 37575cf72..8bb95e123 100644 --- a/src/PartSet/CMakeLists.txt +++ b/src/PartSet/CMakeLists.txt @@ -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 diff --git a/src/PartSet/PartSet_CustomPrs.h b/src/PartSet/PartSet_CustomPrs.h index c02541611..fc8359681 100755 --- a/src/PartSet/PartSet_CustomPrs.h +++ b/src/PartSet/PartSet_CustomPrs.h @@ -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 diff --git a/src/PartSet/PartSet_ExternalObjectsMgr.cpp b/src/PartSet/PartSet_ExternalObjectsMgr.cpp index 85c9ce0dd..a33d6c391 100755 --- a/src/PartSet/PartSet_ExternalObjectsMgr.cpp +++ b/src/PartSet/PartSet_ExternalObjectsMgr.cpp @@ -72,22 +72,13 @@ ObjectPtr PartSet_ExternalObjectsMgr::externalObject(const ObjectPtr& theSelecte { ObjectPtr aSelectedObject = PartSet_Tools::findFixedObjectByExternal( theShape->impl(), theSelectedObject, theSketch); - FeaturePtr aFeature = ModelAPI_Feature::feature(aSelectedObject); - if (aFeature.get()) { - std::shared_ptr aSketchFeature = - std::dynamic_pointer_cast(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(), - theSelectedObject, theSketch, theTemporary); + FeaturePtr aCreatedFeature; + aSelectedObject = PartSet_Tools::createFixedObjectByExternal(theShape, + theSelectedObject, theSketch, theTemporary, aCreatedFeature); if (aSelectedObject.get() && theTemporary) - myExternalObjectValidated = aSelectedObject; + myExternalObjectValidated = aCreatedFeature; } return aSelectedObject; } diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 5dc11364e..078b18236 100755 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -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 #include #include +#include #include #include #include @@ -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& 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(theWidget); + ModuleBase_WidgetChoice* aChoiceWidget = dynamic_cast(theWidget); if (!aChoiceWidget) return; diff --git a/src/PartSet/PartSet_Module.h b/src/PartSet/PartSet_Module.h index 4a70c942f..cc9bd9ed5 100755 --- a/src/PartSet/PartSet_Module.h +++ b/src/PartSet/PartSet_Module.h @@ -331,6 +331,9 @@ public: /// \param theStdActions - a map of standard actions virtual void updateViewerMenu(const QMap& 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 index 000000000..1ee9856ff --- /dev/null +++ b/src/PartSet/PartSet_PreviewSketchPlane.cpp @@ -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 +// + +#include "PartSet_PreviewSketchPlane.h" +#include "PartSet_Tools.h" + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include + +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(); + 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 aPlane = PartSet_Tools::sketchPlane(theSketch); + if (!aPlane.get()) + return; + + if (!myPlane) { // If planes are not created + std::shared_ptr anOrigin = std::dynamic_pointer_cast( + theSketch->data()->attribute(SketchPlugin_Sketch::ORIGIN_ID())); + std::shared_ptr aNormal = std::dynamic_pointer_cast( + theSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID())); + + // Create Preview + // default planes parameters + std::shared_ptr 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 + (theSketch->data()->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID())); + if (aSelAttr) { + std::shared_ptr 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 anOriginPnt; + double aSize = getSketchBoundingBoxSize(theSketch, anOriginPnt); + if (aSize <= 0) + return; + myOrigin = anOriginPnt; + createPreviewPlane(aSize); +} + +AISObjectPtr PartSet_PreviewSketchPlane::createPreviewPlane(double theSize) +{ + std::vector 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 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 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(); + if (!anAISIO.IsNull()) { + anAISIO->Attributes()->SetFaceBoundaryDraw( Standard_True ); + anAISIO->SetDisplayMode(aDispMode); + } + return aAIS; + } +} + +void PartSet_PreviewSketchPlane::getShapeParameters(const GeomShapePtr& theShape, + std::shared_ptr& 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& theSketch, + std::shared_ptr& 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 aResults = aFeature->results(); + std::list::const_iterator aResultIt; + for (aResultIt = aResults.begin(); aResultIt != aResults.end(); ++aResultIt) { + ResultPtr aResult = *aResultIt; + std::shared_ptr aShapePtr = aResult->shape(); + if (aShapePtr.get()) { + TopoDS_Shape aShape = aShapePtr->impl(); + 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(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 index 000000000..b2d32c843 --- /dev/null +++ b/src/PartSet/PartSet_PreviewSketchPlane.h @@ -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 +// + +#ifndef PartSet_PreviewSketchPlane_H +#define PartSet_PreviewSketchPlane_H + +#include + +#include +#include +#include + +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& 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& 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& 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& theShape, + std::shared_ptr& 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& theSketch, + std::shared_ptr& theCentralPnt); + +private: + bool mySketchDisplayed; + AISObjectPtr myPlane; + std::shared_ptr myOrigin; //! an origin of the plane + std::shared_ptr myNormal; //! a normal vector of the plane + + std::shared_ptr myOtherSketchOrigin; + double myOtherSketchSize; +}; + +#endif \ No newline at end of file diff --git a/src/PartSet/PartSet_SketcherMgr.cpp b/src/PartSet/PartSet_SketcherMgr.cpp index eab2a165c..88334e9ee 100755 --- a/src/PartSet/PartSet_SketcherMgr.cpp +++ b/src/PartSet/PartSet_SketcherMgr.cpp @@ -27,6 +27,7 @@ #include "PartSet_WidgetEditor.h" #include "PartSet_ResultSketchPrs.h" #include "PartSet_ExternalPointsMgr.h" +#include "PartSet_PreviewSketchPlane.h" #include #include @@ -83,6 +84,7 @@ #include #include #include +#include #include @@ -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 aSPFeature = std::dynamic_pointer_cast(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(aFOperation->feature()); + mySketchPlane->createSketchPlane(myCurrentSketch, myModule->workshop()); XGUI_ModuleConnector* aConnector = dynamic_cast(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 diff --git a/src/PartSet/PartSet_SketcherMgr.h b/src/PartSet/PartSet_SketcherMgr.h index 92c74ef8c..7f76b48c0 100644 --- a/src/PartSet/PartSet_SketcherMgr.h +++ b/src/PartSet/PartSet_SketcherMgr.h @@ -25,6 +25,7 @@ #include "PartSet_Filters.h" #include "PartSet_Tools.h" +#include "PartSet_PreviewSketchPlane.h" #include #include @@ -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; diff --git a/src/PartSet/PartSet_Tools.cpp b/src/PartSet/PartSet_Tools.cpp index 2a5f0f08d..61a05c9d2 100755 --- a/src/PartSet/PartSet_Tools.cpp +++ b/src/PartSet/PartSet_Tools.cpp @@ -70,6 +70,7 @@ #include #include #include +#include #include #include @@ -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 aInEdge = std::shared_ptr(new GeomAPI_Edge()); - aInEdge->setImpl(new TopoDS_Shape(theShape)); - aResult = findExternalEdge(theSketch, aInEdge); - } - if (theShape.ShapeType() == TopAbs_VERTEX) { - std::shared_ptr aInVert = std::shared_ptr(new GeomAPI_Vertex()); - aInVert->setImpl(new TopoDS_Shape(theShape)); - aResult = findExternalVertex(theSketch, aInVert); + ResultPtr aResult = std::dynamic_pointer_cast(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& theShape, + const ObjectPtr& theObject, + CompositeFeaturePtr theSketch, + const bool theTemporary, + FeaturePtr& theCreatedFeature) { + ResultPtr aResult = std::dynamic_pointer_cast(theObject); + + if (!aResult.get()) + return ResultPtr(); + + FeaturePtr aProjectionFeature = theSketch->addFeature(SketchPlugin_Projection::ID()); + theCreatedFeature = aProjectionFeature; + AttributeSelectionPtr anExternalAttr = std::dynamic_pointer_cast( + aProjectionFeature->attribute(SketchPlugin_Projection::EXTERNAL_FEATURE_ID())); + anExternalAttr->setValue(aResult, theShape); + AttributeBooleanPtr anIntoResult = std::dynamic_pointer_cast + (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& return false; } -ResultPtr PartSet_Tools::findExternalEdge(CompositeFeaturePtr theSketch, - std::shared_ptr theEdge) -{ - for (int i = 0; i < theSketch->numberOfSubs(); i++) { - FeaturePtr aFeature = theSketch->subFeature(i); - std::shared_ptr aSketchFea = - std::dynamic_pointer_cast(aFeature); - // not displayed result of feature projection should not be returned as external edge - if (aSketchFea && aSketchFea->canBeDisplayed()) { - if (aSketchFea->isExternal()) { - std::list aResults = aSketchFea->results(); - std::list::const_iterator aIt; - for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) { - ResultConstructionPtr aRes = - std::dynamic_pointer_cast(*aIt); - if (aRes) { - std::shared_ptr aShape = aRes->shape(); - if (aShape) { - if (theEdge->isEqual(aShape)) - return aRes; - } - } - } - } - } - } - return ResultPtr(); -} - - -ResultPtr PartSet_Tools::findExternalVertex(CompositeFeaturePtr theSketch, - std::shared_ptr theVert) -{ - for (int i = 0; i < theSketch->numberOfSubs(); i++) { - FeaturePtr aFeature = theSketch->subFeature(i); - std::shared_ptr aSketchFea = - std::dynamic_pointer_cast(aFeature); - if (aSketchFea) { - if (aSketchFea->isExternal()) { - std::list aResults = aSketchFea->results(); - std::list::const_iterator aIt; - for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) { - ResultConstructionPtr aRes = - std::dynamic_pointer_cast(*aIt); - if (aRes) { - std::shared_ptr 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(); - 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) { diff --git a/src/PartSet/PartSet_Tools.h b/src/PartSet/PartSet_Tools.h index b7c0a22c9..486d361e0 100755 --- a/src/PartSet/PartSet_Tools.h +++ b/src/PartSet/PartSet_Tools.h @@ -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 createFixedObjectByExternal( - const TopoDS_Shape& theShape, + const std::shared_ptr& 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>& theSelected, const std::shared_ptr& 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 findExternalEdge(CompositeFeaturePtr theSketch, - std::shared_ptr 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 findExternalVertex(CompositeFeaturePtr theSketch, - std::shared_ptr 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& 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& theCoincidencies, std::string theAttr, QList& 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& aRefsList = theFeature->data()->refsToMe(); + std::set::const_iterator anIt; + for (anIt = aRefsList.cbegin(); anIt != aRefsList.cend(); ++anIt) { + FeaturePtr aRefFeature = std::dynamic_pointer_cast((*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 index 071e06f7e..000000000 --- a/src/PartSet/PartSet_WidgetChoice.h +++ /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 -// - -#ifndef PartSet_WidgetChoice_H -#define PartSet_WidgetChoice_H - -#include "PartSet.h" -#include - -/** -* \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 diff --git a/src/PartSet/PartSet_WidgetPoint2d.cpp b/src/PartSet/PartSet_WidgetPoint2d.cpp index 3d9d933e9..37d9fb015 100644 --- a/src/PartSet/PartSet_WidgetPoint2d.cpp +++ b/src/PartSet/PartSet_WidgetPoint2d.cpp @@ -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) { diff --git a/src/PartSet/PartSet_WidgetShapeSelector.cpp b/src/PartSet/PartSet_WidgetShapeSelector.cpp index 6b70c7eaa..ead2a719a 100755 --- a/src/PartSet/PartSet_WidgetShapeSelector.cpp +++ b/src/PartSet/PartSet_WidgetShapeSelector.cpp @@ -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 aSPFeature = - std::dynamic_pointer_cast(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; - }*/ } //******************************************************************** diff --git a/src/PartSet/PartSet_WidgetSketchLabel.cpp b/src/PartSet/PartSet_WidgetSketchLabel.cpp index aa209656b..8485a1b49 100644 --- a/src/PartSet/PartSet_WidgetSketchLabel.cpp +++ b/src/PartSet/PartSet_WidgetSketchLabel.cpp @@ -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(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(aFeature); + std::shared_ptr aPlane = PartSet_Tools::sketchPlane(aSketch); + if (aPlane.get()) + aModule->sketchMgr()->previewSketchPlane()->setOtherSketchParameters(thePrs->shape()); + } + } + } + CompositeFeaturePtr aSketch = std::dynamic_pointer_cast(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 aGShape; diff --git a/src/SketchPlugin/SketchPlugin_ConstraintLength.cpp b/src/SketchPlugin/SketchPlugin_ConstraintLength.cpp index 504314fbd..6eda688a8 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintLength.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintLength.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -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, diff --git a/src/SketchPlugin/SketchPlugin_ConstraintLength.h b/src/SketchPlugin/SketchPlugin_ConstraintLength.h index 50e9ebb9b..13666de04 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintLength.h +++ b/src/SketchPlugin/SketchPlugin_ConstraintLength.h @@ -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 index 0000000000000000000000000000000000000000..88730b3b5c22bcd95c48590a29a7fae4d24ab31f GIT binary patch literal 584 zcmV-O0=NB%P)zB`BMNxqy$>nG?8f}bE0DF7OKooc_?UDWm2tpkJDlkFr zu(`huD4)MXn%)O4lO$Kz-u{tEFflPqlB`HtB?z8dz5e!4fX2r1gyBP^5@~u77y>>J zhIi#$rhbwH;5%k_fZK9z4YT){J+)e`(jGH8r&haO0=FYGOpXNHSbi}ebU+Gt zK7syUL<7J8@ZSSEi|E1QXJ-PX{yNsmX?Bl2GHDGNVnUOb4}Ij=T*Ro4Sk?> zIxWne0hfX2I2Xye`5VKV}oiB234VcUg0FLJkXG|F= z0jt2*`~b6)nJMWta3W=|i`g#H3reNC)@p6axn^#F#c?#WyIQRh1pDs-vmQyZgXe7k z_t@TkWsu}8-3Q1_1i^J+78n4Zkz(KhW=|}RcmJd`H$aPv)AakdfEaj$??1Gytxuzt z<_6$-J)|?%Zg2d}(%b-xqVGUq#lDS@WB=Mq8DyCgIxRq}^#y5INS z@8IJ-7-yVu`b5KUQLR<2)$Zj{zmP}KvB16&(8bAxVxQ;thDO02Bv-28-$k zaqcvpcL9+_;4>m$Gj4ps^Gf~B&~HE*jdfrFSkPMSJa7lN1XOzGM~Za2WpOUfs<)>( zAW^g;&Rxft6R6H1@&;%kvV*GW$z^6FgGg3acO;IVOB7us2xbtu4}1jX)!Hz3fnQ`c zHoi%-`AFh;8aRb9+gbd`CgC4toLj@WOy>XIhW~_sf9v7ndJuF{cXn%OsXWnc=O=)4 z-*-A*>Rf+&a;7-@ZY4i~XD?rsfKnPT-TcCAZteHO8#o$P+lr + diff --git a/src/SketcherPrs/SketcherPrs_LengthDimension.cpp b/src/SketcherPrs/SketcherPrs_LengthDimension.cpp index 34fb6a6ee..3aeebbc2b 100644 --- a/src/SketcherPrs/SketcherPrs_LengthDimension.cpp +++ b/src/SketcherPrs/SketcherPrs_LengthDimension.cpp @@ -39,6 +39,7 @@ #include #include +#include #include @@ -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 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); diff --git a/src/SketcherPrs/SketcherPrs_Radius.cpp b/src/SketcherPrs/SketcherPrs_Radius.cpp index fe5fbaa99..bc784cb38 100644 --- a/src/SketcherPrs/SketcherPrs_Radius.cpp +++ b/src/SketcherPrs/SketcherPrs_Radius.cpp @@ -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); diff --git a/src/SketcherPrs/SketcherPrs_Tools.h b/src/SketcherPrs/SketcherPrs_Tools.h index 550edad50..bdb0c5737 100644 --- a/src/SketcherPrs/SketcherPrs_Tools.h +++ b/src/SketcherPrs/SketcherPrs_Tools.h @@ -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 diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index b735f2a51..4a9582d29 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -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(); 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 diff --git a/src/XGUI/XGUI_Displayer.h b/src/XGUI/XGUI_Displayer.h index 71e50a7fd..9b606dab3 100644 --- a/src/XGUI/XGUI_Displayer.h +++ b/src/XGUI/XGUI_Displayer.h @@ -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 diff --git a/src/XGUI/XGUI_MenuMgr.cpp b/src/XGUI/XGUI_MenuMgr.cpp index fdb129faa..76ca0417f 100755 --- a/src/XGUI/XGUI_MenuMgr.cpp +++ b/src/XGUI/XGUI_MenuMgr.cpp @@ -99,7 +99,7 @@ void XGUI_MenuMgr::addFeature(const std::shared_ptr& 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& } 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, diff --git a/src/XGUI/XGUI_OperationMgr.cpp b/src/XGUI/XGUI_OperationMgr.cpp index 42f892d21..3c6073c7f 100644 --- a/src/XGUI/XGUI_OperationMgr.cpp +++ b/src/XGUI/XGUI_OperationMgr.cpp @@ -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(sender()); diff --git a/src/XGUI/XGUI_OperationMgr.h b/src/XGUI/XGUI_OperationMgr.h index 3e6f3b099..b180436b3 100755 --- a/src/XGUI/XGUI_OperationMgr.h +++ b/src/XGUI/XGUI_OperationMgr.h @@ -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 diff --git a/src/XGUI/XGUI_Tools.cpp b/src/XGUI/XGUI_Tools.cpp index 0c5fcd7cf..b52be827e 100644 --- a/src/XGUI/XGUI_Tools.cpp +++ b/src/XGUI/XGUI_Tools.cpp @@ -169,7 +169,7 @@ bool canRename(const ObjectPtr& theObject, const QString& theName) XGUI_Workshop* workshop(ModuleBase_IWorkshop* theWorkshop) { XGUI_ModuleConnector* aConnector = dynamic_cast(theWorkshop); - return aConnector->workshop(); + return aConnector ? aConnector->workshop() : 0; } } diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 0ab1b602c..72d452562 100755 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -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"); } -- 2.39.2