Commit 9f985fc3 authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum

[ADD] - added basic project file loading functionality to kernel. Needs a lot of improvement.

parent 7db1cc05
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <string>
#include "WFileNotFound.h"
WFileNotFound::WFileNotFound( const std::string& msg )
: WException( msg )
{
// init members
}
WFileNotFound::~WFileNotFound() throw()
{
// clean up
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WFILENOTFOUND_H
#define WFILENOTFOUND_H
#include <string>
#include "../WException.h"
/**
* Thrown whenever a file was not found.
*/
class WFileNotFound : public WException
{
public:
/**
* Default constructor.
* \param msg the exception message.
*/
explicit WFileNotFound( const std::string& msg = "The file could not be found." );
/**
* Destructor.
*/
virtual ~WFileNotFound() throw();
protected:
private:
};
#endif // WFILENOTFOUND_H
......@@ -45,6 +45,7 @@
#include "WModule.h"
#include "WBatchLoader.h"
#include "WModuleFactory.h"
#include "WModuleProjectFileCombiner.h"
#include "../graphicsEngine/WGraphicsEngine.h"
......@@ -182,6 +183,10 @@ void WKernel::threadMain()
}
}
// TODO(ebaum): remove!
WModuleProjectFileCombiner mc = WModuleProjectFileCombiner( "/home/ebaum/test.prj" );
mc.apply();
// actually there is nothing more to do here
waitForStop();
......
......@@ -162,7 +162,6 @@ public:
*/
static std::string getShaderPath();
/**
* get for roi manager
*/
......
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include "WKernel.h"
#include "WModuleContainer.h"
#include "WModuleCombiner.h"
WModuleCombiner::WModuleCombiner( boost::shared_ptr< WModuleContainer > target ):
m_container( target )
{
// initialize members
}
WModuleCombiner::WModuleCombiner():
m_container( WKernel::getRunningKernel()->getRootContainer() )
{
// initialize members
}
WModuleCombiner::~WModuleCombiner()
{
// cleanup
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WMODULECOMBINER_H
#define WMODULECOMBINER_H
#include "WModuleContainer.h"
/**
* This is a base class for all module combination classes. The basic idea is to hide the actual combination work from others. These classes may
* be useful in the GUI. The GUI can create a module combiner instance in a special way, with an interface the GUI wants to have. Then, the
* kernel can construct the actual module graph out of it. Another purpose is some kind of project file loading. One can write a combiner which
* loads projects files and creates a module graph out of it. The only think which all the combiners need to know: the target container. Derive
* all specific combiner classes from this one.
*/
class WModuleCombiner
{
public:
/**
* Creates an empty combiner.
*
* \param target the target container where to add the modules to.
*/
WModuleCombiner( boost::shared_ptr< WModuleContainer > target );
/**
* Creates an empty combiner. This constructor automatically uses the kernel's root container as target container.
*/
WModuleCombiner();
/**
* Destructor.
*/
virtual ~WModuleCombiner();
/**
* Apply the internal module structure to the target container. Be aware, that this operation might take some time, as modules can be
* connected only if they are "ready", which, at least with WMData modules, might take some time.
*
*/
virtual void apply() = 0;
protected:
/**
* The module container to use for the modules.
*/
boost::shared_ptr< WModuleContainer > m_container;
private:
};
#endif // WMODULECOMBINER_H
......@@ -120,6 +120,8 @@ void WModuleFactory::load()
boost::shared_ptr< WModule > WModuleFactory::create( boost::shared_ptr< WModule > prototype )
{
wlog::debug( "ModuleFactory" ) << "Creating new instance of prototype \"" << prototype->getName() << "\".";
// for this a read lock is sufficient
boost::shared_lock< boost::shared_mutex > slock = boost::shared_lock< boost::shared_mutex >( m_prototypesLock );
......
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <iostream>
#include <map>
#include <utility>
#include <boost/regex.hpp>
#include <boost/lexical_cast.hpp>
#include "WKernel.h"
#include "WModuleCombiner.h"
#include "WModuleFactory.h"
#include "../common/exceptions/WFileNotFound.h"
#include "../common/WLogger.h"
#include "WModuleProjectFileCombiner.h"
WModuleProjectFileCombiner::WModuleProjectFileCombiner( boost::filesystem::path project, boost::shared_ptr< WModuleContainer > target ):
WModuleCombiner( target ),
m_project( project )
{
// initialize members
}
WModuleProjectFileCombiner::WModuleProjectFileCombiner( boost::filesystem::path project ):
WModuleCombiner( WKernel::getRunningKernel()->getRootContainer() ),
m_project( project )
{
// initialize members
}
WModuleProjectFileCombiner::~WModuleProjectFileCombiner()
{
// cleanup
}
void WModuleProjectFileCombiner::apply()
{
wlog::info( "Kernel" ) << "Loading project file \"" << m_project.file_string() << "\".";
// read the file
std::ifstream input( m_project.file_string().c_str() );
if ( !input.is_open() )
{
throw WFileNotFound( "The project file \"" + m_project.file_string() + "\" does not exist." );
}
// this is the proper regular expression for modules
static const boost::regex modRe ( "^MODULE:([0-9]*):(.*)$" );
static const boost::regex conRe ( "^CONNECTION:\\(([0-9]*),(.*)\\)->\\(([0-9]*),(.*)\\)$" );
static const boost::regex propRe( "^PROPERTY:\\(([0-9]*),(.*)\\)=(.*)$" );
static const boost::regex commentRe( "^//.*$" );
// some maps which describe the module graph
// These maps are used to read in the file and to later on build the actual graph
typedef std::pair< unsigned int, boost::shared_ptr< WModule > > ModuleID;
std::map< unsigned int, boost::shared_ptr< WModule > > modules;
// list of connections
typedef std::pair< unsigned int, std::string > Connector;
typedef std::pair< Connector, Connector > Connection;
std::list< Connection > connections;
// list of properties
typedef std::pair< unsigned int, std::string > Property;
typedef std::pair< Property, std::string > PropertyValue;
std::list< PropertyValue > properties;
// read it line by line
std::string line; // the current line
boost::smatch matches; // the list of matches
int i = 0; // line counter
while ( std::getline( input, line ) )
{
i++;
if ( boost::regex_match( line, matches, modRe ) )
{
// it is a module line
// matches[1] is the ID
// matches[2] is the name of the module
wlog::debug( "Project Loader [Parser]" ) << "Line " << i << ": Module \"" << matches[2] << "\" with ID " << matches[1];
// create a module instance
boost::shared_ptr< WModule > proto = WModuleFactory::getModuleFactory()-> isPrototypeAvailable( matches[2] );
if ( !proto )
{
wlog::error( "Project Loader" ) << "There is no prototype available for module \"" << matches[2] << "\". Skipping.";
}
else
{
boost::shared_ptr< WModule > module = WModuleFactory::getModuleFactory()->create( proto );
modules.insert( ModuleID( boost::lexical_cast< unsigned int >( matches[1] ), module ) );
}
}
else if ( boost::regex_match( line, matches, conRe ) )
{
// it is a connector line
// matches[1] and [2] are the module ID and connector name of the output connector
// matches[3] and [4] are the module ID and connector name of the target input connector
wlog::debug( "Project Loader [Parser]" ) << "Line " << i << ": Connection between \"" << matches[2] << "\" of module " << matches[1] <<
" and \"" << matches[4] << "\" of module " << matches[3] << ".";
// now we search in modules[ matches[1] ] for an output connector named matches[2]
connections.push_back( Connection( Connector( boost::lexical_cast< unsigned int >( matches[1] ), matches[2] ),
Connector( boost::lexical_cast< unsigned int >( matches[3] ), matches[4] ) ) );
}
else if ( boost::regex_match( line, matches, propRe ) )
{
// it is a property line
// matches[1] is the module ID
// matches[2] is the property name
// matches[3] is the property value
wlog::debug( "Project Loader [Parser]" ) << "Line " << i << ": Property \"" << matches[2] << "\" of module " << matches[1] << " set to " <<
matches[3];
properties.push_back( PropertyValue( Property( boost::lexical_cast< unsigned int >( matches[1] ), matches[2] ), matches[3] ) );
}
else if ( !line.empty() && !boost::regex_match( line, matches, commentRe ) )
{
wlog::debug( "Project Loader [Parser]" ) << "Line " << i << ": Malformed. Skipping.";
}
}
// close it
input.close();
// now, as we have created the modules, we need to set the properties for each of it.
for ( std::list< PropertyValue >::const_iterator iter = properties.begin(); iter != properties.end(); ++iter )
{
// grab corresponding module
if ( !modules.count( ( *iter ).first.first ) )
{
wlog::error( "Project Loader" ) << "There is no module with ID \"" << ( *iter ).first.first << "\" to set the property \"" <<
( *iter ).first.second << "\" for. Skipping.";
continue;
}
boost::shared_ptr< WModule > m = modules[ ( *iter ).first.first ];
// has this module the specified property?
boost::shared_ptr< WPropertyBase > prop = m->getProperties2()->findProperty( ( *iter ).first.second );
if ( !prop )
{
wlog::error( "Project Loader" ) << "The module \"" << m->getName() << "\" has no property named \"" <<
( *iter ).first.second << "\". Skipping.";
continue;
}
else
{
// set the property here
// TODO(ebaum): write
}
}
// now add each module to the target container
for ( std::map< unsigned int, boost::shared_ptr< WModule > >::const_iterator iter = modules.begin(); iter != modules.end(); ++iter )
{
m_container->add( ( *iter ).second );
}
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WMODULEPROJECTFILECOMBINER_H
#define WMODULEPROJECTFILECOMBINER_H
#include <boost/shared_ptr.hpp>
#include <boost/filesystem.hpp>
#include "WModuleCombiner.h"
/**
* This is a base class for all module combination classes. The basic idea is to hide the actual combination work from others. These classes may
* be useful in the GUI. The GUI can create a module combiner instance in a special way, with an interface the GUI wants to have. Then, the
* kernel can construct the actual module graph out of it. Another purpose is some kind of project file loading. One can write a combiner which
* loads projects files and creates a module graph out of it. The only think which all the combiners need to know: the target container. Derive
* all specific combiner classes from this one.
*/
class WModuleProjectFileCombiner: public WModuleCombiner
{
public:
/**
* Creates an empty combiner.
*
* \param target the target container where to add the modules to.
* \param project the project file to load.
*/
WModuleProjectFileCombiner( boost::filesystem::path project, boost::shared_ptr< WModuleContainer > target );
/**
* Creates an empty combiner. This constructor automatically uses the kernel's root container as target container.
*
* \param project the project file to load.
*/
WModuleProjectFileCombiner( boost::filesystem::path project );
/**
* Destructor.
*/
virtual ~WModuleProjectFileCombiner();
/**
* Apply the internal module structure to the target container. Be aware, that this operation might take some time, as modules can be
* connected only if they are "ready", which, at least with WMData modules, might take some time. It applies the loaded project file.
*
* \note the loader for project files is very tolerant. It does not abort. It tries to load as much as possible. The only exception that gets
* thrown whenever the file could not be opened.
*
* \throw WFileNotFound whenever the project file could not be opened.
*/
virtual void apply();
protected:
/**
* The project file path. This file gets loaded during apply().
*/
boost::filesystem::path m_project;
private:
};
#endif // WMODULEPROJECTFILECOMBINER_H
......@@ -97,6 +97,8 @@ void WMDirectVolumeRendering::properties()
"transfer function.", true );
m_isoValue = m_properties2->addProperty( "Isovalue", "The Isovalue used whenever the Isosurface Mode is turned on.",
50 );
m_isoColor = m_properties2->addProperty( "Iso Color", "The color to blend the isosurface with.", WColor( 1.0, 1.0, 1.0, 1.0 ),
m_propCondition );
}
void WMDirectVolumeRendering::moduleMain()
......@@ -141,6 +143,13 @@ void WMDirectVolumeRendering::moduleMain()
}
}
// m_isoColor changed
if ( m_isoColor->changed() )
{
// a new color requires the proxy geometry to be rebuild as we store it as color in this geometry
dataChanged = true;
}
// As the data has changed, we need to recreate the texture.
if ( dataChanged )
{
......@@ -158,7 +167,7 @@ void WMDirectVolumeRendering::moduleMain()
std::pair< wmath::WPosition, wmath::WPosition > bb = grid->getBoundingBox();
// use the OSG Shapes, create unit cube
osg::ref_ptr< osg::Node > cube = wge::generateSolidBoundingBoxNode( bb.first, bb.second, WColor( 0.0, 0.0, 0.0, 1.0 ) );
osg::ref_ptr< osg::Node > cube = wge::generateSolidBoundingBoxNode( bb.first, bb.second, m_isoColor->get( true ) );
m_shader->apply( cube );
// bind the texture to the node
......@@ -172,8 +181,10 @@ void WMDirectVolumeRendering::moduleMain()
// setup all those uniforms
osg::ref_ptr< osg::Uniform > isovalue = new osg::Uniform( "u_isovalue", static_cast< float >( m_isoValue->get() / 100.0 ) );
isovalue->setUpdateCallback( new SafeUniformCallback( this ) );
osg::ref_ptr< osg::Uniform > isosurface = new osg::Uniform( "u_isosurface", m_isoSurface->get() );
isosurface->setUpdateCallback( new SafeUniformCallback( this ) );
rootState->addUniform( isovalue );
rootState->addUniform( isosurface );
......
......@@ -127,6 +127,11 @@ private:
*/
WPropInt m_isoValue;
/**
* The color used when in isosurface mode for blending.
*/
WPropColor m_isoColor;
/**
* A condition used to notify about changes in several properties.
*/
......
......@@ -88,7 +88,7 @@ void main()
discard;
}
gl_FragColor = vec4( vec3( 1.0 - i / 150.0 ), 1.0 );
gl_FragColor = 0.5 * ( gl_Color + vec4( vec3( 1.0 - i / 250.0 ), 1.0 ) );
}
......
......@@ -70,5 +70,6 @@ void main()
// Simply project the vertex
gl_Position = ftransform();
gl_FrontColor = gl_Color;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment