From 6eed4757d3a9b32b47ffa7f60653a5301332d477 Mon Sep 17 00:00:00 2001
From: Thomas Witkowski <thomas.witkowski@gmx.de>
Date: Tue, 5 Jan 2010 12:17:59 +0000
Subject: [PATCH] Merged with povray branch.

---
 AMDiS/bin/Makefile.am     |   1 +
 AMDiS/bin/Makefile.in     |  16 +-
 AMDiS/src/AMDiS.h         |   1 +
 AMDiS/src/FileWriter.cc   |  15 ++
 AMDiS/src/FileWriter.h    |  12 ++
 AMDiS/src/PovrayWriter.cc | 425 ++++++++++++++++++++++++++++++++++++++
 AMDiS/src/PovrayWriter.h  |  88 ++++++++
 7 files changed, 555 insertions(+), 3 deletions(-)
 create mode 100644 AMDiS/src/PovrayWriter.cc
 create mode 100644 AMDiS/src/PovrayWriter.h

diff --git a/AMDiS/bin/Makefile.am b/AMDiS/bin/Makefile.am
index 6b8700e0..52be8ab4 100644
--- a/AMDiS/bin/Makefile.am
+++ b/AMDiS/bin/Makefile.am
@@ -204,6 +204,7 @@ $(SOURCE_DIR)/TecPlotWriter.cc \
 $(SOURCE_DIR)/ValueWriter.cc \
 $(SOURCE_DIR)/VtkWriter.h $(SOURCE_DIR)/VtkWriter.cc \
 $(SOURCE_DIR)/PngWriter.h $(SOURCE_DIR)/PngWriter.cc \
+$(SOURCE_DIR)/PovrayWriter.h $(SOURCE_DIR)/PovrayWriter.cc \
 $(SOURCE_DIR)/DataCollector.h $(SOURCE_DIR)/DataCollector.cc \
 $(SOURCE_DIR)/ElementInfo.h \
 $(SOURCE_DIR)/VertexInfo.h \
diff --git a/AMDiS/bin/Makefile.in b/AMDiS/bin/Makefile.in
index 11fc047d..8cb4f015 100644
--- a/AMDiS/bin/Makefile.in
+++ b/AMDiS/bin/Makefile.in
@@ -214,6 +214,7 @@ am__libamdis_la_SOURCES_DIST = $(PARALLEL_DIR)/ParallelDomainBase.h \
 	$(SOURCE_DIR)/TecPlotWriter.cc $(SOURCE_DIR)/ValueWriter.cc \
 	$(SOURCE_DIR)/VtkWriter.h $(SOURCE_DIR)/VtkWriter.cc \
 	$(SOURCE_DIR)/PngWriter.h $(SOURCE_DIR)/PngWriter.cc \
+	$(SOURCE_DIR)/PovrayWriter.h $(SOURCE_DIR)/PovrayWriter.cc \
 	$(SOURCE_DIR)/DataCollector.h $(SOURCE_DIR)/DataCollector.cc \
 	$(SOURCE_DIR)/ElementInfo.h $(SOURCE_DIR)/VertexInfo.h \
 	$(SOURCE_DIR)/PeriodicInfo.h $(SOURCE_DIR)/OpenMP.h \
@@ -285,9 +286,9 @@ am_libamdis_la_OBJECTS = $(am__objects_2) libamdis_la-DOFIndexed.lo \
 	libamdis_la-Traverse.lo libamdis_la-TraverseParallel.lo \
 	libamdis_la-Triangle.lo libamdis_la-TecPlotWriter.lo \
 	libamdis_la-ValueWriter.lo libamdis_la-VtkWriter.lo \
-	libamdis_la-PngWriter.lo libamdis_la-DataCollector.lo \
-	libamdis_la-ScalableQuadrature.lo libamdis_la-SubElInfo.lo \
-	libamdis_la-InteriorBoundary.lo \
+	libamdis_la-PngWriter.lo libamdis_la-PovrayWriter.lo \
+	libamdis_la-DataCollector.lo libamdis_la-ScalableQuadrature.lo \
+	libamdis_la-SubElInfo.lo libamdis_la-InteriorBoundary.lo \
 	libamdis_la-ElementDofIterator.lo libamdis_la-AdaptParaReal.lo
 libamdis_la_OBJECTS = $(am_libamdis_la_OBJECTS)
 libcompositeFEM_la_LIBADD =
