From 3bb056033567ef420a3eb7cdc2a2cada3d94ee06 Mon Sep 17 00:00:00 2001 From: nds Date: Thu, 15 May 2014 14:40:55 +0400 Subject: [PATCH] refs #30 - Sketch base GUI: create, draw lines Undo/Redo for a line under sketch. --- src/PartSet/PartSet_Listener.cpp | 22 +++++++++++--- src/PartSet/PartSet_Module.cpp | 33 +++++++++++++++++++++ src/PartSet/PartSet_Module.h | 4 +++ src/PartSet/PartSet_OperationSketch.cpp | 25 ++++++++++++++++ src/PartSet/PartSet_OperationSketch.h | 4 +++ src/PartSet/PartSet_OperationSketchBase.cpp | 6 ++++ src/PartSet/PartSet_OperationSketchBase.h | 6 ++++ src/SketchPlugin/SketchPlugin_Line.cpp | 26 ++++++++-------- src/XGUI/XGUI_Displayer.cpp | 27 +++++++++++++++++ src/XGUI/XGUI_Displayer.h | 7 +++++ src/XGUI/XGUI_OperationMgr.cpp | 23 +++++++++++--- src/XGUI/XGUI_OperationMgr.h | 7 +++++ src/XGUI/XGUI_Workshop.cpp | 2 ++ 13 files changed, 172 insertions(+), 20 deletions(-) diff --git a/src/PartSet/PartSet_Listener.cpp b/src/PartSet/PartSet_Listener.cpp index 3e1c4886a..9615dac4c 100644 --- a/src/PartSet/PartSet_Listener.cpp +++ b/src/PartSet/PartSet_Listener.cpp @@ -21,8 +21,9 @@ PartSet_Listener::PartSet_Listener(PartSet_Module* theModule) : myModule(theModule) { Events_Loop* aLoop = Events_Loop::loop(); - Events_ID aFeatureUpdatedId = aLoop->eventByName(EVENT_FEATURE_UPDATED); - aLoop->registerListener(this, aFeatureUpdatedId); + aLoop->registerListener(this, aLoop->eventByName(EVENT_FEATURE_UPDATED)); + aLoop->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_CREATED)); + aLoop->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_DELETED)); } PartSet_Listener::~PartSet_Listener() @@ -32,11 +33,24 @@ PartSet_Listener::~PartSet_Listener() //****************************************************** void PartSet_Listener::processEvent(const Events_Message* theMessage) { - if (QString(theMessage->eventID().eventText()) == EVENT_FEATURE_UPDATED) + QString aType = QString(theMessage->eventID().eventText()); + if (aType == EVENT_FEATURE_UPDATED || + aType == EVENT_FEATURE_CREATED) { const Model_FeatureUpdatedMessage* aUpdMsg = dynamic_cast(theMessage); boost::shared_ptr aFeature = aUpdMsg->feature(); - if (myModule->workshop()->displayer()->IsVisible(aFeature)) + if (myModule->workshop()->displayer()->IsVisible(aFeature) || + aType == EVENT_FEATURE_CREATED) myModule->visualizePreview(aFeature, true); } + if (aType == EVENT_FEATURE_DELETED) + { + const Model_FeatureDeletedMessage* aDelMsg = dynamic_cast(theMessage); + boost::shared_ptr aDoc = aDelMsg->document(); + + std::string aGroup = aDelMsg->group(); + if (aDelMsg->group().compare("Sketch") == 0) { // Update only Sketch group + myModule->updateCurrentPreview(aGroup); + } + } } diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index d7a92caf5..9e47626c8 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -308,3 +308,36 @@ void PartSet_Module::visualizePreview(boost::shared_ptr theFea aDisplayer->Erase(anOperation->feature()); } } + +void PartSet_Module::updateCurrentPreview(const std::string& theCmdId) +{ + ModuleBase_Operation* anOperation = myWorkshop->operationMgr()->currentOperation(); + if (!anOperation) + return; + + PartSet_OperationSketchBase* aPreviewOp = dynamic_cast(anOperation); + if (!aPreviewOp) + return; + + boost::shared_ptr aFeature = aPreviewOp->feature(); + if (!aFeature || aFeature->getKind() != theCmdId) + return; + + std::map, boost::shared_ptr > + aList = aPreviewOp->preview(); + XGUI_Displayer* aDisplayer = myWorkshop->displayer(); + std::list aModes = aPreviewOp->getSelectionModes(aPreviewOp->feature()); + + std::map, boost::shared_ptr >::const_iterator + anIt = aList.begin(), aLast = aList.end(); + aDisplayer->EraseAll(false); + for (; anIt != aLast; anIt++) { + boost::shared_ptr aFeature = (*anIt).first; + boost::shared_ptr aPreview = (*anIt).second; + aDisplayer->RedisplayInLocalContext(aFeature, + aPreview ? aPreview->impl() : TopoDS_Shape(), + aModes, false); + } + aDisplayer->UpdateViewer(); +} + diff --git a/src/PartSet/PartSet_Module.h b/src/PartSet/PartSet_Module.h index 6138a43dc..14a418d01 100644 --- a/src/PartSet/PartSet_Module.h +++ b/src/PartSet/PartSet_Module.h @@ -44,6 +44,10 @@ public: /// \param isDisplay the state whether the presentation should be displayed or erased void visualizePreview(boost::shared_ptr theFeature, bool isDisplay); + /// Updates current operation preview, if it has it. + /// \param theCmdId the operation name + void updateCurrentPreview(const std::string& theCmdId); + public slots: void onFeatureTriggered(); /// SLOT, that is called after the operation is stopped. Switched off the modfications performed diff --git a/src/PartSet/PartSet_OperationSketch.cpp b/src/PartSet/PartSet_OperationSketch.cpp index e5290aa77..bcbbf1571 100644 --- a/src/PartSet/PartSet_OperationSketch.cpp +++ b/src/PartSet/PartSet_OperationSketch.cpp @@ -11,6 +11,8 @@ #include #include +#include + #include #include #include @@ -79,6 +81,29 @@ void PartSet_OperationSketch::mouseMoved(QMouseEvent* theEvent, Handle(V3d_View) emit launchOperation(PartSet_OperationEditLine::Type(), aFeature); } +std::map, boost::shared_ptr > + PartSet_OperationSketch::preview() const +{ + std::map, boost::shared_ptr > aPreviewMap; + + boost::shared_ptr aFeature; + + boost::shared_ptr aData = feature()->data(); + boost::shared_ptr aRefList = + boost::dynamic_pointer_cast(aData->attribute(SKETCH_ATTR_FEATURES)); + + std::list > aFeatures = aRefList->list(); + std::list >::const_iterator anIt = aFeatures.begin(), + aLast = aFeatures.end(); + for (; anIt != aLast; anIt++) { + aFeature = boost::dynamic_pointer_cast(*anIt); + boost::shared_ptr aPreview = aFeature->preview(); + if (aPreview) + aPreviewMap[aFeature] = aPreview; + } + return aPreviewMap; +} + void PartSet_OperationSketch::setSketchPlane(const TopoDS_Shape& theShape) { if (theShape.IsNull()) diff --git a/src/PartSet/PartSet_OperationSketch.h b/src/PartSet/PartSet_OperationSketch.h index 227722dc7..3f8215ac9 100644 --- a/src/PartSet/PartSet_OperationSketch.h +++ b/src/PartSet/PartSet_OperationSketch.h @@ -47,6 +47,10 @@ public: virtual void mouseMoved(QMouseEvent* theEvent, Handle_V3d_View theView, const std::list& theSelected); + /// Returns the map of the operation previews including the nested feature previews + /// \return the map of feature to the feature preview + virtual std::map, boost::shared_ptr > + preview() const; signals: /// signal about the sketch plane is selected /// \param theX the value in the X direction of the plane diff --git a/src/PartSet/PartSet_OperationSketchBase.cpp b/src/PartSet/PartSet_OperationSketchBase.cpp index 4113c3cba..daa0211b1 100644 --- a/src/PartSet/PartSet_OperationSketchBase.cpp +++ b/src/PartSet/PartSet_OperationSketchBase.cpp @@ -32,6 +32,12 @@ boost::shared_ptr PartSet_OperationSketchBase::preview( return aFeature->preview(); } +std::map, boost::shared_ptr > + PartSet_OperationSketchBase::preview() const +{ + return std::map, boost::shared_ptr >(); +} + boost::shared_ptr PartSet_OperationSketchBase::createFeature() { boost::shared_ptr aFeature = ModuleBase_Operation::createFeature(); diff --git a/src/PartSet/PartSet_OperationSketchBase.h b/src/PartSet/PartSet_OperationSketchBase.h index b30f29935..cce1c5511 100644 --- a/src/PartSet/PartSet_OperationSketchBase.h +++ b/src/PartSet/PartSet_OperationSketchBase.h @@ -15,6 +15,8 @@ #include #include +#include + class Handle_V3d_View; class QMouseEvent; class GeomAPI_Shape; @@ -43,6 +45,10 @@ public: /// \param theFeature the feature object to obtain the preview boost::shared_ptr preview(boost::shared_ptr theFeature) const; + /// Returns the map of the operation previews including the nested feature previews + /// \return the map of feature to the feature preview + virtual std::map, boost::shared_ptr > preview() const; + /// Returns the operation local selection mode /// \param theFeature the feature object to get the selection mode /// \return the selection mode diff --git a/src/SketchPlugin/SketchPlugin_Line.cpp b/src/SketchPlugin/SketchPlugin_Line.cpp index 8462d99bd..5c71d3779 100644 --- a/src/SketchPlugin/SketchPlugin_Line.cpp +++ b/src/SketchPlugin/SketchPlugin_Line.cpp @@ -16,6 +16,7 @@ const double PLANE_SIZE = 200; SketchPlugin_Line::SketchPlugin_Line() { + setSketch(0); } void SketchPlugin_Line::initAttributes() @@ -31,17 +32,18 @@ void SketchPlugin_Line::execute() const boost::shared_ptr& SketchPlugin_Line::preview() { SketchPlugin_Sketch* aSketch = sketch(); - // compute a start point in 3D view - boost::shared_ptr aStartAttr = - boost::dynamic_pointer_cast(data()->attribute(LINE_ATTR_START)); - boost::shared_ptr aStart(aSketch->to3D(aStartAttr->x(), aStartAttr->y())); - // compute an end point in 3D view - boost::shared_ptr anEndAttr = - boost::dynamic_pointer_cast(data()->attribute(LINE_ATTR_END)); - boost::shared_ptr anEnd(aSketch->to3D(anEndAttr->x(), anEndAttr->y())); - // make linear edge - boost::shared_ptr anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd); - setPreview(anEdge); - + if (aSketch) { + // compute a start point in 3D view + boost::shared_ptr aStartAttr = + boost::dynamic_pointer_cast(data()->attribute(LINE_ATTR_START)); + boost::shared_ptr aStart(aSketch->to3D(aStartAttr->x(), aStartAttr->y())); + // compute an end point in 3D view + boost::shared_ptr anEndAttr = + boost::dynamic_pointer_cast(data()->attribute(LINE_ATTR_END)); + boost::shared_ptr anEnd(aSketch->to3D(anEndAttr->x(), anEndAttr->y())); + // make linear edge + boost::shared_ptr anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd); + setPreview(anEdge); + } return getPreview(); } diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index 20a6f721e..2613adae6 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -141,6 +141,26 @@ void XGUI_Displayer::RedisplayInLocalContext(boost::shared_ptr aContext->UpdateCurrentViewer(); } +void XGUI_Displayer::EraseAll(const bool isUpdateViewer) +{ + Handle(AIS_InteractiveContext) ic = AISContext(); + + AIS_ListOfInteractive aList; + ic->DisplayedObjects(aList); + AIS_ListIteratorOfListOfInteractive anIter(aList); + for (; anIter.More(); anIter.Next()) { + if ((anIter.Value()->DynamicType() == STANDARD_TYPE(AIS_Trihedron))) + continue; + + // erase an object + Handle(AIS_InteractiveObject) anIO = anIter.Value(); + ic->Erase(anIO, false); + } + myFeature2AISObjectMap.clear(); + if (isUpdateViewer) + ic->UpdateCurrentViewer(); +} + void XGUI_Displayer::CloseLocalContexts(const bool isUpdateViewer) { closeAllContexts(true); @@ -156,6 +176,13 @@ void XGUI_Displayer::closeAllContexts(const bool isUpdateViewer) } } +void XGUI_Displayer::UpdateViewer() +{ + Handle(AIS_InteractiveContext) ic = AISContext(); + if (!ic.IsNull()) + ic->UpdateCurrentViewer(); +} + Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const { return myWorkshop->viewer()->AISContext(); diff --git a/src/XGUI/XGUI_Displayer.h b/src/XGUI/XGUI_Displayer.h index cda9331e6..a8bfbe2f3 100644 --- a/src/XGUI/XGUI_Displayer.h +++ b/src/XGUI/XGUI_Displayer.h @@ -81,10 +81,17 @@ public: /// \param isUpdateViewer the parameter whether the viewer should be update immediatelly void Erase(boost::shared_ptr theFeature, const bool isUpdateViewer = true); + /// Erase all presentations + /// \param isUpdateViewer the parameter whether the viewer should be update immediatelly + void EraseAll(const bool isUpdateViewer = true); + /// Deactivates selection of sub-shapes /// \param isUpdateViewer the parameter whether the viewer should be update immediatelly void CloseLocalContexts(const bool isUpdateViewer = true); + /// Updates the viewer + void UpdateViewer(); + protected: /// Deactivate local selection /// \param isUpdateViewer the state wether the viewer should be updated immediatelly diff --git a/src/XGUI/XGUI_OperationMgr.cpp b/src/XGUI/XGUI_OperationMgr.cpp index 7119a8fa1..00419c692 100644 --- a/src/XGUI/XGUI_OperationMgr.cpp +++ b/src/XGUI/XGUI_OperationMgr.cpp @@ -46,6 +46,16 @@ bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation) return true; } +bool XGUI_OperationMgr::abortOperation() +{ + ModuleBase_Operation* aCurrentOp = currentOperation(); + if (!aCurrentOp || !canStopOperation()) + return false; + + aCurrentOp->abort(); + return true; +} + void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation) { connect(theOperation, SIGNAL(stopped()), this, SLOT(onOperationStopped())); @@ -60,10 +70,7 @@ bool XGUI_OperationMgr::canStartOperation(ModuleBase_Operation* theOperation) ModuleBase_Operation* aCurrentOp = currentOperation(); if (aCurrentOp && !theOperation->isGranted()) { - int anAnswer = QMessageBox::question(0, tr("Operation launch"), - tr("Previous operation is not finished and will be aborted"), - QMessageBox::Ok, QMessageBox::Cancel); - if (anAnswer == QMessageBox::Ok) { + if (canStopOperation()) { aCurrentOp->abort(); } else { aCanStart = false; @@ -72,6 +79,14 @@ bool XGUI_OperationMgr::canStartOperation(ModuleBase_Operation* theOperation) return aCanStart; } +bool XGUI_OperationMgr::canStopOperation() +{ + int anAnswer = QMessageBox::question(0, tr("Operation launch"), + tr("Previous operation is not finished and will be aborted"), + QMessageBox::Ok, QMessageBox::Cancel); + return anAnswer == QMessageBox::Ok; +} + void XGUI_OperationMgr::onOperationStopped() { ModuleBase_Operation* aSenderOperation = dynamic_cast(sender()); diff --git a/src/XGUI/XGUI_OperationMgr.h b/src/XGUI/XGUI_OperationMgr.h index fc6214d56..41323570e 100644 --- a/src/XGUI/XGUI_OperationMgr.h +++ b/src/XGUI/XGUI_OperationMgr.h @@ -43,6 +43,10 @@ public: /// \return the state whether the current operation is started bool startOperation(ModuleBase_Operation* theOperation); + /// Abort the operation and append it to the stack of operations + /// \return the state whether the current operation is aborted + bool abortOperation(); + signals: /// Signal about an operation is started. It is emitted after the start() of operation is done. void operationStarted(); @@ -62,6 +66,9 @@ protected: /// \param theOperation an operation to check bool canStartOperation(ModuleBase_Operation* theOperation); + /// Returns whether the operation can be stopped. + bool canStopOperation(); + protected slots: /// Slot that is called by an operation stop. Removes the stopped operation form the stack. /// If there is a suspended operation, restart it. diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index aeb505f9d..aa2318703 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -470,6 +470,8 @@ void XGUI_Workshop::onUndo() objectBrowser()->setCurrentIndex(QModelIndex()); boost::shared_ptr aMgr = ModelAPI_PluginManager::get(); boost::shared_ptr aDoc = aMgr->rootDocument(); + if (!operationMgr()->abortOperation()) + return; aDoc->undo(); updateCommandStatus(); } -- 2.39.2