diff --git a/Cargo.lock b/Cargo.lock index e938e7b..99e403b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,6 +4,7 @@ version = "0.1.0" dependencies = [ "crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)", + "lodepng 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "nom 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -18,6 +19,11 @@ dependencies = [ "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "c_vec" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "crossbeam" version = "0.2.9" @@ -47,6 +53,16 @@ name = "libc" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "lodepng" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "c_vec 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "rgb 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "memchr" version = "0.1.11" @@ -85,6 +101,11 @@ name = "regex-syntax" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rgb" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rustc-serialize" version = "0.3.19" diff --git a/Cargo.toml b/Cargo.toml index 055d67b..8172713 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,4 +9,5 @@ rustc-serialize = "0.3" nom = "1.2" scoped_threadpool = "0.1" crossbeam = "0.2" -num_cpus = "0.2" \ No newline at end of file +num_cpus = "0.2" +lodepng = "0.8" \ No newline at end of file diff --git a/example_scenes/cornell_box.psy b/example_scenes/cornell_box.psy index 54cb937..17132d4 100644 --- a/example_scenes/cornell_box.psy +++ b/example_scenes/cornell_box.psy @@ -1,6 +1,6 @@ Scene $Scene_fr1 { Output { - Path ["test_renders/cornell_box.ppm"] + Path ["test_renders/cornell_box.png"] } RenderSettings { Resolution [512 512] diff --git a/example_scenes/cube.psy b/example_scenes/cube.psy index 75968a1..d7220ab 100644 --- a/example_scenes/cube.psy +++ b/example_scenes/cube.psy @@ -1,6 +1,6 @@ Scene $Scene_fr1 { Output { - Path ["test_renders/cube.ppm"] + Path ["test_renders/cube.png"] } RenderSettings { Resolution [960 540] diff --git a/psychoblend/psy_export.py b/psychoblend/psy_export.py index 2cd8bcb..c4b4af4 100644 --- a/psychoblend/psy_export.py +++ b/psychoblend/psy_export.py @@ -316,47 +316,17 @@ class PsychoExporter: time_meshes += [ob.to_mesh(self.scene, True, 'RENDER')] # Export mesh data if necessary - if export_mesh and ob.data.psychopath.is_subdivision_surface == False: - # Exporting normal mesh - self.mesh_names[mesh_name] = True - self.w.write("Assembly $%s {\n" % escape_name(mesh_name)) - self.w.indent() - - # Write patches - polys = time_meshes[0].polygons - face_count = 0 - for poly in polys: - face_count += 1 - if len(poly.vertices) == 4: - # Object - self.w.write("BilinearPatch $%s.%d {\n" % (escape_name(mesh_name), face_count)) - self.w.indent() - for i in range(len(time_meshes)): - verts = time_meshes[i].vertices - vstr = "" - for vi in [poly.vertices[0], poly.vertices[1], poly.vertices[3], poly.vertices[2]]: - v = verts[vi].co - vstr += ("%f %f %f " % (v[0], v[1], v[2])) - self.w.write("Vertices [%s]\n" % vstr[:-1]) - self.w.unindent() - self.w.write("}\n") - # Instance - self.w.write("Instance {\n") - self.w.indent() - self.w.write("Data [$%s.%d]\n" % (escape_name(mesh_name), face_count)) - self.w.unindent() - self.w.write("}\n") - for m in time_meshes: - bpy.data.meshes.remove(m) - - # Assembly section end - self.w.unindent() - self.w.write("}\n") - elif export_mesh and ob.data.psychopath.is_subdivision_surface == True: - # Exporting subdivision surface cage - self.mesh_names[mesh_name] = True - self.w.write("SubdivisionSurface $%s {\n" % escape_name(mesh_name)) - self.w.indent() + if export_mesh: + if ob.data.psychopath.is_subdivision_surface == False: + # Exporting normal mesh + self.mesh_names[mesh_name] = True + self.w.write("MeshSurface $%s {\n" % escape_name(mesh_name)) + self.w.indent() + elif ob.data.psychopath.is_subdivision_surface == True: + # Exporting subdivision surface cage + self.mesh_names[mesh_name] = True + self.w.write("SubdivisionSurface $%s {\n" % escape_name(mesh_name)) + self.w.indent() # Write vertices for ti in range(len(time_meshes)): diff --git a/src/image.rs b/src/image.rs index 40430c8..07c73e2 100644 --- a/src/image.rs +++ b/src/image.rs @@ -10,6 +10,8 @@ use std::cell::{RefCell, UnsafeCell}; use std::mem; use std::cmp; +use lodepng; + use color::{XYZ, xyz_to_rec709e}; #[derive(Debug)] @@ -124,6 +126,32 @@ impl Image { // Done Ok(()) } + + pub fn write_png(&mut self, path: &Path) -> io::Result<()> { + let mut image = Vec::new(); + + // Convert pixels + for y in 0..self.res.1 { + for x in 0..self.res.0 { + let (r, g, b) = quantize_tri_255(xyz_to_srgbe(self.get(x, y).to_tuple())); + let d = lodepng::RGB::new(r, g, b); + image.push(d); + } + } + + // Write file + if let Err(_) = lodepng::encode_file(path, + &image, + self.res.0, + self.res.1, + lodepng::ColorType::LCT_RGB, + 8) { + panic!("Couldn't write PNG file."); + } + + // Done + Ok(()) + } } #[derive(Debug)] diff --git a/src/main.rs b/src/main.rs index 666f8b4..8764420 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ extern crate docopt; extern crate scoped_threadpool; extern crate crossbeam; extern crate num_cpus; +extern crate lodepng; #[macro_use] extern crate nom; diff --git a/src/renderer.rs b/src/renderer.rs index 5bbfcfe..00e5d8f 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -208,7 +208,7 @@ impl Renderer { // Write rendered image to disk - let _ = image.write_binary_ppm(Path::new(&self.output_file)); + let _ = image.write_png(Path::new(&self.output_file)); } }