Commit aa8cad4f authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum

[MERGE]

parents 3f4c8829 8e0db2f3
......@@ -23,3 +23,7 @@ syntax: glob
.cproject
syntax: regexp
^Debug$
syntax: glob
.settings
syntax: glob
Release
all:
pdflatex openWalnutDesign
pdflatex openWalnutDesign
bibtex openWalnutDesign
bibtex openWalnutDesign
pdflatex openWalnutDesign
pdflatex openWalnutDesign
cp openWalnutDesign.pdf openWalnutDesignDocument.pdf
clean:
rm openWalnutDesign.aux openWalnutDesign.log openWalnutDesign.out openWalnutDesign.toc openWalnutDesign.bbl openWalnutDesign.blg openWalnutDesign.pdf openWalnutDesignDocument.pdf
......@@ -66,6 +66,8 @@ section stem from the following website:
\includegraphics[width=\textwidth]{WValue_hierachy}
\caption{The class hierarchy describing high-level values in OpenWalnut.}
\end{figure}
\section{Literature}
For a general overview on visualization in medicine \cite{Preim:2007:VMT} can be recommended.
\chapter{GUI}
The GUI module is the only part where we allow gui-toolkit related code. For example, this means that the use of any QT class is
......@@ -122,6 +124,6 @@ myValuePointer = getValuesPointer<float *>()
\begin{itemize}
\item Data can not be manipulated!
\end{itemize}
\bibliography{../../books}
\end{document}
......@@ -15,6 +15,8 @@ IF( CMAKE_HOST_SYSTEM MATCHES Linux )
SET( LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib CACHE PATH "The libraries will be put into this directory." )
ELSEIF( CMAKE_HOST_SYSTEM MATCHES Windows )
SET( LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin CACHE PATH "The libraries will be put into this directory." )
ELSEIF( CMAKE_HOST_SYSTEM MATCHES Darwin )
SET( LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib CACHE PATH "The libraries will be put into this directory." )
ELSE()
MESSAGE( FATAL_ERROR "Could not determine platform type! (expected Linux or Windows)!" )
ENDIF()
......@@ -30,7 +32,7 @@ ENDIF( CMAKE_BUILD_TYPE STREQUAL "Static" )
# To see which boost libs we currently use, you may run the following command
# in the trunk/src directory on a linux box to make some investigations:
# grep -i include `find . -type f` | grep boost | awk '{print $2}' | sort | uniq
FIND_PACKAGE( Boost REQUIRED program_options thread filesystem signals )
FIND_PACKAGE( Boost REQUIRED program_options thread system filesystem date_time signals )
ASSERT_GE_VERSION( "Boost" "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}" 1.36.0 )
INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIR} )
......@@ -54,10 +56,11 @@ FIND_PACKAGE( osg ${MIN_OSG_VERSION} REQUIRED )
FIND_PACKAGE( osgUtil ${MIN_OSG_VERSION} REQUIRED )
FIND_PACKAGE( osgDB ${MIN_OSG_VERSION} REQUIRED )
FIND_PACKAGE( osgViewer ${MIN_OSG_VERSION} REQUIRED )
FIND_PACKAGE( osgText ${MIN_OSG_VERSION} REQUIRED )
FIND_PACKAGE( osgGA ${MIN_OSG_VERSION} REQUIRED )
FIND_PACKAGE( OpenThreads ${MIN_OSG_VERSION} REQUIRED )
SET( OPENSCENEGRAPH_LIBRARIES ${OSGDB_LIBRARY} ${OSGGA_LIBRARY} ${OSGUTIL_LIBRARY} ${OSGVIEWER_LIBRARY} ${OSG_LIBRARY} ${OPENTHREADS_LIBRARY} )
SET( OPENSCENEGRAPH_INCLUDE_DIRS ${OSG_INCLUDE_DIR} ${OSGDB_INCLUDE_DIR} ${OSGGA_INCLUDE_DIR} ${OSGVIEWER_INCLUDE_DIR} ${OSGUTIL_INCLUDE_DIR} ${OPENTHREADS_INCLUDE_DIR} )
SET( OPENSCENEGRAPH_LIBRARIES ${OSGDB_LIBRARY} ${OSGTEXT_LIBRARY} ${OSGGA_LIBRARY} ${OSGUTIL_LIBRARY} ${OSGVIEWER_LIBRARY} ${OSG_LIBRARY} ${OPENTHREADS_LIBRARY} )
SET( OPENSCENEGRAPH_INCLUDE_DIRS ${OSG_INCLUDE_DIR} ${OSGDB_INCLUDE_DIR} ${OSGTEXT_INCLUDE_DIR} ${OSGGA_INCLUDE_DIR} ${OSGVIEWER_INCLUDE_DIR} ${OSGUTIL_INCLUDE_DIR} ${OPENTHREADS_INCLUDE_DIR} )
# When new cmake version available >=2.6.4 we may use this the line below instead the stuff above
# FIND_PACKAGE( OpenSceneGraph 2.8.0 REQUIRED osgDB osgUtil osgGA osgViewer OpenThreads )
INCLUDE_DIRECTORIES( ${OPENSCENEGRAPH_INCLUDE_DIRS} )
......@@ -95,7 +98,7 @@ IF( NOT CMAKE_BUILD_TYPE STREQUAL "Static" )
ADD_SUBDIRECTORY( kernel )
ADD_SUBDIRECTORY( common )
ADD_EXECUTABLE( walnut OpenWalnut.cpp utils/WOptionHandler.cpp )
TARGET_LINK_LIBRARIES( walnut kernel dataHandler guiqt4 common ${Boost_LIBRARIES} )
TARGET_LINK_LIBRARIES( walnut kernel dataHandler gui guiqt4 common ${Boost_LIBRARIES} )
ELSE( NOT CMAKE_BUILD_TYPE STREQUAL "Static" )
FILE( GLOB_RECURSE ALL_SRC ${PROJECT_SOURCE_DIR}/*.cpp )
......@@ -104,7 +107,6 @@ ELSE( NOT CMAKE_BUILD_TYPE STREQUAL "Static" )
# Package dependencies:
FIND_PACKAGE( Qt4 REQUIRED )
FIND_PACKAGE( GLEW REQUIRED )
# Includes:
INCLUDE_DIRECTORIES( ${QT_INCLUDE_DIR} )
......@@ -118,7 +120,7 @@ ELSE( NOT CMAKE_BUILD_TYPE STREQUAL "Static" )
QT4_WRAP_CPP( GUI_QT4_MOC_SRCS ${GUI_QT4_MOC_HDRS} )
ADD_EXECUTABLE( walnut ${ALL_SRC} ${NIFTI_SRC} ${GUI_QT4_MOC_SRCS} )
TARGET_LINK_LIBRARIES( walnut ${Boost_LIBRARIES} ${OSG_LIBRARIES} ${QT_LINK_LIBRARIES} ${GLEW_LIBRARY} )
TARGET_LINK_LIBRARIES( walnut ${Boost_LIBRARIES} ${OSG_LIBRARIES} ${QT_LINK_LIBRARIES} )
ENDIF ( NOT CMAKE_BUILD_TYPE STREQUAL "Static" )
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/bin/shaders)
......@@ -207,7 +209,7 @@ ADD_CUSTOM_TARGET( cleantest
#-------------------------------------------------------------------------------------------------------------
# Checks if all is well to commit (aka commitCheck, cicheck)
ADD_CUSTOM_TARGET( cicheck
COMMAND make test && make stylecheck
COMMAND make stylecheck && make test
COMMENT "Checks if all is well to commit"
)
......@@ -227,3 +229,12 @@ ADD_CUSTOM_TARGET( many
cmake . && make all -j4 && make fixtures && make stylecheck && make test && make doc
COMMENT "Make many special make targets in combination."
)
#-------------------------------------------------------------------------------------------------------------
# Make target for MacOS. The difference to the normal one is that we need to fix some paths in libraries.
IF( CMAKE_HOST_SYSTEM MATCHES Darwin )
ADD_CUSTOM_TARGET( macos
make all && ${PROJECT_SOURCE_DIR}/../tools/MacOS/macOS_install_tool
COMMENT "Make on MacOS. This incudes fixing paths in libraries."
)
ENDIF()
......@@ -26,6 +26,10 @@
#include "common/WException.h"
#include "common/WSegmentationFault.h"
#include "common/WLogger.h"
#include "gui/WGUI.h"
#include "gui/qt4/WMainApplication.h"
#include "kernel/WKernel.h"
......@@ -51,8 +55,16 @@ int main( int argc, char* argv[] )
// install signal handler as early as possible
WSegmentationFault::installSignalHandler();
// initialize GUI
boost::shared_ptr< WGUI > gui = boost::shared_ptr< WGUI >( new WMainApplication() );
// init logger
WLogger logger;
logger.run();
// init the kernel
WKernel kernel = WKernel( argc, argv );
WKernel kernel = WKernel( argc, argv, gui );
int code = kernel.run();
return code;
}
//---------------------------------------------------------------------------
//
// 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 <boost/algorithm/string.hpp>
#include "WLogEntry.h"
WLogEntry:: WLogEntry( std::string logTime, std::string message, LogLevel level, std::string source )
: m_time( logTime ),
m_message( message ),
m_level( level ),
m_source( source )
{
}
WLogEntry::~WLogEntry()
{
}
std::string WLogEntry::getLogString( std::string format )
{
std::string s = format;
boost::ireplace_first( s, "%t", m_time );
switch ( m_level )
{
case LL_DEBUG:
boost::ireplace_first( s, "%l", "DEBUG " );
break;
case LL_INFO:
boost::ireplace_first( s, "%l", "INFO " );
break;
case LL_WARNING:
boost::ireplace_first( s, "%l", "WARNING" );
break;
case LL_ERROR:
boost::ireplace_first( s, "%l", "ERROR " );
break;
default:
break;
}
boost::ireplace_first( s, "%m", m_message );
boost::ireplace_first( s, "%s", m_source );
return s;
}
LogLevel WLogEntry::getLogLevel()
{
return m_level;
}
//---------------------------------------------------------------------------
//
// 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 WLOGENTRY_H
#define WLOGENTRY_H
#include <string>
/**
* Various log levels, to distinguish output on its level.
*/
typedef enum
{
LL_DEBUG = 0,
LL_INFO,
LL_WARNING,
LL_ERROR
}
LogLevel;
/**
* Represents a simple log message with some attributes.
*/
class WLogEntry
{
public:
/**
* Construtcs a log message entry
*/
WLogEntry( std::string logTime, std::string message, LogLevel level, std::string source = "" );
/**
* Destroys a log message entry.
*/
virtual ~WLogEntry();
/**
* \return String of this log entry.
*/
std::string getLogString( std::string format = "[%t] *%l* %m \n" );
/**
* \return log level of this entry.
*/
LogLevel getLogLevel();
protected:
private:
/**
* The time the log message was received
*/
std::string m_time;
/**
* The actual message
*/
std::string m_message;
/**
* Log level
*/
LogLevel m_level;
/**
* Source (e.g. module name) where this log message comes from.
*/
std::string m_source;
};
#endif // WLOGENTRY_H
//---------------------------------------------------------------------------
//
// 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 <string>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/filesystem/fstream.hpp>
#include "WLogger.h"
/**
* Used for program wide access to the logger.
*/
WLogger* logger = NULL;
WLogger::WLogger( std::string fileName, LogLevel level ):
WThreadedRunner(),
m_LogLevel( level ),
m_STDOUTLevel( level ),
m_STDERRLevel( LL_ERROR ),
m_LogFileLevel( level ),
m_LogFileName( fileName ),
m_QueueMutex()
{
logger = this;
addLogMessage( "Initalizing Logger", "Logger", LL_DEBUG );
addLogMessage( "===============================================================================", "Logger", LL_INFO );
addLogMessage( "= Starting Log Session =", "Logger", LL_INFO );
addLogMessage( "===============================================================================", "Logger", LL_INFO );
}
WLogger::~WLogger()
{
}
WLogger* WLogger::getLogger()
{
return logger;
}
void WLogger::setLogLevel( LogLevel level )
{
m_LogLevel = level;
}
void WLogger::setSTDOUTLevel( LogLevel level )
{
m_STDOUTLevel = level;
}
void WLogger::setSTDERRLevel( LogLevel level )
{
m_STDERRLevel = level;
}
void WLogger::setLogFileLevel( LogLevel level )
{
m_LogFileLevel = level;
}
void WLogger::setLogFileName( std::string fileName )
{
boost::filesystem::path p( fileName );
// TODO(schurade): check if this is a _VALID_ path (existence is not needed)
m_LogFileName = fileName;
}
void WLogger::addLogMessage( std::string message, std::string source, LogLevel level )
{
if ( m_LogLevel > level || m_FinishRequested )
{
return;
}
boost::posix_time::ptime t( boost::posix_time::second_clock::local_time() );
std::string timeString( to_simple_string( t ) );
WLogEntry entry( timeString, message, level, source );
boost::mutex::scoped_lock l( m_QueueMutex );
m_LogQueue.push( entry );
}
void WLogger::processQueue()
{
boost::mutex::scoped_lock l( m_QueueMutex );
while ( !m_LogQueue.empty() )
{
WLogEntry entry = m_LogQueue.front();
m_LogQueue.pop();
m_SessionLog.push_back( entry );
if ( entry.getLogLevel() >= m_STDOUTLevel )
{
std::cout << entry.getLogString();
}
if ( entry.getLogLevel() >= m_STDERRLevel )
{
std::cerr << entry.getLogString();
}
if ( entry.getLogLevel() >= m_LogFileLevel )
{
// TODO(schurade): first open file, then write to file, then close the file
// for atomic file usage.
boost::filesystem::path p( "walnut.log" );
boost::filesystem::ofstream ofs( p, boost::filesystem::ofstream::app );
ofs << entry.getLogString();
}
}
}
void WLogger::threadMain()
{
// Since the modules run in a separate thread: such loops are possible
while ( !m_FinishRequested )
{
processQueue();
// do fancy stuff
sleep( 1 );
}
// clean up stuff
}
......@@ -22,104 +22,134 @@
//
//---------------------------------------------------------------------------
#ifndef WLOADERVTK_TEST_H
#define WLOADERVTK_TEST_H
#ifndef WLOGGER_H
#define WLOGGER_H
#include <queue>
#include <string>
#include <vector>
#include <boost/filesystem.hpp>
#include <cxxtest/TestSuite.h>
#include <boost/shared_ptr.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/locks.hpp>
#include "../common/WThreadedRunner.h"
#include "../WLoaderVTK.h"
#include "../../WDataHandler.h"
#include "WLogEntry.h"
/**
* Unit tests the WLoaderVTK class.
* Does actual logging of WLogEntries down to stdout or something similar.
*/
class WLoaderVTKTest : public CxxTest::TestSuite
class WLogger: public WThreadedRunner
{
public:
/**
* Create test environment.
*/
void setUp( void )
{
m_dataHandler = boost::shared_ptr< WDataHandler >( new WDataHandler() );
m_vtkFile = boost::filesystem::path( "fixtures/VTK/ascii-2nd-order-tensor.vtk" );
assert( boost::filesystem::exists( m_vtkFile ) );
}
/**
* A valid "header" of a VTK file consists of 4 lines of text (this is
* arbitrary specified by me, the author of this class)
* 1. VTK version stuff
* 2. VTK description header stuff (max 256 chars)
* 3. BINARY or ASCII
* 4. DATASET type
*
* Further description about the DATASET e.g. ORIGIN in case of
* STRUCTURED_POINTS does not belong to the header.
* Constructor
*/
WLogger( std::string fileName = "walnut.log", LogLevel level = LL_DEBUG );
/**
* Destructor.
*/
virtual ~WLogger();
/**
* Returns pointer to the currently running logger instance.
*
* FYI: It makes really sense to restrict the header to 4 lines since since
* every VTK file must have at least 4 lines describing in ASCII what comes
* next.
*/
void testReadHeader( void )
{
WLoaderVTK loader( m_vtkFile.string(), m_dataHandler );
loader.readHeader();
std::vector< std::string > expected;
expected.push_back( "# vtk DataFile Version 3.0" );
expected.push_back( "vtk output" );
expected.push_back( "ASCII" );
expected.push_back( "DATASET STRUCTURED_POINTS" );
TS_ASSERT_EQUALS( loader.m_header, expected );
}
/**
* If the path is not valid there should be thrown an exception
*/
void testReadHeaderOnInvalidFile( void )
{
WLoaderVTK loader( "no/such/file", m_dataHandler );
TS_ASSERT_THROWS_EQUALS( loader.readHeader(),
const WDHIOFailure &e,
e.what(),
std::string( "Invalid file or filename: no/such/file" ) );
}
/**
* If the header introduces a STRUCTURED_POINTS VTK DATASET then true
* should be returned.
*/
void testCheckDatasetType( void )
{
WLoaderVTK loader( m_vtkFile.string(), m_dataHandler );
loader.readHeader();
TS_ASSERT_EQUALS( loader.datasetTypeIs( "STRUCTURED_POINTS" ), true );
}
/**
* A VTK file is typically either in BINARY or ASCII format.
*/
void testBinaryOrAscii( void )
{
WLoaderVTK loader( m_vtkFile.string(), m_dataHandler );
loader.readHeader();
TS_ASSERT_EQUALS( loader.isBinary(), false );
}
* \return pointer to logger instance.
*/
static WLogger* getLogger();
/**
* Sets the global log level
*/
void setLogLevel( LogLevel level );
/**
* Sets the log level for stdout.
*/
void setSTDOUTLevel( LogLevel level );
/**
* Sets the log level for stderr.
*/
void setSTDERRLevel( LogLevel level );
/**
* Sets the log level for the given log file.
*/
void setLogFileLevel( LogLevel level );
/**