From 8612c4f99f3d91bac764f17694a1cbd4989ab1c1 Mon Sep 17 00:00:00 2001 From: wmayer Date: Sat, 11 Feb 2017 16:16:26 +0100 Subject: [PATCH] write custom action class to notify shape node about vbo changes --- src/Gui/SoFCDB.cpp | 2 + src/Gui/SoFCSelectionAction.cpp | 65 +++++++++++++++++++ src/Gui/SoFCSelectionAction.h | 94 +++++++++++++++++----------- src/Mod/Part/Gui/SoBrepFaceSet.cpp | 6 ++ src/Mod/Part/Gui/SoBrepFaceSet.h | 2 - src/Mod/Part/Gui/ViewProviderExt.cpp | 5 +- 6 files changed, 134 insertions(+), 40 deletions(-) diff --git a/src/Gui/SoFCDB.cpp b/src/Gui/SoFCDB.cpp index 3df835c0b..bf0db3a26 100644 --- a/src/Gui/SoFCDB.cpp +++ b/src/Gui/SoFCDB.cpp @@ -98,6 +98,7 @@ void Gui::SoFCDB::init() SoFCDocumentObjectAction ::initClass(); SoGLSelectAction ::initClass(); SoVisibleFaceAction ::initClass(); + SoUpdateVBOAction ::initClass(); SoBoxSelectionRenderAction ::initClass(); SoFCVectorizeSVGAction ::initClass(); SoFCVectorizeU3DAction ::initClass(); @@ -189,6 +190,7 @@ void Gui::SoFCDB::finish() SoFCEnableSelectionAction ::finish(); SoFCEnableHighlightAction ::finish(); SoFCSelectionColorAction ::finish(); + SoUpdateVBOAction ::finish(); SoFCHighlightColorAction ::finish(); storage->unref(); diff --git a/src/Gui/SoFCSelectionAction.cpp b/src/Gui/SoFCSelectionAction.cpp index 967a3adad..da0a879f2 100644 --- a/src/Gui/SoFCSelectionAction.cpp +++ b/src/Gui/SoFCSelectionAction.cpp @@ -821,6 +821,71 @@ SbBool SoVisibleFaceAction::isHandled() const // --------------------------------------------------------------- + +SO_ACTION_SOURCE(SoUpdateVBOAction); + +/** + * The order of the defined SO_ACTION_ADD_METHOD statements is very important. First the base + * classes and afterwards subclasses of them must be listed, otherwise the registered methods + * of subclasses will be overridden. For more details see the thread in the Coin3d forum + * https://www.coin3d.org/pipermail/coin-discuss/2004-May/004346.html. + * This means that \c SoSwitch must be listed after \c SoGroup and \c SoFCSelection after + * \c SoSeparator because both classes inherits the others. + */ +void SoUpdateVBOAction::initClass() +{ + SO_ACTION_INIT_CLASS(SoUpdateVBOAction,SoAction); + + SO_ENABLE(SoUpdateVBOAction, SoSwitchElement); + + SO_ACTION_ADD_METHOD(SoNode,nullAction); + + SO_ENABLE(SoUpdateVBOAction, SoModelMatrixElement); + SO_ENABLE(SoUpdateVBOAction, SoProjectionMatrixElement); + SO_ENABLE(SoUpdateVBOAction, SoCoordinateElement); + SO_ENABLE(SoUpdateVBOAction, SoViewVolumeElement); + SO_ENABLE(SoUpdateVBOAction, SoViewingMatrixElement); + SO_ENABLE(SoUpdateVBOAction, SoViewportRegionElement); + + + SO_ACTION_ADD_METHOD(SoCamera,callDoAction); + SO_ACTION_ADD_METHOD(SoCoordinate3,callDoAction); + SO_ACTION_ADD_METHOD(SoCoordinate4,callDoAction); + SO_ACTION_ADD_METHOD(SoGroup,callDoAction); + SO_ACTION_ADD_METHOD(SoSwitch,callDoAction); + SO_ACTION_ADD_METHOD(SoShape,callDoAction); + SO_ACTION_ADD_METHOD(SoIndexedFaceSet,callDoAction); + + SO_ACTION_ADD_METHOD(SoSeparator,callDoAction); + SO_ACTION_ADD_METHOD(SoFCSelection,callDoAction); +} + +SoUpdateVBOAction::SoUpdateVBOAction () +{ + SO_ACTION_CONSTRUCTOR(SoUpdateVBOAction); +} + +SoUpdateVBOAction::~SoUpdateVBOAction() +{ +} + +void SoUpdateVBOAction::finish() +{ + atexit_cleanup(); +} + +void SoUpdateVBOAction::beginTraversal(SoNode *node) +{ + traverse(node); +} + +void SoUpdateVBOAction::callDoAction(SoAction *action,SoNode *node) +{ + node->doAction(action); +} + +// --------------------------------------------------------------- + namespace Gui { class SoBoxSelectionRenderActionP { public: diff --git a/src/Gui/SoFCSelectionAction.h b/src/Gui/SoFCSelectionAction.h index 37ab54a21..78b965bda 100644 --- a/src/Gui/SoFCSelectionAction.h +++ b/src/Gui/SoFCSelectionAction.h @@ -27,8 +27,8 @@ //#include #include #include -#include -#include +#include +#include #include class SoSFString; @@ -280,45 +280,67 @@ private: private: SbBool _handled; }; - -class SoBoxSelectionRenderActionP; + +class SoBoxSelectionRenderActionP; /** * The SoBoxSelectionRenderAction class renders the scene with highlighted boxes around selections. * @author Werner Mayer */ -class GuiExport SoBoxSelectionRenderAction : public SoGLRenderAction { - typedef SoGLRenderAction inherited; - - SO_ACTION_HEADER(SoBoxSelectionRenderAction); - -public: - SoBoxSelectionRenderAction(void); - SoBoxSelectionRenderAction(const SbViewportRegion & viewportregion); - virtual ~SoBoxSelectionRenderAction(); - - static void initClass(void); - - virtual void apply(SoNode * node); - virtual void apply(SoPath * path); +class GuiExport SoBoxSelectionRenderAction : public SoGLRenderAction { + typedef SoGLRenderAction inherited; + + SO_ACTION_HEADER(SoBoxSelectionRenderAction); + +public: + SoBoxSelectionRenderAction(void); + SoBoxSelectionRenderAction(const SbViewportRegion & viewportregion); + virtual ~SoBoxSelectionRenderAction(); + + static void initClass(void); + + virtual void apply(SoNode * node); + virtual void apply(SoPath * path); virtual void apply(const SoPathList & pathlist, SbBool obeysrules = false); - void setVisible(SbBool b) { hlVisible = b; } - SbBool isVisible() const { return hlVisible; } - void setColor(const SbColor & color); - const SbColor & getColor(void); - void setLinePattern(unsigned short pattern); - unsigned short getLinePattern(void) const; - void setLineWidth(const float width); - float getLineWidth(void) const; - -protected: - SbBool hlVisible; - -private: - void constructorCommon(void); - void drawBoxes(SoPath * pathtothis, const SoPathList * pathlist); - - SoBoxSelectionRenderActionP * pimpl; -}; + void setVisible(SbBool b) { hlVisible = b; } + SbBool isVisible() const { return hlVisible; } + void setColor(const SbColor & color); + const SbColor & getColor(void); + void setLinePattern(unsigned short pattern); + unsigned short getLinePattern(void) const; + void setLineWidth(const float width); + float getLineWidth(void) const; + +protected: + SbBool hlVisible; + +private: + void constructorCommon(void); + void drawBoxes(SoPath * pathtothis, const SoPathList * pathlist); + + SoBoxSelectionRenderActionP * pimpl; +}; + +/** + * Helper class no notify nodes to update VBO. + * @author Werner Mayer + */ +class GuiExport SoUpdateVBOAction : public SoAction +{ + SO_ACTION_HEADER(SoUpdateVBOAction); + +public: + SoUpdateVBOAction (); + ~SoUpdateVBOAction(); + + static void initClass(); + static void finish(void); + +protected: + virtual void beginTraversal(SoNode *node); + +private: + static void callDoAction(SoAction *action,SoNode *node); +}; } // namespace Gui diff --git a/src/Mod/Part/Gui/SoBrepFaceSet.cpp b/src/Mod/Part/Gui/SoBrepFaceSet.cpp index dcdf15a4d..ed4e59a5d 100644 --- a/src/Mod/Part/Gui/SoBrepFaceSet.cpp +++ b/src/Mod/Part/Gui/SoBrepFaceSet.cpp @@ -247,6 +247,12 @@ void SoBrepFaceSet::doAction(SoAction* action) } } } + // The recommended way to set 'updateVbo' is to reimplement the method 'notify' + // but the class made this method private so that we can't override it. + // So, the alternative way is to write a custom SoAction class. + else if (action->getTypeId() == Gui::SoUpdateVBOAction::getClassTypeId()) { + this->updateVbo = true; + } inherited::doAction(action); } diff --git a/src/Mod/Part/Gui/SoBrepFaceSet.h b/src/Mod/Part/Gui/SoBrepFaceSet.h index abfd13969..a8542a2bd 100644 --- a/src/Mod/Part/Gui/SoBrepFaceSet.h +++ b/src/Mod/Part/Gui/SoBrepFaceSet.h @@ -143,9 +143,7 @@ private: // Define some VBO pointer for the current mesh SbBool vboAvailable; -public: SbBool updateVbo; -private: uint32_t myvbo[2]; SbBool vboLoaded; uint32_t indice_array; diff --git a/src/Mod/Part/Gui/ViewProviderExt.cpp b/src/Mod/Part/Gui/ViewProviderExt.cpp index fde56ebd8..b7c814427 100644 --- a/src/Mod/Part/Gui/ViewProviderExt.cpp +++ b/src/Mod/Part/Gui/ViewProviderExt.cpp @@ -106,6 +106,7 @@ #include #include +#include #include #include #include @@ -800,8 +801,8 @@ void ViewProviderPartExt::reload() void ViewProviderPartExt::updateData(const App::Property* prop) { if (prop->getTypeId() == Part::PropertyPartShape::getClassTypeId()) { - // vejmarie: Force VBO update of the part - this->faceset->updateVbo = true; + Gui::SoUpdateVBOAction action; + action.apply(this->faceset); // get the shape to show const TopoDS_Shape &cShape = static_cast(prop)->getValue();