Commit aacf47e5 authored by Alexander Wiebel's avatar Alexander Wiebel
Browse files

[MERGE]

parents c3d0ca72 8c9b5b7c
......@@ -152,5 +152,8 @@ ENDIF()
# Modules
# build modules
ADD_SUBDIRECTORY( modules )
OPTION( OW_MODULE_BUILD "Enable this to build the modules." ON )
IF( OW_MODULE_BUILD )
ADD_SUBDIRECTORY( modules )
ENDIF()
......@@ -65,7 +65,7 @@ namespace wlimits
*
* \return True if the value is a NaN, false otherwise.
*/
template< typename T > bool isnan( T value );
template< typename T > bool isNaN( T value );
/**
* Determines if a number is considered as infinity or not.
......@@ -76,15 +76,15 @@ namespace wlimits
*
* \return True if the value is infinity, false otherwise.
*/
template< typename T > bool isinf( T value );
template< typename T > bool isInf( T value );
}
template< typename T > bool wlimits::isnan( T value )
template< typename T > bool wlimits::isNaN( T value )
{
return boost::math::isnan( value );
}
template< typename T > bool wlimits::isinf( T value )
template< typename T > bool wlimits::isInf( T value )
{
return boost::math::isinf( value );
}
......
......@@ -57,6 +57,57 @@
*/
namespace string_utils
{
/**
* Conversion class to convert a string to a given target type. We place this in separate classes as we are not allowed to specialize
* function templates. But we need specializations for certain cases.
*
* \tparam Target target type
*/
template< typename Target >
struct fromStringImpl
{
/**
* Convert a given string to the target type. If this fails, a exception is thrown.
*
* \throw WTypeMismatch if source string cannot be converted to target type value.
*
* \param from source string
*
* \return target value
*/
static Target fromString( const std::string& from )
{
std::stringstream ss( from );
Target value;
ss >> value;
if( ss.fail() )
{
throw WTypeMismatch( "Specified string could not be converted to target type." );
}
return value;
}
};
/**
* Conversion class to convert a string to a given target type. This is a specialization whenever a string is given as input type
*/
template<>
struct fromStringImpl< std::string >
{
/**
* Convert a given string to the target type. Never fails.
*
* \param from source string
*
* \return copy of the source string
*/
static std::string fromString( const std::string& from )
{
return from;
}
};
/**
* Convert a given value to a string. The input value must provide a operator<< or be a standard scalar type.
*
......@@ -106,14 +157,7 @@ namespace string_utils
template< typename T >
inline T fromString( const std::string& str )
{
std::stringstream ss( str );
T value;
ss >> value;
if( ss.fail() )
{
throw WTypeMismatch( "Specified string could not be converted to target type." );
}
return value;
return fromStringImpl< T >::fromString( str );
}
/** We consider the following characters as whitespace:
......@@ -185,8 +229,8 @@ namespace string_utils
* \return A vector of strings containing the tokens.
*/
std::vector< std::string > tokenize( const std::string& source,
const std::string& delim = WHITESPACE,
bool compress = true );
const std::string& delim = WHITESPACE,
bool compress = true );
/**
* Writes every vector to an output stream such as cout, if its elements
......
......@@ -49,7 +49,7 @@
#include "exceptions/WNotFound.h"
/**
* This namespace contains the WStructuredTextParser data types and the parser. It builds up the abstract syntax tree (AST)
* This namespace contains the WStructuredTextParser data types and the parser. It builds up the abstract syntax tree (AST)
* for the given input which later can be traversed.
*/
namespace WStructuredTextParser
......@@ -186,14 +186,14 @@ namespace WStructuredTextParser
explicit Grammar( std::ostream& error ): Grammar::base_type( file, "WStructuredTextParser::Grammar" ) // NOLINT - non-const ref
{
// a key begins with a letter
key %= qi::char_( "a-zA-Z_" ) >> *qi::char_( "a-zA-Z_0-9" );
key %= qi::char_( "a-zA-Z_" ) >> *qi::char_( "a-zA-Z_0-9" );
// a value is a quoted string. Multi-line strings possible
value %= qi::lexeme[ '"' >> +( qi::char_ - '"' ) >> '"' ];
value %= '"' >> *( ~qi::char_( "\"" ) | qi::char_( " " ) ) >> '"';
// a pair is: key = value
kvpair %= key >> '=' >> value >> ';';
kvpair %= key >> '=' >> value >> ';';
// a comment is // + arbitrary symbols
comment %= qi::lexeme[ qi::char_( "/" ) >> qi::char_( "/" ) ] >>
qi::lexeme[ *qi::char_( "a-zA-Z_0-9!\"#$%&'()*,:;<>?@\\^`{|}~/ .@=[]§!+-" ) ];
comment %= qi::lexeme[ qi::char_( "/" ) >> qi::char_( "/" ) >> *qi::char_( "a-zA-Z_0-9!\"#$%&'()*,:;<>?@\\^`{|}~/ .@=[]§!+-" ) ];
// a object is a name, and a set of nested objects or key-value pairs
object %= ( key | value ) >> '{' >> *( object | kvpair | comment ) >> '}' >> *qi::char_( ";" );
// a file is basically an object without name.
......@@ -247,7 +247,7 @@ namespace WStructuredTextParser
/**
* Value rule. See constructor for exact definition.
*/
qi::rule< Iterator, ValueType(), ascii::space_type > value;
qi::rule< Iterator, ValueType() > value;
};
/**
......
......@@ -29,7 +29,6 @@
#include <boost/math/constants/constants.hpp>
#include "WLine.h"
#include "WPlane.h"
#include "linearAlgebra/WLinearAlgebra.h"
......@@ -50,22 +49,6 @@ const float piFloat = boost::math::constants::pi<float>();
*/
const double piDouble = boost::math::constants::pi<double>();
/**
* Tests whether the number stored in the parameter is finite.
* \param number the number to be tested
*/
inline int myIsfinite( double number )
{
#if defined( __linux__ ) || defined( __APPLE__ )
// C99 defines isfinite() as a macro.
return std::isfinite(number);
#elif defined( _WIN32 )
// Microsoft Visual C++ and Borland C++ Builder use _finite().
return _finite(number);
#else
WAssert( false, "isfinite not provided on this platform or platform not known." );
#endif
}
/**
* Checks if the triangle intersects with the given plane. If you are interested in the points of
* intersection if any \see intersection().
......
......@@ -25,6 +25,7 @@
#ifndef WSTRUCTUREDTEXTPARSER_TEST_H
#define WSTRUCTUREDTEXTPARSER_TEST_H
#include <iostream>
#include <string>
#include <vector>
......@@ -139,8 +140,10 @@ public:
// query only values here.
// this MUST return the first found value
TS_ASSERT( t.getValue< std::string >( "level0/notuniquekv", "default" ) == "hello" );
TS_ASSERT_EQUALS( t.getValue< std::string >( "level0/notuniquekv", "default" ), "hello hallo" );
TS_ASSERT( t.getValue< std::string >( "level0/notuniquelevel1/somekv", "default" ) == "abc" );
TS_ASSERT_EQUALS( t.getValue< std::string >( "level0/uniquekv", "default" ), "hello" );
// even if the object name is not unique, it needs to find the unique key value pair
TS_ASSERT( t.getValue< std::string >( "level0/notuniquelevel1/unique", "default" ) == "yes" );
......
......@@ -31,7 +31,7 @@ level0
// test whether the parser finds these key-value pairs (KV)
uniquekv = "hello";
// test if it is able to handle multile, equally named KV
notuniquekv = "hello";
notuniquekv = "hello hallo";
notuniquekv = "world";
// test whether it can handle sub-classes
......
......@@ -35,13 +35,13 @@ WDataSetDipole::WDataSetDipole()
}
WDataSetDipole::WDataSetDipole( WPosition dipPos, std::vector<float> mags, std::vector<float> times )
: m_dipolePosition( dipPos ), m_magnitudes( mags ), m_times( times )
{
WAssert( mags.size() == times.size(), "There has to be a magnitude for every time and vice versa." );
for( size_t id = 0; id < times.size() - 1; ++id )
{
WAssert( times[id] < times[id+1], "Times need to be ascending." );
}
addDipole( dipPos, mags, times );
}
WDataSetDipole::~WDataSetDipole()
......@@ -58,30 +58,48 @@ boost::shared_ptr< WPrototyped > WDataSetDipole::getPrototype()
return m_prototype;
}
WPosition WDataSetDipole::getPosition()
size_t WDataSetDipole::addDipole( WPosition dipPos, std::vector<float> mags, std::vector<float> times )
{
return m_dipolePosition;
Dipole dipole;
dipole.m_dipolePosition = dipPos;
dipole.m_magnitudes = mags;
dipole.m_times = times;
m_dipoles.push_back( dipole );
return m_dipoles.size() - 1;
}
float WDataSetDipole::getMagnitude( float time )
WPosition WDataSetDipole::getPosition( size_t dipoleId )
{
if( time < m_times[0] || time > m_times.back() )
return m_dipoles[dipoleId].m_dipolePosition;
}
size_t WDataSetDipole::getNumberOfDipoles()
{
return m_dipoles.size();
}
float WDataSetDipole::getMagnitude( float time, size_t dipoleId )
{
std::vector<float>& times = m_dipoles[dipoleId].m_times;
std::vector<float>& magnitudes = m_dipoles[dipoleId].m_magnitudes;
if( time < times[0] || time > times.back() )
{
return 0;
}
else
{
size_t upperBoundId;
for( size_t id = 0; id < m_times.size(); ++id )
for( size_t id = 0; id < times.size(); ++id )
{
if( time < m_times[id] )
if( time < times[id] )
{
upperBoundId = id - 1;
break;
}
}
float scale = ( time - m_times[upperBoundId-1] ) / ( m_times[upperBoundId] - m_times[upperBoundId-1] );
float magnitude = m_magnitudes[upperBoundId-1] + scale * ( m_magnitudes[upperBoundId] - m_magnitudes[upperBoundId-1] );
float scale = ( time - times[upperBoundId-1] ) / ( times[upperBoundId] - times[upperBoundId-1] );
float magnitude = magnitudes[upperBoundId-1] + scale * ( magnitudes[upperBoundId] - magnitudes[upperBoundId-1] );
return magnitude;
}
}
......@@ -26,11 +26,11 @@
#define WDATASETDIPOLE_H
#include <vector>
#include <boost/shared_ptr.hpp>
#include "WDataSet.h"
/**
* Represents a dipole dataset.
*/
......@@ -43,7 +43,8 @@ public:
WDataSetDipole();
/**
* Creates a new dipole with given information and checks consistency of the information.
* Creates a new dipole data set containing one dipole
* with the given information and checks consistency of the information.
*
* \param dipPos Spatial location of the dipole
* \param mags Magnitudes of dipole over time
......@@ -63,20 +64,40 @@ public:
*/
static boost::shared_ptr< WPrototyped > getPrototype();
/**
* Adds a new dipole with given information and checks consistency of the information.
*
* \param dipPos Spatial location of the dipole
* \param mags Magnitudes of dipole over time
* \param times Times for the dipole activity
*
* \return Id of the added dipole.
*/
size_t addDipole( WPosition dipPos, std::vector<float> mags, std::vector<float> times );
/**
* Return position of dipole.
*
* \param dipoleId Id number of dipole
* \return Position of the dipole.
*/
WPosition getPosition();
WPosition getPosition( size_t dipoleId = 0 );
/**
* Return magnitude of dipole for a given time.
*
* \param time The selected time.
* \param dipoleId Id number of dipole
* \return Magnitude of the dipole.
*/
float getMagnitude( float time );
float getMagnitude( float time, size_t dipoleId = 0 );
/**
* Return number of dipoles in this dataset
*
* \return number of dipoles in this dataset.
*/
size_t getNumberOfDipoles();
protected:
/**
......@@ -85,9 +106,18 @@ protected:
static boost::shared_ptr< WPrototyped > m_prototype;
private:
WPosition m_dipolePosition; //!< The location of the dipole
std::vector<float> m_magnitudes; //!< The magnitude of the dipole
std::vector<float> m_times; //!< Times for the different magnitudes
/**
* Internal class representing one dipole
*/
class Dipole
{
public:
WPosition m_dipolePosition; //!< The location of the dipole
std::vector<float> m_magnitudes; //!< The magnitude of the dipole
std::vector<float> m_times; //!< Times for the different magnitudes
};
std::vector< Dipole > m_dipoles; //!< List of dipoles representeing this dipoles dataset
};
#endif // WDATASETDIPOLE_H
......@@ -51,7 +51,7 @@ WDataSetTimeSeries::WDataSetTimeSeries( std::vector< boost::shared_ptr< WDataSet
{
WAssert( *dit, "" );
WAssert( g == boost::shared_dynamic_cast< WGridRegular3D >( ( *dit )->getGrid() ), "" );
WAssert( !wlimits::isnan( *tit ), "" );
WAssert( !wlimits::isNaN( *tit ), "" );
WAssert( d == ( *dit )->getValueSet()->getDataType(), "" );
WAssert( ( *dit )->getValueSet()->dimension() == 1, "" );
WAssert( ( *dit )->getValueSet()->order() == 0, "" );
......@@ -107,7 +107,7 @@ bool WDataSetTimeSeries::isTimeSlice( float time ) const
float WDataSetTimeSeries::findNearestTimeSlice( float time ) const
{
WAssert( !wlimits::isnan( time ), "" );
WAssert( !wlimits::isNaN( time ), "" );
if( time > getMaxTime() )
{
return getMaxTime();
......@@ -129,7 +129,7 @@ boost::shared_ptr< WDataSetScalar const > WDataSetTimeSeries::getDataSetPtrAtTim
boost::shared_ptr< WDataSetScalar const > WDataSetTimeSeries::calcDataSetAtTime( float time, std::string const& name ) const
{
WAssert( !wlimits::isnan( time ), "" );
WAssert( !wlimits::isNaN( time ), "" );
if( time < getMinTime() || time > getMaxTime() )
{
return boost::shared_ptr< WDataSetScalar const >();
......
......@@ -263,8 +263,8 @@ Data_T WDataSetTimeSeries::interpolate( WVector3d const& pos, float time, bool*
{
static const float inf = std::numeric_limits< float >::infinity();
WAssert( success, "" );
WAssert( !wlimits::isnan( length( pos ) ), "" );
WAssert( !wlimits::isnan( time ), "" );
WAssert( !wlimits::isNaN( length( pos ) ), "" );
WAssert( !wlimits::isNaN( time ), "" );
if( time < getMinTime() || time > getMaxTime() )
{
*success = false;
......
......@@ -49,7 +49,7 @@ namespace wtracking
// find t such that job.first() + t * dir is a point on the boundary of the current voxel
double t = getDistanceToBoundary( g, job.first, dir );
WAssert( !wlimits::isinf( t ) && !wlimits::isnan( t ), "Warning in WTrackingUtility::followToNextVoxel NaN's or INF's occured" );
WAssert( !wlimits::isInf( t ) && !wlimits::isNaN( t ), "Warning in WTrackingUtility::followToNextVoxel NaN's or INF's occured" );
WAssert( t > 0.0, "" );
WAssert( onBoundary( g, job.first + dir * t ), "" );
......
......@@ -37,7 +37,6 @@
#include <osg/Texture3D>
#include "callbacks/WGEFunctorCallback.h"
#include "../common/WLimits.h"
#include "../common/WBoundingBox.h"
#include "../common/WProperties.h"
#include "../common/WPropertyHelper.h"
......
......@@ -355,6 +355,15 @@ public:
* \return deprecation message
*/
std::string getDeprecationMessage() const;
/**
* The meta information of this module. This contains several information like name, description, icons, help links and so on. It, at least,
* contains the name.
*
* \return the meta info object for this module.
*/
virtual WModuleMetaInformation::ConstSPtr getMetaInformation() const;
protected:
/**
* Entry point after loading the module. Runs in separate thread.
......@@ -418,14 +427,6 @@ protected:
*/
virtual std::string deprecated() const;
/**
* The meta information of this module. This contains several information like name, description, icons, help links and so on. It, at least,
* contains the name.
*
* \return the meta info object for this module.
*/
virtual WModuleMetaInformation::ConstSPtr getMetaInformation() const;
/**
* Manages connector initialization. Gets called by module container.
*
......
......@@ -133,32 +133,36 @@ std::vector< WModuleMetaInformation::Author > WModuleMetaInformation::getAuthors
{
std::vector< WModuleMetaInformation::Author > r;
// did we find some author info? If not, add a nice default OpenWalnut author
WModuleMetaInformation::Author ow = { "OpenWalnut Project", "http://www.openwalnut.org", "", "Design, Development, and Bug Fixing" };
// return a default if not meta data was loaded
if( !m_loaded )
{
r.push_back( ow );
return r;
}
// how much author information is available?
std::vector< std::string > authors = m_metaData.getValues< std::string >( m_name + "/author" );
// prepare some memory
r.resize( authors.size() );
if( authors.empty() )
{
r.push_back( ow );
return r;
}
// for each author, get some associated data if available
// prepare some memory
r.resize( authors.size() );
for( std::vector< std::string >::const_iterator i = authors.begin(); i != authors.end(); ++i )
{
r[ i - authors.begin() ].m_name = *i;
r[ i - authors.begin() ].m_email = m_metaData.getValue< std::string >( m_name + "/" + *i + "/email", "" );
r[ i - authors.begin() ].m_what = m_metaData.getValue< std::string >( m_name + "/" + *i + "/what", "" );
r[ i - authors.begin() ].m_url = m_metaData.getValue< std::string >( m_name + "/" + *i + "/url", "" );
}
// did we find some author info? If not, add a nice default OpenWalnut author
if( !r.size() )
{
WModuleMetaInformation::Author ow = { "OpenWalnut Project", "", "http://www.openwalnut.org", "Design, Development and Bug fixing" };
r.push_back( ow );
}
return r;
}
......@@ -210,3 +214,38 @@ std::vector< std::string > WModuleMetaInformation::getTags() const
return m_metaData.getValues< std::string >( m_name + "/tag" );
}
std::vector< WModuleMetaInformation::Screenshot > WModuleMetaInformation::getScreenshots() const
{
std::vector< WModuleMetaInformation::Screenshot > r;
// return a default if not meta data was loaded
if( !m_loaded )
{
return r;
}
// get the "screenshot"-subtrees
typedef std::vector< WStructuredTextParser::StructuredValueTree > TreeList;
TreeList screenshotInfos = m_metaData.getSubTrees( m_name + "/screenshot" );
for( TreeList::const_iterator i = screenshotInfos.begin(); i != screenshotInfos.end(); ++i )
{
WModuleMetaInformation::Screenshot s;
// get all info:
// these are required
s.m_filename = ( *i ).getValue< boost::filesystem::path >( "filename", "" );
if( s.m_filename.empty() )
{
continue;
}
// optional
s.m_description = ( *i ).getValue< std::string >( "description", "" );
// add
r.push_back( s );
}
return r;
}
......@@ -103,6 +103,22 @@ public:
std::string m_url;
};
/**
* Structure to encapsulate a screenshot info
*/
struct Screenshot
{
/**
* The screenshot filename
*/
boost::filesystem::path m_filename;
/**
* The description text shown for the screenshot.
*/
std::string m_description;
};
/**
* Constructor. The help object will be empty, meaning there is no further meta info available. The name is the only required value. Of
* course, this is of limited use in most cases.
......@@ -179,6 +195,13 @@ public:
* \return the tag list.
*/
std::vector< std::string > getTags() const;
/**
* Returns the list of screenshots.
*
* \return the screenshot list.
*/
std::vector< Screenshot > getScreenshots() const;
protected:
private:
/**
......
......@@ -422,7 +422,7 @@ WSymmetricSphericalHarmonic WMBermanTracking::createRandomODF( std::size_t i )
// "-", because the residuals in the input dataset have differing sign
q( k, 0 ) = v( k, 0 ) - ( m_dataSetResidual->getValueAt( i * v.rows() + z ) / ( sqrt( 1.0 - m_HMat( k, k ) ) ) );
WAssert( !wlimits::isnan( q( k, 0 ) ), "" );
WAssert( !wlimits::isNaN( q( k, 0 ) ), "" );