/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * PovRayExporter.java * Copyright Remco Bouckaert remco@cs.auckland.ac.nz (C) 2011 */ package viz.graphics; import java.io.FileWriter; import java.io.PrintWriter; import java.util.Random; import java.util.Vector; import viz.Node; /** class for exporting a tree to a povray scene **/ public class PovRayExporter { /** main method, creates header as well as tree **/ public static void export(Node tree, String sFile, double fScaleX, double fScaleY, Vector<String> sLabels) { try { FileWriter outFile = new FileWriter(sFile); PrintWriter out = new PrintWriter(outFile); out.println("#version 3.1;"); out.println("global_settings { assumed_gamma 2.2 }"); out.println("#include \"densitree.inc\""); // out.println("camera {Camera1 translate <-400,-400,-11000>}"); // out.println("#declare Bark="); // out.println(" texture{"); // out.println(" pigment{Brown}"); // out.println(" normal{"); // out.println(" bumps 0.6"); // out.println(" scale 24"); // out.println(" }"); // out.println(" finish{phong 0.3 phong_size 200}"); // out.println(" }"); // out.println(" texture {"); // out.println(" pigment {Brown}"); // out.println(" finish {phong 1}"); // out.println("}"); float fTotalHeight = height(tree); out.println("box{<-1255.7326263189316, "+-fTotalHeight*fScaleX+", -300>,<1255.7326263189316, "+(-fTotalHeight*fScaleX-1000)+", 300>"); out.println("texture{T_Grass}}"); out.println("merge {"); exportNode(tree, out, fScaleY, fScaleX, sLabels, fTotalHeight); out.println("}"); out.flush(); out.close(); } catch (Exception e) { e.printStackTrace(); } } /** calculate total height of tree **/ static float height(Node node) { if (node.isLeaf()) { return node.m_fLength; } else { return node.m_fLength + Math.max(height(node.m_left), height(node.m_right)); } } /** recursively position branches of the tree **/ static float exportNode(Node node, PrintWriter out, double fScaleX, double fScaleY, Vector<String> sLabels, float fTotalHeight) { if (node.isLeaf()) { out.println("text"); out.println("{ ttf \"timrom.ttf\" \""+sLabels.elementAt(node.getNr())+"\" 0.001, 0"); out.println(" pigment { rgb 1 }"); out.println(" finish { ambient 1 }"); out.println(" rotate <0,0,45>"); out.println(" scale <50,50,50>"); out.println(" translate <"+-node.m_fPosX* fScaleX+", "+0+", -3>"); out.println("}"); return node.m_fLength; } else { float fHeightL = exportNode(node.m_left, out, fScaleX, fScaleY, sLabels, fTotalHeight); float fHeightR = exportNode(node.m_right, out, fScaleX, fScaleY, sLabels, fTotalHeight); float fHeight = node.m_fLength + Math.max(fHeightL, fHeightR); //float fSkew = (node.m_fPosX - node.m_left.m_fPosX)/node.m_left.m_fLength; float fEndThickness = (float)(fScaleX/2*fHeightL/fTotalHeight); if (node.m_left.isLeaf()) { fEndThickness = (float)(fScaleX/2*0.1); } //fSkew *= fScaleX/fScaleY; // out.println("cone {"); // out.println(" <0,0,0>,"+fScaleX/2*fHeight/fTotalHeight+","); // out.println(" <-1,0,0>,"+fEndThickness); // out.println(" rotate -z*90"); // out.println(" scale <1," + node.m_left.m_fLength* fScaleY+",1>"); // out.println(" matrix < 1.0, 0.0, 0.0,"); // out.println(" "+fSkew+", 1.0, 0.0,"); // out.println(" 0.0, 0.0, 1.0,"); // out.println(" 0.0, 0.0, 0.0 >"); // out.println(" texture {Bark}"); // out.println(" translate <"+-node.m_fPosX* fScaleX+", "+-fHeightL* fScaleY+", -3>"); // out.println("}"); exportBranche(out, -node.m_fPosX* fScaleX, -fHeightL* fScaleY, fScaleX/2*fHeight/fTotalHeight ,-node.m_left.m_fPosX* fScaleX , -(fHeightL+node.m_left.m_fLength)*fScaleY, fEndThickness, 2); //fSkew = (node.m_fPosX - node.m_right.m_fPosX)/node.m_right.m_fLength; //fSkew *= fScaleX/fScaleY; fEndThickness = (float)(fScaleX/2*fHeightR/fTotalHeight); if (node.m_right.isLeaf()) { fEndThickness = (float)(fScaleX/2*0.1); } // out.println("cone {"); // out.println(" <0,0,0>,"+fScaleX/2*fHeight/fTotalHeight+","); // out.println(" <-1,0,0>,"+fEndThickness); // out.println(" rotate -z*90"); // out.println(" scale <1," + node.m_right.m_fLength* fScaleY+",1>"); // out.println(" matrix < 1.0, 0.0, 0.0,"); // out.println(" "+fSkew+", 1.0, 0.0,"); // out.println(" 0.0, 0.0, 1.0,"); // out.println(" 0.0, 0.0, 0.0 >"); // out.println(" texture {Bark}"); // out.println(" translate <"+-node.m_fPosX* fScaleX+", "+-fHeightR* fScaleY+", -3>"); // out.println("}"); exportBranche(out, -node.m_fPosX* fScaleX, -fHeightR* fScaleY, fScaleX/2*fHeight/fTotalHeight ,-node.m_right.m_fPosX* fScaleX , -(fHeightL+node.m_right.m_fLength)*fScaleY, fEndThickness, 2); return fHeight; } } // exportNode static Random m_random = new Random(); static void exportBranche(PrintWriter out, double fX0, double fY0, double fWidth0, double fX1, double fY1, double fWidth1, int nDepth) { if (nDepth == 0) { exportBranche(out, fX0, fY0, fWidth0, fX1, fY1, fWidth1); } else { double fX2 = (fX0+fX1)/2 + (0.5-m_random.nextDouble()) * (fX0-fX1)/2; double fY2 = (fY0+fY1)/2; //fX2 = (fX0+fX1)/2; double fYDelta = 0*(0.5-m_random.nextDouble()) * (fY0-fY1)/10; double fWidth2 = (fWidth0+fWidth1)/2; exportBranche(out, fX2, fY0 + (fY0-fY1)/2.0, fWidth2, fX1, fY0, fWidth1- fYDelta, nDepth-1); exportBranche(out, fX0, fY0, fWidth0, fX2, fY2+ fYDelta, fWidth2, nDepth-1); } } static void exportBranche(PrintWriter out, double fX0, double fY0, double fWidth0, double fX1, double fY1, double fWidth1) { double fSkew = (fX1-fX0)/(fY0-fY1); out.println("cone {"); out.println(" <0,0,0>,"+fWidth0+","); out.println(" <-1,0,0>,"+fWidth1); out.println(" rotate -z*90"); out.println(" scale <1," +(fY0-fY1)+",1>"); out.println(" matrix < 1.0, 0.0, 0.0,"); out.println(" "+fSkew+", 1.0, 0.0,"); out.println(" 0.0, 0.0, 1.0,"); out.println(" 0.0, 0.0, 0.0 >"); out.println(" texture {Bark}"); out.println(" translate <"+fX0+", "+fY0+", -3>"); out.println("}"); } // exportBranch }