Sample

Schnappinger/aoi/artofillusion.translators.POVExporter

Human rating uses the original dataset scale.

Human2.06
Lines677

Scores

MethodScoreScaleDataset rank
(0–100)
Posnett00–1; higher is more readable
4.5Δ 3.1
Scalabrino0.2670–1; higher is more readable
1.7Δ 5.9
Dorn00–1; higher is more readable
5.9Δ 1.7
Mi0.1120–1; higher is more readable
10.9Δ 3.3
LLOC493Logical lines; fewer is more readable
3.6Δ 4.0
DeepSeek V4 Pro7.670–20; mean of three runs
5.4Δ 2.1
GPT-6.1 Sol110–20; mean of three runs
3.3Δ 4.3
BTTF0.1460–1; higher is more readable
6.6Δ 1.0
Human2.061–4; original rating
7.6

Views

Source code

/* Copyright (C) 2002-2007 by Norbert Krieg and Peter Eastman 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. */ package artofillusion.translators; import artofillusion.*; import artofillusion.math.*; import artofillusion.ui.*; import artofillusion.object.*; import artofillusion.texture.*; import buoy.widget.*; import java.io.*; import java.util.*; /** POVExporter contains the actual routines for exporting POV files. */ public class POVExporter { static boolean DEBUG=false; static int DIRECTIONAL_LIGHT_DISTANCE=10000; // for directional light simulating static int MAXIMAL_LIGHT_FADE_DISTANCE=10000; // = decay rate is set to zero static int TIGHTNESS=10; // = decay rate for the spotlight static char CHAR_REPLACE='_'; static final String TEXTURE_NAME_PREFIX="AOI"; // prefix of the texture declaration for povray files static final char REPLACEMENT_CHARACTER='_'; // replacement for non allowed characters in names static final String FIX_SEPARATOR="."; // The separator in file names of suffices and prefices static String exportFileName="Untitled"; public static void exportFile(BFrame parent, Scene theScene) { // Display a dialog box with options on how to export the scene. ValueField errorField = new ValueField(0.05, ValueField.POSITIVE); BCheckBox smoothBox = new BCheckBox("Smooth Meshes", true); BCheckBox includeBox = new BCheckBox("Produce Extra Includefile for Povray textures", true); BComboBox exportChoice = new BComboBox(new String [] { Translate.text("exportWholeScene"), Translate.text("selectedObjectsOnly") }); ComponentsDialog dlg; if (theScene.getSelection().length > 0) dlg = new ComponentsDialog(parent, Translate.text("exportToPOV"), new Widget [] {exportChoice, Translate.label("maxSurfaceError"), errorField, includeBox, smoothBox}, new String [] {"", "", "", "", ""}); else dlg = new ComponentsDialog(parent, Translate.text("exportToPOV"), new Widget [] {Translate.label("maxSurfaceError"), errorField, includeBox, smoothBox}, new String [] {"", "", "", ""}); if (!dlg.clickedOk()) return; // Ask the user to select the output file. BFileChooser fc = new BFileChooser(BFileChooser.SAVE_FILE, Translate.text("exportToPOV")); String suffix=".pov", suffix2=".inc"; fc.setSelectedFile(new File(exportFileName+suffix)); if (ArtOfIllusion.getCurrentDirectory() != null) fc.setDirectory(new File(ArtOfIllusion.getCurrentDirectory())); // Get the result if (!fc.showDialog(parent)) return; File path = fc.getDirectory(); int endpos=fc.getSelectedFile().getName().indexOf(FIX_SEPARATOR); if (endpos==-1) endpos=fc.getSelectedFile().getName().length(); exportFileName=fc.getSelectedFile().getName().substring(0,endpos); ArtOfIllusion.setCurrentDirectory(fc.getDirectory().getAbsolutePath()); // Check whether file/s exist/s File f=null; f=new File(path, exportFileName+suffix); if (f.exists()) { //overwrite dialog String options[] = new String [] {Translate.text("Yes"), Translate.text("No")}; int choice = new BStandardDialog("", Translate.text("overwriteFile", exportFileName+suffix), BStandardDialog.QUESTION).showOptionDialog(parent, options, options[1]); if (choice==1) return; } // Check whether to produce an include file or not boolean bIncludeFile=includeBox.getState(); if (bIncludeFile) { f=new File(path, exportFileName+suffix2); if (f.exists()) { // overwrite dialog, if not then write a single pov file and inform the user String options[] = new String [] {Translate.text("Yes"), Translate.text("No")}; int choice = new BStandardDialog("", Translate.text("overwriteFile", exportFileName+suffix2), BStandardDialog.QUESTION).showOptionDialog(parent, options, options[1]); if (choice==1) bIncludeFile=false; // Write to the povray file } } // Create the output file. try { FileOutputStream fos = new FileOutputStream(new File(path, exportFileName+suffix)); BufferedOutputStream bos = new BufferedOutputStream(fos); FileOutputStream fos2=null; BufferedOutputStream bos2=null; if (bIncludeFile) { fos2=new FileOutputStream(new File(path, exportFileName+suffix2)); bos2=new BufferedOutputStream(fos2); } writeScene(theScene, bos,exportChoice.getSelectedIndex() == 0, errorField.getValue(), smoothBox.getState(),bos2,exportFileName+suffix2); bos.close(); if (bos2!=null) bos2.close(); fos.close(); if (fos2!=null) fos2.close(); } catch (IOException ex) { new BStandardDialog("", new String [] {Translate.text("errorExportingScene"), ex.getMessage() == null ? "" : ex.getMessage()}, BStandardDialog.ERROR).showMessageDialog(parent); } } /* Write out the scene in POV format to the specified OutputStream. The other parameters correspond to the options in the dialog box displayed by exportFile(). */ static void writeScene(Scene theScene, OutputStream os, boolean wholeScene, double tol, boolean smooth, OutputStream os2, String includeFileName) { PrintWriter out = new PrintWriter(os); PrintWriter out2 = out; boolean bIncludeFile=false; if (os2!=null) { out2=new PrintWriter(os2); bIncludeFile=true; } // Write the header information. write("// POV V3.5", out, 0); write("// Produced by Art of Illusion (Peter Eastman) "+ArtOfIllusion.getVersion(), out, 0); write("// and POVExporter plugin (Norbert Krieg) version 1.11", out, 0); write("// creation date: "+new Date().toString(),out,0); write("",out,0); if (bIncludeFile) { write("// POV V3.5 (include file)",out2,0); write("// Produced by Art of Illusion (Peter Eastman) "+ArtOfIllusion.getVersion(), out2, 0); write("// and POVExporter plugin (Norbert Krieg) version 1.11", out2, 0); write("// creation date: "+new Date().toString(),out2,0); write("",out2,0); } // Language spezific settings write("#version 3.5;",out,0); write("",out,0); // Global settings // only if writeing a whole scene if (wholeScene) { write("// Global settings",out,0); // Background color RGBColor color = theScene.getEnvironmentColor(); write("background { color rgb <"+color.getRed()+","+color.getGreen()+","+color.getBlue()+"> }", out, 0); // global settings for povray write("global_settings {",out,0); // ambient color color=theScene.getAmbientColor(); write("ambient_light <"+color.getRed()+","+color.getGreen()+","+color.getBlue()+">",out,1); // global settings for povray end write("}",out,0); // fog if present if (theScene.getFogState()) { color=theScene.getFogColor(); write("fog {",out,0); write("color <"+color.getRed()+","+color.getGreen()+","+color.getBlue()+">",out,1); write("distance "+theScene.getFogDistance(),out,1); write("}",out,0); } } write("",out,0); // Write declarations, camera, lights and objects into file int selected[] = theScene.getSelection(); int maxIndex=0; // writing the declarations write("// texture declarations",out2,0); if (wholeScene) { maxIndex=theScene.getNumObjects(); for (int i = 0; i < maxIndex; i++) writeTexture(theScene,theScene.getObject(i),out2,1); } else { maxIndex=selected.length; for (int i = 0; i < maxIndex; i++) writeTexture(theScene,theScene.getObject(selected[i]),out2,1); } out2.flush(); // write a language directive to include the texture declarations if (bIncludeFile) { write("#include \""+includeFileName+"\"",out,0); } // writing the objects write("",out,0); if (wholeScene) { maxIndex=theScene.getNumObjects(); for (int i = 0; i < maxIndex; i++) writeObjects(theScene,theScene.getObject(i),out,smooth,tol); } else { maxIndex=selected.length; for (int i = 0; i < maxIndex; i++) writeObjects(theScene,theScene.getObject(selected[i]),out,smooth,tol); } out.flush(); } /* Write a single line to the PrintWriter, indented by the specified number of tabs. */ static void write(String str, PrintWriter out, int indent) { for (int i = 0; i < indent; i++) out.print("\t"); out.print(str); out.println(); } static String getVec3String(Vec3 vec) { if (vec == null) return "<1,0,0>"; double x=Math.round(vec.x*1e6)/1e6; double y=Math.round(vec.y*1e6)/1e6; double z=Math.round(vec.z*1e6)/1e6; return "<"+x+","+y+","+z+">"; } static private String cleanName (String oldName) { StringBuffer workString=new StringBuffer(oldName.trim()); for (int i=0;i<workString.length();i++) { char c=workString.charAt(i); if (! java.lang.Character.isLetterOrDigit(c)) { workString.setCharAt(i,CHAR_REPLACE); } } return workString.toString(); } /* Write out a series of rotations corresponding to a coordinate system. */ private static void writeRotation(CoordinateSystem coords, PrintWriter out, int indent) { double [] rot=coords.getRotationAngles(); write("rotate <0,0,"+(-rot[2])+">",out,indent); write("rotate <"+(-rot[0])+",0,0>",out,indent); write("rotate <0,"+(-rot[1])+",0>",out,indent); } /* Write out an Appearance node describing a Texture. */ static void writeTexture(Scene theScene, ObjectInfo obj, PrintWriter out,int indent) { // ObjectInfo obj=theScene.getObject(index); Texture tex = obj.getObject().getTexture(); if (tex == null) return; TextureSpec spec; spec = new TextureSpec(); tex.getAverageSpec(spec, theScene.getTime(), obj.getObject().getAverageParameterValues()); String texName=cleanName(tex.getName()); if (tex.getID()==1) texName=cleanName(obj.getName()); if (DEBUG) { System.err.println("Texture "+tex.getName()+":\t"+tex.getID()); } write("#declare "+TEXTURE_NAME_PREFIX+texName+" = ",out,0); write("texture {",out,indent); write("pigment {",out,indent+1); write("color <"+spec.diffuse.getRed()+","+spec.diffuse.getGreen()+","+spec.diffuse.getBlue()+">",out,indent+2); write("}",out,indent+1); write("finish {",out,indent+1); write("ambient "+Math.max(spec.emissive.getRed(), Math.max(spec.emissive.getGreen(), spec.emissive.getBlue())), out, indent+2); write("specular "+Math.max(spec.specular.getRed(), Math.max(spec.specular.getGreen(), spec.specular.getBlue())), out, indent+2); write("roughness "+spec.roughness,out,indent+2); write("}",out,indent+1); write("}",out,indent); /* write("emissiveColor "+spec.emissive.getRed()+" "+spec.emissive.getGreen()+" "+spec.emissive.getBlue(), out, indent+2); write("specularColor "+spec.specular.getRed()+" "+spec.specular.getGreen()+" "+spec.specular.getBlue(), out, indent+2); write("shininess "+(1.0-spec.roughness), out, indent+2); write("transparency "+Math.max(spec.transparent.getRed(), Math.max(spec.transparent.getGreen(), spec.transparent.getBlue())), out, indent+2); write("ambientIntensity 1", out, indent+2); write("}", out, indent+1); write("}", out, indent); */ } static void writeObjects(Scene theScene, ObjectInfo obj, PrintWriter out,boolean smooth,double tolerance) { // Camera setting // (not very good because of extra loop count - but for readability purposes of POV file better) if (!obj.isVisible()) return; if (obj.getObject() instanceof SceneCamera) { write("// Camera settings",out,0); ObjectInfo info = (ObjectInfo)obj; CoordinateSystem coords = info.getCoords().duplicate(); // n�tig ???? obwohl KoSys linksh�ndig???? //coords.setOrientation(coords.getZDirection().times(-1.0), coords.getUpDirection().times(1.0)); Vec3 orig=coords.getOrigin(); String location="location "+getVec3String(orig); Vec3 zdir = coords.getZDirection(); Vec3 updir = coords.getUpDirection(); Vec3 rightdir = zdir.cross(updir).times(1.33); String direction="direction <"+zdir.x+","+zdir.y+","+zdir.z+">"; String up="up <"+updir.x+","+updir.y+","+updir.z+">"; String right="right <"+rightdir.x+","+rightdir.y+","+rightdir.z+">"; String angle="angle "+(((SceneCamera) obj.getObject()).getFieldOfView()*1.33); write("camera {",out,0); write("perspective",out,1); write(location,out,1); write(direction,out,1); write(up,out,1); write(right,out,1); write(angle,out,1); write("}",out,0); if (DEBUG) { System.err.println("Camera:"); System.err.println("// Standort:\t"+orig.toString()); System.err.println("// Blickrichtung:\t"+coords.getZDirection().toString()); System.err.println("// Up-Richtung:\t"+coords.getUpDirection().toString()); System.err.println("// Right (for aspect ratio):\t"+coords.getUpDirection().cross(coords.getZDirection()).times(1.33).toString()); } write("",out,0); } // Light setting // in extra loop for having it at the beginning of the povray file // Directional Light // in POVRAY it is a very far away point light // i.e. 10000 units should be in most cases far enough else if (obj.getObject() instanceof DirectionalLight) { write("// Directional light (simulated as far away point light distance="+DIRECTIONAL_LIGHT_DISTANCE+"units)",out,0); DirectionalLight light=(DirectionalLight) obj.getObject(); ObjectInfo info=(ObjectInfo)obj.duplicate(); CoordinateSystem coords = info.getCoords(); Vec3 zdir=coords.getZDirection(); float intensity=light.getIntensity(); RGBColor color=light.getColor().duplicate(); color.scale(intensity); zdir.normalize(); // to get a defined distance zdir.scale(-DIRECTIONAL_LIGHT_DISTANCE); write("// "+ info.getName(),out,0); write("light_source {",out,0); write(getVec3String(zdir),out,1); write("color <"+color.getRed()+","+color.getGreen()+","+color.getBlue()+">",out,1); write("parallel",out,1); write("point_at "+getVec3String(new Vec3(0,0,0)),out,1); write("}",out,0); write("",out,0); if (DEBUG) { System.err.println("// Directional Light source"); System.err.println("// --> point light:"); System.err.println("// Position:\t"+zdir.toString()); System.err.println("// Color:\t"+color.toString()); } } else if (obj.getObject() instanceof PointLight) { write("// Point light",out,0); write("// decay is different than in Art Of Illusion",out,0); write("// the point light source has actually no \"radius\"",out,0); PointLight light=(PointLight) obj.getObject(); ObjectInfo info=(ObjectInfo)obj.duplicate(); CoordinateSystem coords = info.getCoords(); Vec3 orig=coords.getOrigin(); float intensity=light.getIntensity(); RGBColor color=light.getColor().duplicate(); color.scale(intensity); //double radius=light.getRadius(); float dr=light.getDecayRate(); double fadeDistance=MAXIMAL_LIGHT_FADE_DISTANCE; if (dr!=0.0) fadeDistance=0.5/(new Float(dr).doubleValue()); double fadePower=2.0; if (fadeDistance>=5.0) fadePower=1.0; // only linear instead of squared write("// "+ info.getName(),out,0); write("light_source {",out,0); write(getVec3String(orig),out,1); write("color <"+color.getRed()+","+color.getGreen()+","+color.getBlue()+">",out,1); if (light.getType() != Light.TYPE_NORMAL) write("shadowless",out,1); write("fade_distance "+fadeDistance,out,1); write("fade_power "+fadePower,out,1); write("}",out,0); write("",out,0); if (DEBUG) { System.err.println("// Point Light source"); System.err.println("// --> point light:"); System.err.println("// Position:\t"+orig.toString()); System.err.println("// FadeDistance:\t"+fadeDistance); System.err.println("// FadePower:\t"+fadePower); } } else if (obj.getObject() instanceof SpotLight) { write("// Spot light",out,0); write("// the spot light source has actually no \"radius\"",out,0); SpotLight light=(SpotLight) obj.getObject(); ObjectInfo info=(ObjectInfo)obj.duplicate(); CoordinateSystem coords = info.getCoords(); Vec3 zdir=coords.getZDirection(); Vec3 orig=coords.getOrigin(); // get the point to which a spotlight points at (orig + zdir) Vec3 pointat=orig.plus(zdir); // Adjust Color RGBColor color=light.getColor().duplicate(); float intensity=light.getIntensity(); color.scale(intensity); // calculating the radius and fallof angle for POVRAY // not all possibilities of povray's spotlight used double radius=light.getAngle()/2.0*(1.0-light.getFalloff()); double falloff=light.getAngle()/2.0; // calculate the decay rate float dr=light.getDecayRate(); double fadeDistance=MAXIMAL_LIGHT_FADE_DISTANCE; if (dr!=0.0) fadeDistance=0.5/(new Float(dr).doubleValue()); double fadePower=2.0; if (fadeDistance>=5.0) fadePower=1.0; // only linear instead of squared write("// "+ info.getName(),out,0); write("light_source {",out,0); write(getVec3String(orig),out,1); write("color <"+color.getRed()+","+color.getGreen()+","+color.getBlue()+">",out,1); write("spotlight",out,1); write("point_at "+getVec3String(pointat),out,1); write("radius "+radius,out,1); write("falloff "+falloff,out,1); write("tightness "+TIGHTNESS,out,1); // simulates the AoI's behavior if (light.getType() != Light.TYPE_NORMAL) write("shadowless",out,1); write("fade_distance "+fadeDistance,out,1); write("fade_power "+fadePower,out,1); write("}",out,0); write("",out,0); if (DEBUG) { System.err.println("// Spotlight source"); System.err.println("// --> spot light:"); System.err.println("// Position:\t"+orig.toString()); System.err.println("// Point at:\t"+pointat.toString()); System.err.println("// Color:\t"+color.toString()); System.err.println("// Radius:\t"+radius); System.err.println("// Falloff:\t"+falloff); System.err.println("// Tightness:\t"+TIGHTNESS); if (light.getType() != Light.TYPE_NORMAL) System.err.println("shadowless"); System.err.println("// FadeDistance:\t"+fadeDistance); System.err.println("// FadePower:\t"+fadePower); } } // Cube setting else if (obj.getObject() instanceof Cube) { write("// Cube settings",out,0); ObjectInfo info=(ObjectInfo)obj.duplicate(); CoordinateSystem coords = info.getCoords(); Vec3 size = info.getBounds().getSize(), orig=coords.getOrigin(); String texName=cleanName(info.getObject().getTexture().getName()); if (info.getObject().getTexture().getID()==1) texName=cleanName(info.getName()); size.scale(0.5); write("// "+ info.getName(),out,0); write("box {",out,0); write(getVec3String(new Vec3(-1,-1,-1))+", "+getVec3String(new Vec3(1,1,1)),out,1); write("scale "+getVec3String(size),out,1); writeRotation(coords,out,1); write("translate "+getVec3String(orig),out,1); write("texture { "+TEXTURE_NAME_PREFIX+texName+" }",out,1); write("}",out,0); write("",out,0); if (DEBUG) { System.err.println("Box:"); System.err.println("Mittelpunkt:"+orig.toString()); System.err.println("Gr��e:"+size.times(2.0).toString()); System.err.println("Eckpunkte:\t(lu): "+getVec3String(orig.minus(size))); System.err.println(" \t(ro): "+getVec3String(orig.plus(size))); System.err.println(); } } // sphere and ellipse setting // (only for testing purposes in an extra loop) else if (obj.getObject() instanceof Sphere) { write("// Sphere settings",out,0); Sphere sphere=(Sphere) obj.getObject(); ObjectInfo info=(ObjectInfo)obj.duplicate(); CoordinateSystem coords = info.getCoords(); //coords.setOrientation(coords.getZDirection().times(-1.0), coords.getUpDirection().times(1.0)); Vec3 size = sphere.getRadii(), orig=coords.getOrigin(); String texName=cleanName(info.getObject().getTexture().getName()); if (info.getObject().getTexture().getID()==1) texName=cleanName(info.getName()); write("// "+ info.getName(),out,0); write("sphere {",out,0); write("<0,0,0>, 1",out,1); // standard sphere write("scale "+getVec3String(size),out,1); writeRotation(coords,out,1); write("translate "+getVec3String(orig),out,1); write("texture { "+TEXTURE_NAME_PREFIX+texName+" }",out,1); write("}",out,0); write("",out,0); if (DEBUG) { double rot[] = coords.getRotationAngles(); System.err.println("Sphere:"); System.err.println("// Mittelpunkt:\t"+orig.toString()); System.err.println("// Gr��e:\t"+size.times(2.0).toString()); System.err.println("// Rotation (x-axis):\t"+rot[0]); System.err.println("// (y-axis):\t"+rot[1]); System.err.println("// (z-axis):\t"+rot[2]); System.err.println(); } } // cylinder setting // will be transkripted to a cone object // (only for testing purposes in an extra loop) else if (obj.getObject() instanceof Cylinder) { write("// Cylinder settings",out,0); Cylinder cyl=(Cylinder) obj.getObject(); ObjectInfo info=(ObjectInfo)obj.duplicate(); CoordinateSystem coords = info.getCoords(); Vec3 orig=coords.getOrigin(); double ratio=cyl.getRatio(); Vec3 size=cyl.getBounds().getSize(); String texName=cleanName(info.getObject().getTexture().getName()); if (info.getObject().getTexture().getID()==1) texName=cleanName(info.getName()); size.scale(0.5); write("// "+ info.getName(),out,0); write("cone {",out,0); write("<0,-1,0>, 1, <0,1,0>, "+ratio,out,1); // standard sphere write("scale "+getVec3String(size),out,1); writeRotation(coords,out,1); write("translate "+getVec3String(orig),out,1); write("texture { "+TEXTURE_NAME_PREFIX+texName+" }",out,1); write("}",out,0); write("",out,0); if (DEBUG) { double rot[] = coords.getRotationAngles(); System.err.println("Cone:"); System.err.println("// Mittelpunkt:\t"+orig.toString()); System.err.println("// Gr��e:\t"+size.times(2.0).toString()); System.err.println("// Rotation (x-axis):\t"+rot[0]); System.err.println("// (y-axis):\t"+rot[1]); System.err.println("// (z-axis):\t"+rot[2]); System.err.println(); } } // Mesh for not smoothed triangle meshes // (only for testing purposes in an extra loop) else if ((obj.getObject() instanceof TriangleMesh) && (!smooth)) { write("// Triangle Mesh (mesh2) not smoothed",out,0); TriangleMesh trimesh=(TriangleMesh) obj.getObject(); ObjectInfo info=(ObjectInfo)obj.duplicate(); CoordinateSystem coords = info.getCoords(); Vec3 orig=coords.getOrigin(); String texName=cleanName(info.getObject().getTexture().getName()); if (info.getObject().getTexture().getID()==1) texName=cleanName(info.getName()); MeshVertex vert[] = trimesh.getVertices(); TriangleMesh.Face face[] = (trimesh.getFaces()); write("// "+ info.getName(),out,0); write("mesh2 {",out,0); write("vertex_vectors {",out,1); write(vert.length+",",out,2); for (int j = 0; j < vert.length; j++) { if (j!=vert.length-1) { write(getVec3String(vert[j].r)+",",out,2); } else { write(getVec3String(vert[j].r),out,2); } } write("}",out,1); write("face_indices {",out,1); write(face.length+",",out,2); for (int j = 0; j < face.length; j++) { if (j!=face.length-1) { write("<"+face[j].v1+","+face[j].v2+","+face[j].v3+"> ,",out,2); } else { write("<"+face[j].v1+","+face[j].v2+","+face[j].v3+">",out,2); } } write("}",out,1); write("texture { "+TEXTURE_NAME_PREFIX+texName+" }",out,1); writeRotation(coords,out,1); write("translate "+getVec3String(orig),out,1); write("}",out,0); write("",out,0); if (DEBUG) { System.err.println("Mesh"); System.err.println("Name:\t"+ info.getName()); System.err.println("Mittelpunkt:\t"+orig.toString()); System.err.println(); } } // if it is a grouping object else if ((obj.getObject()) instanceof ObjectCollection) { Enumeration objects = ((ObjectCollection) obj.getObject()).getObjects(obj, false, theScene); while (objects.hasMoreElements()) writeObjects(theScene,(ObjectInfo)objects.nextElement(),out,smooth,tolerance); } // any other object else { /* if smoothed mesh or any other object */ write("// smoothed object",out,0); ObjectInfo info=(ObjectInfo)obj.duplicate(); RenderingMesh mesh = info.getRenderingMesh(tolerance); write("// "+ info.getName(),out,0); if (mesh != null) { // only if you can render the mesh Vec3 vert[] = mesh.vert, norm[] = mesh.norm; RenderingTriangle face[] = mesh.triangle; CoordinateSystem coords = info.getCoords(); Vec3 orig=coords.getOrigin(); String texName=cleanName(info.getObject().getTexture().getName()); if (info.getObject().getTexture().getID()==1) texName=cleanName(info.getName()); write("mesh2 {",out,0); write("vertex_vectors {",out,1); write(vert.length+",",out,2); for (int j = 0; j < vert.length; j++) { if (j!=vert.length-1) { write(getVec3String(vert[j])+",",out,2); } else { write(getVec3String(vert[j]),out,2); } } write("}",out,1); write("normal_vectors {",out,1); write(norm.length+",",out,2); for (int j = 0; j < norm.length; j++) { if (j!=norm.length-1) { write(getVec3String(norm[j])+",",out,2); } else { write(getVec3String(norm[j]),out,2); } } write("}",out,1); write("face_indices {",out,1); write(face.length+",",out,2); for (int j = 0; j < face.length; j++) { if (j!=face.length-1) { write("<"+face[j].v1+","+face[j].v2+","+face[j].v3+"> ,",out,2); } else { write("<"+face[j].v1+","+face[j].v2+","+face[j].v3+">",out,2); } } write("}",out,1); write("normal_indices {",out,1); write(face.length+",",out,2); for (int j = 0; j < face.length; j++) { if (j!=face.length-1) { write("<"+face[j].n1+","+face[j].n2+","+face[j].n3+"> ,",out,2); } else { write("<"+face[j].n1+","+face[j].n2+","+face[j].n3+">",out,2); } } write("}",out,1); write("texture { "+TEXTURE_NAME_PREFIX+texName+" }",out,1); writeRotation(coords,out,1); write("translate "+getVec3String(orig),out,1); write("}",out,0); write("",out,0); if (DEBUG) { System.err.println("Mesh"); System.err.println("Name:\t"+ info.getName()); System.err.println("Mittelpunkt:\t"+orig.toString()); System.err.println(); } } write("",out,0); } } // Klasse writeObject ende }

Loading feature diagnosis…

Source regions

Feature contributions

Feature contributions

FeatureValueContribution
(log-odds)
Halstead volumeHow much symbolic information the code contains. It combines the total number of operators and values with the number of distinct ones.53991.183−1781.709
Source linesThe number of non-empty source lines.677+270.8
Byte entropyHow varied the bytes in the source text are. Repeated bytes give a lower value; a more even mixture gives a higher value.5.196−7.794

Intercept 8.87 + feature contributions = -1509.833 (log-odds).
Score = sigmoid(-1509.833) = 0.

Score0.267

Feature contributions

FeatureValueContribution
(log-odds)
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.678−22.97
Indentation frequencyHow rapidly indentation changes from line to line.534+17.733
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.534−11.833
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.676.953+9.053
Identifier layout (horizontal)How rapidly the visual pattern of identifier characters changes from left to right. It measures spatial frequency, not the meaning of the names.189.976−4.382
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.189.985+2.261
Operator visual areaThe share of the code’s visual area occupied by operators such as +, =, and *.0.133−0.351

Intercept 0.07 + feature contributions = -10.418 (log-odds).
Score = sigmoid(-10.418) = 0.

Score0.112
Score493
Run 1

The code suffers from significant readability issues. The writeObjects method is extremely long (200+ lines) and contains deeply nested if-else chains that could be refactored into separate methods or classes. Action granularity is inconsistent - many lines contain multiple operations, especially string concatenations with method calls. Method names like writeObjects actually handle cameras, lights, and all object types, making intent unclear. While the write helper method aids consistency, it requires passing PrintWriter and indent level repeatedly, creating verbose repetitive calls. The code mixes concerns: file dialogs, error handling, and POV generation are intertwined. Several comments contain typos and non-English text (e.g., 'Gr��e', 'n�tig'), suggesting poor maintenance. However, the code does have some positive aspects: consistent indentation in POV output, clear section comments, and method decomposition for texture writing. The excessive length of conditional blocks, duplication in loop patterns (checking if j is last element), and large monolithic methods significantly impact readability.

Run 2

The code suffers from severe readability issues. The primary method writeObjects is extremely long (over 300 lines) with deeply nested if-else chains handling many object types, violating single responsibility. There is significant duplication in texture name retrieval, mesh writing, and light handling. Method names like writeObjects imply one action but contain many. Comments are verbose and sometimes unhelpful (e.g., German fragments, TODO-like notes). Indentation is inconsistent—many blocks use extra braces unnecessarily, and some methods have excessive nesting (up to 4-5 levels). Magic numbers appear throughout (1e6, 1.33, 10000) without explanation. Variable names are often unclear (dr, fos2, bos2). However, there is some structure: separate write() helper, reasonable method extraction for writeTexture and writeRotation, and consistent use of write() for output. The code is maintainable only with effort, and its length and branching make it difficult to follow.

Run 3

The code has a clear overall structure with separated methods, but readability suffers from multiple issues. The main writeObjects method is excessively long (hundreds of lines) and contains deeply nested conditionals for different object types. While individual lines are relatively simple, the debugging blocks with System.err.println create noise. Mixed indentation styles (tabs vs spaces) reduce consistency. Some commented-out code remains (e.g., in writeTexture), and there are German comments mixed with English. Variable names are generally descriptive, but methods like 'write' have generic names. The action granularity is mostly one action per line, but the conditional chains make the reading flow difficult. The code also mixes concerns: file I/O, scene traversal, object type handling, and debug output are intertwined. Overall, the code is maintainable but would benefit from refactoring into smaller methods and removing debug noise.

Run 1

Code Structure: Export orchestration and formatting helpers are separated, but writeObjects is a monolithic type-dispatch method with substantial duplication. Nesting: Mostly moderate, though mesh branches combine conditionals and loops across several levels. Clarity of intent: Method names and section comments establish the export purpose, but abbreviated variables, magic numbers, stale comments, and mixed-language debug text obscure details. Code length: Excessively long due to repeated texture naming, light calculations, mesh serialization, and debugging blocks; commented-out code adds clutter. Action granularity: Most statements perform one action per line, but inline conditionals, loop bodies, and combined declarations reduce consistency. Reading flow: Export stages follow a logical sequence, but inconsistent indentation, spacing, brace styles, dense string concatenation, and lengthy branches interrupt scanning.

Run 2

Code Structure: Export setup, scene writing, and formatting helpers are separated, but writeObjects is an oversized type-dispatch method with substantial duplication. Nesting: Mostly moderate, though mesh serialization combines branches, loops, and conditionals across several levels. Clarity of intent: Method names and section comments explain the export pipeline, but abbreviated variables, magic numbers, stale comments, and commented-out code obscure details. Code length: Unnecessarily long due to repeated light, texture, transformation, mesh, and debugging logic that could be extracted into helpers. Action granularity: Most statements perform one action per line, but inline conditionals, loop bodies, and combined declarations reduce scanability. Reading flow: The overall progression from options to files to scene output is logical, and object-specific branches are recognizable. However, inconsistent indentation, spacing, brace placement, long string concatenations, and extensive debug blocks interrupt that flow.

Run 3

Code Structure: Export setup, scene writing, and formatting helpers are separated logically, but writeObjects is an oversized type-dispatch method with substantial duplication. Nesting: Most branches are moderately shallow, though mesh serialization combines conditional branches, loops, and inner conditions. Clarity of intent: Descriptive method names and section comments explain the exporter’s purpose; abbreviated variables, magic numbers, stale comments, and commented-out code obscure details. Code length: Excessive repetition in light handling, texture naming, mesh output, and debugging makes the implementation unnecessarily long. Action granularity: Most statements perform one action per line, but inline conditionals, loop bodies, and multiple-variable declarations reduce scanability. Reading flow: The export sequence and object-specific sections are understandable, but inconsistent indentation, spacing, brace styles, long string concatenations, and mixed-language comments interrupt the flow.