Abstraction over format
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -4418,9 +4418,11 @@ dependencies = [
|
|||||||
"common",
|
"common",
|
||||||
"criterion",
|
"criterion",
|
||||||
"goo_format",
|
"goo_format",
|
||||||
|
"image 0.25.1",
|
||||||
"nalgebra 0.32.6",
|
"nalgebra 0.32.6",
|
||||||
"obj-rs",
|
"obj-rs",
|
||||||
"ordered-float",
|
"ordered-float",
|
||||||
|
"parking_lot",
|
||||||
"rayon",
|
"rayon",
|
||||||
"stl_io",
|
"stl_io",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
4
TODO.md
4
TODO.md
@@ -75,6 +75,8 @@
|
|||||||
- [x] Fix Z translation being doubled
|
- [x] Fix Z translation being doubled
|
||||||
- [ ] Merge goo_format changes into goo crate
|
- [ ] Merge goo_format changes into goo crate
|
||||||
- [ ] Implement .ctb format (see <https://github.com/cbiffle/catibo/blob/master/doc/cbddlp-ctb.adoc>)
|
- [ ] Implement .ctb format (see <https://github.com/cbiffle/catibo/blob/master/doc/cbddlp-ctb.adoc>)
|
||||||
|
- [x] Generic format system
|
||||||
|
- [ ] Fix plugins / post processes
|
||||||
- [ ] Undo / Redo
|
- [ ] Undo / Redo
|
||||||
- [x] Close file menu if button clicked
|
- [x] Close file menu if button clicked
|
||||||
- [x] Allow dragging in project to load them
|
- [x] Allow dragging in project to load them
|
||||||
@@ -82,5 +84,5 @@
|
|||||||
- [ ] Save on remote thread
|
- [ ] Save on remote thread
|
||||||
- [ ] Printer profiles
|
- [ ] Printer profiles
|
||||||
- [x] Save config on quit
|
- [x] Save config on quit
|
||||||
- [ ] Refactor plugins to post processors
|
- [x] Refactor plugins to post processors
|
||||||
- [ ] Update readme
|
- [ ] Update readme
|
||||||
|
@@ -1,8 +1,12 @@
|
|||||||
use nalgebra::{Vector2, Vector3};
|
use nalgebra::{Vector2, Vector3};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::format::Format;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct SliceConfig {
|
pub struct SliceConfig {
|
||||||
|
pub format: Format,
|
||||||
|
|
||||||
pub platform_resolution: Vector2<u32>,
|
pub platform_resolution: Vector2<u32>,
|
||||||
pub platform_size: Vector3<f32>,
|
pub platform_size: Vector3<f32>,
|
||||||
pub slice_height: f32,
|
pub slice_height: f32,
|
||||||
@@ -25,6 +29,8 @@ pub struct ExposureConfig {
|
|||||||
impl Default for SliceConfig {
|
impl Default for SliceConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
format: Format::Goo,
|
||||||
|
|
||||||
platform_resolution: Vector2::new(11_520, 5_120),
|
platform_resolution: Vector2::new(11_520, 5_120),
|
||||||
platform_size: Vector3::new(218.88, 122.904, 260.0),
|
platform_size: Vector3::new(218.88, 122.904, 260.0),
|
||||||
slice_height: 0.05,
|
slice_height: 0.05,
|
||||||
|
6
common/src/format.rs
Normal file
6
common/src/format.rs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
|
pub enum Format {
|
||||||
|
Goo,
|
||||||
|
}
|
@@ -1,4 +1,5 @@
|
|||||||
pub mod config;
|
pub mod config;
|
||||||
|
pub mod format;
|
||||||
pub mod image;
|
pub mod image;
|
||||||
pub mod misc;
|
pub mod misc;
|
||||||
pub mod oklab;
|
pub mod oklab;
|
||||||
|
@@ -13,7 +13,6 @@ use egui::Visuals;
|
|||||||
use egui_dock::{DockState, NodeIndex};
|
use egui_dock::{DockState, NodeIndex};
|
||||||
use egui_phosphor::regular::CARET_RIGHT;
|
use egui_phosphor::regular::CARET_RIGHT;
|
||||||
use egui_tracing::EventCollector;
|
use egui_tracing::EventCollector;
|
||||||
use image::imageops::FilterType;
|
|
||||||
use nalgebra::Vector2;
|
use nalgebra::Vector2;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
@@ -33,8 +32,7 @@ use crate::{
|
|||||||
windows::{self, Tab},
|
windows::{self, Tab},
|
||||||
};
|
};
|
||||||
use common::config::SliceConfig;
|
use common::config::SliceConfig;
|
||||||
use goo_format::{File as GooFile, LayerEncoder, PreviewImage};
|
use slicer::{format::FormatSliceFile, slicer::Slicer, Pos};
|
||||||
use slicer::{slicer::Slicer, Pos};
|
|
||||||
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod project;
|
pub mod project;
|
||||||
@@ -174,19 +172,12 @@ impl App {
|
|||||||
[{ self.slice_operation } as slice_operation],
|
[{ self.slice_operation } as slice_operation],
|
||||||
move || {
|
move || {
|
||||||
let slice_operation = slice_operation.as_ref().unwrap();
|
let slice_operation = slice_operation.as_ref().unwrap();
|
||||||
let mut goo = GooFile::from_slice_result(slicer.slice::<LayerEncoder>());
|
let preview_image = slice_operation.preview_image();
|
||||||
|
let file = FormatSliceFile::from_slice_result(preview_image, slicer.slice_format());
|
||||||
|
|
||||||
{
|
let layers = file.info().layers as usize;
|
||||||
let preview_image = slice_operation.preview_image();
|
|
||||||
goo.header.big_preview =
|
|
||||||
PreviewImage::from_image_scaled(&preview_image, FilterType::Nearest);
|
|
||||||
goo.header.small_preview =
|
|
||||||
PreviewImage::from_image_scaled(&preview_image, FilterType::Nearest);
|
|
||||||
}
|
|
||||||
|
|
||||||
let layers = goo.layers.len();
|
|
||||||
slice_operation.add_result(SliceResult {
|
slice_operation.add_result(SliceResult {
|
||||||
goo,
|
file,
|
||||||
slice_preview_layer: 0,
|
slice_preview_layer: 0,
|
||||||
last_preview_layer: 0,
|
last_preview_layer: 0,
|
||||||
preview_offset: Vector2::new(0.0, 0.0),
|
preview_offset: Vector2::new(0.0, 0.0),
|
||||||
|
@@ -7,11 +7,10 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use common::misc::human_duration;
|
use common::misc::human_duration;
|
||||||
use goo_format::File as GooFile;
|
|
||||||
use image::RgbaImage;
|
use image::RgbaImage;
|
||||||
use nalgebra::Vector2;
|
use nalgebra::Vector2;
|
||||||
use parking_lot::{Condvar, MappedMutexGuard, Mutex, MutexGuard};
|
use parking_lot::{Condvar, MappedMutexGuard, Mutex, MutexGuard};
|
||||||
use slicer::slicer::Progress as SliceProgress;
|
use slicer::{format::FormatSliceFile, slicer::Progress as SliceProgress};
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
@@ -30,7 +29,7 @@ pub struct SliceOperation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct SliceResult {
|
pub struct SliceResult {
|
||||||
pub goo: GooFile,
|
pub file: FormatSliceFile,
|
||||||
|
|
||||||
pub slice_preview_layer: usize,
|
pub slice_preview_layer: usize,
|
||||||
pub last_preview_layer: usize,
|
pub last_preview_layer: usize,
|
||||||
@@ -95,7 +94,7 @@ impl SliceOperation {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let goo = &mut result.as_mut().unwrap().goo;
|
let goo = &mut result.as_mut().unwrap().file;
|
||||||
app.plugin_manager.post_slice(app, goo);
|
app.plugin_manager.post_slice(app, goo);
|
||||||
self.has_post_processed = true;
|
self.has_post_processed = true;
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
use egui::{Context, Ui};
|
use egui::{Context, Ui};
|
||||||
|
use slicer::format::FormatSliceFile;
|
||||||
|
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use goo_format::File as GooFile;
|
use goo_format::File as GooFile;
|
||||||
@@ -18,9 +19,10 @@ pub struct PluginManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PluginManager {
|
impl PluginManager {
|
||||||
pub fn post_slice(&self, app: &App, goo: &mut GooFile) {
|
pub fn post_slice(&self, app: &App, goo: &mut FormatSliceFile) {
|
||||||
for plugin in &self.plugins {
|
for plugin in &self.plugins {
|
||||||
plugin.post_slice(app, goo);
|
// TODO: FIX PLUGINS
|
||||||
|
// plugin.post_slice(app, goo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,6 @@ use egui::{
|
|||||||
};
|
};
|
||||||
use egui_phosphor::regular::{FLOPPY_DISK_BACK, PAPER_PLANE_TILT};
|
use egui_phosphor::regular::{FLOPPY_DISK_BACK, PAPER_PLANE_TILT};
|
||||||
use egui_wgpu::Callback;
|
use egui_wgpu::Callback;
|
||||||
use goo_format::LayerDecoder;
|
|
||||||
use nalgebra::Vector2;
|
use nalgebra::Vector2;
|
||||||
use rfd::FileDialog;
|
use rfd::FileDialog;
|
||||||
|
|
||||||
@@ -82,7 +81,7 @@ pub fn ui(app: &mut App, ctx: &Context) {
|
|||||||
let result = result.as_ref().unwrap();
|
let result = result.as_ref().unwrap();
|
||||||
|
|
||||||
let mut serializer = DynamicSerializer::new();
|
let mut serializer = DynamicSerializer::new();
|
||||||
result.goo.serialize(&mut serializer);
|
result.file.serialize(&mut serializer);
|
||||||
let data = Arc::new(serializer.into_inner());
|
let data = Arc::new(serializer.into_inner());
|
||||||
|
|
||||||
let mainboard_id = printer.mainboard_id.clone();
|
let mainboard_id = printer.mainboard_id.clone();
|
||||||
@@ -101,7 +100,7 @@ pub fn ui(app: &mut App, ctx: &Context) {
|
|||||||
if let Some(path) = FileDialog::new().save_file() {
|
if let Some(path) = FileDialog::new().save_file() {
|
||||||
let mut file = File::create(path).unwrap();
|
let mut file = File::create(path).unwrap();
|
||||||
let mut serializer = DynamicSerializer::new();
|
let mut serializer = DynamicSerializer::new();
|
||||||
result.goo.serialize(&mut serializer);
|
result.file.serialize(&mut serializer);
|
||||||
file.write_all(&serializer.into_inner()).unwrap();
|
file.write_all(&serializer.into_inner()).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,7 +119,7 @@ pub fn ui(app: &mut App, ctx: &Context) {
|
|||||||
let layer_digits = result.layer_count.1 as usize;
|
let layer_digits = result.layer_count.1 as usize;
|
||||||
ui.add(
|
ui.add(
|
||||||
DragValue::new(&mut result.slice_preview_layer)
|
DragValue::new(&mut result.slice_preview_layer)
|
||||||
.clamp_range(1..=result.goo.layers.len())
|
.clamp_range(1..=result.file.info().layers)
|
||||||
.custom_formatter(|n, _| {
|
.custom_formatter(|n, _| {
|
||||||
format!("{:0>layer_digits$}/{}", n, result.layer_count.0)
|
format!("{:0>layer_digits$}/{}", n, result.layer_count.0)
|
||||||
}),
|
}),
|
||||||
@@ -152,38 +151,27 @@ pub fn ui(app: &mut App, ctx: &Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn slice_preview(ui: &mut egui::Ui, result: &mut SliceResult) {
|
fn slice_preview(ui: &mut egui::Ui, result: &mut SliceResult) {
|
||||||
|
let info = result.file.info();
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.spacing_mut().slider_width = ui.available_size().x
|
ui.spacing_mut().slider_width =
|
||||||
/ result.goo.header.x_resolution as f32
|
ui.available_size().x / info.resolution.x as f32 * info.resolution.y as f32 - 10.0;
|
||||||
* result.goo.header.y_resolution as f32
|
|
||||||
- 10.0;
|
|
||||||
ui.add(
|
ui.add(
|
||||||
Slider::new(&mut result.slice_preview_layer, 1..=result.goo.layers.len())
|
Slider::new(&mut result.slice_preview_layer, 1..=info.layers as usize)
|
||||||
.vertical()
|
.vertical()
|
||||||
.handle_shape(HandleShape::Rect { aspect_ratio: 1.0 })
|
.handle_shape(HandleShape::Rect { aspect_ratio: 1.0 })
|
||||||
.show_value(false),
|
.show_value(false),
|
||||||
);
|
);
|
||||||
|
|
||||||
let (width, height) = (
|
let (width, height) = (info.resolution.x as u32, info.resolution.y as u32);
|
||||||
result.goo.header.x_resolution as u32,
|
|
||||||
result.goo.header.y_resolution as u32,
|
|
||||||
);
|
|
||||||
|
|
||||||
result.slice_preview_layer = result.slice_preview_layer.clamp(1, result.goo.layers.len());
|
result.slice_preview_layer = result.slice_preview_layer.clamp(1, info.layers as usize);
|
||||||
let new_preview = if result.last_preview_layer != result.slice_preview_layer {
|
let new_preview = if result.last_preview_layer != result.slice_preview_layer {
|
||||||
result.last_preview_layer = result.slice_preview_layer;
|
result.last_preview_layer = result.slice_preview_layer;
|
||||||
|
|
||||||
let layer_data = &result.goo.layers[result.slice_preview_layer - 1].data;
|
|
||||||
let decoder = LayerDecoder::new(layer_data);
|
|
||||||
|
|
||||||
let mut image = vec![0; (width * height) as usize];
|
let mut image = vec![0; (width * height) as usize];
|
||||||
let mut pixel = 0;
|
let layer = result.slice_preview_layer - 1;
|
||||||
for run in decoder {
|
result.file.decode_layer(layer, &mut image);
|
||||||
for _ in 0..run.length {
|
|
||||||
image[pixel] = run.value;
|
|
||||||
pixel += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(image)
|
Some(image)
|
||||||
} else {
|
} else {
|
||||||
@@ -195,8 +183,7 @@ fn slice_preview(ui: &mut egui::Ui, result: &mut SliceResult) {
|
|||||||
let (rect, response) = ui.allocate_exact_size(
|
let (rect, response) = ui.allocate_exact_size(
|
||||||
Vec2::new(
|
Vec2::new(
|
||||||
available_size.x,
|
available_size.x,
|
||||||
available_size.x / result.goo.header.x_resolution as f32
|
available_size.x / info.resolution.x as f32 * info.resolution.y as f32,
|
||||||
* result.goo.header.y_resolution as f32,
|
|
||||||
),
|
),
|
||||||
Sense::drag(),
|
Sense::drag(),
|
||||||
);
|
);
|
||||||
@@ -215,10 +202,7 @@ fn slice_preview(ui: &mut egui::Ui, result: &mut SliceResult) {
|
|||||||
let callback = Callback::new_paint_callback(
|
let callback = Callback::new_paint_callback(
|
||||||
rect,
|
rect,
|
||||||
SlicePreviewRenderCallback {
|
SlicePreviewRenderCallback {
|
||||||
dimensions: Vector2::new(
|
dimensions: Vector2::new(info.resolution.x as u32, info.resolution.y as u32),
|
||||||
result.goo.header.x_resolution as u32,
|
|
||||||
result.goo.header.y_resolution as u32,
|
|
||||||
),
|
|
||||||
offset: result.preview_offset,
|
offset: result.preview_offset,
|
||||||
scale: preview_scale,
|
scale: preview_scale,
|
||||||
new_preview,
|
new_preview,
|
||||||
|
@@ -5,9 +5,11 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
|
image.workspace = true
|
||||||
nalgebra.workspace = true
|
nalgebra.workspace = true
|
||||||
obj-rs.workspace = true
|
obj-rs.workspace = true
|
||||||
ordered-float.workspace = true
|
ordered-float.workspace = true
|
||||||
|
parking_lot.workspace = true
|
||||||
rayon.workspace = true
|
rayon.workspace = true
|
||||||
stl_io.workspace = true
|
stl_io.workspace = true
|
||||||
tracing.workspace = true
|
tracing.workspace = true
|
||||||
|
74
slicer/src/format.rs
Normal file
74
slicer/src/format.rs
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
use goo_format::PreviewImage;
|
||||||
|
use image::{imageops::FilterType, RgbaImage};
|
||||||
|
use nalgebra::Vector2;
|
||||||
|
use parking_lot::MappedMutexGuard;
|
||||||
|
|
||||||
|
use common::{misc::SliceResult, serde::Serializer};
|
||||||
|
|
||||||
|
pub enum FormatSliceResult<'a> {
|
||||||
|
Goo(SliceResult<'a, goo_format::LayerContent>),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum FormatSliceFile {
|
||||||
|
Goo(goo_format::File),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SliceInfo {
|
||||||
|
pub layers: u32,
|
||||||
|
pub resolution: Vector2<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: convert to dynamic dispatch
|
||||||
|
|
||||||
|
impl FormatSliceFile {
|
||||||
|
pub fn from_slice_result(
|
||||||
|
preview_image: MappedMutexGuard<'_, RgbaImage>,
|
||||||
|
slice_result: FormatSliceResult,
|
||||||
|
) -> Self {
|
||||||
|
match slice_result {
|
||||||
|
FormatSliceResult::Goo(result) => {
|
||||||
|
let mut file = goo_format::File::from_slice_result(result);
|
||||||
|
file.header.big_preview =
|
||||||
|
PreviewImage::from_image_scaled(&preview_image, FilterType::Nearest);
|
||||||
|
file.header.small_preview =
|
||||||
|
PreviewImage::from_image_scaled(&preview_image, FilterType::Nearest);
|
||||||
|
Self::Goo(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serialize<T: Serializer>(&self, ser: &mut T) {
|
||||||
|
match self {
|
||||||
|
FormatSliceFile::Goo(file) => file.serialize(ser),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn info(&self) -> SliceInfo {
|
||||||
|
match self {
|
||||||
|
FormatSliceFile::Goo(file) => SliceInfo {
|
||||||
|
layers: file.header.layer_count,
|
||||||
|
resolution: Vector2::new(
|
||||||
|
file.header.x_resolution as u32,
|
||||||
|
file.header.y_resolution as u32,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decode_layer(&self, layer: usize, image: &mut [u8]) {
|
||||||
|
match self {
|
||||||
|
FormatSliceFile::Goo(file) => {
|
||||||
|
let layer_data = &file.layers[layer].data;
|
||||||
|
let decoder = goo_format::LayerDecoder::new(layer_data);
|
||||||
|
|
||||||
|
let mut pixel = 0;
|
||||||
|
for run in decoder {
|
||||||
|
for _ in 0..run.length {
|
||||||
|
image[pixel] = run.value;
|
||||||
|
pixel += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -3,6 +3,7 @@
|
|||||||
use nalgebra::Vector3;
|
use nalgebra::Vector3;
|
||||||
|
|
||||||
pub mod builder;
|
pub mod builder;
|
||||||
|
pub mod format;
|
||||||
pub mod half_edge;
|
pub mod half_edge;
|
||||||
pub mod mesh;
|
pub mod mesh;
|
||||||
pub mod segments;
|
pub mod segments;
|
||||||
|
@@ -10,6 +10,7 @@ use nalgebra::{Vector2, Vector3};
|
|||||||
|
|
||||||
use common::{
|
use common::{
|
||||||
config::{ExposureConfig, SliceConfig},
|
config::{ExposureConfig, SliceConfig},
|
||||||
|
format::Format,
|
||||||
serde::DynamicSerializer,
|
serde::DynamicSerializer,
|
||||||
};
|
};
|
||||||
use goo_format::{File as GooFile, LayerEncoder};
|
use goo_format::{File as GooFile, LayerEncoder};
|
||||||
@@ -20,6 +21,8 @@ fn main() -> Result<()> {
|
|||||||
const OUTPUT_PATH: &str = "output.goo";
|
const OUTPUT_PATH: &str = "output.goo";
|
||||||
|
|
||||||
let slice_config = SliceConfig {
|
let slice_config = SliceConfig {
|
||||||
|
format: Format::Goo,
|
||||||
|
|
||||||
platform_resolution: Vector2::new(11_520, 5_120),
|
platform_resolution: Vector2::new(11_520, 5_120),
|
||||||
platform_size: Vector3::new(218.88, 122.904, 260.0),
|
platform_size: Vector3::new(218.88, 122.904, 260.0),
|
||||||
slice_height: 0.05,
|
slice_height: 0.05,
|
||||||
|
@@ -8,12 +8,13 @@ use std::{
|
|||||||
|
|
||||||
use common::{
|
use common::{
|
||||||
config::SliceConfig,
|
config::SliceConfig,
|
||||||
|
format::Format,
|
||||||
misc::{EncodableLayer, SliceResult},
|
misc::{EncodableLayer, SliceResult},
|
||||||
};
|
};
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||||
|
|
||||||
use crate::{mesh::Mesh, segments::Segments1D, Pos};
|
use crate::{format::FormatSliceResult, mesh::Mesh, segments::Segments1D, Pos};
|
||||||
|
|
||||||
/// Used to slice a mesh.
|
/// Used to slice a mesh.
|
||||||
pub struct Slicer {
|
pub struct Slicer {
|
||||||
@@ -68,6 +69,12 @@ impl Slicer {
|
|||||||
self.progress.clone()
|
self.progress.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn slice_format(&self) -> FormatSliceResult {
|
||||||
|
match self.slice_config.format {
|
||||||
|
Format::Goo => FormatSliceResult::Goo(self.slice::<goo_format::LayerEncoder>()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Actually runs the slicing operation, it is multithreaded.
|
/// Actually runs the slicing operation, it is multithreaded.
|
||||||
pub fn slice<Layer: EncodableLayer>(&self) -> SliceResult<Layer::Output> {
|
pub fn slice<Layer: EncodableLayer>(&self) -> SliceResult<Layer::Output> {
|
||||||
let pixels = (self.slice_config.platform_resolution.x
|
let pixels = (self.slice_config.platform_resolution.x
|
||||||
|
Reference in New Issue
Block a user