Gui: refactor bounding box selection style

Previously, box style selection is rendered using customized
SoBoxSelectionRenderAction, which does not support selection context,
i.e. it does not work with Link.

This patch implements context aware bound box rendering inside
SoFCSelectionRoot, SoFCSelection and SoFCPathAnnotation (for always on
top rendering). The box rendering in SoBoxSelectionRenderAction is
disabled on construction. Box style selection can be enabled for
individual object through property SelectionStyle (moved from
ViewProviderGeometryObject to ViewProviderDocumentObject), or globally
through Parameter BaseApp/Preferences/View/ShowSelectionBoundingBox.

In addition, the parameter BaseApp/Preferences/View/UseNewSelection is
used to override selection model reported from
ViewProvider::useNewSelectionModel(). The reason being that, the same
parameter is already used to toggle selection model inside
SoFCSelection. This avoids inconsistency of selection model choice
between view provider and the SoFCSelection node inside. Note that if
the parameter 'UseNewSelection' is set to false, those view providers
that choose old selection model will not work with Link.
This commit is contained in:
Zheng, Lei
2019-09-17 20:42:39 +08:00
committed by wwmayer
parent a0adbd5e2b
commit 45fd865fc0
20 changed files with 488 additions and 262 deletions

View File

@@ -27,6 +27,9 @@
# include <qstring.h>
# include <Inventor/details/SoFaceDetail.h>
# include <Inventor/details/SoLineDetail.h>
# include <Inventor/nodes/SoCube.h>
# include <Inventor/actions/SoGetBoundingBoxAction.h>
# include <Inventor/nodes/SoCube.h>
#endif
#include <Inventor/elements/SoOverrideElement.h>
@@ -686,10 +689,11 @@ SoFCSelection::GLRenderBelowPath(SoGLRenderAction * action)
#ifdef NO_FRONTBUFFER
// check if preselection is active
state->push();
this->setOverride(action,ctx);
inherited::GLRenderBelowPath(action);
state->pop();
if(this->setOverride(action,ctx)) {
inherited::GLRenderBelowPath(action);
state->pop();
} else
inherited::GLRenderBelowPath(action);
#else
// Set up state for locate highlighting (if necessary)
GLint oldDepthFunc;
@@ -726,10 +730,11 @@ void SoFCSelection::GLRender(SoGLRenderAction * action)
#ifdef NO_FRONTBUFFER
// check if preselection is active
state->push();
this->setOverride(action,ctx);
inherited::GLRender(action);
state->pop();
if(this->setOverride(action,ctx)) {
inherited::GLRender(action);
state->pop();
} else
inherited::GLRender(action);
#else
// Set up state for locate highlighting (if necessary)
GLint oldDepthFunc;
@@ -767,10 +772,11 @@ SoFCSelection::GLRenderInPath(SoGLRenderAction * action)
#ifdef NO_FRONTBUFFER
// check if preselection is active
SoState * state = action->getState();
state->push();
this->setOverride(action,ctx);
inherited::GLRenderInPath(action);
state->pop();
if(this->setOverride(action,ctx)) {
inherited::GLRenderInPath(action);
state->pop();
} else
inherited::GLRenderInPath(action);
#else
// Set up state for locate highlighting (if necessary)
GLint oldDepthFunc;
@@ -948,13 +954,13 @@ SoFCSelection::readInstance ( SoInput * in, unsigned short flags )
//
// update override state before rendering
//
void
bool
SoFCSelection::setOverride(SoGLRenderAction * action, SelContextPtr ctx)
{
HighlightModes mymode = (HighlightModes) this->highlightMode.getValue();
bool preselected = ctx && ctx->isHighlighted() && (useNewSelection.getValue()||mymode == AUTO);
if (!preselected && mymode!=ON && (!ctx || !ctx->isSelected()))
return;
return false;
// uniqueId is returned by SoNode::getNodeId(). It is used to notify change
// and for render cache update. In order to update cache on selection state
@@ -963,10 +969,21 @@ SoFCSelection::setOverride(SoGLRenderAction * action, SelContextPtr ctx)
auto oldId = this->uniqueId;
this->uniqueId ^= std::hash<void*>()(ctx.get()) + 0x9e3779b9 + (oldId << 6) + (oldId >> 2);
Styles mystyle = (Styles) this->style.getValue();
if(mystyle == SoFCSelection::BOX) {
SoFCSelectionRoot::renderBBox(
action,this,preselected?ctx->highlightColor:ctx->selectionColor);
this->uniqueId = oldId;
return false;
}
//Base::Console().Log("SoFCSelection::setOverride() (%p)\n",this);
SoState * state = action->getState();
state->push();
SoMaterialBindingElement::set(state,SoMaterialBindingElement::OVERALL);
SoOverrideElement::setMaterialBindingOverride(state,this,true);
if(!preselected)
SoLazyElement::setEmissive(state, &ctx->selectionColor);
@@ -974,8 +991,7 @@ SoFCSelection::setOverride(SoGLRenderAction * action, SelContextPtr ctx)
SoLazyElement::setEmissive(state, &ctx->highlightColor);
SoOverrideElement::setEmissiveColorOverride(state, this, true);
Styles mystyle = (Styles) this->style.getValue();
if (mystyle == SoFCSelection::EMISSIVE_DIFFUSE) {
if(mystyle == SoFCSelection::EMISSIVE_DIFFUSE) {
if(!preselected)
SoLazyElement::setDiffuse(state, this,1, &ctx->selectionColor,&colorpacker);
else
@@ -984,6 +1000,7 @@ SoFCSelection::setOverride(SoGLRenderAction * action, SelContextPtr ctx)
}
this->uniqueId = oldId;
return true;
}
// private convenience method