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:
@@ -44,10 +44,18 @@
|
||||
# include <Inventor/elements/SoLineWidthElement.h>
|
||||
# include <Inventor/errors/SoDebugError.h>
|
||||
# include <Inventor/misc/SoState.h>
|
||||
# include <Inventor/nodes/SoGroup.h>
|
||||
# include <Inventor/actions/SoSearchAction.h>
|
||||
#endif
|
||||
|
||||
#include <Gui/Selection/SoFCUnifiedSelection.h>
|
||||
#include <Gui/Selection/Selection.h>
|
||||
#include <Base/Console.h>
|
||||
#include "SoBrepEdgeSet.h"
|
||||
#include "SoBrepFaceSet.h"
|
||||
#include "ViewProviderExt.h"
|
||||
|
||||
#include <Gui/Inventor/So3DAnnotation.h>
|
||||
|
||||
|
||||
using namespace PartGui;
|
||||
@@ -79,6 +87,20 @@ void SoBrepEdgeSet::GLRender(SoGLRenderAction *action)
|
||||
SelContextPtr ctx = Gui::SoFCSelectionRoot::getRenderContext<SelContext>(this,selContext,ctx2);
|
||||
if(ctx2 && ctx2->selectionIndex.empty())
|
||||
return;
|
||||
|
||||
|
||||
if (Gui::Selection()
|
||||
.isPickGeometryActive() && !Gui::SoDelayedAnnotationsElement::isProcessingDelayedPaths
|
||||
&& ((ctx && !ctx->hl.empty()) || viewProvider->isFaceHighlightActive())) {
|
||||
// if we are using pickgeometry - add this to delayed paths with priority
|
||||
// as we want to get this rendered on top of everything
|
||||
viewProvider->setFaceHighlightActive(true);
|
||||
Gui::SoDelayedAnnotationsElement::addDelayedPath(action->getState(),
|
||||
action->getCurPath()->copy(),
|
||||
200);
|
||||
return;
|
||||
}
|
||||
|
||||
if(selContext2->checkGlobal(ctx)) {
|
||||
if(selContext2->isSelectAll()) {
|
||||
selContext2->sl.clear();
|
||||
@@ -132,9 +154,23 @@ void SoBrepEdgeSet::GLRender(SoGLRenderAction *action)
|
||||
}
|
||||
if(ctx2 && !ctx2->selectionIndex.empty())
|
||||
renderSelection(action,ctx2,false);
|
||||
else
|
||||
else if (Gui::Selection().isPickGeometryActive()
|
||||
&& ((ctx && !ctx->hl.empty()) || viewProvider->isFaceHighlightActive())
|
||||
&& Gui::SoDelayedAnnotationsElement::isProcessingDelayedPaths) {
|
||||
state->push();
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDepthMask(false);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
inherited::GLRender(action);
|
||||
|
||||
state->pop();
|
||||
}
|
||||
else {
|
||||
inherited::GLRender(action);
|
||||
}
|
||||
|
||||
// Workaround for #0000433
|
||||
//#if !defined(FC_OS_WIN32)
|
||||
if(!action->isRenderingDelayedPaths())
|
||||
|
||||
@@ -36,6 +36,8 @@ class SoTextureCoordinateBundle;
|
||||
|
||||
namespace PartGui {
|
||||
|
||||
class ViewProviderPartExt;
|
||||
|
||||
class PartGuiExport SoBrepEdgeSet : public SoIndexedLineSet {
|
||||
using inherited = SoIndexedLineSet;
|
||||
|
||||
@@ -44,6 +46,8 @@ class PartGuiExport SoBrepEdgeSet : public SoIndexedLineSet {
|
||||
public:
|
||||
static void initClass();
|
||||
SoBrepEdgeSet();
|
||||
|
||||
void setViewProvider(ViewProviderPartExt* vp) { viewProvider = vp; }
|
||||
|
||||
protected:
|
||||
~SoBrepEdgeSet() override = default;
|
||||
@@ -68,11 +72,15 @@ private:
|
||||
void renderSelection(SoGLRenderAction *action, SelContextPtr, bool push=true);
|
||||
bool validIndexes(const SoCoordinateElement*, const std::vector<int32_t>&) const;
|
||||
|
||||
|
||||
private:
|
||||
SelContextPtr selContext;
|
||||
SelContextPtr selContext2;
|
||||
Gui::SoFCSelectionCounter selCounter;
|
||||
uint32_t packedColor{0};
|
||||
|
||||
// backreference to viewprovider that owns this node
|
||||
ViewProviderPartExt* viewProvider = nullptr;
|
||||
};
|
||||
|
||||
} // namespace PartGui
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -38,6 +38,8 @@ class SoTextureCoordinateBundle;
|
||||
|
||||
namespace PartGui {
|
||||
|
||||
class ViewProviderPartExt;
|
||||
|
||||
/**
|
||||
* First some words to the history and the reason why we have this class:
|
||||
* In older FreeCAD versions we had an own Inventor node for each sub-element of a shape with its own highlight node.
|
||||
@@ -79,6 +81,8 @@ class PartGuiExport SoBrepFaceSet : public SoIndexedFaceSet {
|
||||
public:
|
||||
static void initClass();
|
||||
SoBrepFaceSet();
|
||||
|
||||
void setViewProvider(ViewProviderPartExt* vp) { viewProvider = vp; }
|
||||
|
||||
SoMFInt32 partIndex;
|
||||
|
||||
@@ -154,6 +158,9 @@ private:
|
||||
// Define some VBO pointer for the current mesh
|
||||
class VBO;
|
||||
std::unique_ptr<VBO> pimpl;
|
||||
|
||||
// backreference to viewprovider that owns this node
|
||||
ViewProviderPartExt* viewProvider = nullptr;
|
||||
};
|
||||
|
||||
} // namespace PartGui
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
#endif
|
||||
|
||||
#include <Gui/Selection/SoFCUnifiedSelection.h>
|
||||
#include <Gui/Inventor/So3DAnnotation.h>
|
||||
|
||||
#include "ViewProviderExt.h"
|
||||
#include "SoBrepPointSet.h"
|
||||
|
||||
|
||||
@@ -81,6 +83,18 @@ void SoBrepPointSet::GLRender(SoGLRenderAction *action)
|
||||
return;
|
||||
if(selContext2->checkGlobal(ctx))
|
||||
ctx = selContext2;
|
||||
|
||||
// for pickgeometry, add this node to delayed path if it is highlighted and render it on
|
||||
// top of everything else (highest priority)
|
||||
if (Gui::Selection().isPickGeometryActive() && ctx && ctx->isHighlighted()
|
||||
&& !ctx->isHighlightAll() && ctx->highlightIndex >= 0
|
||||
&& !Gui::SoDelayedAnnotationsElement::isProcessingDelayedPaths) {
|
||||
viewProvider->setFaceHighlightActive(true);
|
||||
Gui::SoDelayedAnnotationsElement::addDelayedPath(action->getState(),
|
||||
action->getCurPath()->copy(),
|
||||
300);
|
||||
return;
|
||||
}
|
||||
|
||||
if(ctx && ctx->highlightIndex == std::numeric_limits<int>::max()) {
|
||||
if(ctx->selectionIndex.empty() || ctx->isSelectAll()) {
|
||||
@@ -121,8 +135,15 @@ void SoBrepPointSet::GLRender(SoGLRenderAction *action)
|
||||
}
|
||||
if(ctx2 && !ctx2->selectionIndex.empty())
|
||||
renderSelection(action,ctx2,false);
|
||||
else
|
||||
else if (Gui::SoDelayedAnnotationsElement::isProcessingDelayedPaths) {
|
||||
glPushAttrib(GL_DEPTH_BUFFER_BIT);
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
inherited::GLRender(action);
|
||||
glPopAttrib();
|
||||
}
|
||||
else {
|
||||
inherited::GLRender(action);
|
||||
}
|
||||
|
||||
// Workaround for #0000433
|
||||
//#if !defined(FC_OS_WIN32)
|
||||
|
||||
@@ -36,6 +36,8 @@ class SoTextureCoordinateBundle;
|
||||
|
||||
namespace PartGui {
|
||||
|
||||
class ViewProviderPartExt;
|
||||
|
||||
class PartGuiExport SoBrepPointSet : public SoPointSet {
|
||||
using inherited = SoPointSet;
|
||||
|
||||
@@ -44,6 +46,8 @@ class PartGuiExport SoBrepPointSet : public SoPointSet {
|
||||
public:
|
||||
static void initClass();
|
||||
SoBrepPointSet();
|
||||
|
||||
void setViewProvider(ViewProviderPartExt* vp) { viewProvider = vp; }
|
||||
|
||||
protected:
|
||||
~SoBrepPointSet() override = default;
|
||||
@@ -64,6 +68,9 @@ private:
|
||||
SelContextPtr selContext2;
|
||||
Gui::SoFCSelectionCounter selCounter;
|
||||
uint32_t packedColor{0};
|
||||
|
||||
// backreference to viewprovider that owns this node
|
||||
ViewProviderPartExt* viewProvider = nullptr;
|
||||
};
|
||||
|
||||
} // namespace PartGui
|
||||
|
||||
@@ -191,6 +191,7 @@ ViewProviderPartExt::ViewProviderPartExt()
|
||||
coords = new SoCoordinate3();
|
||||
coords->ref();
|
||||
faceset = new SoBrepFaceSet();
|
||||
faceset->setViewProvider(this);
|
||||
faceset->ref();
|
||||
norm = new SoNormal;
|
||||
norm->ref();
|
||||
@@ -198,8 +199,10 @@ ViewProviderPartExt::ViewProviderPartExt()
|
||||
normb->value = SoNormalBinding::PER_VERTEX_INDEXED;
|
||||
normb->ref();
|
||||
lineset = new SoBrepEdgeSet();
|
||||
lineset->setViewProvider(this);
|
||||
lineset->ref();
|
||||
nodeset = new SoBrepPointSet();
|
||||
nodeset->setViewProvider(this);
|
||||
nodeset->ref();
|
||||
|
||||
pcFaceBind = new SoMaterialBinding();
|
||||
@@ -447,9 +450,9 @@ void ViewProviderPartExt::attach(App::DocumentObject *pcFeat)
|
||||
|
||||
// normal viewing with edges and points
|
||||
pcNormalRoot->addChild(pcPointsRoot);
|
||||
pcNormalRoot->addChild(wireframe);
|
||||
pcNormalRoot->addChild(offset);
|
||||
pcNormalRoot->addChild(pcFlatRoot);
|
||||
pcNormalRoot->addChild(wireframe);
|
||||
|
||||
// just faces with no edges or points
|
||||
pcFlatRoot->addChild(pShapeHints);
|
||||
|
||||
@@ -156,6 +156,9 @@ public:
|
||||
|
||||
bool allowOverride(const App::DocumentObject &) const override;
|
||||
|
||||
void setFaceHighlightActive(bool active) { faceHighlightActive = active; }
|
||||
bool isFaceHighlightActive() const { return faceHighlightActive; }
|
||||
|
||||
/** @name Edit methods */
|
||||
//@{
|
||||
void setupContextMenu(QMenu*, QObject*, const char*) override;
|
||||
@@ -213,6 +216,7 @@ protected:
|
||||
|
||||
bool VisualTouched;
|
||||
bool NormalsFromUV;
|
||||
bool faceHighlightActive = false;
|
||||
|
||||
private:
|
||||
Gui::ViewProviderFaceTexture texture;
|
||||
|
||||
Reference in New Issue
Block a user