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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user