Index: /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/BenchTimer.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/BenchTimer.cpp	(revision 2777)
+++ /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/BenchTimer.cpp	(revision 2777)
@@ -0,0 +1,64 @@
+// ===========================================================================
+//  (C) 1999 Vienna University of Technology
+// ===========================================================================
+//  NAME:       BenchTimer
+//  TYPE:       c++ code
+//  PROJECT:    Urban Viz/yare (yet another rendering engine)
+//  CONTENT:    Very accurate timer for Win32 systems
+//				(uses QueryPerformanceCounter, usually microseconds)
+//  VERSION:    0.1
+// ===========================================================================
+//  AUTHORS:    mw      Michael Wimmer
+// ===========================================================================
+//  HISTORY:
+//
+//  15-jul-99 14:00:00  mw      created
+// ===========================================================================
+//  $Header: /usr/local/cvsyare/cvsyamp/src/yareutils/BenchTimer.cpp,v 1.1 2002/11/14 15:22:58 wimmer Exp $ 
+// ===========================================================================
+
+#ifdef WIN32
+
+#include "BenchTimer.h"
+
+#include "merror.h"
+
+// ---------------------------------------------------------------------------
+//  class BenchTimer implementation
+// ---------------------------------------------------------------------------
+
+
+LARGE_INTEGER BenchTimer::frequency;
+bool BenchTimer::isinitialized = false;
+bool BenchTimer::available = false;
+
+// this retrieves the timer frequency - will be called by constructor
+void BenchTimer::InitClass(bool verbose)
+{
+	if (QueryPerformanceFrequency(&frequency))
+	{
+		available = true;
+		if (verbose)
+			//OUT1(SV(double(frequency.QuadPart)));
+			OUT1("QueryPerformanceCounter Frequency: " << double(frequency.QuadPart));
+	}
+	else
+	{
+		EOUT("No high resolution perfomance counter installed!");
+		available = false;
+		frequency.QuadPart = 1;
+	}
+
+	isinitialized = true;
+}
+
+/// returns the frequency
+double BenchTimer::GetFrequency(bool verbose)
+{
+	if (!isinitialized)
+		InitClass(verbose);
+	
+	return double(frequency.QuadPart);
+}
+
+#endif // WIN32
Index: /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/RDTSCTimer.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/RDTSCTimer.cpp	(revision 2777)
+++ /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/RDTSCTimer.cpp	(revision 2777)
@@ -0,0 +1,175 @@
+// ===========================================================================
+//  (C) 1999 Vienna University of Technology
+// ===========================================================================
+//  NAME:       RDTSCTimer
+//  TYPE:       c++ code
+//  PROJECT:    Urban Viz/yare (yet another rendering engine)
+//  CONTENT:    Very accurate timer for Win32 systems
+//				(uses QueryPerformanceCounter, usually microseconds)
+//  VERSION:    0.1
+// ===========================================================================
+//  AUTHORS:    mw      Michael Wimmer
+// ===========================================================================
+//  HISTORY:
+//
+//  15-jul-99 14:00:00  mw      created
+// ===========================================================================
+//  $Header: /usr/local/cvsyare/cvsyare/src/yareutils/RDTSCTimer.cpp,v 1.2 2005/03/07 17:32:09 wimmer Exp $ 
+// ===========================================================================
+
+#ifdef WIN32
+
+#include "RDTSCTimer.h"
+
+#include "merror.h"
+
+
+// ---------------------------------------------------------------------------
+//  class RDTSCTimer implementation
+// ---------------------------------------------------------------------------
+
+LARGE_INTEGER RDTSCTimer::frequency = {0,1};
+bool RDTSCTimer::isinitialized = false;
+bool RDTSCTimer::available = false;
+
+// this retrieves the timer frequency - will be called by constructor
+void RDTSCTimer::InitClass(bool verbose)
+{
+	isinitialized = true;
+	available = true;
+
+    if (verbose)
+		OUT1(("Calibrating RDTSC-Timer at real-time priority...."));
+
+	// Increase process class
+	HANDLE	hProcess = GetCurrentProcess();
+	DWORD	iPriorityClass = GetPriorityClass(hProcess);
+	ASM_ELSE(iPriorityClass, "couldnt change priority class")
+		SetPriorityClass(hProcess, REALTIME_PRIORITY_CLASS);
+	
+	// Increase thread priority 
+	HANDLE 	hThread = GetCurrentThread();
+	DWORD	iPriority = GetThreadPriority(hThread);
+	ASM_ELSE(iPriority != THREAD_PRIORITY_ERROR_RETURN, "couldnt change thread priority")
+		SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
+	
+
+	// Measure CPU frequency
+	LARGE_INTEGER PerfFreq;
+    LARGE_INTEGER  calStart, calEnd;
+    LARGE_INTEGER  perfStart, perfEnd;
+	
+	// warmup
+	RDTSC(calStart);
+	RDTSC(calStart);
+	RDTSC(calStart);
+
+	ASM_RET( QueryPerformanceFrequency( &PerfFreq ), "QueryPerformanceCounter not available for calibrating!");
+	QueryPerformanceCounter( &perfStart );
+    RDTSC(calStart);
+		LARGE_INTEGER endmark; endmark.QuadPart = perfStart.QuadPart + PerfFreq.QuadPart;
+		do { 
+			QueryPerformanceCounter( &perfEnd ); 
+		} while (perfEnd.QuadPart < endmark.QuadPart);
+    RDTSC(calEnd);
+    
+
+	// number of Bench cycles counted
+	LARGE_INTEGER perfcounts; perfcounts.QuadPart = perfEnd.QuadPart - perfStart.QuadPart;
+	// number of RDTSC cycles counted
+	LARGE_INTEGER calcounts; calcounts.QuadPart = calEnd.QuadPart - calStart.QuadPart;
+	// note: this might overflow if processor is over 6GHz:
+	unsigned __int64 temp = calcounts.QuadPart * PerfFreq.QuadPart;
+	frequency.QuadPart = temp / perfcounts.QuadPart;
+
+	//if (verbose)
+	//	OUT1( SV(perfcounts.LowPart)<<SV(calcounts.LowPart)<<SV(calcounts.HighPart)<<SV(PerfFreq.LowPart));
+
+    //
+    // Number of calibration loops
+    //
+	#define CALIBRATION_LOOPS 50000
+
+	///--- measure overhead of different calling conventions
+	
+	ULONG  i;
+	
+	//-- Start/Elapsed overhead
+
+	RDTSCTimer mytimer2;
+    RDTSC(calStart);
+	for( i = 0; i < CALIBRATION_LOOPS; i++ ) {
+        PERF_ENTRY(mytimer2);
+        PERF_EXIT(mytimer2);
+    }
+    RDTSC(calEnd);
+
+	LARGE_INTEGER	CalEntryExitCycles, CalCountedCycles;
+    CalEntryExitCycles.QuadPart = (calEnd.QuadPart - calStart.QuadPart)/CALIBRATION_LOOPS;
+	CalCountedCycles.QuadPart = mytimer2.total_count.QuadPart / CALIBRATION_LOOPS;
+
+
+/*	RDTSCTimer mytimer;
+    RDTSC(calStart);
+	for( i = 0; i < CALIBRATION_LOOPS; i++ ) {
+        mytimer.Start();
+        mytimer.Elapsed();
+    }
+    RDTSC(calEnd);
+
+	LARGE_INTEGER	CalStartElapsedCycles;
+    CalStartElapsedCycles.QuadPart = (calEnd.QuadPart - calStart.QuadPart)/CALIBRATION_LOOPS;
+    
+
+	RDTSCTimer mytimer3;
+    RDTSC(calStart);
+	for( i = 0; i < CALIBRATION_LOOPS; i++ ) {
+        mytimer3.Entry();
+		mytimer3.Exit();
+    }
+    RDTSC(calEnd);
+
+	LARGE_INTEGER	CalEntryExitCycles2, CalCountedCycles2;
+    CalEntryExitCycles2.QuadPart = (calEnd.QuadPart - calStart.QuadPart)/CALIBRATION_LOOPS;
+	CalCountedCycles2.QuadPart = mytimer3.total_count.QuadPart / CALIBRATION_LOOPS;
+*/
+
+    RDTSC(calStart);
+	for( i = 0; i < CALIBRATION_LOOPS; i++ ) {
+		QueryPerformanceCounter( &perfStart );
+		QueryPerformanceCounter( &perfStart );
+    }
+    RDTSC(calEnd);
+
+	LARGE_INTEGER	PerfEntryExitCycles;
+	PerfEntryExitCycles.QuadPart = (calEnd.QuadPart - calStart.QuadPart)/CALIBRATION_LOOPS;
+	
+	// Restore thread and process priority 
+	if (iPriority != THREAD_PRIORITY_ERROR_RETURN)
+		SetThreadPriority(hThread, iPriority);
+
+	if (iPriorityClass)
+		SetPriorityClass(hProcess, iPriorityClass);
+	
+
+	if (verbose)
+	{
+		OUT2("RDTSC frequency: " << frequency.LowPart << ", QueryPerformanceCounter frequency: " << PerfFreq.LowPart);
+		OUT2("Overhead for timer calls in clock cycles:");
+		//OUT2(CalStartElapsedCycles.LowPart << " for timer.start;timer.elapsed;");
+		OUT2(CalEntryExitCycles.LowPart << " for PERF_ENTRY/PERF_EXIT, cycles counted per call: " << CalCountedCycles.LowPart);
+		//OUT2(CalEntryExitCycles2.LowPart << " for Entry()/Exit(), cycles counted per call: " << CalCountedCycles2.LowPart);
+		OUT2(PerfEntryExitCycles.LowPart << " for QueryPerformanceCounter twice");
+	}
+}
+
+/// returns the frequency
+double RDTSCTimer::GetFrequency(bool verbose)
+{
+	if (!isinitialized)
+		InitClass(verbose);
+	
+	return (double)frequency.QuadPart;
+}
+
+#endif // WIN32
Index: /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/PerfTimer.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/PerfTimer.h	(revision 2777)
+++ /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/PerfTimer.h	(revision 2777)
@@ -0,0 +1,47 @@
+// ===========================================================================
+//  (C) 1999 Vienna University of Technology
+// ===========================================================================
+//  NAME:       PerfTimer
+//  TYPE:       c++ header
+//  PROJECT:    Urban Viz/yare (yet another rendering engine)
+//  CONTENT:    Wrapper for all the Performance Timers
+//  VERSION:    0.1
+// ===========================================================================
+//  AUTHORS:    mw      Michael Wimmer
+// ===========================================================================
+//  HISTORY:
+//
+//  15-jul-99 14:00:00  mw      created
+// ===========================================================================
+//  $Header: /usr/local/cvsyare/cvsyare/include/yareutils/PerfTimer.h,v 1.1 2002/09/24 16:53:47 wimmer Exp $ 
+// ===========================================================================
+
+#ifndef NO_PRAGMA_ONCE
+#pragma once
+#endif
+
+#ifndef _PERFTIMER_H
+#define _PERFTIMER_H
+
+//#define NO_RDTSC_TIMER
+
+#ifdef WIN32
+	#ifndef NO_RDTSC_TIMER
+		#include "RDTSCTimer.h"
+		typedef RDTSCTimer PerfTimer;
+	#elif !defined(NO_BENCH_TIMER)
+		#include "BenchTimer.h"
+		typedef BenchTimer PerfTimer;
+	#else // to get a dummy timer for compile checks without windows.h!
+		#define DUMMY_TIMER
+		#define PERFTIMER PerfTimer
+		#include "PerfTimerSkeleton.h"
+		#undef DUMMY_TIMER
+		#undef PERFTIMER
+	#endif
+#else
+	#include "SGITimer.h"
+	typedef SGITimer PerfTimer;
+#endif
+
+#endif // _PERFTIMER_H
Index: /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/BenchTimer.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/BenchTimer.h	(revision 2777)
+++ /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/BenchTimer.h	(revision 2777)
@@ -0,0 +1,70 @@
+// ===========================================================================
+//  (C) 1999 Vienna University of Technology
+// ===========================================================================
+//  NAME:       BenchTimer
+//  TYPE:       c++ header
+//  PROJECT:    Urban Viz/yare (yet another rendering engine)
+//  CONTENT:    Very accurate timer for Win32 systems
+//				(uses QueryPerformanceCounter, usually microseconds)
+//  VERSION:    0.1
+// ===========================================================================
+//  AUTHORS:    mw      Michael Wimmer
+// ===========================================================================
+//  HISTORY:
+//
+//  15-jul-99 14:00:00  mw      created
+// ===========================================================================
+//  $Header: /usr/local/cvsyare/cvsyare/src/yareutils/BenchTimer.h,v 1.1 2002/09/24 16:53:56 wimmer Exp $ 
+// ===========================================================================
+
+#ifndef NO_PRAGMA_ONCE
+#pragma once
+#endif
+
+#ifndef _BENCHTIMER_H
+#define _BENCHTIMER_H
+
+#ifdef WIN32
+
+#if !(_MSC_VER >= 1200)
+#define __forceinline inline 
+#endif
+
+// we definitely want timers to be inlined!
+#define PERFTIMER_INLINE __forceinline
+
+
+	#define WIN32_LEAN_AND_MEAN
+	#define NOMINMAX
+	#include <windows.h>	// for LARGE_INTEGER
+
+	#define PERFTIMER BenchTimer
+	
+	#define TIMEVAL_T LARGE_INTEGER
+	#define TIMEVAL_ZERO(__timval) (__timval).QuadPart = 0;
+	#define TIMEVAL_GET(__timval) QueryPerformanceCounter(&__timval);
+	#define TIMEVAL_TODOUBLE(__timval) 	((double)__timval.QuadPart / (double)frequency.QuadPart)
+	#define TIMEVAL_ASSIGN(__timval1, __timval2) __timval1.QuadPart = __timval2.QuadPart;
+
+	#define TIMEVAL_ADD(total, end, start) \
+		if (end.QuadPart > start.QuadPart) \
+			total.QuadPart += end.QuadPart - start.QuadPart; \
+		else \
+			total.QuadPart += MAXLONGLONG - end.QuadPart + start.QuadPart;
+	
+	#include "PerfTimerSkeleton.h"
+
+#else
+	#define DUMMY_TIMER
+	#include "PerfTimerSkeleton.h"
+	#undef DUMMY_TIMER
+#endif
+
+#undef PERFTIMER
+#undef TIMEVAL_ZERO
+//#undef TIMEVAL_GET
+#undef TIMEVAL_TODOUBLE
+#undef TIMEVAL_ASSIGN
+//#undef TIMEVAL_ADD
+
+#endif	// _BENCHTIMER_H
Index: /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/RDTSCTimer.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/RDTSCTimer.h	(revision 2777)
+++ /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/RDTSCTimer.h	(revision 2777)
@@ -0,0 +1,113 @@
+// ===========================================================================
+//  (C) 1999 Vienna University of Technology
+// ===========================================================================
+//  NAME:       RDTSCTimer
+//  TYPE:       c++ header
+//  PROJECT:    Urban Viz/yare (yet another rendering engine)
+//  CONTENT:    Very accurate timer for Win32 systems
+//				(uses Pentium clock cycle counter, usually microseconds)
+//  VERSION:    0.1
+// ===========================================================================
+//  AUTHORS:    mw      Michael Wimmer
+// ===========================================================================
+//  HISTORY:
+//
+//  15-jul-99 14:00:00  mw      created
+// ===========================================================================
+//  $Header: /usr/local/cvsyare/cvsyare/src/yareutils/RDTSCTimer.h,v 1.1 2002/09/24 16:53:56 wimmer Exp $ 
+// ===========================================================================
+
+#ifndef NO_PRAGMA_ONCE
+#pragma once
+#endif
+
+#ifndef _RDTSCTIMER_H
+#define _RDTSCTIMER_H
+
+// use outdated RDTSC instruction with opcodes and register backup, but without cpuid?
+//#define OLD_RDTSC
+
+// use cpuid instruction to serialize execution
+#define CPUID_RDTSC
+
+
+#ifdef WIN32
+
+#if !(_MSC_VER >= 1200)
+#define __forceinline inline 
+#endif
+
+// we definitely want timers to be inlined!
+# define PERFTIMER_INLINE __forceinline
+
+// the time snapping instruction
+#ifdef OLDRDTSC
+#define RDTSC(_VAR)                \
+   _asm {                          \
+       _asm push eax               \
+       _asm push edx               \
+       _asm _emit 0Fh              \
+       _asm _emit 31h              \
+       _asm mov _VAR.LowPart, eax  \
+       _asm mov _VAR.HighPart, edx \
+       _asm pop edx                \
+       _asm pop eax                \
+   } 
+#else
+#ifdef CPUID_RDTSC
+#define RDTSC(_VAR)                \
+   _asm {                          \
+       _asm xor eax, eax           \
+	   _asm cpuid                  \
+		_asm rdtsc                  \
+       _asm mov _VAR.LowPart, eax  \
+       _asm mov _VAR.HighPart, edx \
+   } 
+#else
+#define RDTSC(_VAR)                \
+   _asm {                          \
+       _asm rdtsc                  \
+       _asm mov _VAR.LowPart, eax  \
+       _asm mov _VAR.HighPart, edx \
+   } 
+#endif
+#endif
+
+	#ifndef WIN32_LEAN_AND_MEAN
+	#define WIN32_LEAN_AND_MEAN
+	#define NOMINMAX
+	#include <windows.h>	// for LARGE_INTEGER
+	#endif
+
+	#define PERFTIMER RDTSCTimer
+	
+	#define TIMEVAL_T LARGE_INTEGER
+	#define TIMEVAL_ZERO(__timval) (__timval).QuadPart = 0;
+	#define TIMEVAL_GET(__timval) { TIMEVAL_T temp; RDTSC(temp); __timval = temp; }
+	#define TIMEVAL_TODOUBLE(__timval) 	((double)__timval.QuadPart / (double)frequency.QuadPart)
+	#define TIMEVAL_ASSIGN(__timval1, __timval2) __timval1.QuadPart = __timval2.QuadPart;
+
+	#define TIMEVAL_ADD(total, end, start) \
+		if (end.QuadPart > start.QuadPart) \
+			total.QuadPart += end.QuadPart - start.QuadPart; \
+		else \
+			total.QuadPart += MAXLONGLONG - end.QuadPart + start.QuadPart;
+	
+	#include "PerfTimerSkeleton.h"
+
+#else
+	#define DUMMY_TIMER
+	#include "PerfTimerSkeleton.h"
+	#undef DUMMY_TIMER
+#endif
+
+#undef PERFTIMER
+#undef TIMEVAL_ZERO
+#undef TIMEVAL_TODOUBLE
+#undef TIMEVAL_ASSIGN
+// still need these for macro versions
+//#undef TIMEVAL_GET
+//#undef TIMEVAL_ADD
+
+
+#endif
Index: /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/merror.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/merror.cpp	(revision 2777)
+++ /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/merror.cpp	(revision 2777)
@@ -0,0 +1,307 @@
+ /* ========================================================================
+  * (C) 2000 Vienna University of Technology
+  * ========================================================================
+  * PROJECT: Urban Viz
+  * ========================================================================*/
+/** several error checking/log facilities.
+  *
+  * for char-strings, 'String' is typedef'd for convenience
+  * This library can be used with old style iostreams 
+  * (define \c OLDSTREAM for that)
+  *
+  * $Header: /usr/local/cvsyare/cvsyamp/src/yareutils/merror.cpp,v 1.1 2002/11/14 15:22:58 wimmer Exp $
+  * @author	 Michael Wimmer
+  * @file                                                                   */
+ /* ========================================================================*/
+
+#include "merror.h"
+
+// The following is to allow this to be compiled with new and old style 
+// iostreams. Special care has to be taken because in ms iostreams, 
+// strstream has a different name and behaves differently!
+#ifndef OLDSTREAM
+# include <fstream>
+# include <strstream>
+# define ERRSTD std
+#else
+# include <fstream.h>
+# if defined(_MSC_VER) && !defined(__SGI_STL)
+#  define MS_STRSTREAM
+#  include <strstrea.h>
+# else
+#  include <strstream.h>
+# endif
+# define ERRSTD
+#endif
+
+
+
+
+// ---------------------------------------------------------------------------
+//  PrivateErrHandler class definition
+// ---------------------------------------------------------------------------
+
+
+// a few functions encapsulated in a class so initialization is easier
+class PrivateErrHandler
+{
+public:
+	/// constructor
+	PrivateErrHandler();
+	
+	/// will be forwarded to outside macros
+	inline ERRSTD::ostream &GetCurrentLogStream();
+
+	/// output the current logstream
+	inline void PrintLogStream(bool overrideconsole);
+
+	/// init the logstream (especially the logfile)
+	void InitLogStream(const char *filename, bool _logtoconsole);
+
+	/// who handles the console stream
+	void SetConsoleStreamHandler(LogStreamToConsoleFunc handler);
+
+	/// console only on/off
+	bool SetLogStream(bool _logtoconsole);
+
+	/// whether to log to file or not
+	void SetLogToFile(bool yesno);
+
+private:
+	// the logfile
+	ERRSTD::ofstream log_ofstream;
+
+	// the logstring (i.e., the primary logging target)
+	ERRSTD::strstream log_ostrstream;
+
+	// log only to console?
+	bool logtoconsole;
+
+	// log to file also?
+	bool logtofile;
+
+	LogStreamToConsoleFunc CurrentLogStreamToConsoleFunc;
+
+	/// just goes to cout
+	inline static void DefaultLogStreamToConsoleFunc(
+		const char *consolestring);
+
+	// shoudn't be used
+	PrivateErrHandler(const PrivateErrHandler &) {}
+	PrivateErrHandler &operator=(const PrivateErrHandler &) { return *this; }
+};
+
+// ---------------------------------------------------------------------------
+//  PrivateErrHandler class implementation
+// ---------------------------------------------------------------------------
+
+
+PrivateErrHandler::PrivateErrHandler()
+	:CurrentLogStreamToConsoleFunc(DefaultLogStreamToConsoleFunc),
+	 logtoconsole(false), logtofile(true)
+{
+}
+
+
+void PrivateErrHandler::SetLogToFile(bool yesno)
+{
+	logtofile = yesno;
+}
+
+
+inline ERRSTD::ostream &PrivateErrHandler::GetCurrentLogStream()
+{
+	return log_ostrstream;
+}
+
+inline void PrivateErrHandler::PrintLogStream(bool overrideconsole)
+{
+	// Note: this is only used with the old strstream, not with ostringstream
+	log_ostrstream << ERRSTD::ends;
+
+	if (log_ofstream && (logtofile || !logtoconsole))
+		log_ofstream << log_ostrstream.str() << ERRSTD::flush;
+
+	if (logtoconsole || overrideconsole || !log_ofstream)
+		CurrentLogStreamToConsoleFunc(log_ostrstream.str());
+	
+	// Note: this was used with ostringstream, but not compatible 
+	// with old iostreams
+	//log_ostringstream.str("");
+	
+	log_ostrstream.rdbuf()->freeze(false);
+	log_ostrstream.seekp(0);
+}
+
+
+void PrivateErrHandler::InitLogStream(const char *filename, 
+									  bool _logtoconsole)
+{
+	// Note: only works on new iostreams!
+#ifdef MS_STRSTREAM
+	log_ofstream.rdbuf()->setbuf(NULL, 0);
+#else
+	log_ofstream.rdbuf()->pubsetbuf(NULL, 0);
+#endif
+		
+	// SGI bug: ios::in assumed!
+	log_ofstream.open(filename,ERRSTD::ios::out|ERRSTD::ios::trunc);
+	
+	if (!log_ofstream)
+	{
+		EOUT("Could not open logfile!");
+	}
+
+	SetLogStream(_logtoconsole);
+
+	OUT0("Logfile opened\n");
+}
+
+void PrivateErrHandler::SetConsoleStreamHandler(
+							LogStreamToConsoleFunc handler)
+{
+	if (handler == NULL)
+		CurrentLogStreamToConsoleFunc = DefaultLogStreamToConsoleFunc;
+	else
+		CurrentLogStreamToConsoleFunc = handler;
+}
+
+bool PrivateErrHandler::SetLogStream(bool _logtoconsole)
+{
+	bool x = logtoconsole;
+	logtoconsole = _logtoconsole;
+	return x;
+}
+
+void PrivateErrHandler::DefaultLogStreamToConsoleFunc(
+								const char *consolestring)
+{
+	ERRSTD::cout << consolestring;
+}
+
+
+// ---------------------------------------------------------------------------
+//  Private C-access functions
+// ---------------------------------------------------------------------------
+
+static PrivateErrHandler *theErrHandler = NULL;
+
+inline static void _ErrInitDefault()
+{
+	static bool initialized = false;
+	if (!initialized)
+	{
+		theErrHandler = new PrivateErrHandler;
+		initialized = true;
+	}
+}
+
+// ---------------------------------------------------------------------------
+//  Public interface - exposed to macros
+// ---------------------------------------------------------------------------
+
+// logstream used by macros - this is necessary so that logstreams don't 
+// give an error if used in global constructors (which are constructed 
+// prior to the logfile)
+ERRSTD::ostream &_GetLogStream()
+{
+	_ErrInitDefault();
+	
+	return theErrHandler->GetCurrentLogStream();
+}
+
+ERRSTD::ostream &_LogStreamDone(ERRSTD::ostream &os, bool overrideconsole)
+{
+	_ErrInitDefault();
+	theErrHandler->PrintLogStream(overrideconsole);
+
+	return os;
+}
+
+
+// ---------------------------------------------------------------------------
+//  Public interface - exposed directly to application
+// ---------------------------------------------------------------------------
+
+void SetConsoleStreamHandler(LogStreamToConsoleFunc handler)
+{
+	_ErrInitDefault();
+
+	theErrHandler->SetConsoleStreamHandler(handler);
+}
+
+void InitLogStream(const char *filename, bool logtofile)
+{
+	_ErrInitDefault();
+	
+	theErrHandler->InitLogStream(filename, !logtofile);
+}
+
+bool SetLogStream(bool logtofile)
+{
+	_ErrInitDefault();
+
+	return !theErrHandler->SetLogStream(!logtofile);
+}
+
+void SetLogToFile(bool yesno)
+{
+	_ErrInitDefault();
+
+	theErrHandler->SetLogToFile(yesno);
+}
+
+
+// ---------------------------------------------------------------------------
+//  Win32-stuff
+// ---------------------------------------------------------------------------
+
+#ifdef WIN32
+
+#define WIN32_LEAN_AND_MEAN
+#define NOMINMAX
+#include <windows.h>	// for MessageBox and stuff
+
+void Msg(const char *msg, const char *title) 
+{
+  //	MessageBox(NULL, msg, title, MB_OK);
+}
+
+/// gets WIN32 API error message (used by CHKMS-macros)
+char *GetErrorStringMS(DWORD errorValue)
+{
+	LPVOID lpMsgBuf;
+
+	FormatMessage( 
+		FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+		FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_MAX_WIDTH_MASK,
+		NULL,
+		errorValue,
+		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+		(LPTSTR) &lpMsgBuf,
+		0,
+		NULL 
+	);
+
+	//String message;
+	char *message;
+	if (lpMsgBuf)
+	{
+		message = (char *)lpMsgBuf;
+
+		// Free the buffer.
+		LocalFree( lpMsgBuf );
+	}
+	else
+	{
+		message = "No error message returned";
+	}
+
+	return message;
+}
+
+#else
+// nop functions for non-Win32 systems
+void Msg(const char *msg, const char *title) {}
+char *GetErrorStringMS(unsigned long errorValue) { return ""; }
+#endif
Index: /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/PerfTimerSkeleton.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/PerfTimerSkeleton.h	(revision 2777)
+++ /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/PerfTimerSkeleton.h	(revision 2777)
@@ -0,0 +1,173 @@
+// ---------------------------------------------------------------------------
+//  class PERFTIMER definition
+// ---------------------------------------------------------------------------
+
+#ifndef DUMMY_TIMER
+
+/** Very accurate Timer class for benchmarking on SGI systems.
+	This timer can be used to accurately take measurements
+	on all SGI-systems, usually in the microseconds range.
+
+	Note: getting the time on an unavailable Timer returns garbage.
+*/
+class PERFTIMER
+{
+private:
+	static TIMEVAL_T frequency;
+	static bool isinitialized;
+	static bool available;
+
+public:	// public for macro versions of Entry/Exit
+	TIMEVAL_T start_count;
+	TIMEVAL_T total_count;
+
+
+public:
+	
+	// this retrieves the timer frequency - will be called by constructor
+	// NOTE: allow this to be called externally, so logging can be enabled!
+	static void InitClass(bool verbose);
+
+	
+	/// the time type used for Perftimers
+	typedef double t_time;
+
+	/// returns the frequency
+	static double GetFrequency(bool verbose = false);
+
+	/// Constructor calls Start
+	PERFTIMER(bool verbose = false);
+
+	/// use in conjunction with Exit() to time parts of code that are called more than once
+	void Entry();
+	/// stop counting but remember total
+	void Exit();
+	/// read total time elapsed and reset the time - to be used with Entry()/Exit()
+	double TotalTime();
+	
+	/// reset and start the counter - use for timing one piece of code (implicit Entry())
+	void Start();
+	/** returns elapsed time in seconds - if restart is true, timer is also restarted - use with Start()
+		(implicit Exit()/Entry() with same timestamp, with restart: implicit Exit()/TotalTime()/Entry())
+	*/
+	double Elapsed(bool restart = true);
+	/** returns elapsed time in milliseconds - if restart is true, timer is also restarted - use with Start()
+		(implicit Exit()/Entry() with same timestamp, with restart: implicit Exit()/TotalTime()/Entry())
+	*/
+	double Elapsedms(bool restart = true);
+	
+	// returns elapsed time in cycles - if restart is true, timer is also restarted
+	//unsigned int ElapsedCycles(bool restart = true);
+	
+	/// false if no appropriate hardware found
+	bool Available();
+};
+
+// ---------------------------------------------------------------------------
+//  class PERFTIMER inline implementation
+// ---------------------------------------------------------------------------
+
+PERFTIMER_INLINE bool PERFTIMER::Available()
+{
+	/// HACK: no SGI detection!
+	return available;
+}
+
+// macro version to ensure inlining
+#define PERF_ENTRY(perftimer) TIMEVAL_GET((perftimer).start_count);
+
+PERFTIMER_INLINE void PERFTIMER::Entry()
+{
+	TIMEVAL_GET(start_count);
+}
+
+PERFTIMER_INLINE void PERFTIMER::Start()
+{
+	TIMEVAL_ZERO(total_count);
+	Entry();
+}
+
+// macro version to ensure inlining
+#define PERF_EXIT(perftimer) { TIMEVAL_T end_count; TIMEVAL_GET(end_count); TIMEVAL_ADD((perftimer).total_count, end_count, (perftimer).start_count);}
+
+PERFTIMER_INLINE void PERFTIMER::Exit()
+{
+	TIMEVAL_T end_count;
+	TIMEVAL_GET(end_count);
+	TIMEVAL_ADD(total_count, end_count, start_count);
+}
+
+
+PERFTIMER_INLINE double PERFTIMER::TotalTime()
+{
+	double time = TIMEVAL_TODOUBLE(total_count);
+	TIMEVAL_ZERO(total_count);
+
+	return time;
+}
+
+// returns elapsed time in seconds - if restart is true, timer is also restarted
+PERFTIMER_INLINE double PERFTIMER::Elapsed(bool restart)
+{
+	TIMEVAL_T end_count;
+	TIMEVAL_GET(end_count);
+	TIMEVAL_ADD(total_count, end_count, start_count);
+
+	TIMEVAL_ASSIGN(start_count, end_count); // unnecessary for entry/exit operation, but doesn't hurt
+
+	double time = TIMEVAL_TODOUBLE(total_count);
+
+	if (restart)
+	{
+		TIMEVAL_ZERO(total_count);
+	}
+	
+	return time;
+}
+
+// returns elapsed time in milliseconds - if restart is true, timer is also restarted
+PERFTIMER_INLINE double PERFTIMER::Elapsedms(bool restart)
+{
+	TIMEVAL_T end_count;
+	TIMEVAL_GET(end_count);
+	TIMEVAL_ADD(total_count, end_count, start_count);
+
+	TIMEVAL_ASSIGN(start_count, end_count); // unnecessary for entry/exit operation, but doesn't hurt
+
+	double time = TIMEVAL_TODOUBLE(total_count);
+
+	if (restart)
+	{
+		TIMEVAL_ZERO(total_count);
+	}
+	
+	return time * 1000.;
+}
+
+// Constructor calls Start
+PERFTIMER_INLINE PERFTIMER::PERFTIMER(bool verbose)
+{
+	if (!isinitialized)
+		InitClass(verbose);
+
+	//TIMEVAL_ZERO(total_count);
+	Start();
+}
+
+#else
+
+class PERFTIMER
+{
+public:
+	PERFTIMER(bool x = false) {}
+	static double GetFrequency(bool) {return 1;}
+	void Start() {}
+	double Elapsed(bool restart = true) { return 0; }
+	double Elapsedms(bool restart = true) { return 0; }
+	void Entry() {}
+	void Exit() {}
+	double TotalCount() { return 0; }
+	bool Available() { return false; }
+};
+
+#endif
Index: /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/mstring.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/mstring.h	(revision 2777)
+++ /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/mstring.h	(revision 2777)
@@ -0,0 +1,309 @@
+ /* ========================================================================
+  * (C) 2000 Vienna University of Technology
+  * ========================================================================
+  * PROJECT: Urban Viz
+  * ========================================================================*/
+/** very handy template String class.
+  *
+  * for char-strings, 'String' is typedef'd for convenience
+  * Note: can be used standalone in all std-conforming C++ environments
+  *
+  * $Header: /usr/local/cvsyare/cvsyamp/include/mstring.h,v 1.1 2002/11/14 15:22:48 wimmer Exp $
+  * @author	 Michael Wimmer
+  * @file                                                                   */
+ /* ========================================================================*/
+
+#ifndef NO_PRAGMA_ONCE
+#pragma once
+#endif
+
+#ifndef MSTRING_H
+#define MSTRING_H
+
+// remove completely stupid MSVC warning
+#ifdef _MSC_VER
+#pragma warning(disable: 4786) // 'identifier' : identifier was truncated to 
+							   // 'number' characters in the debug information
+#endif
+
+// Note: this always uses namespace std. no namespace precautions!
+#include <string>
+using std::basic_string;
+
+// ---------------------------------------------------------------------------
+//  class mbasic_string definition
+// ---------------------------------------------------------------------------
+
+// internally used
+static const char *MSTRING_WHITESPACE = " \t";
+
+
+/** Very handy String class.
+	Normally, you would use \c mbasic_string<char>, here typedef'd as 'String'.
+
+	Improves upon basic_string by adding:
+	- most importantly, a cast to const char *
+	- some useful Basic like operations, 
+	  such as Left, Mid, Right, Trim, Upper, ...
+*/
+template<class E>
+class mbasic_string : public  basic_string<E> {
+public:
+	// size_type not automatically looked up on sgis
+	typedef typename basic_string<E>::size_type size_type;
+	
+	//-- Constructors
+
+	/// various constructors
+	mbasic_string() : basic_string<E>() {}
+	
+	///
+	mbasic_string(const E *s) : basic_string<E>(s) {}
+	
+	/// 
+	mbasic_string(size_type n, const E c) : basic_string<E>(n, c) {}
+	
+	/// 
+	mbasic_string(const E c) : basic_string<E>(1, c) {}
+	
+	/// 
+	mbasic_string(const mbasic_string<E>& mbs) : basic_string<E>(mbs) {}
+	
+	/// 
+	mbasic_string(const basic_string<E>& bs) : basic_string<E>(bs) {}
+
+	//-- Assignment
+
+	/// various assignment ops
+	mbasic_string& operator=(const E c) 
+		{ basic_string<E>::operator=(c); return *this; }
+	
+	///
+	mbasic_string& operator=(const E *s) 
+		{ basic_string<E>::operator=(s); return *this; }
+	
+	///
+	mbasic_string& operator=(const mbasic_string<E>& rhs) 
+		{ basic_string<E>::operator=((const basic_string<E>&)rhs); 
+		  return *this; }
+
+	/// very useful!
+	operator const char*() const { return this->c_str(); }
+
+	//-- special access
+	
+	/// n characters from position pos (n may be out of range)
+	mbasic_string substr(size_type pos = 0, size_type n = npos) const 
+	{  basic_string<E> res = basic_string<E>::substr(pos,n); return res; }
+
+	/// leftmost nr characters (no problem if nr too large)
+	mbasic_string Left(size_type nr) const { return substr(0,nr); }
+	
+	/// rightmost nr characters (no problem if nr too large)
+	mbasic_string Right(size_type nr) const;
+	
+	/** substring from position 'from' to position 'to' (no problems 
+		if args out of range) */
+	mbasic_string Mid(size_type from, size_type to) const
+	{	if (from >= size() || from > to) return ""; 
+									else return substr(from,to-from+1); }
+	
+	//-- padding
+	mbasic_string Pad(char padchar, int length) const;
+
+	//-- trimming
+	
+	/// @name Trimming, converting upper/lower case
+	//@{
+	/// removes whitespace (space, tab) from the right
+	mbasic_string& TrimRightSelf();
+
+	/// removes whitespace (space, tab) from the left
+	mbasic_string& TrimLeftSelf();
+
+	/// removes whitespace from both left and right
+	mbasic_string& TrimSelf();
+
+	/// returns a 'right-trimmed' copy of string
+	mbasic_string TrimRight() const 
+		{ return mbasic_string<E>(*this).TrimRightSelf(); }
+	
+	/// returns a 'left-trimmed' copy of string
+	mbasic_string TrimLeft() const  
+		{ return mbasic_string<E>(*this).TrimLeftSelf(); }
+	
+	/// returns a 'trimmed' copy of string
+	mbasic_string Trim() const { return mbasic_string<E>(*this).TrimSelf();}
+
+	//-- upper/lower conversion
+	
+	/// converts string to uppercase
+	mbasic_string& UpperSelf();
+
+	/// converts string to uppercase
+	mbasic_string& LowerSelf();
+
+	/// returns an uppercase copy of string
+	mbasic_string Upper() const { return mbasic_string<E>(*this).UpperSelf();}
+	
+	/// returns an uppercase copy of string
+	mbasic_string Lower() const { return mbasic_string<E>(*this).LowerSelf();}
+	
+	//@}
+
+	//-- other stuff
+	
+	/** in contrast to empty(), also returns true if string is only 
+		whitespace (space, tab) */
+	bool Empty() const;
+};
+
+/// for convenience (that's what you'll use)
+typedef mbasic_string<char> String;
+
+// ---------------------------------------------------------------------------
+//  class mbasic_string template member implementation
+// ---------------------------------------------------------------------------
+
+template<class E>
+inline mbasic_string<E> mbasic_string<E>::Right(size_type nr) const 
+{
+	// take care that pos doesn't become negative
+	if(nr > size()) 
+	{
+		return *this;
+	}
+	else 
+	{
+		return substr(size()-nr, nr);
+	}
+}
+
+
+// ----- WARNING: the following only useful for E = char or similar!
+
+template<class E>
+inline bool mbasic_string<E>::Empty() const 
+{
+	return (find_first_not_of(MSTRING_WHITESPACE) == npos);
+}
+
+
+template<class E>
+inline mbasic_string<E>& mbasic_string<E>::TrimRightSelf() 
+{
+	if (!empty())
+	{
+		size_type pos = find_last_not_of(MSTRING_WHITESPACE);
+		if(pos == npos)	// everything whitespace
+			erase();
+		else if(pos != size()-1)	// pos = size()-1 -> no whitespace
+			erase(pos+1);	
+	}
+
+	return *this;
+}
+
+
+template<class E>
+inline mbasic_string<E>& mbasic_string<E>::TrimLeftSelf() 
+{
+
+	if (!empty())
+	{
+		size_type pos = find_first_not_of(MSTRING_WHITESPACE);
+		if(pos == npos)	// everything whitespace
+			erase();
+		else if(pos != 0) 
+			erase(0 , pos);	
+	}
+
+	return *this;
+}
+
+template<class E>
+inline mbasic_string<E>& mbasic_string<E>::TrimSelf() 
+{
+
+	this->TrimRightSelf();
+
+	this->TrimLeftSelf();
+
+	return *this;
+}
+
+
+template<class E>
+inline mbasic_string<E> &mbasic_string<E>::UpperSelf() {
+
+	if (!empty())
+		for(size_type i = 0; i < length(); i++)
+			at(i) = (E)toupper(at(i));
+
+	return *this;
+}
+
+template<class E>
+inline mbasic_string<E> &mbasic_string<E>::LowerSelf() {
+
+	if (!empty())
+		for(size_type i = 0; i < length(); i++)
+			at(i) = (E)tolower(at(i));
+
+	return *this;
+}
+
+template<class E>
+inline mbasic_string<E> mbasic_string<E>::Pad(char padchar, int length) const
+{
+	mbasic_string<E> result(*this);
+	while (result.length() < length)
+		result += padchar;
+	return result;
+}
+
+// --------- operator+() definitions
+
+/// string concatentation (defined multiple times to allow good overloads)
+template<class E>
+inline mbasic_string<E> operator+(const mbasic_string<E>& lhs, 
+								  const mbasic_string<E>& rhs) 
+{
+
+	return mbasic_string<E>(lhs) += rhs;
+}
+
+
+///
+template<class E>
+inline mbasic_string<E> operator+(const mbasic_string<E>& lhs, const E *rhs) 
+{
+
+	return mbasic_string<E>(lhs) += rhs;
+}
+
+///
+template<class E>
+inline mbasic_string<E> operator+(const mbasic_string<E>& lhs, const E rhs) 
+{
+
+	return mbasic_string<E>(lhs) += rhs;
+}
+
+///
+template<class E>
+inline mbasic_string<E> operator+(const E *lhs, const mbasic_string<E>& rhs) 
+{
+
+	return mbasic_string<E>(lhs) += rhs;
+}
+
+///
+template<class E>
+inline mbasic_string<E> operator+(const E lhs, const mbasic_string<E>& rhs) 
+{
+
+	return mbasic_string<E>(1,lhs) += rhs;
+}
+
+#endif // _MSTRING_H
Index: /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/merror.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/merror.h	(revision 2777)
+++ /GTP/trunk/App/Demos/Vis/CHC_revisited/Timer/merror.h	(revision 2777)
@@ -0,0 +1,339 @@
+ /* ========================================================================
+  * (C) 2000 Vienna University of Technology
+  * ========================================================================
+  * PROJECT: Urban Viz
+  * ========================================================================*/
+/** several error checking/log facilities.
+  *
+  * for char-strings, 'String' is typedef'd for convenience
+  * This library can be used standalone, with old style iostreams 
+  * (define \c OLDSTREAM for that) or new style iostreams
+  *
+  * $Header: /usr/local/cvsyare/cvsyamp/include/merror.h,v 1.3 2003/01/06 19:01:32 wimmer Exp $
+  * @author	 Michael Wimmer
+  * @file                                                                   */
+ /* ========================================================================*/
+
+#ifndef NO_PRAGMA_ONCE
+#pragma once
+#endif
+
+#ifndef MERROR_H
+#define MERROR_H
+
+
+// this library can be used with new and old style iostreams
+#ifndef OLDSTREAM
+# include <iostream>
+# define ERRSTD std
+#else
+# include <iostream.h>
+# define ERRSTD
+#endif
+
+
+// ---------------------------------------------------------------------------
+//  General macros
+// ---------------------------------------------------------------------------
+
+/// always use this to delete an object
+#define DELPTR(ptr) do { if (ptr) { delete (ptr); (ptr) = NULL; } } while (0)
+/// always use this to delete an array of objects
+#define DELAPTR(ptr) do { if (ptr) { delete [] (ptr); (ptr) = NULL; } } while (0)
+
+
+// ---------------------------------------------------------------------------
+//  Log file initialization
+// ---------------------------------------------------------------------------
+
+// gets global logfile, used by OUT/ASSERT/etc macros, to allow 
+// logstream to be used in global constructors
+ERRSTD::ostream &_GetLogStream();
+// enables use of curses or other things
+ERRSTD::ostream &_LogStreamDone(ERRSTD::ostream &os, 
+								bool overrideconsole = false);
+
+/** an application can declare a function of this type to redirect 
+	console output. */
+typedef void (*LogStreamToConsoleFunc)(const char *consoleoutput);
+
+/// Set a handler to redirect console output
+void SetConsoleStreamHandler(LogStreamToConsoleFunc handler);
+
+/// enables/disables logging to logfile (for performance reasons)
+void SetLogToFile(bool yesno);
+
+
+/** initializes the logfile for \c OUT/ASSERT  etc macros - call once at 
+	beginning if you desire file output
+    (for logtofile=false output goes to \c cerr initially) */
+void InitLogStream(const char *filename = "error.log", bool logtofileonly = true);	
+
+/// if true, logs to logfile, otherwise logs to console (\c cerr)
+bool SetLogStream(bool logtofileonly);
+
+
+// ---------------------------------------------------------------------------
+//  Log file definitions and macros
+// ---------------------------------------------------------------------------
+
+
+/** @name Logfile output macros
+	Any of those will write a string to the console and, if desired,
+	to the logfile.
+	They differ in the amount of tabs they prepend.
+	Note: all macros (except OUT0) PREPEND a carriage return!
+*/
+//@{
+
+
+/// stream a variable; example: \c OUT1(SV(refcount))  gives ' refcount = 5 '
+#define SV(x) " " #x "=" << (x) << " "
+
+/// stream a string; example: \c OUT1(SS(filename)) gives ' filename = "abc" '
+#define SS(x) "\"" << x << "\""
+
+// ------- logfile output macros
+
+/** stream to logfile.
+	(NOTE: don't insert \c endl here! use OUT1 for that - this is if you DON'T
+	want linebreaks!) */
+#define OUT0(__xx) _LogStreamDone(_GetLogStream() << __xx)
+/// stream to logfile (use if you want linebreaks!) - for normal use
+#define OUT1(__xx) OUT0("\n" << __xx)
+/// like \c OUT1, but with a TAB in front
+#define OUT2(__xx) OUT1("\t" << __xx)
+/// prepends 2 TABs
+#define OUT3(__xx) OUT1("\t\t" << __xx)
+/// prepends i TABs
+#define OUTI(__ii,__xx) { _GetLogStream() << "\n"; \
+					for (int __jj = 0; __jj < __ii; __jj ++)	\
+					_GetLogStream() << "\t";					\
+					_LogStreamDone(_GetLogStream() << __xx); }
+
+#define HERE " ("__FILE__", " << __LINE__ << ") ("__DATE__")"
+
+// internal macro to allow forced console output
+#define _CONOUT(__xx) _LogStreamDone(_GetLogStream() << "\n" << __xx,true)
+
+/// error message with file, line and date information
+#define EOUT(__xx) _CONOUT("ERROR: " << __xx << HERE)
+/// warning message with file, line and date information
+#define WOUT(__xx) _CONOUT("\tWARNING: " << __xx << HERE)
+
+//@}
+
+/* ---------------------------------------------------------------------------
+    Assertion macros: test the parameter result (if (!result) and take 
+		approprate action if failed:
+  
+    ASM_xxx 2nd parameter specifies an error message for the logfile
+    ASS_xxx no error message
+    xxx if failed, just print error message
+	xxx_RETVAL if failed, the 3rd macro parameter is returned
+    xxx_RET return is called (for void functions)
+	xxx_ELSE if failed, output the error message, else execute following 
+		statement
+    _ASM_TEMPLATE is used for creating the other macros.
+   -------------------------------------------------------------------------*/
+
+// used by ASM_*
+#define _BLOCK do
+#define _BLBEGIN _BLOCK {
+#define _BLEND } while (0)
+#define _NOP 4==4
+
+#ifndef RELEASE_BUILD
+	#define _ASM_TEMPLATE(result, errstr, stmt) \
+		_BLBEGIN if(!(result)) { EOUT(errstr); stmt; } _BLEND
+	
+	#define _ASS_TEMPLATE(result, stmt) \
+		_BLBEGIN if(!(result)) { stmt; } _BLEND
+
+	#define _CHKM_TEMPLATE(result, errstr, stmt) \
+		_BLBEGIN if(!(result)) { EOUT(errstr); stmt; } _BLEND
+
+	#define _CHKMS_TEMPLATE(result, stmt) \
+		_BLBEGIN if((result)==NULL) \
+		{ DWORD errorValue = GetLastError(); EOUTMS( SV(errorValue) << \
+		  GetErrorStringMS(errorValue)); stmt; } _BLEND
+
+#else
+	#define _ASM_TEMPLATE(result, errstr, stmt) _BLBEGIN _NOP; _BLEND
+	#define _ASS_TEMPLATE(result, stmt) _BLBEGIN _NOP; _BLEND
+	#define _CHKM_TEMPLATE(result, errstr, stmt) \
+		_BLBEGIN if (!(result)) { stmt }; _BLEND
+	#define _CHKMS_TEMPLATE(result, stmt) _CHKM_TEMPLATE(result, "", stmt)
+#endif
+
+// ---------------------------------------------------------------------------
+//  ASSERT macros - code will NOT be executed in release builds
+// ---------------------------------------------------------------------------
+
+/** @name Assertion and error checking macros
+	Use for ALL error checking in your code.
+	They are useful to check a return code, print a message
+	and take appropriate action.
+	Generally, ASM_* macros are for code consistency checks, 
+	whereas CHK_* macros should be used for errors that could
+	occur also in the final program (like file not found etc.).
+*/
+//@{
+
+/** logs error message, returns \c value if \c result==NULL
+	(all ASM_* map to a NOOP in Release builds - use CHKM_* 
+	if the code needs to get executed!!!) */
+#define ASM_RETVAL(result, errstr, value) \
+	_ASM_TEMPLATE(result, errstr, return (value))
+
+/// \c ASM_RETVAL for void-functions
+#define ASM_RET(result, errstr) _ASM_TEMPLATE(result, errstr, return)
+
+/// like \c ASM_RETVAL, but does an \c exit(-1)
+// NOTE: this should NOT have a CHKM-version, as this would result 
+//		 in a bad exit behaviour!
+#define ASM_EXIT(result, errstr) _ASM_TEMPLATE(result, errstr, exit(-1))
+
+// ---------------------------------------------------------------------------
+//  CHECK macros - code WILL be executed in release builds
+// ---------------------------------------------------------------------------
+
+/// \c ASM_RETVAL for code that needs to be executed also in release-builds
+#define CHKM_RETVAL(result, errstr, value) \
+	_CHKM_TEMPLATE(result, errstr, return (value))
+/// 
+#define CHKM_RET(result, errstr) _CHKM_TEMPLATE(result, errstr, return)
+
+
+// ---------------------------------------------------------------------------
+//  Macros not used much
+// ---------------------------------------------------------------------------
+
+
+/// like \c ASM_RETVAL but without logging anything
+#define ASS_RETVAL(result, value) _ASS_TEMPLATE(result, return (value))
+/// like \c ASM_RET but without logging anything
+#define ASS_RET(result, errstr) _ASS_TEMPLATE(result, return)
+
+#ifndef RELEASE_BUILD
+
+/// log error msg if result==NULL, no further action
+#define ASM(result, errstr) _BLBEGIN if(!(result)) { EOUT(errstr); } _BLEND
+
+/** \c if(!result) and logs error msg. Example: 
+	\code ASM_IF(res, "failed!") { do_cleanup; } else { do_good_code; } 
+	\endcode */
+#define ASM_IF(result, errstr) if((!(result)) ? (EOUT(errstr),true) : false) 
+
+/** only the \c else -path of \c ASM_IF. Example: 
+	\code ASM_ELSE(res, "bad input") { do_good_code; } \endcode */
+#define ASM_ELSE(result, errstr) if (!(result)) { EOUT(errstr); } else
+
+/// \c ASM_IF that also evaluates \c result in release-builds
+#define CHKM_IF(result, errstr) ASM_IF(result, errstr)
+
+/// see \c CHKM_IF
+#define CHKM_ELSE(result, errstr) ASM_ELSE(result, errstr)
+
+/** special: if result is false, output the offending statement 
+	(saves you the trouble of inventing error strings!) */
+#define ASSERTSELF(result) _BLBEGIN if(!(result)) { EOUT(#result); } _BLEND
+
+/** for some Win32 API calls (those where the result contains errorcode): 
+	print error msg if statement fails */
+#define CHKMS_FORMAT(result) \
+	_BLBEGIN int hResult = (result); if((hResult) != NULL) \
+	{ EOUT( GetAPIErrorString(hResult) + #result ); } _BLEND
+
+/// outputs any OpenGL error accumulated so far
+#define CHKGL _BLBEGIN GLenum error; \
+	if ( (error = glGetError()) != GL_NO_ERROR) \
+	EOUT("gl error " << gluErrorString(error)); _BLEND;
+
+#ifdef WIN32
+#include <malloc.h>
+/// checks the heap for consistency (useful for errors seemingly in stl!)
+#define CHKHEAP _BLBEGIN int hpres; if ( (hpres = _heapchk()) != _HEAPOK ) \
+	EOUT("Heap error: " << hpres); _BLEND;
+#else
+#define CHKHEAP
+#endif
+
+
+#ifndef DBG_LVL
+/** override this define in C++-settings to change 
+	behaviour of \c DBG and \c REL */
+#define DBG_LVL 1
+#endif
+
+#else
+
+#define ASM(result, errstr) _ASM_TEMPLATE(result, errstr, _NOP)
+
+#define ASSERTSELF(result) _BLBEGIN _NOP; _BLEND
+#define CHKMS_FORMAT(result) _BLBEGIN (result);  _BLEND
+
+#define ASM_IF(result, errstr) if(false) 
+#define ASM_ELSE(result, errstr) if (false) _NOP; else
+#define CHKM_IF(result, errstr) if(!(result)) 
+#define CHKM_ELSE(result, errstr) if(result)
+#define CHKGL
+#define CHKHEAP
+
+#ifndef DBG_LVL
+#define DBG_LVL 0
+#endif
+
+#endif
+
+#if DBG_LVL > 0
+	/** the following statement/block is only executed in debug-builds 
+		(\c DBG_LVL = 1) */
+	#define DDBG if(true) 
+	/** the following statement/block is only executed in release-builds 
+		(\c DBG_LVL = 0) */
+	#define RREL if(false)
+#else
+	#define DDBG if(false)
+	#define RREL if(true)
+#endif
+
+//@}
+
+// ---------------------------------------------------------------------------
+//  Microsoft Win32 API errors
+// ---------------------------------------------------------------------------
+
+/** @name Win32 only
+	These macros should be used for Win32 API-calls
+*/
+//@{
+
+/// put a messagebox to screen - WIN32 only
+void Msg(const char *message, const char *title = NULL);
+
+/// gets WIN32 API error message (used by CHKMS-macros)
+extern char *GetErrorStringMS(unsigned long errorValue);
+
+#define EOUTMS(x) _CONOUT("\nERRMS: " << x << HERE)
+#define WOUTMS(x) _CONOUT("\nWARNMS: " << x << HERE)
+
+/// for Win32 API calls: prints error message if statement fails
+#define CHKMS(result) _CHKMS_TEMPLATE(result, _NOP)
+/** for Win32 API calls: prints error message and returns value 
+	if statement fails */
+#define CHKMS_RETVAL(result, value) _CHKMS_TEMPLATE(result, return (value))
+/// for Win32 API calls: prints error message and returns if statement fails
+#define CHKMS_RET(result) _CHKMS_TEMPLATE(result, return)
+
+//@}
+
+// C4127: conditional expression is constant (because of merror)
+// C4514 unreferenced inline function has been removed (also in stl.h)
+#ifdef WIN32
+#pragma warning(disable: 4127 4514)
+#endif
+
+#undef ERRSTD
+
+#endif // MERROR_H
