Skip to content

Instantly share code, notes, and snippets.

@monkstone
Created January 22, 2012 21:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save monkstone/1658952 to your computer and use it in GitHub Desktop.
Save monkstone/1658952 to your computer and use it in GitHub Desktop.
Exporting from processing sketches (using Hemesh library) directly to PovRAY mesh2
/**
* Modified to include ability to export as PovRAY mesh2 by Martin Prout 2012
*/
package wblut.hemesh.tools;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Iterator;
import javolution.util.FastMap;
import wblut.geom.WB_Normal;
import wblut.geom.WB_XYZ;
import wblut.hemesh.core.*;
/**
*
* Collection of export functions.
*
* @author Frederik Vanhoutte, W:Blut
*
*/
public class HET_Export {
/*
* Copyright (c) 2006-2011 Karsten Schmidt This library is free software;
* you can redistribute it and/or modify it under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2.1 of the License, or (at your option) any
* later version. http://creativecommons.org/licenses/LGPL/2.1/ This library
* is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
* more details. You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301, USA
*/
/**
* Saves the mesh as OBJ format by appending it to the given mesh
* {@link HET_OBJWriter} instance. Karsten Schmidt, 2011
*
* @param obj
*/
public static void saveToOBJ(final HE_Mesh mesh, final HET_OBJWriter obj) {
final HE_Mesh triMesh = mesh.get();
triMesh.triangulateFaces();
final int vOffset = obj.getCurrVertexOffset() + 1;
final int nOffset = obj.getCurrNormalOffset() + 1;
obj.newObject(mesh.key().toString());
// vertices
final FastMap<Integer, Integer> keyToIndex = new FastMap<Integer, Integer>(
mesh.numberOfVertices());
Iterator<HE_Vertex> vItr = triMesh.vItr();
HE_Vertex v;
int i = 0;
while (vItr.hasNext()) {
v = vItr.next();
keyToIndex.put(v.key(), i);
obj.vertex(v);
i++;
}
vItr = mesh.vItr();
while (vItr.hasNext()) {
obj.normal(vItr.next().getVertexNormal());
}
// faces
final Iterator<HE_Face> fItr = triMesh.fItr();
HE_Face f;
while (fItr.hasNext()) {
f = fItr.next();
obj.faceWithNormals(keyToIndex.get(f.getHalfedge().getVertex().key())
+ vOffset, keyToIndex.get(f.getHalfedge().getNextInFace().getVertex().key())
+ vOffset, keyToIndex.get(f.getHalfedge().getPrevInFace().getVertex().key())
+ vOffset, keyToIndex.get(f.getHalfedge().getVertex().key())
+ nOffset, keyToIndex.get(f.getHalfedge().getNextInFace().getVertex().key())
+ nOffset, keyToIndex.get(f.getHalfedge().getPrevInFace().getVertex().key())
+ nOffset);
}
}
/**
* Saves the mesh as OBJ format to the given {@link OutputStream}. Currently
* no texture coordinates are supported or written. Karsten Schmidt, 2011
*
* @param stream
*/
public static void saveToOBJ(final HE_Mesh mesh, final OutputStream stream) {
final HET_OBJWriter obj = new HET_OBJWriter();
obj.beginSave(stream);
saveToOBJ(mesh, obj);
obj.endSave();
}
/**
* Saves the mesh as OBJ format to the given file path. Existing files will
* be overwritten. Karsten Schmidt, 2011
*
* @param path
*/
public static void saveToOBJ(final HE_Mesh mesh, final String path) {
final HET_OBJWriter obj = new HET_OBJWriter();
obj.beginSave(path);
saveToOBJ(mesh, obj);
obj.endSave();
}
/**
* Export mesh to binary STL file. Heav(i/en)ly inspired by Marius Watz
*
* @param path file path
* @param scale scaling factor
*/
public static void saveToSTL(final HE_Mesh mesh, final String path,
final double scale) {
final HE_Mesh save = mesh.get();
save.triangulateFaces();
FileOutputStream out;
try {
out = new FileOutputStream(path);
byte[] header = new byte[80];
final ByteBuffer buf = ByteBuffer.allocate(200);
header = new byte[80];
buf.get(header, 0, 80);
out.write(header);
buf.rewind();
buf.order(ByteOrder.LITTLE_ENDIAN);
buf.putInt(save.numberOfFaces());
buf.rewind();
buf.get(header, 0, 4);
out.write(header, 0, 4);
buf.rewind();
buf.clear();
header = new byte[50];
HE_Face f;
final Iterator<HE_Face> fItr = save.fItr();
while (fItr.hasNext()) {
f = fItr.next();
final WB_Normal n = f.getFaceNormal();
final WB_XYZ v1 = f.getHalfedge().getVertex();
final WB_XYZ v2 = f.getHalfedge().getNextInFace().getVertex();
final WB_XYZ v3 = f.getHalfedge().getNextInFace().getNextInFace().getVertex();
buf.rewind();
buf.putFloat((float) n.x);
buf.putFloat((float) n.y);
buf.putFloat((float) n.z);
buf.putFloat((float) (scale * v1.x));
buf.putFloat((float) (scale * v1.y));
buf.putFloat((float) (scale * v1.z));
buf.putFloat((float) (scale * v2.x));
buf.putFloat((float) (scale * v2.y));
buf.putFloat((float) (scale * v2.z));
buf.putFloat((float) (scale * v3.x));
buf.putFloat((float) (scale * v3.y));
buf.putFloat((float) (scale * v3.z));
buf.rewind();
buf.get(header);
out.write(header);
}
out.flush();
out.close();
} catch (final Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Saves the mesh as simpleMesh format to the given file path. Existing
* files will be overwritten. The file gives the vertex coordinates and an
* indexed facelist.
*
* @param path
*/
public static void saveToSimpleMesh(final HE_Mesh mesh, final String path) {
final HET_SimpleMeshWriter hem = new HET_SimpleMeshWriter();
hem.beginSave(path);
final WB_XYZ[] points = mesh.getVerticesAsPoint();
hem.intValue(mesh.numberOfVertices());
hem.vertices(points);
final int[][] faces = mesh.getFacesAsInt();
hem.intValue(mesh.numberOfFaces());
hem.faces(faces);
hem.endSave();
}
/**
* Saves the mesh as hemesh format to the given file path. Existing files
* will be overwritten. The file contains the vertex coordinates and all
* half-edge interconnection information. Larger than a simpleMesh but much
* quicker to rebuild.
*
* @param path
*/
public static void saveToHemesh(final HE_Mesh mesh, final String path) {
final HET_HemeshWriter hem = new HET_HemeshWriter();
hem.beginSave(path);
final FastMap<Integer, Integer> vertexKeys = new FastMap<Integer, Integer>();
Iterator<HE_Vertex> vItr = mesh.vItr();
int i = 0;
while (vItr.hasNext()) {
vertexKeys.put(vItr.next().key(), i);
i++;
}
final FastMap<Integer, Integer> halfedgeKeys = new FastMap<Integer, Integer>();
Iterator<HE_Halfedge> heItr = mesh.heItr();
i = 0;
while (heItr.hasNext()) {
halfedgeKeys.put(heItr.next().key(), i);
i++;
}
final FastMap<Integer, Integer> edgeKeys = new FastMap<Integer, Integer>();
Iterator<HE_Edge> eItr = mesh.eItr();
i = 0;
while (eItr.hasNext()) {
edgeKeys.put(eItr.next().key(), i);
i++;
}
final FastMap<Integer, Integer> faceKeys = new FastMap<Integer, Integer>();
Iterator<HE_Face> fItr = mesh.fItr();
i = 0;
while (fItr.hasNext()) {
faceKeys.put(fItr.next().key(), i);
i++;
}
hem.sizes(mesh.numberOfVertices(), mesh.numberOfHalfedges(), mesh.numberOfEdges(), mesh.numberOfFaces());
vItr = mesh.vItr();
HE_Vertex v;
Integer heid;
while (vItr.hasNext()) {
v = vItr.next();
if (v.getHalfedge() == null) {
heid = -1;
} else {
heid = halfedgeKeys.get(v.getHalfedge().key());
if (heid == null) {
heid = -1;
}
}
hem.vertex(v, heid);
}
heItr = mesh.heItr();
HE_Halfedge he;
Integer vid, henextid, hepairid, eid, fid;
while (heItr.hasNext()) {
he = heItr.next();
if (he.getVertex() == null) {
vid = -1;
} else {
vid = vertexKeys.get(he.getVertex().key());
if (vid == null) {
vid = -1;
}
}
if (he.getNextInFace() == null) {
henextid = -1;
} else {
henextid = halfedgeKeys.get(he.getNextInFace().key());
if (henextid == null) {
henextid = -1;
}
}
if (he.getPair() == null) {
hepairid = -1;
} else {
hepairid = halfedgeKeys.get(he.getPair().key());
if (hepairid == null) {
hepairid = -1;
}
}
if (he.getEdge() == null) {
eid = -1;
} else {
eid = edgeKeys.get(he.getEdge().key());
if (eid == null) {
eid = -1;
}
}
if (he.getFace() == null) {
fid = -1;
} else {
fid = faceKeys.get(he.getFace().key());
if (fid == null) {
fid = -1;
}
}
hem.halfedge(vid, henextid, hepairid, eid, fid);
}
eItr = mesh.eItr();
HE_Edge e;
while (eItr.hasNext()) {
e = eItr.next();
if (e.getHalfedge() == null) {
heid = -1;
} else {
heid = halfedgeKeys.get(e.getHalfedge().key());
if (heid == null) {
heid = -1;
}
}
hem.edge(heid);
}
fItr = mesh.fItr();
HE_Face f;
while (fItr.hasNext()) {
f = fItr.next();
if (f.getHalfedge() == null) {
heid = -1;
} else {
heid = halfedgeKeys.get(f.getHalfedge().key());
if (heid == null) {
heid = -1;
}
}
hem.face(heid);
}
hem.endSave();
}
/**
* Saves the mesh as binary hemesh format to the given file path. Existing
* files will be overwritten. The file contains the vertex coordinates and
* all half-edge interconnection information. About the same size of a
* simpleMesh but a lot quicker to rebuild. Due to compression about half as
* fast as an ordinary hemesh file but only a third in size.
*
* @param path
*/
public static void saveToBinaryHemesh(final HE_Mesh mesh, final String path) {
final HET_BinaryHemeshWriter hem = new HET_BinaryHemeshWriter();
hem.beginSave(path);
final FastMap<Integer, Integer> vertexKeys = new FastMap<Integer, Integer>();
Iterator<HE_Vertex> vItr = mesh.vItr();
int i = 0;
while (vItr.hasNext()) {
vertexKeys.put(vItr.next().key(), i);
i++;
}
final FastMap<Integer, Integer> halfedgeKeys = new FastMap<Integer, Integer>();
Iterator<HE_Halfedge> heItr = mesh.heItr();
i = 0;
while (heItr.hasNext()) {
halfedgeKeys.put(heItr.next().key(), i);
i++;
}
final FastMap<Integer, Integer> edgeKeys = new FastMap<Integer, Integer>();
Iterator<HE_Edge> eItr = mesh.eItr();
i = 0;
while (eItr.hasNext()) {
edgeKeys.put(eItr.next().key(), i);
i++;
}
final FastMap<Integer, Integer> faceKeys = new FastMap<Integer, Integer>();
Iterator<HE_Face> fItr = mesh.fItr();
i = 0;
while (fItr.hasNext()) {
faceKeys.put(fItr.next().key(), i);
i++;
}
hem.sizes(mesh.numberOfVertices(), mesh.numberOfHalfedges(), mesh.numberOfEdges(), mesh.numberOfFaces());
vItr = mesh.vItr();
HE_Vertex v;
Integer heid;
while (vItr.hasNext()) {
v = vItr.next();
if (v.getHalfedge() == null) {
heid = -1;
} else {
heid = halfedgeKeys.get(v.getHalfedge().key());
if (heid == null) {
heid = -1;
}
}
hem.vertex(v, heid);
}
heItr = mesh.heItr();
HE_Halfedge he;
Integer vid, henextid, hepairid, eid, fid;
while (heItr.hasNext()) {
he = heItr.next();
if (he.getVertex() == null) {
vid = -1;
} else {
vid = vertexKeys.get(he.getVertex().key());
if (vid == null) {
vid = -1;
}
}
if (he.getNextInFace() == null) {
henextid = -1;
} else {
henextid = halfedgeKeys.get(he.getNextInFace().key());
if (henextid == null) {
henextid = -1;
}
}
if (he.getPair() == null) {
hepairid = -1;
} else {
hepairid = halfedgeKeys.get(he.getPair().key());
if (hepairid == null) {
hepairid = -1;
}
}
if (he.getEdge() == null) {
eid = -1;
} else {
eid = edgeKeys.get(he.getEdge().key());
if (eid == null) {
eid = -1;
}
}
if (he.getFace() == null) {
fid = -1;
} else {
fid = faceKeys.get(he.getFace().key());
if (fid == null) {
fid = -1;
}
}
hem.halfedge(vid, henextid, hepairid, eid, fid);
}
eItr = mesh.eItr();
HE_Edge e;
while (eItr.hasNext()) {
e = eItr.next();
if (e.getHalfedge() == null) {
heid = -1;
} else {
heid = halfedgeKeys.get(e.getHalfedge().key());
if (heid == null) {
heid = -1;
}
}
hem.edge(heid);
}
fItr = mesh.fItr();
HE_Face f;
while (fItr.hasNext()) {
f = fItr.next();
if (f.getHalfedge() == null) {
heid = -1;
} else {
heid = halfedgeKeys.get(f.getHalfedge().key());
if (heid == null) {
heid = -1;
}
}
hem.face(heid);
}
hem.endSave();
}
/**
* Saves the mesh as PovRAY mesh2 format by appending it to the given mesh
* {@link HET_POVWriter} instance.
*
* @param obj
* @param pov instance of HET_POVWriter
* @param normals smooth faces
*/
public static void saveAsPOV(HE_Mesh mesh, HET_POVWriter pov, boolean normals) {
HE_Mesh triMesh = mesh.get();
int vOffset = pov.getCurrVertexOffset();
pov.beginMesh2(String.format("obj%d", mesh.key()));
FastMap<Integer, Integer> keyToIndex = new FastMap<Integer, Integer>(mesh.numberOfVertices());
Iterator<HE_Vertex> vItr = triMesh.vItr();
int vcount = mesh.numberOfVertices();
pov.total(vcount);
HE_Vertex v;
int fcount = 0;
while (vItr.hasNext()) {
v = vItr.next();
keyToIndex.put(v.key(), fcount);
pov.vertex(v);
fcount++;
}
pov.endSection();
if (normals) {
pov.beginNormals(vcount);
vItr = triMesh.vItr();
while (vItr.hasNext()) {
pov.vertex(vItr.next().getVertexNormal());
}
pov.endSection();
}
Iterator<HE_Face> fItr = triMesh.fItr();
pov.beginIndices(triMesh.numberOfFaces());
HE_Face f;
while (fItr.hasNext()) {
f = fItr.next();
pov.face(keyToIndex.get(f.getHalfedge().getVertex().key()) + vOffset, keyToIndex.get(f.getHalfedge().getNextInFace().getVertex().key()) + vOffset, keyToIndex.get(f.getHalfedge().getPrevInFace().getVertex().key()) + vOffset);
}
pov.endSection();
}
/**
* Saves the mesh as PovRAY format to the given {@link PrintWriter}.
*
* @param mesh HE_Mesh
* @param pw PrintWriter
*/
public static void saveAsPOV(HE_Mesh mesh, PrintWriter pw) {
saveAsPOV(mesh, pw, true);
}
/**
* Saves the mesh as PovRAY format to the given {@link PrintWriter}.
*
* @param mesh HE_Mesh
* @param pw PrintWriter
* @param saveNormals boolean (Smooth face or otherwise)
*/
public static void saveAsPOV(HE_Mesh mesh, PrintWriter pw, boolean saveNormals) {
HET_POVWriter obj = new HET_POVWriter();
obj.beginSave(pw);
saveAsPOV(mesh, obj, saveNormals);
obj.endSave();
}
}
/**
* Based on Karsten Schmidt's and Frederik Vanhoutte's Obj export code /*
* Copyright Martin Prout (2012) This library is free software; you can
* redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; either version
* 2.1 of the License, or (at your option) any later version.
* http://creativecommons.org/licenses/LGPL/2.1/ This library is distributed in
* the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU Lesser General Public License for more details. You should have
* received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 51 Franklin St,
* Fifth Floor, Boston, MA 02110-1301, USA
*/
package wblut.hemesh.tools;
/**
* Bare bones PovRAY 3D format exporter. Purely handles the writing of data to
* the .inc file, as a mesh2 object. See {@link HET_Export} for details.
*
* @see HET_Export#saveAsPOV(HE_Mesh, HET_POVWriter, boolean)
*/
import java.io.PrintWriter;
import wblut.geom.WB_Normal;
import wblut.geom.WB_XYZ;
/**
*
* @author Martin Prout
*/
public class HET_POVWriter {
final String COMMA = ", ";
/**
*
*/
protected PrintWriter povWriter;
/**
*
*/
protected int numVerticesWritten = 0;
/**
*
*/
protected int numNormalsWritten = 0;
/**
* Handles PrintWriter input
*
* @param pw
*/
public void beginSave(PrintWriter pw) {
povWriter = pw;
handleBeginSave();
}
/**
* End of mesh2 declaration
*/
public void endSave() {
povWriter.println("}");
povWriter.flush();
}
/**
* Begin the mesh2 output as a PovRAY declaration
*
* @param name
*/
public void beginMesh2(String name) {
StringBuilder pov = new StringBuilder("#declare ");
pov.append(name);
pov.append(" = mesh2{\n");
pov.append("\tvertex_vectors {");
povWriter.println(pov);
}
/**
* End the current section ie vertex_vector, normal_vector or face_indices
*/
public void endSection() {
povWriter.println("\t}");
}
/**
* Output start of normal_vectors
*
* @param count
*/
public void beginNormals(int count) {
povWriter.println("\tnormal_vectors{");
total(count);
}
/**
* Output start of face_indices
*
* @param count
*/
public void beginIndices(int count) {
povWriter.println("\tface_indices{");
total(count);
}
/**
* Used to output total count vertex_vector, normal_vector & face_indices
*
* @param count
*/
public void total(int count) {
povWriter.println(String.format("\t%d,",
count));
}
/**
* Face vertex indices
*
* @param a
* @param b
* @param c
*/
public void face(final int a, final int b, final int c) {
povWriter.println(buildVector(a, b, c));
}
/**
*
* @return
*/
public int getCurrNormalOffset() {
return numNormalsWritten;
}
/**
*
* @return
*/
public int getCurrVertexOffset() {
return numVerticesWritten;
}
/**
*
*/
protected void handleBeginSave() {
povWriter.println("// generated by HE_POVExport");
numVerticesWritten = 0;
numNormalsWritten = 0;
}
/**
*
* @param name
*/
public void newObject(final String name) {
povWriter.println(name);
}
/**
* Triangle normals
*
* @param n
*/
public void normal(final WB_Normal n) {
povWriter.println(buildVector(n));
numNormalsWritten++;
}
/**
* Triangle vertices
*
* @param v
*/
public void vertex(WB_XYZ v) {
povWriter.println(buildVector(v));
numVerticesWritten++;
}
private StringBuilder buildVector(int a, int b, int c) {
StringBuilder my_vector = new StringBuilder(120);
my_vector.append('\t').append('<');
my_vector.append(a).append(COMMA);
my_vector.append(b).append(COMMA);
my_vector.append(c).append('>');
return my_vector.append(COMMA);
}
private StringBuilder buildVector(WB_Normal n) {
StringBuilder my_vector = new StringBuilder(120);
my_vector.append('\t').append('<');
my_vector.append(n.x).append(COMMA);
my_vector.append(n.y * -1).append(COMMA);
my_vector.append(n.z * -1).append('>');
return my_vector.append(COMMA);
}
private StringBuilder buildVector(WB_XYZ v) {
StringBuilder my_vector = new StringBuilder(120);
my_vector.append('\t').append('<');
my_vector.append(v.x).append(COMMA);
my_vector.append(v.y * -1).append(COMMA);
my_vector.append(v.z * -1).append('>');
return my_vector.append(COMMA);
}
}
; mesh0.ini high quaility setting set quality = 5 say for preview
Input_File_Name=mesh0.pov
quality=11
Antialias=true
Sampling_Method=2
Width=1024
Height=768
// Persistence Of Vision Ray Tracer Scene Description File
// File: Simple Scene <template for povwriter>
// Vers: 3.7
// Date: January 2012
// Auth: Martin Prout
#version 3.7;
global_settings{
assumed_gamma 1.0
radiosity{
pretrace_start 0.04
pretrace_end 0.01
count 200
recursion_limit 3
nearest_count 10
error_bound 0.5
}
}
#include "colors.inc"
#include "skies.inc"
#include "mesh0.inc"
#include "metals.inc"
// ---------------declare adjustments to processing scene
#declare ScaleP5 = 0.1; // scale factor
#declare TransXP5 = -100; // translate in X axis
#declare TransYP5 = 200; // translate in Y axis
#declare TransZP5 = -150; // translate in Z axis
#declare RotYP5 = 15; // rotate around Y axis
#declare RotXP5 = 0; // rotate around Y axis
#declare RotZP5 = 0; // rotate around Y axis
// ---------------end of declare adjustments to scene
//----------------declare default colors
#declare CornellRed = rgb<0.57, 0.025, 0.025>; // Right wall Cornell Box
#declare CornellGreen = rgb<0.025, 0.236, 0.025>; // Left wall Cornell Box
#declare LineFill = rgb<1.0, 0.9, 0.8>; // polygon outline color
#declare LineCol = rgb<0.3, 0.225, 0.12>; // polygon outline color
#declare TransFill = rgbf<1.0, 0.95, 0.8, 0.7>; // polygon outline color
#declare BuddhaGold = rgb<195, 160, 4>/255; // Custom Gold
//----------------end declare default colors #### paste sketch after this ####
//----------------begin declare finish
#declare Finish0=finish{diffuse 0.75 emission 0} // Stroke
#declare Finish1=finish{diffuse 0.78 emission 0} // Cornell Box Light Patch
#declare Finish2=finish{emission 0.1 phong 0.5 phong_size 10.0} // Processing object finish
//----------------end declare finish
#declare SWIDTH=1.0; // processing equivalent is stroke width
//----------------begin declare pigment
#declare Pigment0 = pigment{rgb<1, 1, 1>} // Cornell Box Light Patch
//----------------end declare pigment
//----------------begin declare texture
#declare WhiteT=texture{pigment{White} finish{Finish0}} //
#declare RedT=texture{pigment{CornellRed} finish{Finish0}} // Cornell Box Walls
#declare GreenT=texture{pigment{CornellGreen} finish{Finish0}} //
#declare Texture0=texture{pigment{LineFill} finish{Finish1}} // this is for 'stroke' color
//----------------end declare texture
//----------------declare scene Settings
#declare camera0 = camera { // define additional cameras to suit viewing preferences
location <-1.5, 30.0, -150.0>
direction <0.0, 0.0, 2.0>
up <0.0, 1.0, 0.0>
right <1.33333, 0.0, 0.0>
look_at <0.0, 25.0, 35.0>
}
#declare light0 = light_source { <100.0, 100.0, -200.0> colour White }
#declare ground0 = plane { <0.0, 1.0, 0.0>, 0.0 // a reflective ground plane
pigment { NeonBlue }
finish {reflection 0.15}
}
//------------------end of declare scene settings
// -----------------set the scene
camera { camera0 } // ------------------------------------------
// The use of declared values makes it possible to easily
light_source{ light0 } // change the way the scene is rendered. Just define an
// additional camera say for your template, and do the
sky_sphere{ S_Cloud3 } // substitution here. Retain the original definition and
// you can easily backtrack. Definitions can also be saved
plane{ ground0 } // as included file see colors.inc for an example.
// ---------------------------------------------
// -----------------end set the scene
object{
mesh2{ obj0 } // name obj0 created by modified Hemesh library
texture {T_Silver_5E}
scale<0.1, 0.1, 0.1>
translate<0, 10, 0>
}
object{
mesh2{ obj2 } // name obj2 created by modified Hemesh library (why not 1?)
texture {T_Copper_1A}
scale<0.1, 0.1, 0.1>
translate<0, 10, 0>
}
package test;
/**
* Copyright Martin Prout (2012) This library is free software; you can
* redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; either version
* 2.1 of the License, or (at your option) any later version.
* http://creativecommons.org/licenses/LGPL/2.1/ This library is distributed in
* the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU Lesser General Public License for more details. You should have
* received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 51 Franklin St,
* Fifth Floor, Boston, MA 02110-1301, USA
*/
import java.io.PrintWriter;
import processing.core.PApplet;
import wblut.hemesh.core.HE_Mesh;
import wblut.hemesh.creators.HEC_IsoSurface;
import wblut.hemesh.modifiers.HEM_Smooth;
import wblut.hemesh.tools.HET_Export;
import wblut.processing.WB_Render;
public class SimpleExport extends PApplet {
HE_Mesh mesh;
HE_Mesh invMesh;
WB_Render render;
int res;
@Override
public void setup() {
size(800, 800, P3D);
smooth();
res = 4;
float[][][] values = new float[res + 1][res + 1][res + 1];
for (int i = 0; i < res + 1; i++) {
for (int j = 0; j < res + 1; j++) {
for (int k = 0; k < res + 1; k++) {
values[i][j][k] = 2.1f * noise(0.35f * i, 0.35f * j, 0.35f * k);
}
}
}
HEC_IsoSurface creator = new HEC_IsoSurface();
creator.setResolution(res, res, res);// number of cells in x,y,z direction
creator.setSize(400.0f / res, 400.0f / res, 400.0f / res);// cell size
creator.setValues(values);// values corresponding to the grid points
// values can also be double[][][]
creator.setIsolevel(1);// isolevel to mesh
creator.setInvert(false);// invert mesh
creator.setBoundary(100);// value of isoFunction outside grid
// use creator.clearBoundary() to rest boundary values to "no value".
// A boundary value of "no value" results in an open mesh
mesh = new HE_Mesh(creator);
mesh.modify(new HEM_Smooth().setIterations(2).setAutoRescale(true));
creator.setInvert(true);
invMesh = new HE_Mesh(creator);
invMesh.modify(new HEM_Smooth().setIterations(2).setAutoRescale(true));
render = new WB_Render(this);
}
@Override
public void draw() {
background(120);
lights();
translate(400, 400, 0);
rotateY(mouseX * 1.0f / width * TWO_PI);
rotateX(mouseY * 1.0f / height * TWO_PI);
noStroke();
fill(255);
render.drawFaces(mesh);
fill(255, 0, 0);
render.drawFaces(invMesh);
stroke(0);
render.drawEdges(mesh);
stroke(255, 0, 0, 80);
render.drawEdges(invMesh);
}
@Override
public void keyPressed() {
if (key == 's') {
String fileID = "mesh0";
PrintWriter pw = this.createWriter(fileID + ".inc");
// HET_Export.saveAsPOV(mesh, pw, false); // no normals (see facets)
// HET_Export.saveAsPOV(invMesh, pw, false);
HET_Export.saveAsPOV(mesh, pw); // default use normals (smooth faces)
HET_Export.saveAsPOV(invMesh, pw);
pw.flush();
pw.close();
}
exit();
}
static public void main(String args[]) {
PApplet.main(new String[]{"--bgcolor=#DFDFDF", "test.SimpleExport"});
}
}
import wblut.math.*;
import wblut.processing.*;
import wblut.hemesh.creators.*;
import wblut.hemesh.core.*;
import processing.opengl.*;
import wblut.hemesh.modifiers.*;
import wblut.hemesh.tools.HET_Export;
HE_Mesh mesh;
HE_Mesh invMesh;
WB_Render render;
int res;
void setup() {
size(800, 800, OPENGL);
smooth();
res=20;
float[][][] values=new float[res+1][res+1][res+1];
for (int i = 0; i < res+1; i++) {
for (int j = 0; j < res+1; j++) {
for (int k = 0; k < res+1; k++) {
values[i][j][k]=2.1*noise(0.35*i, 0.35*j, 0.35*k);
}
}
}
HEC_IsoSurface creator=new HEC_IsoSurface();
creator.setResolution(res, res, res);// number of cells in x,y,z direction
creator.setSize(400.0/res, 400.0/res, 400.0/res);// cell size
creator.setValues(values);// values corresponding to the grid points
// values can also be double[][][]
creator.setIsolevel(1);// isolevel to mesh
creator.setInvert(false);// invert mesh
creator.setBoundary(100);// value of isoFunction outside grid
// use creator.clearBoundary() to rest boundary values to "no value".
// A boundary value of "no value" results in an open mesh
mesh=new HE_Mesh(creator);
mesh.modify(new HEM_Smooth().setIterations(20).setAutoRescale(true));
creator.setInvert(true);
invMesh=new HE_Mesh(creator);
invMesh.modify(new HEM_Smooth().setIterations(3).setAutoRescale(true));
render=new WB_Render(this);
}
void draw() {
background(120);
lights();
translate(400, 400, 0);
rotateY(mouseX*1.0f/width*TWO_PI);
rotateX(mouseY*1.0f/height*TWO_PI);
noStroke();
fill(255);
render.drawFaces(mesh);
fill(255, 0, 0);
render.drawFaces(invMesh);
stroke(0);
render.drawEdges(mesh);
stroke(255, 0, 0, 80);
render.drawEdges(invMesh);
}
void keyPressed() {
if (key == 's') {
String fileID = "mesh0";
PrintWriter pw = this.createWriter(fileID + ".inc");
HET_Export.saveAsPOV(mesh, pw, false); // no normals (see facets)
//HET_Export.saveAsPOV(invMesh, pw, false);
//HET_Export.saveAsPOV(mesh, pw);
HET_Export.saveAsPOV(invMesh, pw); // default is to use normals (smooth faces)
pw.flush();
pw.close();
}
exit();
}
@monkstone
Copy link
Author

Update 29 January 2011.
User must now provide a PrintWriter (this simplifies user interface, particularly when createWriter() convenience method is used.
The default option is provide normals, and hence smooth faces, however seeing facets such as glass can be aesthetically pleasing, so I now include option of controlling whether normal_vectors are created.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment