Merge pull request #26703 from tetektoza/fix/25840_draw_parts_of_constraints_ontop_of_others

Gui: Render constraint text, arrowheads and constraint icons above geometry lines
This commit is contained in:
Kacper Donat
2026-01-07 05:39:05 +01:00
committed by GitHub
2 changed files with 118 additions and 84 deletions

View File

@@ -57,6 +57,10 @@
// NOLINTBEGIN(readability-magic-numbers,cppcoreguidelines-pro-bounds-pointer-arithmetic)
constexpr const float ZCONSTR {0.006F};
// Z offset for arrowheads and text to render them ON TOP of geometry lines.
// Geometry lines are at Z ~0.005-0.008, so this offset ensures arrowheads
// and text selection primitives are above them and remain selectable.
constexpr const float ZARROW_TEXT_OFFSET {0.010F};
using namespace Gui;
@@ -117,9 +121,11 @@ void glDrawArrow(const SbVec3f& base, const SbVec3f& dir, float width, float len
SbVec3f arrowLeft = base - length * dir + width * normal;
SbVec3f arrowRight = base - length * dir - width * normal;
// Draw arrowheads
// Draw arrowheads at elevated Z to render ON TOP of geometry lines
glBegin(GL_TRIANGLES);
glVertexes({base, arrowLeft, arrowRight});
glVertex3f(base[0], base[1], ZARROW_TEXT_OFFSET);
glVertex3f(arrowLeft[0], arrowLeft[1], ZARROW_TEXT_OFFSET);
glVertex3f(arrowRight[0], arrowRight[1], ZARROW_TEXT_OFFSET);
glEnd();
}
@@ -701,19 +707,19 @@ void SoDatumLabel::generateDistancePrimitives(SoAction* action, const SbVec3f& p
DistanceGeometry geom = calculateDistanceGeometry(points);
// generate selectable primitive for txt label
SbVec3f img1 = SbVec3f(-this->imgWidth / 2, -this->imgHeight / 2, 0.F);
SbVec3f img2 = SbVec3f(-this->imgWidth / 2, this->imgHeight / 2, 0.F);
SbVec3f img3 = SbVec3f(this->imgWidth / 2, -this->imgHeight / 2, 0.F);
SbVec3f img4 = SbVec3f(this->imgWidth / 2, this->imgHeight / 2, 0.F);
// generate selectable primitive for txt label at elevated Z for selection above geometry
SbVec3f img1 = SbVec3f(-this->imgWidth / 2, -this->imgHeight / 2, ZARROW_TEXT_OFFSET);
SbVec3f img2 = SbVec3f(-this->imgWidth / 2, this->imgHeight / 2, ZARROW_TEXT_OFFSET);
SbVec3f img3 = SbVec3f(this->imgWidth / 2, -this->imgHeight / 2, ZARROW_TEXT_OFFSET);
SbVec3f img4 = SbVec3f(this->imgWidth / 2, this->imgHeight / 2, ZARROW_TEXT_OFFSET);
float s = sin(geom.angle);
float c = cos(geom.angle);
img1 = SbVec3f((img1[0] * c) - (img1[1] * s), (img1[0] * s) + (img1[1] * c), 0.F);
img2 = SbVec3f((img2[0] * c) - (img2[1] * s), (img2[0] * s) + (img2[1] * c), 0.F);
img3 = SbVec3f((img3[0] * c) - (img3[1] * s), (img3[0] * s) + (img3[1] * c), 0.F);
img4 = SbVec3f((img4[0] * c) - (img4[1] * s), (img4[0] * s) + (img4[1] * c), 0.F);
img1 = SbVec3f((img1[0] * c) - (img1[1] * s), (img1[0] * s) + (img1[1] * c), ZARROW_TEXT_OFFSET);
img2 = SbVec3f((img2[0] * c) - (img2[1] * s), (img2[0] * s) + (img2[1] * c), ZARROW_TEXT_OFFSET);
img3 = SbVec3f((img3[0] * c) - (img3[1] * s), (img3[0] * s) + (img3[1] * c), ZARROW_TEXT_OFFSET);
img4 = SbVec3f((img4[0] * c) - (img4[1] * s), (img4[0] * s) + (img4[1] * c), ZARROW_TEXT_OFFSET);
img1 += geom.textOffset;
img2 += geom.textOffset;
@@ -746,24 +752,24 @@ void SoDatumLabel::generateDistancePrimitives(SoAction* action, const SbVec3f& p
generateLineSelectionPrimitive(action, geom.par1, geom.par2, lineWidth);
generateLineSelectionPrimitive(action, geom.par3, geom.par4, lineWidth);
// begin generation of selectable primitives for arrow-heads
// begin generation of selectable primitives for arrow-heads at elevated Z
this->beginShape(action, TRIANGLES);
pv.setNormal(SbVec3f(0.F, 0.F, 1.F));
// 1st arrow-head
pv.setPoint(geom.par1);
pv.setPoint(SbVec3f(geom.par1[0], geom.par1[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
pv.setPoint(geom.ar1);
pv.setPoint(SbVec3f(geom.ar1[0], geom.ar1[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
pv.setPoint(geom.ar2);
pv.setPoint(SbVec3f(geom.ar2[0], geom.ar2[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
// 2nd arrow-head
pv.setPoint(geom.par4);
pv.setPoint(SbVec3f(geom.par4[0], geom.par4[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
pv.setPoint(geom.ar3);
pv.setPoint(SbVec3f(geom.ar3[0], geom.ar3[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
pv.setPoint(geom.ar4);
pv.setPoint(SbVec3f(geom.ar4[0], geom.ar4[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
this->endShape();
@@ -774,19 +780,19 @@ void SoDatumLabel::generateDiameterPrimitives(SoAction* action, const SbVec3f& p
SbVec3f points[2] = {p1, p2};
DiameterGeometry geom = calculateDiameterGeometry(points);
// generate selectable primitive for text label
SbVec3f img1 = SbVec3f(-this->imgWidth / 2, -this->imgHeight / 2, 0.F);
SbVec3f img2 = SbVec3f(-this->imgWidth / 2, this->imgHeight / 2, 0.F);
SbVec3f img3 = SbVec3f(this->imgWidth / 2, -this->imgHeight / 2, 0.F);
SbVec3f img4 = SbVec3f(this->imgWidth / 2, this->imgHeight / 2, 0.F);
// generate selectable primitive for text label at elevated Z for selection above geometry
SbVec3f img1 = SbVec3f(-this->imgWidth / 2, -this->imgHeight / 2, ZARROW_TEXT_OFFSET);
SbVec3f img2 = SbVec3f(-this->imgWidth / 2, this->imgHeight / 2, ZARROW_TEXT_OFFSET);
SbVec3f img3 = SbVec3f(this->imgWidth / 2, -this->imgHeight / 2, ZARROW_TEXT_OFFSET);
SbVec3f img4 = SbVec3f(this->imgWidth / 2, this->imgHeight / 2, ZARROW_TEXT_OFFSET);
float s = sin(geom.angle);
float c = cos(geom.angle);
img1 = SbVec3f((img1[0] * c) - (img1[1] * s), (img1[0] * s) + (img1[1] * c), 0.F);
img2 = SbVec3f((img2[0] * c) - (img2[1] * s), (img2[0] * s) + (img2[1] * c), 0.F);
img3 = SbVec3f((img3[0] * c) - (img3[1] * s), (img3[0] * s) + (img3[1] * c), 0.F);
img4 = SbVec3f((img4[0] * c) - (img4[1] * s), (img4[0] * s) + (img4[1] * c), 0.F);
img1 = SbVec3f((img1[0] * c) - (img1[1] * s), (img1[0] * s) + (img1[1] * c), ZARROW_TEXT_OFFSET);
img2 = SbVec3f((img2[0] * c) - (img2[1] * s), (img2[0] * s) + (img2[1] * c), ZARROW_TEXT_OFFSET);
img3 = SbVec3f((img3[0] * c) - (img3[1] * s), (img3[0] * s) + (img3[1] * c), ZARROW_TEXT_OFFSET);
img4 = SbVec3f((img4[0] * c) - (img4[1] * s), (img4[0] * s) + (img4[1] * c), ZARROW_TEXT_OFFSET);
img1 += geom.textOffset;
img2 += geom.textOffset;
@@ -815,25 +821,25 @@ void SoDatumLabel::generateDiameterPrimitives(SoAction* action, const SbVec3f& p
generateLineSelectionPrimitive(action, geom.p1, geom.pnt1, lineWidth);
generateLineSelectionPrimitive(action, geom.pnt2, geom.p2, lineWidth);
// Generate selectable primitives for arrow heads
// Generate selectable primitives for arrow heads at elevated Z
this->beginShape(action, TRIANGLES);
pv.setNormal(SbVec3f(0.F, 0.F, 1.F));
// first arrow-head
pv.setPoint(geom.ar0);
pv.setPoint(SbVec3f(geom.ar0[0], geom.ar0[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
pv.setPoint(geom.ar1);
pv.setPoint(SbVec3f(geom.ar1[0], geom.ar1[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
pv.setPoint(geom.ar2);
pv.setPoint(SbVec3f(geom.ar2[0], geom.ar2[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
// second arrow-head but only for diameter
if (geom.isDiameter) {
pv.setPoint(geom.ar0_1);
pv.setPoint(SbVec3f(geom.ar0_1[0], geom.ar0_1[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
pv.setPoint(geom.ar1_1);
pv.setPoint(SbVec3f(geom.ar1_1[0], geom.ar1_1[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
pv.setPoint(geom.ar2_1);
pv.setPoint(SbVec3f(geom.ar2_1[0], geom.ar2_1[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
}
@@ -867,11 +873,11 @@ void SoDatumLabel::generateAnglePrimitives(SoAction* action, const SbVec3f& p0)
SbVec3f points[1] = {p0};
AngleGeometry geom = calculateAngleGeometry(points);
// generate selectable primitive for text label
SbVec3f img1 = SbVec3f(-this->imgWidth / 2, -this->imgHeight / 2, 0.F);
SbVec3f img2 = SbVec3f(-this->imgWidth / 2, this->imgHeight / 2, 0.F);
SbVec3f img3 = SbVec3f(this->imgWidth / 2, -this->imgHeight / 2, 0.F);
SbVec3f img4 = SbVec3f(this->imgWidth / 2, this->imgHeight / 2, 0.F);
// generate selectable primitive for text label at elevated Z for selection above geometry
SbVec3f img1 = SbVec3f(-this->imgWidth / 2, -this->imgHeight / 2, ZARROW_TEXT_OFFSET);
SbVec3f img2 = SbVec3f(-this->imgWidth / 2, this->imgHeight / 2, ZARROW_TEXT_OFFSET);
SbVec3f img3 = SbVec3f(this->imgWidth / 2, -this->imgHeight / 2, ZARROW_TEXT_OFFSET);
SbVec3f img4 = SbVec3f(this->imgWidth / 2, this->imgHeight / 2, ZARROW_TEXT_OFFSET);
img1 += geom.textOffset;
img2 += geom.textOffset;
@@ -953,26 +959,26 @@ void SoDatumLabel::generateSymmetricPrimitives(SoAction* action, const SbVec3f&
generateLineSelectionPrimitive(action, geom.p1, geom.ar0, lineWidth);
generateLineSelectionPrimitive(action, geom.p2, geom.ar3, lineWidth);
// generate selectable primitives for arrow heads as triangles
// generate selectable primitives for arrow heads as triangles at elevated Z
SoPrimitiveVertex pv;
pv.setNormal(SbVec3f(0.F, 0.F, 1.F));
this->beginShape(action, TRIANGLES);
// first arrow
pv.setPoint(geom.ar0);
pv.setPoint(SbVec3f(geom.ar0[0], geom.ar0[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
pv.setPoint(geom.ar1);
pv.setPoint(SbVec3f(geom.ar1[0], geom.ar1[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
pv.setPoint(geom.ar2);
pv.setPoint(SbVec3f(geom.ar2[0], geom.ar2[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
// second arrow
pv.setPoint(geom.ar3);
pv.setPoint(SbVec3f(geom.ar3[0], geom.ar3[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
pv.setPoint(geom.ar4);
pv.setPoint(SbVec3f(geom.ar4[0], geom.ar4[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
pv.setPoint(geom.ar5);
pv.setPoint(SbVec3f(geom.ar5[0], geom.ar5[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
this->endShape();
@@ -989,19 +995,19 @@ void SoDatumLabel::generateArcLengthPrimitives(
SbVec3f points[3] = {ctr, p1, p2};
ArcLengthGeometry geom = calculateArcLengthGeometry(points);
// generate selectable primitive for text label
SbVec3f img1 = SbVec3f(-this->imgWidth / 2, -this->imgHeight / 2, 0.F);
SbVec3f img2 = SbVec3f(-this->imgWidth / 2, this->imgHeight / 2, 0.F);
SbVec3f img3 = SbVec3f(this->imgWidth / 2, -this->imgHeight / 2, 0.F);
SbVec3f img4 = SbVec3f(this->imgWidth / 2, this->imgHeight / 2, 0.F);
// generate selectable primitive for text label at elevated Z for selection above geometry
SbVec3f img1 = SbVec3f(-this->imgWidth / 2, -this->imgHeight / 2, ZARROW_TEXT_OFFSET);
SbVec3f img2 = SbVec3f(-this->imgWidth / 2, this->imgHeight / 2, ZARROW_TEXT_OFFSET);
SbVec3f img3 = SbVec3f(this->imgWidth / 2, -this->imgHeight / 2, ZARROW_TEXT_OFFSET);
SbVec3f img4 = SbVec3f(this->imgWidth / 2, this->imgHeight / 2, ZARROW_TEXT_OFFSET);
float s = sin(geom.angle);
float c = cos(geom.angle);
img1 = SbVec3f((img1[0] * c) - (img1[1] * s), (img1[0] * s) + (img1[1] * c), 0.F);
img2 = SbVec3f((img2[0] * c) - (img2[1] * s), (img2[0] * s) + (img2[1] * c), 0.F);
img3 = SbVec3f((img3[0] * c) - (img3[1] * s), (img3[0] * s) + (img3[1] * c), 0.F);
img4 = SbVec3f((img4[0] * c) - (img4[1] * s), (img4[0] * s) + (img4[1] * c), 0.F);
img1 = SbVec3f((img1[0] * c) - (img1[1] * s), (img1[0] * s) + (img1[1] * c), ZARROW_TEXT_OFFSET);
img2 = SbVec3f((img2[0] * c) - (img2[1] * s), (img2[0] * s) + (img2[1] * c), ZARROW_TEXT_OFFSET);
img3 = SbVec3f((img3[0] * c) - (img3[1] * s), (img3[0] * s) + (img3[1] * c), ZARROW_TEXT_OFFSET);
img4 = SbVec3f((img4[0] * c) - (img4[1] * s), (img4[0] * s) + (img4[1] * c), ZARROW_TEXT_OFFSET);
img1 += geom.textOffset;
img2 += geom.textOffset;
@@ -1173,10 +1179,17 @@ void SoDatumLabel::GLRender(SoGLRenderAction* action)
state->push();
// Set General OpenGL Properties
glPushAttrib(GL_ENABLE_BIT | GL_PIXEL_MODE_BIT | GL_COLOR_BUFFER_BIT);
glPushAttrib(GL_ENABLE_BIT | GL_PIXEL_MODE_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_LIGHTING);
glDisable(GL_CULL_FACE);
// Explicitly enable depth testing for constraint lines. This is needed because the
// constraint group may have depth testing disabled (to allow icons to render on top),
// but we want constraint LINES to render BELOW geometry lines.
// Arrowheads are drawn at elevated Z (ZARROW_TEXT_OFFSET) so they render on top.
// Text rendering disables depth testing separately.
glEnable(GL_DEPTH_TEST);
// Enable Anti-alias
if (action->isSmoothing()) {
glEnable(GL_LINE_SMOOTH);
@@ -1282,15 +1295,15 @@ void SoDatumLabel::drawDistance(const SbVec3f* points, float& angle, SbVec3f& te
glVertex2f(geom.par4[0], geom.par4[1]);
glEnd();
// Draw the arrowheads
// Draw the arrowheads at elevated Z to render ON TOP of geometry lines
glBegin(GL_TRIANGLES);
glVertex2f(geom.par1[0], geom.par1[1]);
glVertex2f(geom.ar1[0], geom.ar1[1]);
glVertex2f(geom.ar2[0], geom.ar2[1]);
glVertex3f(geom.par1[0], geom.par1[1], ZARROW_TEXT_OFFSET);
glVertex3f(geom.ar1[0], geom.ar1[1], ZARROW_TEXT_OFFSET);
glVertex3f(geom.ar2[0], geom.ar2[1], ZARROW_TEXT_OFFSET);
glVertex2f(geom.par4[0], geom.par4[1]);
glVertex2f(geom.ar3[0], geom.ar3[1]);
glVertex2f(geom.ar4[0], geom.ar4[1]);
glVertex3f(geom.par4[0], geom.par4[1], ZARROW_TEXT_OFFSET);
glVertex3f(geom.ar3[0], geom.ar3[1], ZARROW_TEXT_OFFSET);
glVertex3f(geom.ar4[0], geom.ar4[1], ZARROW_TEXT_OFFSET);
glEnd();
if (this->datumtype.getValue() == DISTANCE) {
@@ -1335,18 +1348,19 @@ void SoDatumLabel::drawRadiusOrDiameter(const SbVec3f* points, float& angle, SbV
glVertex2f(geom.p2[0], geom.p2[1]);
glEnd();
// Draw arrowhead at elevated Z to render ON TOP of geometry lines
glBegin(GL_TRIANGLES);
glVertex2f(geom.ar0[0], geom.ar0[1]);
glVertex2f(geom.ar1[0], geom.ar1[1]);
glVertex2f(geom.ar2[0], geom.ar2[1]);
glVertex3f(geom.ar0[0], geom.ar0[1], ZARROW_TEXT_OFFSET);
glVertex3f(geom.ar1[0], geom.ar1[1], ZARROW_TEXT_OFFSET);
glVertex3f(geom.ar2[0], geom.ar2[1], ZARROW_TEXT_OFFSET);
glEnd();
if (geom.isDiameter) {
// Draw second arrowhead
// Draw second arrowhead at elevated Z
glBegin(GL_TRIANGLES);
glVertex2f(geom.ar0_1[0], geom.ar0_1[1]);
glVertex2f(geom.ar1_1[0], geom.ar1_1[1]);
glVertex2f(geom.ar2_1[0], geom.ar2_1[1]);
glVertex3f(geom.ar0_1[0], geom.ar0_1[1], ZARROW_TEXT_OFFSET);
glVertex3f(geom.ar1_1[0], geom.ar1_1[1], ZARROW_TEXT_OFFSET);
glVertex3f(geom.ar2_1[0], geom.ar2_1[1], ZARROW_TEXT_OFFSET);
glEnd();
}
@@ -1386,24 +1400,32 @@ void SoDatumLabel::drawSymmetric(const SbVec3f* points)
// use shared geometry calculation
SymmetricGeometry geom = calculateSymmetricGeometry(points);
// draw first arrow
// draw first constraint line (at constraint Z)
glBegin(GL_LINES);
glVertex3f(geom.p1[0], geom.p1[1], ZCONSTR);
glVertex3f(geom.ar0[0], geom.ar0[1], ZCONSTR);
glVertex3f(geom.ar0[0], geom.ar0[1], ZCONSTR);
glVertex3f(geom.ar1[0], geom.ar1[1], ZCONSTR);
glVertex3f(geom.ar0[0], geom.ar0[1], ZCONSTR);
glVertex3f(geom.ar2[0], geom.ar2[1], ZCONSTR);
glEnd();
// draw second arrow
// draw first arrowhead at elevated Z to render ON TOP of geometry lines
glBegin(GL_LINES);
glVertex3f(geom.ar0[0], geom.ar0[1], ZARROW_TEXT_OFFSET);
glVertex3f(geom.ar1[0], geom.ar1[1], ZARROW_TEXT_OFFSET);
glVertex3f(geom.ar0[0], geom.ar0[1], ZARROW_TEXT_OFFSET);
glVertex3f(geom.ar2[0], geom.ar2[1], ZARROW_TEXT_OFFSET);
glEnd();
// draw second constraint line (at constraint Z)
glBegin(GL_LINES);
glVertex3f(geom.p2[0], geom.p2[1], ZCONSTR);
glVertex3f(geom.ar3[0], geom.ar3[1], ZCONSTR);
glVertex3f(geom.ar3[0], geom.ar3[1], ZCONSTR);
glVertex3f(geom.ar4[0], geom.ar4[1], ZCONSTR);
glVertex3f(geom.ar3[0], geom.ar3[1], ZCONSTR);
glVertex3f(geom.ar5[0], geom.ar5[1], ZCONSTR);
glEnd();
// draw second arrowhead at elevated Z to render ON TOP of geometry lines
glBegin(GL_LINES);
glVertex3f(geom.ar3[0], geom.ar3[1], ZARROW_TEXT_OFFSET);
glVertex3f(geom.ar4[0], geom.ar4[1], ZARROW_TEXT_OFFSET);
glVertex3f(geom.ar3[0], geom.ar3[1], ZARROW_TEXT_OFFSET);
glVertex3f(geom.ar5[0], geom.ar5[1], ZARROW_TEXT_OFFSET);
glEnd();
}
@@ -1888,7 +1910,7 @@ void SoDatumLabel::generateArrowSelectionPrimitive(
float length
)
{
// create selectable arrow as a triangle
// create selectable arrow as a triangle at elevated Z for selection above geometry
SbVec3f tip = base + dir * length;
SbVec3f perp = SbVec3f(-dir[1], dir[0], 0) * (width / 2.0f);
@@ -1899,11 +1921,11 @@ void SoDatumLabel::generateArrowSelectionPrimitive(
pv.setNormal(SbVec3f(0.F, 0.F, 1.F));
this->beginShape(action, TRIANGLES);
pv.setPoint(tip);
pv.setPoint(SbVec3f(tip[0], tip[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
pv.setPoint(p1);
pv.setPoint(SbVec3f(p1[0], p1[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
pv.setPoint(p2);
pv.setPoint(SbVec3f(p2[0], p2[1], ZARROW_TEXT_OFFSET));
shapeVertex(&pv);
this->endShape();
}

View File

@@ -36,6 +36,7 @@
#include <Inventor/SbVec3f.h>
#include <Inventor/SoPickedPoint.h>
#include <Inventor/nodes/SoAnnotation.h>
#include <Inventor/nodes/SoDepthBuffer.h>
#include <Inventor/nodes/SoDrawStyle.h>
#include <Inventor/nodes/SoGroup.h>
#include <Inventor/nodes/SoImage.h>
@@ -2985,10 +2986,21 @@ void EditModeConstraintCoinManager::createEditModeInventorNodes()
editModeScenegraphNodes.EditRoot->addChild(editModeScenegraphNodes.constrGrpSelect);
setConstraintSelectability(); // Ensure default value;
// disable depth testing for constraint icons so they render ON TOP of geometry lines
// check issues #25840 and #11603
SoDepthBuffer* constrDepthOff = new SoDepthBuffer();
constrDepthOff->test.setValue(false);
editModeScenegraphNodes.EditRoot->addChild(constrDepthOff);
editModeScenegraphNodes.constrGroup = new SmSwitchboard();
editModeScenegraphNodes.constrGroup->setName("ConstraintGroup");
editModeScenegraphNodes.EditRoot->addChild(editModeScenegraphNodes.constrGroup);
// re-enable depth testing for the rest of the nodes
SoDepthBuffer* constrDepthOn = new SoDepthBuffer();
constrDepthOn->test.setValue(true);
editModeScenegraphNodes.EditRoot->addChild(constrDepthOn);
SoPickStyle* ps = new SoPickStyle(); // used to following nodes aren't impacted
ps->style.setValue(SoPickStyle::SHAPE);
editModeScenegraphNodes.EditRoot->addChild(ps);