diff --git a/examples/osgtransferfunction/osgtransferfunction.cpp b/examples/osgtransferfunction/osgtransferfunction.cpp index 7c59b7cb5..a3e8216de 100644 --- a/examples/osgtransferfunction/osgtransferfunction.cpp +++ b/examples/osgtransferfunction/osgtransferfunction.cpp @@ -20,12 +20,15 @@ #include #include #include +#include +#include #include #include #include #include +#include #include #include @@ -245,7 +248,7 @@ osg::Node* Histogram::createGraphicalRepresentation() return transform.release(); } -osg::Node* createGraphicalRepresentation(osg::TransferFunction1D* tf, unsigned int channel) +osg::Node* createGraphicalRepresentation(osg::TransferFunction1D* tf) { typedef osg::TransferFunction1D::ColorMap ColorMap; ColorMap& colorMap = tf->getColorMap(); @@ -264,7 +267,7 @@ osg::Node* createGraphicalRepresentation(osg::TransferFunction1D* tf, unsigned i itr != colorMap.end(); ++itr) { - float y = itr->second[channel]; + float y = itr->second[3]; if (y>yMax) yMax = y; } @@ -284,11 +287,9 @@ osg::Node* createGraphicalRepresentation(osg::TransferFunction1D* tf, unsigned i geometry->setVertexArray(vertices.get()); osg::ref_ptr colours = new osg::Vec4Array; - geometry->setColorArray(colours.get(), osg::Array::BIND_PER_PRIMITIVE_SET); - colours->push_back(osg::Vec4(1.0,1.0,1.0,1.0)); - colours->push_back(osg::Vec4(1.0,1.0,1.0,1.0)); - colours->push_back(osg::Vec4(1.0,1.0,1.0,0.1)); + geometry->setColorArray(colours.get(), osg::Array::BIND_PER_VERTEX); + osg::Vec4 background_color(1.0f, 1.0f, 1.0f, 0.1f); unsigned numColumnsRequired = colorMap.size(); vertices->reserve(numColumnsRequired*3); @@ -297,11 +298,22 @@ osg::Node* createGraphicalRepresentation(osg::TransferFunction1D* tf, unsigned i ++itr) { float x = itr->first; - float y = itr->second[channel]; + osg::Vec4 color = itr->second; + + float y = itr->second[3]; + color[3] = 1.0f; vertices->push_back(osg::Vec3(x*xScale, 0.0f, depth)); + colours->push_back(color); + vertices->push_back(osg::Vec3(x*xScale, y*yScale, depth)); + colours->push_back(color); + + vertices->push_back(osg::Vec3(x*xScale, y*yScale, depth)); + colours->push_back(background_color); + vertices->push_back(osg::Vec3(x*xScale, yMax*yScale, depth)); + colours->push_back(background_color); } osg::ref_ptr background_primitives = new osg::DrawElementsUShort(GL_TRIANGLE_STRIP); @@ -309,10 +321,10 @@ osg::Node* createGraphicalRepresentation(osg::TransferFunction1D* tf, unsigned i osg::ref_ptr outline_primitives = new osg::DrawElementsUShort(GL_LINE_STRIP); for(unsigned int i=0; ipush_back(iv+3); background_primitives->push_back(iv+2); - background_primitives->push_back(iv+1); historgram_primitives->push_back(iv+1); historgram_primitives->push_back(iv+0); @@ -370,6 +382,78 @@ osg::TransferFunction1D* readTransferFunctionFile(const std::string& filename, f return tf; } +class FindTransferFunctionPropertyVisitor : public osgVolume::PropertyVisitor +{ +public: + + osg::ref_ptr _tfp; + +#if 0 + virtual void apply(osgVolume::SwitchProperty& sp) + { + OSG_NOTICE<<"Found SwitchProperty"<(sp)); + } + + virtual void apply(osgVolume::CompositeProperty& cp) + { + OSG_NOTICE<<"Found CompositeProperty"<accept(*this); + } + } +#endif + virtual void apply(osgVolume::TransferFunctionProperty& tfp) + { + OSG_NOTICE<<"Found TransferFunctionProperty "<<&tfp< _tfp; + + virtual void apply(osgVolume::SwitchProperty& sp) + { + OSG_NOTICE<<"Found SwitchProperty"<accept(*this); + } + } + + virtual void apply(osgVolume::CompositeProperty& cp) + { + OSG_NOTICE<<"Found CompositeProperty, inserting transfer function"< > Tiles; + Tiles _tiles; + + void apply(osg::Group& group) + { + osgVolume::VolumeTile* tile = dynamic_cast(&group); + if (tile) _tiles.push_back(tile); + else traverse(group); + } +}; int main(int argc, char ** argv) { @@ -384,42 +468,133 @@ int main(int argc, char ** argv) tf = readTransferFunctionFile(filename); } - osg::ref_ptr layer; + bool createHistorgram = arguments.read("--histogram"); osg::ref_ptr model = osgDB::readNodeFiles(arguments); - osgVolume::VolumeTile* volumeTile = dynamic_cast(model.get()); - if (!volumeTile) + typedef std::vector< osg::ref_ptr > Nodes; + Nodes nodes; + + if (!model && !tf) { - OSG_NOTICE<<"Please specify volume dataset on command line."<getLayer(); + osgVolume::ImageLayer* imageLayer = 0; - if (!layer) + + if (model.valid()) { - OSG_NOTICE<<"No layer loaded."< volumeTile = dynamic_cast(model.get()); + if (volumeTile.valid()) + { + OSG_NOTICE<<"Inserting Volume above VolumeTile."< volume = new osgVolume::Volume; + volume->addChild(model.get()); + model = volume.get(); + } + + nodes.push_back(model.get()); + + FindVolumeTiles fvt; + model->accept(fvt); + + if (!fvt._tiles.empty()) imageLayer = dynamic_cast(fvt._tiles[0]->getLayer()); + } + + + if (createHistorgram && imageLayer) + { + Histogram histogram; + histogram.analyse(imageLayer->getImage()); + nodes.push_back(histogram.createGraphicalRepresentation()); + } + + if (imageLayer) + { + osgVolume::Property* property = imageLayer->getProperty(); + if (property) + { + FindTransferFunctionPropertyVisitor ftfpv; + property->accept(ftfpv); + + if (ftfpv._tfp.valid()) + { + if (tf.valid()) + { + OSG_NOTICE<<"Need to replace volumes transfer function"<setTransferFunction(tf.get()); + } + else + { + OSG_NOTICE<<"Using volumes transfer function"<(ftfpv._tfp->getTransferFunction()); + } + } + else if (tf.valid()) + { + // No exisitng trasfer function but need to assign one + OSG_NOTICE<<"Need to assign transfer function to CompositeProperty"<accept(itfpv); + } + } + else if (tf.valid()) + { + OSG_NOTICE<<"Assign transfer function directly"<setProperty(new osgVolume::TransferFunctionProperty(tf.get())); + } + } + + if (tf.valid()) + { + nodes.push_back(createGraphicalRepresentation(tf.get())); + } + + if (nodes.empty()) + { + OSG_NOTICE<<"Please specify dataset on command line."< imageLayer = dynamic_cast(layer.get()); - - osg::ref_ptr image = imageLayer.valid() ? imageLayer->getImage() : 0; - - if (!image) + if (nodes.size()==1) viewer.setSceneData(nodes[0].get()); + else { - OSG_NOTICE<<"No image found."< group = new osg::Group; + + for(Nodes::iterator itr = nodes.begin(); + itr != nodes.end(); + ++itr) + { + osg::ref_ptr child = *itr; + if (!child) continue; +#if 0 + osg::ComputeBoundsVisitor cbv; + child->accept(cbv); + + osg::BoundingBox bb = cbv.getBoundingBox(); + double scale = 1.0/(bb.xMax()-bb.xMin()); +#endif + osg::BoundingSphere bb = child->getBound(); + double scale = 0.7/bb.radius(); + + osg::ref_ptr pat = new osg::PositionAttitudeTransform; + pat->addChild(child.get()); + pat->setPosition(position); + pat->setPivotPoint(bb.center()); + pat->setScale(osg::Vec3d(scale, scale, scale)); + position.x() += 1.1; + + group->addChild(pat.get()); + } + + viewer.setSceneData(group.get()); } - Histogram histogram; - histogram.analyse(image.get()); - osg::ref_ptr group = new osg::Group; - group->addChild(histogram.createGraphicalRepresentation()); - //if (tf.valid()) group->addChild(createGraphicalRepresentation(tf.get(),1)); - - viewer.setSceneData(group.get()); osgDB::writeNodeFile(*viewer.getSceneData(),"graph.osgt");