Gui: Scene inspector improvements (#18781)
* Improve naming for root scene graph switch/separator nodes. * Improve scene graph inspector. This commit improves the scene graph inspector by improving the UI layout and displaying information in a more human-readable way. Instead of having a main generic string column for all node-specific data, introduce specific columns for node name, memory address and data. Better visualization was also added for `SoDrawStyle`, `SoPickStyle` and `SoCoordinate3` node types.
This commit is contained in:
@@ -23,6 +23,9 @@
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <Inventor/nodes/SoSeparator.h>
|
||||
# include <Inventor/nodes/SoDrawStyle.h>
|
||||
# include <Inventor/nodes/SoPickStyle.h>
|
||||
# include <Inventor/nodes/SoCoordinate3.h>
|
||||
# include <QHeaderView>
|
||||
# include <QTextStream>
|
||||
#endif
|
||||
@@ -45,12 +48,20 @@ SceneModel::SceneModel(QObject* parent)
|
||||
{
|
||||
}
|
||||
|
||||
enum class Column: std::int8_t {
|
||||
INVENTOR_TREE = 0,
|
||||
NAME = 1,
|
||||
MEMORY_ADDRESS = 2,
|
||||
DATA = 3,
|
||||
COUNT = 4,
|
||||
};
|
||||
|
||||
SceneModel::~SceneModel() = default;
|
||||
|
||||
int SceneModel::columnCount (const QModelIndex & parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return 2;
|
||||
return static_cast<int>(Column::COUNT);
|
||||
}
|
||||
|
||||
Qt::ItemFlags SceneModel::flags (const QModelIndex & index) const
|
||||
@@ -63,10 +74,19 @@ QVariant SceneModel::headerData (int section, Qt::Orientation orientation, int r
|
||||
if (orientation == Qt::Horizontal) {
|
||||
if (role != Qt::DisplayRole)
|
||||
return {};
|
||||
if (section == 0)
|
||||
|
||||
switch ((Column)section) {
|
||||
case Column::INVENTOR_TREE:
|
||||
return tr("Inventor Tree");
|
||||
else if (section == 1)
|
||||
case Column::NAME:
|
||||
return tr("Name");
|
||||
case Column::MEMORY_ADDRESS:
|
||||
return tr("Address");
|
||||
case Column::DATA:
|
||||
return tr("Data");
|
||||
default:
|
||||
assert(0 && "Not handled yet");
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
@@ -82,42 +102,135 @@ void SceneModel::setNode(SoNode* node)
|
||||
this->clear();
|
||||
this->setHeaderData(0, Qt::Horizontal, tr("Nodes"), Qt::DisplayRole);
|
||||
|
||||
this->insertColumns(0,2);
|
||||
this->insertColumns(0, static_cast<int>(Column::COUNT));
|
||||
this->insertRows(0,1);
|
||||
setNode(this->index(0, 0), node);
|
||||
}
|
||||
|
||||
static std::string_view formatSoSwitchValue(int32_t value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case SO_SWITCH_NONE:
|
||||
return {"None"};
|
||||
case SO_SWITCH_INHERIT:
|
||||
return {"Inherit"};
|
||||
case SO_SWITCH_ALL:
|
||||
return {"All"};
|
||||
default:
|
||||
return {"Child"};
|
||||
}
|
||||
}
|
||||
|
||||
static std::string_view formatSoSeparatorCacheEnabled(int32_t value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case SoSeparator::OFF:
|
||||
return {"Off"};
|
||||
case SoSeparator::ON:
|
||||
return {"On"};
|
||||
case SoSeparator::AUTO:
|
||||
return {"Auto"};
|
||||
default:
|
||||
throw Base::ValueError();
|
||||
}
|
||||
}
|
||||
|
||||
static std::string_view formatSoDrawStyleElement(int32_t value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case SoDrawStyleElement::FILLED:
|
||||
return {"Filled"};
|
||||
case SoDrawStyleElement::LINES:
|
||||
return {"Lines"};
|
||||
case SoDrawStyleElement::POINTS:
|
||||
return {"Points"};
|
||||
case SoDrawStyleElement::INVISIBLE:
|
||||
return {"Invisible"};
|
||||
default:
|
||||
throw Base::ValueError();
|
||||
}
|
||||
}
|
||||
|
||||
static std::string_view formatSoPickStyleElement(int32_t value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case SoPickStyleElement::SHAPE:
|
||||
return {"Shape"};
|
||||
case SoPickStyleElement::BOUNDING_BOX:
|
||||
return {"BoundingBox"};
|
||||
case SoPickStyleElement::UNPICKABLE:
|
||||
return {"Unpickable"};
|
||||
case SoPickStyleElement::SHAPE_ON_TOP:
|
||||
return {"ShapeOnTop"};
|
||||
case SoPickStyleElement::BOUNDING_BOX_ON_TOP:
|
||||
return {"BoundingBoxOnTop"};
|
||||
case SoPickStyleElement::SHAPE_FRONTFACES:
|
||||
return {"ShapeFrontFaces"};
|
||||
default:
|
||||
throw Base::ValueError();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneModel::setNode(QModelIndex index, SoNode* node)
|
||||
{
|
||||
this->setData(index, QVariant(QString::fromLatin1(QByteArray(node->getTypeId().getName()))));
|
||||
if (node->getTypeId().isDerivedFrom(SoGroup::getClassTypeId())) {
|
||||
auto group = static_cast<SoGroup*>(node);
|
||||
// insert SoGroup icon
|
||||
this->insertColumns(0,2,index);
|
||||
this->insertRows(0,group->getNumChildren(), index);
|
||||
for (int i=0; i<group->getNumChildren();i++) {
|
||||
SoNode* child = group->getChild(i);
|
||||
setNode(this->index(i, 0, index), child);
|
||||
this->setData(index.siblingAtColumn(static_cast<int>(Column::INVENTOR_TREE)),
|
||||
QVariant(QString::fromLatin1(QByteArray(node->getTypeId().getName()))));
|
||||
|
||||
QHash<SoNode*, QString>::iterator it = nodeNames.find(child);
|
||||
QString name;
|
||||
QTextStream stream(&name);
|
||||
stream << child << ", ";
|
||||
if(child->isOfType(SoSwitch::getClassTypeId())) {
|
||||
auto pcSwitch = static_cast<SoSwitch*>(child);
|
||||
stream << pcSwitch->whichChild.getValue() << ", ";
|
||||
} else if (child->isOfType(SoSeparator::getClassTypeId())) {
|
||||
auto pcSeparator = static_cast<SoSeparator*>(child);
|
||||
stream << pcSeparator->renderCaching.getValue() << ", ";
|
||||
}
|
||||
if (it != nodeNames.end())
|
||||
stream << it.value();
|
||||
else
|
||||
stream << child->getName();
|
||||
this->setData(this->index(i, 1, index), QVariant(name));
|
||||
QHash<SoNode*, QString>::iterator it = nodeNames.find(node);
|
||||
const QString name {
|
||||
(it != nodeNames.end()) ? it.value()
|
||||
: QString::fromLatin1(QByteArray(node->getName()))
|
||||
};
|
||||
this->setData(index.siblingAtColumn(static_cast<int>(Column::NAME)), QVariant(name));
|
||||
|
||||
this->setData(index.siblingAtColumn(static_cast<int>(Column::MEMORY_ADDRESS)),
|
||||
QVariant(QString::fromStdString(fmt::format("{}", (void*)node))));
|
||||
|
||||
QString data;
|
||||
QTextStream stream(&data);
|
||||
if(static_cast<bool>(node->isOfType(SoSwitch::getClassTypeId()))) {
|
||||
auto pcSwitch = static_cast<SoSwitch*>(node);
|
||||
auto value = pcSwitch->whichChild.getValue();
|
||||
stream << fmt::format("Which: {} ({})", formatSoSwitchValue(value), value).c_str();
|
||||
} else if (static_cast<bool>(node->isOfType(SoSeparator::getClassTypeId()))) {
|
||||
auto pcSeparator = static_cast<SoSeparator*>(node);
|
||||
auto value = pcSeparator->renderCaching.getValue();
|
||||
stream << fmt::format("RenderCaching: {} ({})", formatSoSeparatorCacheEnabled(value), value).c_str();
|
||||
} else if (static_cast<bool>(node->isOfType(SoDrawStyle::getClassTypeId()))) {
|
||||
auto pcDrawStyle = static_cast<SoDrawStyle*>(node);
|
||||
auto value = pcDrawStyle->style.getValue();
|
||||
stream << fmt::format("Style: {} ({})", formatSoDrawStyleElement(value), value).c_str();
|
||||
} else if (static_cast<bool>(node->isOfType(SoPickStyle::getClassTypeId()))) {
|
||||
auto pcPickStyle = static_cast<SoPickStyle*>(node);
|
||||
auto value = pcPickStyle->style.getValue();
|
||||
stream << fmt::format("Style: {} ({})", formatSoPickStyleElement(value), value).c_str();
|
||||
} else if (static_cast<bool>(node->isOfType(SoCoordinate3::getClassTypeId()))) {
|
||||
auto pcCoords = static_cast<SoCoordinate3*>(node);
|
||||
auto values = pcCoords->point.getValues(0);
|
||||
if (values) {
|
||||
float x { 0 };
|
||||
float y { 0 };
|
||||
float z { 0 };
|
||||
values->getValue(x, y, z);
|
||||
stream << fmt::format("XYZ: {}, {}, {}", x, y, z).c_str();
|
||||
}
|
||||
}
|
||||
|
||||
this->setData(index.siblingAtColumn((int)Column::DATA), QVariant(data));
|
||||
|
||||
if (static_cast<bool>(node->getTypeId().isDerivedFrom(SoGroup::getClassTypeId()))) {
|
||||
auto group = static_cast<SoGroup*>(node);
|
||||
this->insertColumns(0, static_cast<int>(Column::COUNT), index);
|
||||
this->insertRows(0, group->getNumChildren(), index);
|
||||
for (int i=0; i < group->getNumChildren(); i++) {
|
||||
SoNode* child = group->getChild(i);
|
||||
setNode(this->index(i, 0, index), child);
|
||||
}
|
||||
}
|
||||
// insert icon
|
||||
}
|
||||
|
||||
void SceneModel::setNodeNames(const QHash<SoNode*, QString>& names)
|
||||
@@ -169,7 +282,12 @@ void DlgInspector::setNode(SoNode* node)
|
||||
model->setNode(node);
|
||||
|
||||
QHeaderView* header = ui->treeView->header();
|
||||
header->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
header->setSectionResizeMode(static_cast<int>(Column::INVENTOR_TREE), QHeaderView::Interactive);
|
||||
header->resizeSection(static_cast<int>(Column::INVENTOR_TREE), 300);
|
||||
header->setSectionResizeMode(static_cast<int>(Column::NAME), QHeaderView::Interactive);
|
||||
header->resizeSection(static_cast<int>(Column::NAME), 200);
|
||||
header->setSectionResizeMode(static_cast<int>(Column::MEMORY_ADDRESS), QHeaderView::Interactive);
|
||||
header->setSectionResizeMode(static_cast<int>(Column::DATA), QHeaderView::Stretch);
|
||||
header->setSectionsMovable(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>296</width>
|
||||
<width>805</width>
|
||||
<height>583</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
||||
@@ -49,19 +49,22 @@ View3DInventorSelection::View3DInventorSelection(SoFCUnifiedSelection* root)
|
||||
|
||||
pcGroupOnTop = new SoSeparator;
|
||||
pcGroupOnTop->ref();
|
||||
pcGroupOnTop->setName("GroupOnTop");
|
||||
root->addChild(pcGroupOnTop);
|
||||
|
||||
auto pcGroupOnTopPickStyle = new SoPickStyle;
|
||||
pcGroupOnTopPickStyle->style = SoPickStyle::UNPICKABLE;
|
||||
pcGroupOnTopPickStyle->setOverride(true);
|
||||
pcGroupOnTopPickStyle->setName("GroupOnTopPickStyle");
|
||||
pcGroupOnTop->addChild(pcGroupOnTopPickStyle);
|
||||
|
||||
coin_setenv("COIN_SEPARATE_DIFFUSE_TRANSPARENCY_OVERRIDE", "1", TRUE);
|
||||
auto pcOnTopMaterial = new SoMaterial;
|
||||
pcOnTopMaterial->transparency = 0.5;
|
||||
pcOnTopMaterial->diffuseColor.setIgnored(true);
|
||||
pcOnTopMaterial->setOverride(true);
|
||||
pcGroupOnTop->addChild(pcOnTopMaterial);
|
||||
auto pcGroupOnTopMaterial = new SoMaterial;
|
||||
pcGroupOnTopMaterial->transparency = 0.5;
|
||||
pcGroupOnTopMaterial->diffuseColor.setIgnored(true);
|
||||
pcGroupOnTopMaterial->setOverride(true);
|
||||
pcGroupOnTopMaterial->setName("GroupOnTopMaterial");
|
||||
pcGroupOnTop->addChild(pcGroupOnTopMaterial);
|
||||
|
||||
{
|
||||
auto selRoot = new SoFCSelectionRoot;
|
||||
|
||||
@@ -443,6 +443,7 @@ void View3DInventorViewer::init()
|
||||
backgroundroot = new SoSeparator;
|
||||
backgroundroot->ref();
|
||||
this->backgroundroot->addChild(cam);
|
||||
this->backgroundroot->setName("backgroundroot");
|
||||
|
||||
// Background stuff
|
||||
pcBackGround = new SoFCBackgroundGradient;
|
||||
@@ -451,6 +452,7 @@ void View3DInventorViewer::init()
|
||||
// Set up foreground, overlaid scenegraph.
|
||||
this->foregroundroot = new SoSeparator;
|
||||
this->foregroundroot->ref();
|
||||
this->foregroundroot->setName("foregroundroot");
|
||||
|
||||
auto lm = new SoLightModel;
|
||||
lm->model = SoLightModel::BASE_COLOR;
|
||||
@@ -493,9 +495,14 @@ void View3DInventorViewer::init()
|
||||
pEventCallback->addEventCallback(SoEvent::getClassTypeId(), handleEventCB, this);
|
||||
|
||||
dimensionRoot = new SoSwitch(SO_SWITCH_NONE);
|
||||
dimensionRoot->setName("RootDimensions");
|
||||
pcViewProviderRoot->addChild(dimensionRoot);
|
||||
dimensionRoot->addChild(new SoSwitch()); //first one will be for the 3d dimensions.
|
||||
dimensionRoot->addChild(new SoSwitch()); //second one for the delta dimensions.
|
||||
auto dimensions3d = new SoSwitch();
|
||||
dimensions3d->setName("_3dDimensions");
|
||||
dimensionRoot->addChild(dimensions3d); //first one will be for the 3d dimensions.
|
||||
auto dimensionsDelta = new SoSwitch();
|
||||
dimensionsDelta->setName("DeltaDimensions");
|
||||
dimensionRoot->addChild(dimensionsDelta); //second one for the delta dimensions.
|
||||
|
||||
// This is a callback node that logs all action that traverse the Inventor tree.
|
||||
#if defined (FC_DEBUG) && defined(FC_LOGGING_CB)
|
||||
@@ -521,6 +528,7 @@ void View3DInventorViewer::init()
|
||||
// Create group for the physical object
|
||||
objectGroup = new SoGroup();
|
||||
objectGroup->ref();
|
||||
objectGroup->setName("ObjectGroup");
|
||||
pcViewProviderRoot->addChild(objectGroup);
|
||||
|
||||
// Set our own render action which show a bounding box if
|
||||
|
||||
@@ -107,6 +107,7 @@ ViewProvider::ViewProvider()
|
||||
pcRoot->ref();
|
||||
pcModeSwitch = new SoSwitch();
|
||||
pcModeSwitch->ref();
|
||||
pcModeSwitch->setName("ModeSwitch");
|
||||
pcTransform = new SoFCTransform();
|
||||
pcTransform->ref();
|
||||
pcRoot->addChild(pcTransform);
|
||||
|
||||
@@ -101,12 +101,15 @@ ViewProviderGeometryObject::ViewProviderGeometryObject()
|
||||
pcShapeMaterial = new SoMaterial;
|
||||
setCoinAppearance(mat);
|
||||
pcShapeMaterial->ref();
|
||||
pcShapeMaterial->setName("ShapeMaterial");
|
||||
|
||||
pcBoundingBox = new Gui::SoFCBoundingBox;
|
||||
pcBoundingBox->ref();
|
||||
pcBoundingBox->setName("BoundingBox");
|
||||
|
||||
pcBoundColor = new SoBaseColor();
|
||||
pcBoundColor->ref();
|
||||
pcBoundColor->setName("BoundColor");
|
||||
|
||||
sPixmap = "Feature";
|
||||
}
|
||||
@@ -302,6 +305,7 @@ void ViewProviderGeometryObject::showBoundingBox(bool show)
|
||||
blue = ((bbcol >> 8) & 0xff) / 255.0F;
|
||||
|
||||
pcBoundSwitch = new SoSwitch();
|
||||
pcBoundSwitch->setName("BoundSwitch");
|
||||
auto pBoundingSep = new SoSeparator();
|
||||
auto lineStyle = new SoDrawStyle;
|
||||
lineStyle->lineWidth = 2.0F;
|
||||
|
||||
@@ -48,14 +48,18 @@ ViewProviderTextureExtension::ViewProviderTextureExtension()
|
||||
|
||||
pcSwitchAppearance = new SoSwitch;
|
||||
pcSwitchAppearance->ref();
|
||||
pcSwitchAppearance->setName("SwitchAppearance");
|
||||
pcSwitchTexture = new SoSwitch;
|
||||
pcSwitchTexture->ref();
|
||||
pcSwitchTexture->setName("SwitchTexture");
|
||||
|
||||
pcShapeTexture2D = new SoTexture2;
|
||||
pcShapeTexture2D->ref();
|
||||
pcShapeTexture2D->setName("ShapeTexture2D");
|
||||
|
||||
pcTextureGroup3D = new SoGroup;
|
||||
pcTextureGroup3D->ref();
|
||||
pcTextureGroup3D->setName("TextureGroup3D");
|
||||
}
|
||||
|
||||
void ViewProviderTextureExtension::setup(SoMaterial* pcShapeMaterial)
|
||||
@@ -160,10 +164,13 @@ ViewProviderFaceTexture::ViewProviderFaceTexture()
|
||||
// Support for textured faces
|
||||
pcShapeTexture3D = new SoTexture3;
|
||||
pcShapeTexture3D->ref();
|
||||
pcShapeTexture3D->setName("ShapeTexture3D");
|
||||
pcShapeCoordinates = new SoCoordinate3;
|
||||
pcShapeCoordinates->ref();
|
||||
pcShapeCoordinates->setName("ShapeCoordinates");
|
||||
pcShapeFaceset = new SoIndexedFaceSet;
|
||||
pcShapeFaceset->ref();
|
||||
pcShapeFaceset->setName("ShapeFaceset");
|
||||
}
|
||||
|
||||
ViewProviderFaceTexture::~ViewProviderFaceTexture()
|
||||
|
||||
@@ -214,28 +214,35 @@ ViewProviderPartExt::ViewProviderPartExt()
|
||||
|
||||
pcFaceBind = new SoMaterialBinding();
|
||||
pcFaceBind->ref();
|
||||
pcFaceBind->setName("FaceBind");
|
||||
|
||||
pcLineBind = new SoMaterialBinding();
|
||||
pcLineBind->ref();
|
||||
pcLineBind->setName("LineBind");
|
||||
pcLineMaterial = new SoMaterial;
|
||||
pcLineMaterial->ref();
|
||||
pcLineMaterial->setName("LineMaterial");
|
||||
LineMaterial.touch();
|
||||
|
||||
pcPointBind = new SoMaterialBinding();
|
||||
pcPointBind->ref();
|
||||
pcPointBind->setName("PointBind");
|
||||
pcPointMaterial = new SoMaterial;
|
||||
pcPointMaterial->ref();
|
||||
pcPointMaterial->setName("PointMaterial");
|
||||
PointMaterial.touch();
|
||||
|
||||
pcLineStyle = new SoDrawStyle();
|
||||
pcLineStyle->ref();
|
||||
pcLineStyle->style = SoDrawStyle::LINES;
|
||||
pcLineStyle->lineWidth = LineWidth.getValue();
|
||||
pcLineStyle->setName("LineStyle");
|
||||
|
||||
pcPointStyle = new SoDrawStyle();
|
||||
pcPointStyle->ref();
|
||||
pcPointStyle->style = SoDrawStyle::POINTS;
|
||||
pcPointStyle->pointSize = PointSize.getValue();
|
||||
pcPointStyle->setName("PointStyle");
|
||||
|
||||
pShapeHints = new SoShapeHints;
|
||||
pShapeHints->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE;
|
||||
@@ -410,9 +417,13 @@ void ViewProviderPartExt::attach(App::DocumentObject *pcFeat)
|
||||
|
||||
// Workaround for #0000433, i.e. use SoSeparator instead of SoGroup
|
||||
auto* pcNormalRoot = new SoSeparator();
|
||||
pcNormalRoot->setName("NormalRoot");
|
||||
auto* pcFlatRoot = new SoSeparator();
|
||||
pcFlatRoot->setName("FlatRoot");
|
||||
auto* pcWireframeRoot = new SoSeparator();
|
||||
pcWireframeRoot->setName("WireframeRoot");
|
||||
auto* pcPointsRoot = new SoSeparator();
|
||||
pcPointsRoot->setName("PointsRoot");
|
||||
auto* wireframe = new SoSeparator();
|
||||
|
||||
// Must turn off all intermediate render caching, and let pcRoot to handle
|
||||
@@ -452,6 +463,7 @@ void ViewProviderPartExt::attach(App::DocumentObject *pcFeat)
|
||||
pcFlatRoot->addChild(texture.getAppearance());
|
||||
texture.setup(pcShapeMaterial);
|
||||
SoDrawStyle* pcFaceStyle = new SoDrawStyle();
|
||||
pcFaceStyle->setName("FaceStyle");
|
||||
pcFaceStyle->style = SoDrawStyle::FILLED;
|
||||
pcFlatRoot->addChild(pcFaceStyle);
|
||||
pcFlatRoot->addChild(norm);
|
||||
|
||||
Reference in New Issue
Block a user