@@ -616,6 +617,7 @@ $(SOURCE_DIR)/TecPlotWriter.cc \
 $(SOURCE_DIR)/ValueWriter.cc \
 $(SOURCE_DIR)/VtkWriter.h $(SOURCE_DIR)/VtkWriter.cc \
 $(SOURCE_DIR)/PngWriter.h $(SOURCE_DIR)/PngWriter.cc \
+$(SOURCE_DIR)/PovrayWriter.h $(SOURCE_DIR)/PovrayWriter.cc \
 $(SOURCE_DIR)/DataCollector.h $(SOURCE_DIR)/DataCollector.cc \
 $(SOURCE_DIR)/ElementInfo.h \
 $(SOURCE_DIR)/VertexInfo.h \
@@ -782,6 +784,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Parametric.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-PeriodicBC.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-PngWriter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-PovrayWriter.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ProblemInstat.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ProblemInterpolScal.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ProblemInterpolVec.Plo@am__quote@
@@ -1478,6 +1481,13 @@ libamdis_la-PngWriter.lo: $(SOURCE_DIR)/PngWriter.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-PngWriter.lo `test -f '$(SOURCE_DIR)/PngWriter.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/PngWriter.cc
 
+libamdis_la-PovrayWriter.lo: $(SOURCE_DIR)/PovrayWriter.cc
+@am__fastdepCXX_TRUE@	if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-PovrayWriter.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-PovrayWriter.Tpo" -c -o libamdis_la-PovrayWriter.lo `test -f '$(SOURCE_DIR)/PovrayWriter.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/PovrayWriter.cc; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/libamdis_la-PovrayWriter.Tpo" "$(DEPDIR)/libamdis_la-PovrayWriter.Plo"; else rm -f "$(DEPDIR)/libamdis_la-PovrayWriter.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$(SOURCE_DIR)/PovrayWriter.cc' object='libamdis_la-PovrayWriter.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-PovrayWriter.lo `test -f '$(SOURCE_DIR)/PovrayWriter.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/PovrayWriter.cc
+
 libamdis_la-DataCollector.lo: $(SOURCE_DIR)/DataCollector.cc
 @am__fastdepCXX_TRUE@	if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-DataCollector.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-DataCollector.Tpo" -c -o libamdis_la-DataCollector.lo `test -f '$(SOURCE_DIR)/DataCollector.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DataCollector.cc; \
 @am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/libamdis_la-DataCollector.Tpo" "$(DEPDIR)/libamdis_la-DataCollector.Plo"; else rm -f "$(DEPDIR)/libamdis_la-DataCollector.Tpo"; exit 1; fi
diff --git a/AMDiS/src/AMDiS.h b/AMDiS/src/AMDiS.h
index f102b77c..fb28db69 100644
--- a/AMDiS/src/AMDiS.h
+++ b/AMDiS/src/AMDiS.h
@@ -63,6 +63,7 @@
 #include "PeriodicMap.h"
 #include "PeriodicBC.h"
 #include "PngWriter.h"
+#include "PovrayWriter.h"
 #include "ProblemScal.h"
 #include "ProblemVec.h"
 #include "ProblemInstat.h"
diff --git a/AMDiS/src/FileWriter.cc b/AMDiS/src/FileWriter.cc
index d6bf9a72..62db97dc 100644
--- a/AMDiS/src/FileWriter.cc
+++ b/AMDiS/src/FileWriter.cc
@@ -7,6 +7,7 @@
 #include "MacroWriter.h"
 #include "VtkWriter.h"
 #include "PngWriter.h"
+#include "PovrayWriter.h"
 #include "FiniteElemSpace.h"
 #include "AdaptInfo.h"
 #include "Flag.h"
