write custom action class to notify shape node about vbo changes

This commit is contained in:
wmayer 2017-02-11 16:16:26 +01:00
parent 56ff88ea46
commit 8612c4f99f
6 changed files with 134 additions and 40 deletions

View File

@ -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();

View File

@ -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:

View File

@ -27,8 +27,8 @@
//#include <Inventor/SoAction.h>
#include <Inventor/actions/SoSubAction.h>
#include <Inventor/events/SoSubEvent.h>
#include <Inventor/actions/SoGLRenderAction.h>
#include <Inventor/SbColor.h>
#include <Inventor/actions/SoGLRenderAction.h>
#include <Inventor/SbColor.h>
#include <vector>
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

View File

@ -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);
}

View File

@ -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;

View File

@ -106,6 +106,7 @@
#include <App/Document.h>
#include <Gui/SoFCUnifiedSelection.h>
#include <Gui/SoFCSelectionAction.h>
#include <Gui/Selection.h>
#include <Gui/View3DInventorViewer.h>
#include <Gui/Utilities.h>
@ -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<const Part::PropertyPartShape*>(prop)->getValue();