diff --git a/src/osgPlugins/CMakeLists.txt b/src/osgPlugins/CMakeLists.txt index 2562ffaf6..e911d4c9f 100644 --- a/src/osgPlugins/CMakeLists.txt +++ b/src/osgPlugins/CMakeLists.txt @@ -1,5 +1,5 @@ #--------------------------------------------------- -# OSG CMAKE SUPPORT +# OSG CMAKE SUPPORT # (C) by Michael Wagner, mtw@shared-reality.com 2005 # (C) Eric Wing, Luigi Calori and Robert Osfield 2006-2007 #--------------------------------------------------- @@ -22,10 +22,10 @@ ENDIF(MSVC80) SET(TARGET_DEFAULT_PREFIX "osgdb_") SET(TARGET_DEFAULT_LABEL_PREFIX "Plugins") -SET(TARGET_COMMON_LIBRARIES +SET(TARGET_COMMON_LIBRARIES OpenThreads - osg - osgDB + osg + osgDB osgUtil ) @@ -75,15 +75,16 @@ ADD_SUBDIRECTORY(pnm) ADD_SUBDIRECTORY(dds) ADD_SUBDIRECTORY(tga) ADD_SUBDIRECTORY(hdr) +ADD_SUBDIRECTORY(dot) IF(JPEG_FOUND) ADD_SUBDIRECTORY(jpeg) ENDIF(JPEG_FOUND) IF(JASPER_FOUND) - ADD_SUBDIRECTORY(jp2) + ADD_SUBDIRECTORY(jp2) ENDIF(JASPER_FOUND) IF(GIFLIB_FOUND) - ADD_SUBDIRECTORY(gif) + ADD_SUBDIRECTORY(gif) ENDIF(GIFLIB_FOUND) IF(PNG_FOUND) ADD_SUBDIRECTORY(png) @@ -168,7 +169,7 @@ IF(QUICKTIME_FOUND) ENDIF(QUICKTIME_FOUND) IF(FREETYPE_FOUND) - ADD_SUBDIRECTORY(freetype) + ADD_SUBDIRECTORY(freetype) ENDIF(FREETYPE_FOUND) IF(ZLIB_FOUND) ADD_SUBDIRECTORY(zip) @@ -191,4 +192,4 @@ ENDIF(BUILD_OSGWIDGET) # ) #ENDFOREACH(myvar) - + diff --git a/src/osgPlugins/dot/BaseDotVisitor.cpp b/src/osgPlugins/dot/BaseDotVisitor.cpp new file mode 100644 index 000000000..9b0c2236d --- /dev/null +++ b/src/osgPlugins/dot/BaseDotVisitor.cpp @@ -0,0 +1,161 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ +#include "BaseDotVisitor.h" + +#include +#include + +#include +#include +#include + +using namespace osg; + +namespace osgDot { + + BaseDotVisitor::BaseDotVisitor() { + } + + BaseDotVisitor::~BaseDotVisitor() { + } + + bool BaseDotVisitor::run( osg::Node& root, std::ostream* fout ) { + setTraversalMode( TRAVERSE_ALL_CHILDREN ); + if ( fout && *fout ) { + root.accept( *this ); + + *fout << "digraph osg_scenegraph { rankdir = LR;" << std::endl; + + *fout << _nodes.str() << _edges.str(); + + *fout << "}" << std::endl; + + _nodes.clear(); + _edges.clear(); + _objectMap.clear(); + + return true; + } + + return false; + } + + void BaseDotVisitor::apply(Node& node) { + int id; + if ( getOrCreateId( &node, id ) ) { + handle( node, id ); + handleNodeAndTraverse( node, id ); + } + } + + void BaseDotVisitor::apply(Geode& node) { + int id; + if ( getOrCreateId( &node, id ) ) { + handle( node, id ); + handleNodeAndTraverse( node, id ); + + unsigned int i; + for ( i = 0; i < node.getNumDrawables(); i++ ) { + osg::Drawable* drawable = node.getDrawable( i ); + int id2; + if ( getOrCreateId( drawable, id2 ) ) { + handle( *drawable, id2 ); + osg::StateSet* s = drawable->getStateSet(); + if ( s ) { + int id3; + if ( getOrCreateId( s, id3 ) ) { + handle( *s, id3 ); + } + handle( *drawable, *s, id2, id3 ); + } + } + handle( node, *drawable, id, id2 ); + } + + } + + } + + void BaseDotVisitor::apply(Group& node) { + int id; + + if ( getOrCreateId( &node, id ) ) { + handle( node, id ); + handleNodeAndTraverse( node, id ); + + unsigned int i; + for ( i = 0; i < node.getNumChildren(); i++ ) { + osg::Node* child = node.getChild( i ); + //handleNodeAndTraverse( *child ); + int id2; + getOrCreateId( child, id2 ); + handle( node, *child, id, id2 ); + } + + } + + } + + void BaseDotVisitor::handle(osg::Node& node, int id) { + } + + void BaseDotVisitor::handle(osg::Geode& node, int id) { + } + + void BaseDotVisitor::handle(osg::Group& node, int id) { + } + + void BaseDotVisitor::handle(osg::Group& parent, osg::Node& child, int parentID, int childID ) { + } + + void BaseDotVisitor::handleNodeAndTraverse(osg::Node& node, int id) { + osg::StateSet* ss = node.getStateSet(); + if ( ss ) { + int id2; + if ( getOrCreateId( ss, id2 ) ) { + handle( *ss, id2 ); + } + handle( node, *ss, id, id2 ); + } + traverse(node); + } + + void BaseDotVisitor::handle(osg::StateSet& stateset, int id) { + } + + void BaseDotVisitor::handle(osg::Node& node, osg::StateSet& stateset, int parentID, int childID) { + } + + void BaseDotVisitor::handle(osg::Drawable& drawable, int id) { + } + + void BaseDotVisitor::handle(osg::Drawable& drawable, osg::StateSet& stateset, int parentID, int childID ) { + } + + void BaseDotVisitor::handle(osg::Geode& geode, osg::Drawable& drawable, int parentID, int childID ) { + } + + bool BaseDotVisitor::getOrCreateId( osg::Object* object, int &id ) { + assert( object ); + ObjectMap::iterator it = _objectMap.find( object ); + if ( it != _objectMap.end() ) { + id = it->second; + return false; + } + + id = _objectMap.size(); + _objectMap[ object ] = id; + return true; + } + +} // namespace osgDot diff --git a/src/osgPlugins/dot/BaseDotVisitor.h b/src/osgPlugins/dot/BaseDotVisitor.h new file mode 100644 index 000000000..a39083655 --- /dev/null +++ b/src/osgPlugins/dot/BaseDotVisitor.h @@ -0,0 +1,77 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ +#pragma once +#ifndef __DOTBASEVISITOR_H__ +#define __DOTBASEVISITOR_H__ + +#ifndef __cplusplus +#error "this is a c++ - header!" +#endif + +#include + +#include +#include +#include +#include +#include + +namespace osgDot { + + class BaseDotVisitor : public osg::NodeVisitor { + public: + typedef std::map< osg::Object*, int > ObjectMap; + + public: + BaseDotVisitor(); + + virtual ~BaseDotVisitor(); + + bool run( osg::Node& root, std::ostream* ostream ); + + virtual void apply(osg::Node& node); + + virtual void apply(osg::Geode& node); + + virtual void apply(osg::Group& node); + + + protected: + + void handleNodeAndTraverse(osg::Node& node, int id); + + virtual void handle(osg::Node& node, int id); + virtual void handle(osg::Geode& node, int id); + virtual void handle(osg::Group& node, int id); + virtual void handle(osg::StateSet& stateset, int id); + virtual void handle(osg::Drawable& drawable, int id); + + virtual void handle(osg::Node& node, osg::StateSet& stateset, int parentID, int childID); + virtual void handle(osg::Group& parent, osg::Node& child, int parentID, int childID); + virtual void handle(osg::Geode& geode, osg::Drawable& drawable, int parentID, int childID); + virtual void handle(osg::Drawable& drawable, osg::StateSet& stateset, int parentID, int childID ); + + + std::stringstream _nodes; + std::stringstream _edges; + + private: + bool getOrCreateId( osg::Object* object, int& id ); + + ObjectMap _objectMap; + + }; + +} // namespace osgDot + +#endif // __DOTBASEVISITOR_H__ diff --git a/src/osgPlugins/dot/CMakeLists.txt b/src/osgPlugins/dot/CMakeLists.txt new file mode 100644 index 000000000..1914c106d --- /dev/null +++ b/src/osgPlugins/dot/CMakeLists.txt @@ -0,0 +1,6 @@ +#this file is automatically generated by rschmidt + +SET(TARGET_SRC SimpleDotVisitor.cpp BaseDotVisitor.cpp ReaderWriterDOT.cpp) + +#### end var setup ### +SETUP_PLUGIN(dot) diff --git a/src/osgPlugins/dot/ReaderWriterDOT.cpp b/src/osgPlugins/dot/ReaderWriterDOT.cpp new file mode 100644 index 000000000..adef25ea2 --- /dev/null +++ b/src/osgPlugins/dot/ReaderWriterDOT.cpp @@ -0,0 +1,41 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ +#include +#include +#include +#include "SimpleDotVisitor.h" + +class ReaderWriterDOT : public osgDB::ReaderWriter { + public: + virtual const char* className() const { return "DOT Writer"; } + virtual bool acceptsExtension(const std::string& extension) const { return osgDB::equalCaseInsensitive(extension,"dot"); } + + virtual WriteResult writeNode(const osg::Node& node,const std::string& fileName,const Options* options = NULL) const { + std::ofstream o( fileName.c_str(), std::ios_base::out ); + if ( o ) { + return writeNode( node, o, options ); + } + + return WriteResult(WriteResult::ERROR_IN_WRITING_FILE); + } + + virtual WriteResult writeNode(const osg::Node& node,std::ostream& fout,const Options* options = NULL) const { + osgDot::SimpleDotVisitor sdv; + sdv.run( *const_cast( &node ), &fout ); + return WriteResult(WriteResult::FILE_SAVED); + } +}; + +// now register with Registry to instantiate the above +// reader/writer. +REGISTER_OSGPLUGIN(dot, ReaderWriterDOT) diff --git a/src/osgPlugins/dot/SimpleDotVisitor.cpp b/src/osgPlugins/dot/SimpleDotVisitor.cpp new file mode 100644 index 000000000..a46170853 --- /dev/null +++ b/src/osgPlugins/dot/SimpleDotVisitor.cpp @@ -0,0 +1,93 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include "SimpleDotVisitor.h" + +namespace osgDot { + + SimpleDotVisitor::SimpleDotVisitor() { + } + + SimpleDotVisitor::~SimpleDotVisitor() { + } + + void SimpleDotVisitor::handle(osg::Node& node, int id) { + std::stringstream label; + label << " Node"; + if ( !node.getName().empty() ) { label << "| " << node.getName(); } + drawNode( id, "record", "solid", label.str(), "black", "white" ); + } + + void SimpleDotVisitor::handle(osg::Geode& node, int id) { + std::stringstream label; + label << " " << node.className(); + if ( !node.getName().empty() ) { label << "| " << node.getName(); } + drawNode( id, "record", "solid", label.str(), "black", "white" ); + } + + void SimpleDotVisitor::handle(osg::Group& node, int id) { + std::stringstream label; + label << " " << node.className(); + if ( !node.getName().empty() ) { label << "| " << node.getName(); } + drawNode( id, "record", "solid", label.str(), "black", "white" ); + } + + void SimpleDotVisitor::handle(osg::Group& parent, osg::Node& child, int parentID, int childID ) { + drawEdge( parentID, childID, "setlinewidth(2)" ); + } + + void SimpleDotVisitor::handle(osg::StateSet& stateset, int id) { + std::stringstream label; + label << " " << stateset.className(); + if ( !stateset.getName().empty() ) { label << "| " << stateset.getName(); } + drawNode( id, "record", "solid, filled", label.str(), "gray90", "white" ); + } + + void SimpleDotVisitor::handle(osg::Node& node, osg::StateSet& stateset, int parentID, int childID ) { + drawEdge( parentID, childID, "dashed" ); + } + + void SimpleDotVisitor::handle(osg::Drawable& drawable, int id) { + std::stringstream label; + label << " " << drawable.className(); + if ( !drawable.getName().empty() ) { label << "| " << drawable.getName(); } + drawNode( id, "record", "solid, filled", label.str(), "gray90", "white" ); + } + + void SimpleDotVisitor::handle(osg::Geode& geode, osg::Drawable& drawable, int parentID, int childID ) { + drawEdge( parentID, childID, "dashed" ); + } + + void SimpleDotVisitor::handle(osg::Drawable& drawable, osg::StateSet& stateset, int parentID, int childID ) { + drawEdge( parentID, childID, "dashed" ); + } + + void SimpleDotVisitor::drawNode( int id, const std::string& shape, const std::string& style, const std::string& label, const std::string& color, const std::string& fillColor ) { + _nodes << id << + "[shape=\"" << shape << + "\" ,label=\"" << label << + "\" ,style=\"" << style << + "\" ,color=\"" << color << + "\" ,fillColor=\"" << fillColor << + "\"]" << std::endl; + } + + void SimpleDotVisitor::drawEdge( int sourceId, int sinkId, const std::string& style ) { + _edges + << sourceId << ":top -> " + << sinkId << ":top [style=\"" + << style << "\"];" + << std::endl; + } + +} // namespace osgDot diff --git a/src/osgPlugins/dot/SimpleDotVisitor.h b/src/osgPlugins/dot/SimpleDotVisitor.h new file mode 100644 index 000000000..4c3a94235 --- /dev/null +++ b/src/osgPlugins/dot/SimpleDotVisitor.h @@ -0,0 +1,53 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#pragma once +#ifndef __SIMPLEDOTVISITOR_H__ +#define __SIMPLEDOTVISITOR_H__ + +#ifndef __cplusplus +#error "this is a c++ - header!" +#endif + +#include "BaseDotVisitor.h" + +namespace osgDot { + + class SimpleDotVisitor : public BaseDotVisitor { + public: + SimpleDotVisitor(); + + virtual ~SimpleDotVisitor(); + + protected: + virtual void handle(osg::Node& node, int id); + virtual void handle(osg::Geode& geode, int id); + virtual void handle(osg::Group& node, int id); + + virtual void handle(osg::StateSet& stateset, int id); + virtual void handle(osg::Drawable& drawable, int id); + + virtual void handle(osg::Node& node, osg::StateSet& stateset, int parentID, int childID ); + virtual void handle(osg::Geode& geometry, osg::Drawable& drawable, int parentID, int childID ); + virtual void handle(osg::Group& parent, osg::Node& child, int parentID, int childID ); + virtual void handle(osg::Drawable& drawable, osg::StateSet& stateset, int parentID, int childID ); + + virtual void drawNode( int id, const std::string& shape, const std::string& style, const std::string& label, const std::string& color, const std::string& fillColor ); + + virtual void drawEdge( int sourceId, int sinkId, const std::string& style ); + + }; + +} // namespace osgDot + +#endif // __SIMPLEDOTVISITOR_H__