Я получил помощь по моей проблеме на форуме OSG, поблагодарил Криса Хэнсона за указание правильного направления и OSG образцов Гордона Томлисона за реальное решение.
Код посетителя (заголовок):
#pragma once
#include <osg/array>
#include <osg/geode>
#include <osg/Geometry>
#include <osg/NodeVisitor>
#include <osg/Vec4>
class ColorVisitor : public osg::NodeVisitor
{
public:
ColorVisitor();
ColorVisitor(const osg::Vec4 &color);
virtual ~ColorVisitor();
virtual void ColorVisitor::apply(osg::Node &node);
virtual void ColorVisitor::apply(osg::Geode &geode);
virtual void ColorVisitor::setColor(const float r, const float g, const float b, const float a = 1.0f);
virtual void ColorVisitor::setColor(const osg::Vec4 &color);
private:
osg::Vec4 m_color;
osg::ref_ptr< osg::Vec4Array > m_colorArrays;
};
Реализация класса посетителя:
#include "ColorVisitor.h"
ColorVisitor::ColorVisitor(): osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
{
m_color.set(1.0, 1.0, 1.0, 1.0);
m_colorArrays = new osg::Vec4Array;
m_colorArrays->push_back(m_color);
};
ColorVisitor::ColorVisitor(const osg::Vec4 &color): osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
{
m_color = color;
m_colorArrays = new osg::Vec4Array;
m_colorArrays->push_back(m_color);
};
ColorVisitor::~ColorVisitor()
{
};
void ColorVisitor::apply(osg::Node &node) {
// --------------------------------------------
//
// Handle traversal of osg::Node node types
//
// --------------------------------------------
traverse(node);
};
void ColorVisitor::apply(osg::Geode &geode) {
// ------------------------------------------------
//
// Handle traversal of osg::Geode node types
//
// ------------------------------------------------
osg::StateSet *state = NULL;
unsigned int vertNum = 0;
//
// We need to iterate through all the drawables check if
// the contain any geometry that we will need to process
//
unsigned int numGeoms = geode.getNumDrawables();
for (unsigned int geodeIdx = 0; geodeIdx < numGeoms; geodeIdx++)
{
//
// Use 'asGeometry' as its supposed to be faster than a dynamic_cast
// every little saving counts
//
osg::Geometry *curGeom = geode.getDrawable(geodeIdx)->asGeometry();
//
// Only process if the drawable is geometry
//
if (curGeom)
{
osg::Vec4Array *colorArrays = dynamic_cast<osg::Vec4Array *>(curGeom->getColorArray());
if (colorArrays) {
for (unsigned int i = 0; i < colorArrays->size(); i++)
{
osg::Vec4 *color = &colorArrays->operator [](i);
//
// could also use *color = m_color
//
color->set(m_color._v[0], m_color._v[1], m_color._v[2], m_color._v[3]);
}
}
else
{
curGeom->setColorArray(m_colorArrays.get());
curGeom->setColorBinding(osg::Geometry::BIND_OVERALL);
}
}
}
};
void ColorVisitor::setColor(const float r, const float g, const float b, const float a)
{
// -------------------------------------------------------------------
//
// Set the color to change apply to the nodes geometry
//
// -------------------------------------------------------------------
osg::Vec4 *c = &m_colorArrays->operator [](0);
m_color.set(r, g, b, a);
*c = m_color;
};
void ColorVisitor::setColor(const osg::Vec4 &color) {
// -------------------------------------------------------------------
//
// Set the color to change apply to the nodes geometry
//
// -------------------------------------------------------------------
osg::Vec4 *c = &m_colorArrays->operator [](0);
m_color = color;
*c = m_color;
};
И мой код упрощен и обновлен для решения:
osg::Node* lines = osgDB::readNodeFile("lines.dxf");
osg::Geode* geode = new osg::Geode;
ColorVisitor newColor;
newColor.setColor( 1.0f, 0.0f, 0.0f );
topography->accept(newColor);
geode->addChild(lines);
_mViewer->setSceneData(geode);
_mViewer->realize();