Quellcode durchsuchen

Import/export pen/object

Kevin Lee vor 1 Jahr
Ursprung
Commit
fb061d9e9a
7 geänderte Dateien mit 191 neuen und 38 gelöschten Zeilen
  1. 1 1
      Cargo.lock
  2. 1 1
      Cargo.toml
  3. 21 8
      config.yml
  4. 18 7
      src/config/mod.rs
  5. 69 2
      src/config/object.rs
  6. 65 11
      src/config/pen.rs
  7. 16 8
      src/main.rs

+ 1 - 1
Cargo.lock

@@ -222,7 +222,7 @@ dependencies = [
 
 [[package]]
 name = "ezcad_patcher"
-version = "0.1.0"
+version = "1.0.0"
 dependencies = [
  "binrw",
  "clap",

+ 1 - 1
Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "ezcad_patcher"
-version = "0.1.0"
+version = "1.0.0"
 edition = "2021"
 
 [lib]

+ 21 - 8
config.yml

@@ -1,12 +1,12 @@
 Ops: 
-  - !PatchPen
-    Pen: 1
-    Color: [127, 127, 127]
-    Enabled: true
-    LoopCount: 3
-    Speed: 20.0
-    Power: 55.0
-    Frequency: 10000
+  # - !PatchPen
+  #   Pen: 1
+  #   Color: [127, 127, 127]
+  #   Enabled: true
+  #   LoopCount: 3
+  #   Speed: 20.0
+  #   Power: 55.0
+  #   Frequency: 10000
   # - !ClonePen
   #   From: 0
   #   To: 1
@@ -15,3 +15,16 @@ Ops:
   #   From: 1
   #   To: 5
   #   Field: !Speed 10
+  - !ExportPen
+    Index: 0
+    Path: export_pen.bin
+  - !ImportPen
+    Index: 1
+    Path: export_pen.bin
+  - !ExportObject
+    Layer: 0
+    Object: 0
+    Path: export_object.bin
+  - !ImportObject
+    Layer: 0
+    Path: export_object.bin

+ 18 - 7
src/config/mod.rs

@@ -1,7 +1,10 @@
-use ezcad::pen::Pen;
+use ezcad::{array_of::ArrayOf, layer::Layer, pen::Pen};
 use serde::{Deserialize, Serialize};
 
-use self::pen::{ClonePen, PatchPen, PatternPen};
+use self::{
+    object::{ExportObject, ImportObject},
+    pen::{ClonePen, ImportExportPen, PatchPen, PatternPen},
+};
 
 pub mod object;
 pub mod pen;
@@ -11,19 +14,27 @@ pub enum Operation {
     PatchPen(PatchPen),
     ClonePen(ClonePen),
     PatternPen(PatternPen),
+    ExportPen(ImportExportPen),
+    ImportPen(ImportExportPen),
+    ExportObject(ExportObject),
+    ImportObject(ImportObject),
 }
 
 pub trait Operations {
-    fn apply(&self, target: &mut Vec<Pen>);
+    fn apply(&self, pens: &mut Vec<Pen>, layers: &mut ArrayOf<Layer>);
 }
 
 impl Operations for Vec<Operation> {
-    fn apply(&self, target: &mut Vec<Pen>) {
+    fn apply(&self, pens: &mut Vec<Pen>, layers: &mut ArrayOf<Layer>) {
         for op in self {
             match op {
-                Operation::PatchPen(x) => x.patch(target),
-                Operation::ClonePen(x) => x.clone(target),
-                Operation::PatternPen(x) => x.pattern(target),
+                Operation::PatchPen(x) => x.patch(pens),
+                Operation::ClonePen(x) => x.clone(pens),
+                Operation::PatternPen(x) => x.pattern(pens),
+                Operation::ImportPen(x) => x.import(pens),
+                Operation::ExportPen(x) => x.export(pens),
+                Operation::ExportObject(x) => x.export(layers),
+                Operation::ImportObject(x) => x.import(layers),
             }
         }
     }

+ 69 - 2
src/config/object.rs

@@ -1,7 +1,74 @@
+use std::{
+    fs::File,
+    io::{Cursor, Read, Write},
+    path::PathBuf,
+};
+
+use binrw::{BinRead, BinWriterExt};
+use ezcad::{array_of::ArrayOf, layer::Layer, objects::Object};
+use log::debug;
 use serde::{Deserialize, Serialize};
 
 #[derive(Debug, Serialize, Deserialize)]
 #[serde(rename_all = "PascalCase")]
-pub struct Export {
-    layer: u32,
+pub struct ExportObject {
+    layer: usize,
+    object: usize,
+    path: PathBuf,
+}
+
+impl ExportObject {
+    pub fn export(&self, layers: &ArrayOf<Layer>) {
+        debug!(
+            "Exporting object {} in layer {} to '{}'",
+            self.object,
+            self.layer,
+            self.path.to_string_lossy()
+        );
+
+        let layer = layers.get(self.layer).expect("Invalid layer index");
+        let object = layer
+            .objects
+            .get(self.object)
+            .expect("Invalid object index");
+
+        let mut buffer: Cursor<Vec<u8>> = Cursor::new(vec![]);
+        buffer.write_le(object).expect("Failed to serialize object");
+
+        let mut output: File = File::create(&self.path).expect("Failed to open output file");
+        output
+            .write_all(buffer.into_inner().as_slice())
+            .expect("Failed to write to output file");
+    }
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+#[serde(rename_all = "PascalCase")]
+pub struct ImportObject {
+    layer: usize,
+    path: PathBuf,
+}
+
+impl ImportObject {
+    pub fn import(&self, layers: &mut ArrayOf<Layer>) {
+        debug!(
+            "Importing object to layer {} from '{}'",
+            self.layer,
+            self.path.to_string_lossy(),
+        );
+
+        let mut input: File = File::open(&self.path).expect("Failed to open input file");
+
+        let mut buffer: Cursor<Vec<u8>> = Cursor::new(vec![]);
+        input
+            .read_to_end(buffer.get_mut())
+            .expect("Failed to read input file");
+
+        let object: Object =
+            Object::read_le(&mut buffer).expect("Failed to deserialize input as object");
+
+        let layer: &mut Layer = layers.get_mut(self.layer).expect("Invalid layer index");
+
+        (*layer.objects).push(object);
+    }
 }

+ 65 - 11
src/config/pen.rs

@@ -1,3 +1,10 @@
+use std::{
+    fs::File,
+    io::{Cursor, Read, Write},
+    path::PathBuf,
+};
+
+use binrw::{BinRead, BinWriterExt};
 use ezcad::pen::Pen;
 use log::debug;
 use serde::{Deserialize, Serialize};
@@ -21,8 +28,8 @@ pub struct Patch {
 }
 
 impl Patch {
-    fn patch(&self, id: usize, target: &mut Vec<Pen>) {
-        let to_patch: &mut Pen = target.get_mut(id).expect("Invalid pen index");
+    fn patch(&self, id: usize, pens: &mut Vec<Pen>) {
+        let to_patch: &mut Pen = pens.get_mut(id).expect("Invalid pen index");
 
         if let Some(color) = self.color {
             debug!("Patching color for pen #{}: {:?}", id, color);
@@ -88,8 +95,8 @@ pub struct PatchPen {
 }
 
 impl PatchPen {
-    pub fn patch(&self, target: &mut Vec<Pen>) {
-        self.patch.patch(self.pen, target);
+    pub fn patch(&self, pens: &mut Vec<Pen>) {
+        self.patch.patch(self.pen, pens);
     }
 }
 
@@ -103,7 +110,7 @@ pub struct ClonePen {
 }
 
 impl ClonePen {
-    pub fn clone(&self, target: &mut Vec<Pen>) {
+    pub fn clone(&self, pens: &mut Vec<Pen>) {
         debug!("Cloning pen #{} to #{}", self.from, self.to);
         assert!(
             self.to > self.from,
@@ -111,13 +118,13 @@ impl ClonePen {
         );
 
         // Clone pen
-        let src: Pen = target.get(self.from).expect("Invalid pen index").clone();
-        let dst: &mut Pen = target.get_mut(self.to).expect("Invalid pen index");
+        let src: Pen = pens.get(self.from).expect("Invalid pen index").clone();
+        let dst: &mut Pen = pens.get_mut(self.to).expect("Invalid pen index");
         *dst = src;
 
         // Patch pen if needed
         if let Some(patch) = &self.patch {
-            patch.patch(self.to, target);
+            patch.patch(self.to, pens);
         }
     }
 }
@@ -139,7 +146,7 @@ pub struct PatternPen {
 }
 
 impl PatternPen {
-    pub fn pattern(&self, target: &mut Vec<Pen>) {
+    pub fn pattern(&self, pens: &mut Vec<Pen>) {
         debug!("Patterning from pen #{} to #{}", self.from, self.to);
         assert!(
             self.to > self.from,
@@ -147,7 +154,7 @@ impl PatternPen {
         );
 
         // Obtain settings from first pen
-        let src: Pen = target.get(self.from).expect("Invalid pen index").clone();
+        let src: Pen = pens.get(self.from).expect("Invalid pen index").clone();
 
         let mut setting: PatternField = match self.field {
             PatternField::Loops(_) => {
@@ -176,7 +183,7 @@ impl PatternPen {
 
         for dst in (self.from..=self.to).skip(1) {
             // Clone to target pen
-            let pen: &mut Pen = target.get_mut(dst).expect("Invalid pen index");
+            let pen: &mut Pen = pens.get_mut(dst).expect("Invalid pen index");
             *pen = src.clone();
 
             // Calculate new setting
@@ -240,3 +247,50 @@ impl PatternPen {
         }
     }
 }
+
+#[derive(Debug, Serialize, Deserialize)]
+#[serde(rename_all = "PascalCase")]
+pub struct ImportExportPen {
+    index: usize,
+    path: PathBuf,
+}
+
+impl ImportExportPen {
+    pub fn export(&self, pens: &mut Vec<Pen>) {
+        debug!(
+            "Exporting pen #{} to '{}'",
+            self.index,
+            self.path.to_string_lossy()
+        );
+
+        let pen = pens.get(self.index).expect("Invalid pen index");
+
+        let mut buffer: Cursor<Vec<u8>> = Cursor::new(vec![]);
+        buffer.write_le(pen).expect("Failed to serialize pen");
+
+        let mut output: File = File::create(&self.path).expect("Failed to open output file");
+        output
+            .write_all(buffer.into_inner().as_slice())
+            .expect("Failed to write to output file");
+    }
+
+    pub fn import(&self, pens: &mut Vec<Pen>) {
+        debug!(
+            "Importing pen #{} from '{}'",
+            self.index,
+            self.path.to_string_lossy()
+        );
+
+        let mut input: File = File::open(&self.path).expect("Failed to open input file");
+
+        let mut buffer: Cursor<Vec<u8>> = Cursor::new(vec![]);
+        input
+            .read_to_end(buffer.get_mut())
+            .expect("Failed to read input file");
+
+        let pen: Pen = Pen::read_le(&mut buffer).expect("Failed to deserialize input as pen");
+
+        let dst: &mut Pen = pens.get_mut(self.index).expect("Invalid pen index");
+        *dst = pen;
+    }
+}

+ 16 - 8
src/main.rs

@@ -62,7 +62,7 @@ fn main() {
         EzCadHeader::read_le(&mut input_file).expect("Failed to parse input file as EZCAD format");
     trace!("Input file decode time: {:?}", time.elapsed());
 
-    // Re-encode input file and check that it matches original
+    // Sanity check that re-encoded input file matches original
     info!("Validating re-encoding of input file");
     let mut buffer: Cursor<Vec<u8>> = Cursor::new(vec![]);
 
@@ -76,20 +76,26 @@ fn main() {
     }
 
     // Print info on pens with non-default settings
-    for pen in file
+    for (index, pen) in file
         .pens_offset
         .data
         .pens
         .iter()
         .filter(|x| *x.use_default == 0)
+        .enumerate()
     {
-        trace!("{:#?}", pen);
+        trace!("Pen {}: {:#?}", index, pen);
     }
 
     // Print all objects
-    for layer in file.layers_offset.iter() {
-        for object in layer.objects.iter() {
-            trace!("{:#?}", object);
+    for (layer_index, layer) in file.layers_offset.iter().enumerate() {
+        for (object_index, object) in layer.objects.iter().enumerate() {
+            trace!(
+                "Layer {}, Object {}: {:#?}",
+                layer_index,
+                object_index,
+                object
+            );
         }
     }
 
@@ -125,7 +131,9 @@ fn main() {
         let config: Config = serde_yaml::from_str(&config).expect("Failed to parse config file");
 
         // Patch pen settings
-        config.ops.apply(&mut file.pens_offset.data.pens);
+        config
+            .ops
+            .apply(&mut file.pens_offset.data.pens, &mut file.layers_offset);
     }
 
     // Process output
@@ -139,7 +147,7 @@ fn main() {
         trace!("Output file encode time: {:?}", time.elapsed());
 
         // Write buffer to output file
-        let mut output = File::create(output).expect("Failed to open output file");
+        let mut output: File = File::create(output).expect("Failed to open output file");
         output
             .write_all(buffer.into_inner().as_slice())
             .expect("Failed to write to output file");