@@ -108,6 +109,7 @@ namespace AMDiS {
     writeParaViewAnimation = 0;
     writePeriodicFormat = 0;
     writePngFormat = 0;
+    writePovrayFormat = 0;
     pngType = 0;
     appendIndex = 0;
     indexLength = 5;
@@ -142,6 +144,11 @@ namespace AMDiS {
     GET_PARAMETER(0, name + "->index decimals", "%d", &indexDecimals);
     GET_PARAMETER(0, name + "->write every i-th timestep", "%d", &tsModulo);
 
+    GET_PARAMETER(0, name + "->Povray format", "%d", &writePovrayFormat);
+    GET_PARAMETER(0, name + "->Povray template", "%d", &povrayTemplate);
+    GET_PARAMETER(0, name + "->Povray camera location", &povrayCameraLocation);
+    GET_PARAMETER(0, name + "->Povray camera look_at", &povrayCameraLookAt);
+
     std::string compressionStr = "";
     GET_PARAMETER(0, name + "->compression", &compressionStr);
     if (compressionStr == "gzip" || compressionStr == "gz") {
@@ -268,6 +275,14 @@ namespace AMDiS {
       MSG("PNG image file written to %s\n", (fn + ".png").c_str());
     }
 #endif
+
+    if (writePovrayFormat) {
+      PovrayWriter povrayWriter(this, dataCollectors[0]);
+      povrayWriter.writeFile(fn + ".pov");
+
+      MSG("Povray script written to %s\n", (fn + ".pov").c_str());
+    }
+
     
     for (int i = 0; i < static_cast<int>(dataCollectors.size()); i++)
       delete dataCollectors[i];
diff --git a/AMDiS/src/FileWriter.h b/AMDiS/src/FileWriter.h
index 6c7af70c..4369ed57 100644
--- a/AMDiS/src/FileWriter.h
+++ b/AMDiS/src/FileWriter.h
@@ -177,6 +177,18 @@ namespace AMDiS {
     /// 0: Gray color picture; 1: RGB picture.
     int pngType;
 
+    /// 0: Don't write Povray scripts; 1: Write Povray scripts
+    int writePovrayFormat;
+
+    /// camera position for povray script files
+    std::string povrayCameraLocation;
+
+    /// orientation for camera in povray script files
+    std::string povrayCameraLookAt;
+
+    /// name of the template file that will be prepended to all created *.pov files 
+    std::string povrayTemplate;
+
     /** \brief
      * 0: Don't append time index to filename prefix.
      * 1: Append time index to filename prefix.
diff --git a/AMDiS/src/PovrayWriter.cc b/AMDiS/src/PovrayWriter.cc
new file mode 100644
index 00000000..4761ce5b
--- /dev/null
+++ b/AMDiS/src/PovrayWriter.cc
@@ -0,0 +1,425 @@
+#include "PovrayWriter.h"
+#include "DOFVector.h"
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <map>
+#include <algorithm>
+#include "Traverse.h"
+
+using namespace std;
+
+namespace AMDiS {
+
+  /* destructor */
+  PovrayWriter::~PovrayWriter(){
+    // free the memory for the bounding box
+    if(bBox==NULL){
+      delete bBox;
+      bBox = NULL;
+    }
+  }
+
+
+  /* some forward declarations */
+  double computeWeight(double&, double&, double&);
+  string getColorString(double&);
+
+
+  void PovrayWriter::tryMeshTraversal(ofstream &out)
+  {
+    /* prepare some data structures */
+    DOFVector<double> *values = dataCollector->getValues();
+    const FiniteElemSpace *feSpace = dataCollector->getFeSpace();
+    const BasisFunction *basFcts = feSpace->getBasisFcts();
+    DegreeOfFreedom *dofs = new DegreeOfFreedom[basFcts->getNumber()];
+
+    /* create an 'iterator' */ 
+    TraverseStack stack;
+    ElInfo *elInfo =  stack.traverseFirst(dataCollector->getMesh(), -1, 
+					  Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
+
+    /* find min and max values */
+    double min_value = 0;
+    double max_value = 0;
+    if (values->getSize() > 0)
+      min_value = max_value = (*values)[0];
+
+    for (int index = 1; index < values->getSize(); index++) {
+      min_value = min(min_value, (*values)[index]);
+      max_value = max(max_value, (*values)[index]);
+    }
+
+    /* map DOFs to values */
+    std::map <int, double> value_map;
+    while (elInfo) {
+      basFcts->getLocalIndices(elInfo->getElement(), feSpace->getAdmin(), dofs);
+                        
+      int max = Global::getGeo(WORLD)==2 ? 3 : 4;
+
+      for (int i = 0; i < max; i++) {
+	double value = (*values)[dofs[i]];
+	value_map[dofs[i]] = value;
+      }
+
+      elInfo = stack.traverseNext(elInfo);
+    }
+                
+    out << "\ttexture_list {" << endl;
+    out << "\t" << value_map.size() << "," << endl;
+    std::map<int, double>::iterator map_iter;
+    for (map_iter = value_map.begin(); map_iter != value_map.end(); ++map_iter) {
+      double value = map_iter->second;
+      double color_weight =  computeWeight(min_value,max_value,value);
+      out << "\t\ttexture{ pigment{ " << getColorString(color_weight) << "}}";
+      std::map<int, double>::iterator final_iter = value_map.end();
+      --final_iter;
+      if (map_iter != final_iter)
+	out << ",";      
+      out << endl;
+    }
+    out << "\t}" << endl; // end of texture_list
+
+    delete [] dofs;
+  }
+
+  // provides the bounding box of the mesh
+  //         
+  // note: computation is done during the first call other, this might cause
+  //       problems in simulations with changing geometries
+  BoundingBox* PovrayWriter::getBoundingBox(ofstream &out) 
+  {
+    if (bBox != NULL)
+      return bBox;    
+
+    DOFVector< std::list<VertexInfo> > *vertexInfos = dataCollector->getVertexInfos();
+    DOFVector< std::list<VertexInfo> >::Iterator it(vertexInfos, USED_DOFS);
+    int dow = Global::getGeo(WORLD);
+    bBox = new BoundingBox();
+
+    it.reset();
+    std::list<VertexInfo>::iterator it2 = it->begin();
+    bBox->minx = it2->coords[0];
+    bBox->maxx = it2->coords[0];
+    bBox->miny = it2->coords[1];
+    bBox->maxy = it2->coords[1];
+    if (dow == 3){
+      bBox->minz = it2->coords[2];
+      bBox->maxz = it2->coords[2];
+    } else {
+      bBox->minz = bBox->maxz = 0;
+    }
+
+    for (it.reset(); !it.end(); ++it) {
+      // initialize mit and max values with coordinates of first vertex
+      std::list<VertexInfo>::iterator it2 = it->begin();
+      bBox->minx = min(bBox->minx, it2->coords[0]);
+      bBox->maxx = max(bBox->maxx, it2->coords[0]);
+      bBox->miny = min(bBox->miny, it2->coords[1]);
+      bBox->maxy = max(bBox->maxy, it2->coords[1]);
+      if (dow == 3) {
+	bBox->minz = min(bBox->minz, it2->coords[2]);
+	bBox->maxz = max(bBox->maxz, it2->coords[2]); 
+      }
+    }
+
+    return bBox;
+  }
+
+  // computes the weight of a value for color computation
+  double computeWeight(double &min, double &max, double &value)
+  {
+    double interval_length = (max - min); 
+    return (value - min) / interval_length;
+  }
+
+  // determines the color for a given value/weight
+  string getColorString(double &value) 
+  {
+    value = max(0.0, value);
+    value = min(value, 1.0);
+
+    // rot: 1,0,0
+    // blau: 0,0,1
+
+    // currently blue->red gradient
+    stringstream res;
+    res << "rgb<" << value << ",0," << (1 - value) << ">";
+    return res.str();
+  }
+
+  // writes a povray script for the current time step to the specified file
+  int PovrayWriter::writeFile(const std::string filename)
+  {
+    ofstream out;
+    out.open(filename.c_str(), ios::out);
+
+    // TODO: copy content from template script (use string this->fileWriter->povrayTemplate)
+    // copy template file
+
+
+    // delegate all the work to other subroutines
+    writeHeader(out);
+    writeIncludes(out);
+    writeCamera(out);
+    writeLight(out);
+    writeTestStuff(out, *dataCollector);
+    writeMesh2(out, *dataCollector);
+
+    // TODO: remove
+    //tryMeshTraversal(out);
+
+    out.close();
+    return 0;
+  }
+
+  
+  // writes a simple info header (comments only) 
+  void PovrayWriter::writeHeader(ofstream &out) 
+  {
+    out << "// povray file created by AMDiS" << endl;
+    out << endl;
+  }
+
+
+  // writes all neccessary include file declarations
+  void PovrayWriter::writeIncludes(ofstream &out) 
+  {
+    out << "#include \"colors.inc\"" << endl;
+    out << "#include \"stones.inc\"" << endl;
+    out << endl;
+  }
+
+  // computes an appropriate camera position and writes it to the povray file
+  void PovrayWriter::writeCamera(ofstream &out) 
+  {
+    /* TODO: compute adequate camera position (computation needs to be performed
+       only once, same camera position will be used for all iterations) */
+
+    /* TODO: check whether camera position and location have been specified in the
+       init file, use them if present*/
+
+    BoundingBox *box = getBoundingBox(out);
+    int dow = Global::getGeo(WORLD);
+    double centerx = (box->minx+box->maxx)/2.;
+    double centery = (box->miny+box->maxy)/2.;
+    double centerz = (box->minz+box->maxz)/2.;
+
+    if (dow == 2){
+      out << "camera {" << endl;
+      out << "\tlocation <" << centerx << ", " << centery << ", -3>" << endl;
+      out << "\tlook_at  <" << centerx << ", " << centery << ",  0>" << endl;
+      out << "}" << endl << endl; 
+    } else {
+      out << "camera {" << endl;
+      out << "\tlocation <"<< centerx <<", "<<centery<<", -3>" << endl;
+      out << "\tlook_at  <"<< centerx <<", "<<centery<<",  "<<centerz<<">" << endl;
+      out << "}" << endl << endl; 
+    }
+  }
+
+
+  // computes an appropriate light source and writes it to the povray file
+  void PovrayWriter::writeLight(ofstream &out) 
+  {
+    // TODO: compute adequate light position
+    out << "light_source { <0, 0, -15> color White}" << endl;
+  }
+
+
+  // writes the data in the 'mesh2' format
+  void PovrayWriter::writeMesh2(ofstream &out, DataCollector &dataCollector)
+  {
+    // initialization and preparations
+    //Mesh *mesh = dataCollector.getMesh();
+	
+    // begin of mesh2 block
+    out << "mesh2 {" << endl;
+		
+    // delegate work to other methods
+    writeVertexVectors(out, dataCollector);
+    //writeTextureList(out, dataCollector);
+    tryMeshTraversal(out);		
+    writeFaceIndices(out, dataCollector);
+    out << "\t" << "pigment {rgb 1}" << endl;
+    // end of mesh2 block
+    out << "}" << endl;
+  } 
+
+
+  // writes all vertices of the model
+  void PovrayWriter::writeVertexVectors(ofstream &out, DataCollector &dataCollector)
+  {
+    // initialization and preparations
+    Mesh *mesh = dataCollector.getMesh();
+    DOFVector< std::list<VertexInfo> > *vertexInfos = dataCollector.getVertexInfos();
+    DOFVector< std::list<VertexInfo> >::Iterator it(vertexInfos, USED_DOFS);
+
+    // begin of vertex_vectors block
+    out << "\tvertex_vectors {" << endl;
+    int nVertices = mesh->getNumberOfVertices();
+    out << "\t\t" << nVertices << "," << endl;
+
+    // For all DOFs of vertices, write the coordinates.
+    int counter = 0;
+    for (it.reset(); !it.end(); ++it) {
+      // for all vertex infos of this DOF
+      for (std::list<VertexInfo>::iterator it2 = it->begin(); it2 != it->end(); ++it2) {
+	out << endl;		    
+	// TODO: right implementation using STL vector/iterator
+	out  << "\t\t<";
+	WorldVector<double> coords;
+	coords = it2->coords;
+	for (int i = 0; i < Global::getGeo(WORLD); i++){
+	  if (i > 0)
+	    out << ", ";
+
+	  out << std::scientific << coords[i];
+	}	
+	for (int i = Global::getGeo(WORLD); i < 3; i++)
+	  out << ", 0.0";
+	out << ">,";
+      }     
+    }
+    // undo last comma
+    long pos=out.tellp(); //tells pos the actual stream position
+    out.seekp(pos - 1);     //sets stream position -1
+    out <<  endl;         //overwrites the las comma with space
+    // end of vertex_vectors block
+    out << "\t}" << endl;		
+  }
+  
+
+  // writes the list of textures (basically one color for each vertex, used to draw a color gradient on each triangle)
+  void PovrayWriter::writeTextureList(ofstream &out, DataCollector &dataCollector)
+  {
+    // prepare some data structures		
+    Mesh *mesh = dataCollector.getMesh();		
+    DOFVector< std::list<VertexInfo> > *vertexInfos = dataCollector.getVertexInfos();
+    DOFVector< std::list<VertexInfo> >::Iterator it(vertexInfos, USED_DOFS);
+
+
+    // begin of texture_list block
+    out << "\ttexture_list {" << endl;
+
+    // compute and write the number of textures/colors (one for each vertex)
+    int nTextures = mesh->getNumberOfVertices();
+    out << "\t\t" << nTextures << "," << endl;
+
+    // For all DOFs of vertices, write the coordinates.
+    int counter = 0;
+    for (it.reset(); !it.end(); ++it) {
+      // for all vertex infos of this DOF
+      for (std::list<VertexInfo>::iterator it2 = it->begin(); it2 != it->end(); ++it2) {
+	// test: use y-coordinate to compute color
+	double redValue = it2->coords[1];
+	redValue = max(0., redValue);
+	redValue = min(redValue, 1.);
+		    
+	out << "\n\t\ttexture{ pigment{ rgb"<< getColorString(redValue) <<" } }" << ",";
+      }     
+    }
+    long pos = out.tellp();
+    out.seekp(pos - 1);
+    out << endl;
+    // end of texture_list block
+    out << "\t}" << endl;
+  }
+
+
+  // writes the connectivity
+  void PovrayWriter::writeFaceIndices(ofstream &out, DataCollector &dataCollector)
+  {
+    // begin of face_indices block
+    out << "\tface_indices {" << endl;
+
+    std::list<ElementInfo> *elementInfos = dataCollector.getElementInfos();
+    int vertices = dataCollector.getMesh()->getGeo(VERTEX);
+    int meshDim = dataCollector.getMesh()->getDim();		
+    int counter = 0;
+
+    if (meshDim == 2) {
+      int nElements = dataCollector.getElementInfos()->size();
+      out << "\t\t" << nElements << "," << endl;		   	
+      for (std::list<ElementInfo>::iterator iter = elementInfos->begin(); 
+	   iter != elementInfos->end(); iter++) {
+	out << endl;				
+	out << "\t\t<";    			
+	for (int i = 0; i < vertices; i++) {
+	  if (i > 0)
+	    out << ", ";
+	  
+	  out << iter->vertexInfo[i]->outputIndex;
+	}
+	out << ">";
+
+	// write indices again for texture/color mapping
+	for (int i = 0; i < vertices; i++) {
+	  out << ", ";
+	  out << iter->vertexInfo[i]->outputIndex;
+	}
+
+	out << ",";
+      }
+      //Delete last comma 
+      long pos = out.tellp();
+      out.seekp(pos - 1);
+      out << endl;
+    } else if (meshDim == 3) {
+      int nElements = dataCollector.getElementInfos()->size() * 4;
+      out << "\t\t" << nElements << "," << endl;
+      for (std::list<ElementInfo>::iterator iter = elementInfos->begin(); 
+	   iter != elementInfos->end(); iter++) {
+	for (int j = 0; j < vertices; j++) {
+	  out << "/* " << counter++ << " */";
+	  out << "\t\t<"; 
+	  for (int i = 0; i < vertices; i++) {
+	    if (i==j) 
+	      continue;					
+
+	    if (!((j > 0 && i == 0) || (j == 0 && i == 1)))
+	      out << ", ";
+	    
+	    out << iter->vertexInfo[i]->outputIndex;
+	  }
+	  out << ">";
+	  // write indices again for texture/color mapping
+	  for (int i = 0; i < vertices; i++) {
+	    if (i == j) 
+	      continue;
+	    out << ", ";
+	    out << iter->vertexInfo[i]->outputIndex;
+	  }
+	  out << "," << endl;
+	}
+      }
+    }
+
+    // end of face_indices block
+    out << "\n\t}" << endl; //
+  }
+	
+
+
+  /// writes some additional information for debugging purposes
+  void PovrayWriter::writeTestStuff(ofstream &out, DataCollector &dataCollector)
+  {
+    Mesh *mesh = dataCollector.getMesh();
+
+    out << "/*" << endl;
+    out << "TestData:" << endl;
+
+    int dow = Global::getGeo(WORLD);
+    out << " world dimension:\t" << dow << endl;
+
+    out << " dimension:\t" << mesh->getDim() << endl;
+    out << " numberOfNodes:\t" << mesh->getNumberOfNodes() << endl;
+    out << " numberOfEdges:\t" << mesh->getNumberOfEdges() << endl;
+    out << " numberOfVertices:\t" << mesh->getNumberOfVertices() << endl;
+    out << " numberOfFaces:\t" << mesh->getNumberOfFaces() << endl;
+    out << " numberOfElements:\t" << mesh->getNumberOfElements() << endl;
+    out << "*/" << endl << endl;
+  }
+
+} // end of namespace AMDiS
diff --git a/AMDiS/src/PovrayWriter.h b/AMDiS/src/PovrayWriter.h
new file mode 100644
index 00000000..7d9a1b1d
--- /dev/null
+++ b/AMDiS/src/PovrayWriter.h
@@ -0,0 +1,88 @@
+// ============================================================================
+// ==                                                                        ==
+// == AMDiS - Adaptive multidimensional simulations                          ==
+// ==                                                                        ==
+// ============================================================================
+// ==                                                                        ==
+// ==  TU Dresden                                                            ==
+// ==                                                                        ==
+// ==  Institut f�r Wissenschaftliches Rechnen                               ==
+// ==  Zellescher Weg 12-14                                                  ==
+// ==  01069 Dresden                                                         ==
+// ==  germany                                                               ==
+// ==                                                                        ==
+// ============================================================================
+// ==                                                                        ==
+// ==  https://gforge.zih.tu-dresden.de/projects/amdis/                      ==
+// ==                                                                        ==
+// ============================================================================
+
+/** \file FileWriter.h */
+
+// Marcel Schiffel, 23.06.09
+
+#ifndef AMDIS_POVRAYWRITER_H
+#define AMDIS_POVRAYWRITER_H
+
+#include <string>
+#include <fstream>
+#include <iostream>
+#include "DataCollector.h"
+#include "FileWriter.h"
+
+using namespace std;
+
+namespace AMDiS {
+
+
+  typedef struct {
+    double minx;
+    double maxx;
+    double miny;
+    double maxy;
+    double minz;
+    double maxz;
+  } BoundingBox;
+
+
+  class PovrayWriter {
+  public:
+    PovrayWriter(FileWriter *fw, DataCollector *dc) : fileWriter(fw), dataCollector(dc)
+    {
+      FUNCNAME("PovrayWriter::PovrayWriter()");	
+
+      // abort if problem not 3D //FIX THAT!!!
+      /*	TEST_EXIT(dataCollector->getMesh()->getDim()==3)
+		("Povray export only possible for 3D data!");*/  
+
+      bBox = NULL;
+    }
+
+    ~PovrayWriter();
+    int writeFile(const std::string filename);
+
+    // provides the bounding box of the mesh (lazy evaluation, bounding box is computed only once)
+    BoundingBox *getBoundingBox(ofstream&);
+
+  private:
+    FileWriter *fileWriter;
+    DataCollector *dataCollector;
+    BoundingBox *bBox;
+
+    // TODO: remove!
+    void tryMeshTraversal(ofstream&);
+
+    void writeTestStuff(ofstream&, DataCollector&); // TODO: remove/rename
+    void writeHeader(ofstream&);
+    void writeIncludes(ofstream&);
+    void writeCamera(ofstream&);
+    void writeLight(ofstream&);
+    void writeMesh2(ofstream&, DataCollector&);
+    void writeVertexVectors(ofstream&, DataCollector&);
+    void writeTextureList(ofstream&, DataCollector&);
+    void writeFaceIndices(ofstream&, DataCollector&);
+  };
+
+} // end of namespace AMDiS
+
+#endif
-- 
GitLab