Core/Gui: Render primitives on top of the scene in PickGeometry

+ added some better grouping for items, which are assigned per object
  right now. For example, if we exceed 10 items per object it gets an
  additional group.

Co-authored-by: realthunder <realthunder@users.noreply.github.com>
This commit is contained in:
tetektoza
2025-06-25 11:28:25 +02:00
parent 5e0b74dce6
commit edfeff975e
17 changed files with 614 additions and 91 deletions

View File

@@ -73,8 +73,12 @@
#include <Gui/SoFCInteractiveElement.h>
#include <Gui/Selection/SoFCSelectionAction.h>
#include <Gui/Selection/SoFCUnifiedSelection.h>
#include <Gui/Inventor/So3DAnnotation.h>
#include "SoBrepFaceSet.h"
#include "ViewProviderExt.h"
#include "SoBrepEdgeSet.h"
using namespace PartGui;
@@ -188,6 +192,9 @@ void SoBrepFaceSet::doAction(SoAction* action)
ctx->highlightIndex = -1;
touch();
}
if (viewProvider) {
viewProvider->setFaceHighlightActive(false);
}
return;
}
@@ -204,6 +211,9 @@ void SoBrepFaceSet::doAction(SoAction* action)
ctx->highlightIndex = -1;
touch();
}
if (viewProvider) {
viewProvider->setFaceHighlightActive(false);
}
}else {
int index = static_cast<const SoFaceDetail*>(detail)->getPartIndex();
SelContextPtr ctx = Gui::SoFCSelectionRoot::getActionContext(action,this,selContext);
@@ -521,6 +531,40 @@ void SoBrepFaceSet::GLRender(SoGLRenderAction *action)
auto state = action->getState();
selCounter.checkRenderCache(state);
// for the tool add this node to delayed paths as we want to render it on top of the scene
if (Gui::Selection().isPickGeometryActive() && ctx && ctx->isHighlighted()
&& !ctx->isHighlightAll() && ctx->highlightIndex >= 0
&& ctx->highlightIndex < partIndex.getNum()) {
if (!Gui::SoDelayedAnnotationsElement::isProcessingDelayedPaths) {
if (viewProvider) {
viewProvider->setFaceHighlightActive(true);
}
const SoPath* currentPath = action->getCurPath();
Gui::SoDelayedAnnotationsElement::addDelayedPath(action->getState(),
currentPath->copy(),
100);
return;
} else {
// during priority delayed paths processing:
// render base faces normally first, then render highlight on top
inherited::GLRender(action);
state->push();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(false);
glDisable(GL_DEPTH_TEST);
renderHighlight(action, ctx);
state->pop();
return;
}
}
// override material binding to PER_PART_INDEX to achieve
// preselection/selection with transparency
@@ -730,7 +774,7 @@ bool SoBrepFaceSet::overrideMaterialBinding(SoGLRenderAction *action, SelContext
singleColor = ctx?-1:1;
}
bool partialRender = ctx2 && !ctx2->isSelectAll();
bool partialRender = (ctx2 && !ctx2->isSelectAll());
if(singleColor>0 && !partialRender) {
//optimization for single color non-partial rendering
@@ -772,7 +816,8 @@ bool SoBrepFaceSet::overrideMaterialBinding(SoGLRenderAction *action, SelContext
packedColors.push_back(ctx->highlightColor.getPackedValue(trans0));
matIndex[ctx->highlightIndex] = packedColors.size()-1;
}
}else{
}
else{
if(partialRender) {
packedColors.push_back(SbColor(1.0,1.0,1.0).getPackedValue(1.0));
matIndex.resize(partIndex.getNum(),0);
@@ -848,7 +893,7 @@ bool SoBrepFaceSet::overrideMaterialBinding(SoGLRenderAction *action, SelContext
SoLazyElement::setPacked(state, this, packedColors.size(), packedColors.data(), hasTransparency);
SoTextureEnabledElement::set(state,this,false);
if(hasTransparency && action->isRenderingDelayedPaths()) {
if (hasTransparency && action->isRenderingDelayedPaths()) {
// rendering delayed paths means we are doing annotation (e.g.
// always on top rendering). To render transparency correctly in
// this case, we shall use openGL transparency blend. Override