diff --git a/psychoblend/render.py b/psychoblend/render.py index db37a9d..505099f 100644 --- a/psychoblend/render.py +++ b/psychoblend/render.py @@ -77,7 +77,7 @@ class PsychopathRender(bpy.types.RenderEngine): # Start Rendering! try: - self._process = subprocess.Popen([psy_binary] + args, bufsize=1, stdin=subprocess.PIPE, stdout=subprocess.PIPE) + self._process = subprocess.Popen([psy_binary] + args, stdin=subprocess.PIPE, stdout=subprocess.PIPE) except OSError: # TODO, report api print("Psychopath: could not execute '%s'" % psy_binary) @@ -99,16 +99,16 @@ class PsychopathRender(bpy.types.RenderEngine): height = bucket_info[3] - bucket_info[1] # Decode pixel data - pixels = [p for p in struct.iter_unpack("ffff", base64.b64decode(pixels_encoded))] - pixels_flipped = [] + pixels_unpacked = [p for p in struct.iter_unpack("ffff", base64.b64decode(pixels_encoded))] + pixels = [] for i in range(height): n = height - i - 1 - pixels_flipped += pixels[n*width:(n+1)*width] + pixels += pixels_unpacked[n*width:(n+1)*width] # Write pixel data to render image result = self.begin_result(x, y, width, height) lay = result.layers[0].passes["Combined"] - lay.rect = pixels_flipped + lay.rect = pixels self.end_result(result) def _render(self, depsgraph): diff --git a/psychoblend/ui.py b/psychoblend/ui.py index 284005c..46ccf68 100644 --- a/psychoblend/ui.py +++ b/psychoblend/ui.py @@ -74,7 +74,6 @@ register_engine_with_panels( "DATA_PT_mesh_attributes", "DATA_PT_normals", "DATA_PT_remesh", - "DATA_PT_sculpt_vertex_colors", "DATA_PT_shape_keys", "DATA_PT_texture_space", "DATA_PT_uv_texture", diff --git a/src/image.rs b/src/image.rs index df61080..1d2f24c 100644 --- a/src/image.rs +++ b/src/image.rs @@ -235,25 +235,39 @@ impl<'a> Bucket<'a> { /// encoding to base64. The fourth channel is alpha, and is set to 1.0 for /// all pixels. pub fn rgba_base64(&mut self, color_convert: F) -> String + where + F: Fn((f32, f32, f32)) -> (f32, f32, f32), + { + let data_u8 = self.rgba_raw(color_convert); + base64::encode(&data_u8) + } + + /// Returns the bucket's contents as a binary string. + /// + /// The data is laid out as four-floats-per-pixel in scanline order. + /// The fourth channel is alpha, and is set to 1.0 for all pixels. + /// + /// `color_convert` lets you do a colorspace conversion before base64 + /// encoding if desired. + pub fn rgba_raw(&mut self, color_convert: F) -> Vec where F: Fn((f32, f32, f32)) -> (f32, f32, f32), { use std::slice; - let mut data = Vec::with_capacity( - (4 * (self.max.0 - self.min.0) * (self.max.1 - self.min.1)) as usize, + let mut data: Vec = Vec::with_capacity( + std::mem::size_of::() + * (4 * (self.max.0 - self.min.0) * (self.max.1 - self.min.1)) as usize, ); for y in self.min.1..self.max.1 { for x in self.min.0..self.max.0 { let color = color_convert(self.get(x, y).to_tuple()); - data.push(color.0); - data.push(color.1); - data.push(color.2); - data.push(1.0); + data.extend_from_slice(&color.0.to_ne_bytes()); + data.extend_from_slice(&color.1.to_ne_bytes()); + data.extend_from_slice(&color.2.to_ne_bytes()); + data.extend_from_slice(&1.0f32.to_ne_bytes()); } } - let data_u8 = - unsafe { slice::from_raw_parts(&data[0] as *const f32 as *const u8, data.len() * 4) }; - base64::encode(data_u8) + data } } diff --git a/src/renderer.rs b/src/renderer.rs index 1e22d14..8c9bb4f 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -293,16 +293,26 @@ impl<'a> Renderer<'a> { let new_string = format!("{:.2}%", percentage_new); if let Some(bucket_data) = base64_enc { + let mut stdout = std::io::stdout().lock(); // If doing Blender output - println!("DIV"); - println!("{}", new_string); - println!( - "{} {} {} {}", - bucket_min.0, bucket_min.1, bucket_max.0, bucket_max.1 - ); - println!("{}", bucket_data); - println!("BUCKET_END"); - println!("DIV"); + stdout.write_all(b"DIV\n").unwrap(); + stdout + .write_all(format!("{}\n", new_string).as_bytes()) + .unwrap(); + stdout + .write_all( + format!( + "{} {} {} {}\n", + bucket_min.0, bucket_min.1, bucket_max.0, bucket_max.1 + ) + .as_bytes(), + ) + .unwrap(); + stdout + .write_all(format!("{}\n", bucket_data).as_bytes()) + .unwrap(); + stdout.write_all(b"BUCKET_END\n").unwrap(); + stdout.write_all(b"DIV\n").unwrap(); } else { // If doing console output if new_string != old_string {