Browse Source

Fix move/array

Kevin Lee 4 months ago
parent
commit
07bae818fb

BIN
samples/Circle5.mlp


BIN
samples/HatchRectangleSmall.mlp


BIN
samples/Rectangle.mlp


BIN
samples/Rectangle2.mlp


BIN
samples/Rectangle3.mlp


BIN
samples/Rectangle4.mlp


+ 30 - 5
samples/config.yml

@@ -33,7 +33,7 @@ Ops:
   #   Export: 'export.bin'
 
   # - !ObjectOperation
-  #   Input: !Existing { Layer: 0, Object: 0 }
+  #   Input: !Rectangle { Width: 2, Height: 3 }
   #   Z: 1.0
   #   Origin: { X: 10.0, Y: 10.0 }
   #   Pen: 1
@@ -48,12 +48,37 @@ Ops:
   #   ReplaceObject: 0
 
   - !ObjectOperation
-    Input: !Circle { Radius: 10 }
-    Z: 0.0
-    Origin: { X: 0.0, Y: 0.0 }
-    Pen: 0
+    Input: !Existing { Layer: 0, Object: 0 }
+    Z: 1.0
+    Origin: { X: 10.0, Y: 10.0 }
+    Pen: 1
+    Array:
+      Columns: 3
+      Rows: 2
+      Spacing: 10.0
+      RandomizeOrder: False
+      StartingPen: 0
+    # Hatch:
+    #   LineSpacing: 0.01
     ReplaceObject: 0
 
+  # - !ObjectOperation
+  #   Input: !Rectangle { Width: 10, Height: 5}
+  #   Z: 0.0
+  #   Origin: { X: 10.0, Y: 10.0 }
+  #   Pen: 0
+  #   ReplaceObject: 0
+
+  # - !ObjectOperation
+  #   Input: !Existing { Layer: 0, Object: 0 }
+  #   Origin: { X: 10.0, Y: 10.0 }
+  #   ReplaceObject: 0
+
+  # - !ObjectOperation
+  #   Input: !Existing { Layer: 0, Object: 1 }
+  #   Origin: { X: 10.0, Y: 10.0 }
+  #   ReplaceObject: 1
+
   # - !Object
   #   Input: !Circle { Radius: 3.0 }
 

+ 1 - 1
src/config/object.rs

@@ -10,7 +10,7 @@ use ezcad::{
         Object, ObjectCore, Translate,
     },
     pen::Pen,
-    types::{ObjectType, Coordinate},
+    types::{Coordinate, ObjectType},
 };
 use log::{debug, error, warn};
 use rand::{seq::SliceRandom, thread_rng};

+ 14 - 23
src/ezcad/objects/circle.rs

@@ -5,13 +5,12 @@ use diff::Diff;
 
 use crate::{
     field_of::FieldOf,
-    types::{ObjectType, Coordinate, F64, U32},
+    types::{Coordinate, ObjectType, F64, U32},
 };
 
-use super::{ObjectCore, Translate, ObjectModified};
+use super::{ObjectCore, ObjectModifier, Translate};
 
-#[cfg_attr(feature = "default-debug", derive(Debug))]
-#[derive(BinRead, BinWrite, Clone, Diff, PartialEq)]
+#[derive(BinRead, BinWrite, Clone, Debug, Diff, PartialEq)]
 #[diff(attr(
     #[derive(Debug, PartialEq)]
 ))]
@@ -22,22 +21,7 @@ pub struct Circle {
     pub radius: F64,
     pub start_angle: F64, // Radians
     pub clockwise: U32,
-    // origin_x - drawn_x * width_scale = origin_x_delta
-    pub modified: ObjectModified,
-}
-
-// Custom Debug implementation to only print known fields
-#[cfg(not(feature = "default-debug"))]
-impl Debug for Circle {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.debug_struct("Circle")
-            .field("core", &self.core)
-            .field("origin", &self.drawn_origin)
-            .field("radius", &self.radius)
-            .field("start_angle", &self.start_angle)
-            .field("clockwise", &self.clockwise)
-            .finish()
-    }
+    pub modifier: ObjectModifier,
 }
 
 impl Default for Circle {
@@ -48,19 +32,26 @@ impl Default for Circle {
             radius: 0.0.into(),
             start_angle: 0.0.into(),
             clockwise: 0.into(),
-            modified: ObjectModified::default(),
+            modifier: ObjectModifier::default(),
         }
     }
 }
 
+// origin_x = x_correction + drawn_x * x_scale
+// x_correction = origin_x - drawn_x * x_scale
 impl Translate for Circle {
     fn move_absolute(&mut self, origin: Option<Coordinate>, z: Option<f64>) {
-        origin.map(|origin| *self.drawn_origin = origin);
+        origin.map(|origin| {
+            let delta: Coordinate = origin - *self.core.origin;
+            self.modifier.move_relative(delta);
+        });
         self.core.move_absolute(origin, z);
     }
 
     fn move_relative(&mut self, delta: Option<Coordinate>, z: Option<f64>) {
-        delta.map(|delta| *self.drawn_origin += delta);
+        delta.map(|delta| {
+            self.modifier.move_relative(delta);
+        });
         self.core.move_relative(delta, z);
     }
 }

+ 8 - 27
src/ezcad/objects/ellipse.rs

@@ -5,13 +5,12 @@ use diff::Diff;
 
 use crate::{
     field_of::FieldOf,
-    types::{ObjectType, Coordinate, F64, U32},
+    types::{Coordinate, ObjectType, F64, U32},
 };
 
-use super::{ObjectCore, Translate, ObjectModified};
+use super::{ObjectCore, ObjectModifier, Translate};
 
-#[cfg_attr(feature = "default-debug", derive(Debug))]
-#[derive(BinRead, BinWrite, Clone, Diff, PartialEq)]
+#[derive(BinRead, BinWrite, Clone, Debug, Diff, PartialEq)]
 #[diff(attr(
     #[derive(Debug, PartialEq)]
 ))]
@@ -23,26 +22,10 @@ pub struct Ellipse {
     pub drawn_corner_b: FieldOf<Coordinate>,
     pub start_angle: F64, // Radians
     pub end_angle: F64,   // Radians
-    pub modified: ObjectModified,
+    pub modifier: ObjectModifier,
     pub open_curve: U32,
 }
 
-// Custom Debug implementation to only print known fields
-#[cfg(not(feature = "default-debug"))]
-impl Debug for Ellipse {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.debug_struct("Ellipse")
-            .field("core", &self.core)
-            .field("clockwise", &self.clockwise)
-            .field("corner_a", &self.drawn_corner_a)
-            .field("corner_b", &self.drawn_corner_b)
-            .field("start_angle", &self.start_angle)
-            .field("end_angle", &self.end_angle)
-            .field("open_curve", &self.open_curve)
-            .finish()
-    }
-}
-
 impl Default for Ellipse {
     fn default() -> Self {
         Self {
@@ -52,7 +35,7 @@ impl Default for Ellipse {
             drawn_corner_b: Coordinate { x: 0.0, y: 0.0 }.into(),
             start_angle: 0.0.into(),
             end_angle: 0.0.into(),
-            modified: ObjectModified::default(),
+            modifier: ObjectModifier::default(),
             open_curve: 0.into(),
         }
     }
@@ -61,17 +44,15 @@ impl Default for Ellipse {
 impl Translate for Ellipse {
     fn move_absolute(&mut self, origin: Option<Coordinate>, z: Option<f64>) {
         origin.map(|origin| {
-            let delta: Coordinate = *self.core.origin - origin;
-            *self.drawn_corner_a += delta;
-            *self.drawn_corner_b += delta;
+            let delta: Coordinate = origin - *self.core.origin;
+            self.modifier.move_relative(delta);
         });
         self.core.move_absolute(origin, z);
     }
 
     fn move_relative(&mut self, delta: Option<Coordinate>, z: Option<f64>) {
         delta.map(|delta| {
-            *self.drawn_corner_a += delta;
-            *self.drawn_corner_b += delta;
+            self.modifier.move_relative(delta);
         });
         self.core.move_relative(delta, z);
     }

+ 48 - 3
src/ezcad/objects/hatch.rs

@@ -3,7 +3,7 @@ use std::fmt::Debug;
 use crate::{
     array_of::ArrayOf,
     field_of::FieldOf,
-    types::{Field, Coordinate, F64, U32},
+    types::{Coordinate, Field, F64, U32},
 };
 use binrw::{binrw, BinRead, BinWrite};
 use diff::Diff;
@@ -332,6 +332,20 @@ pub struct Hatches {
     pub hatch_lines: ArrayOf<HatchLines>,
 }
 
+impl Hatches {
+    pub fn set_pen(&mut self, pen: u32) {
+        // Ignore self.core.pen
+        self.hatch_lines.iter_mut().for_each(|x| {
+            // Ignore HatchLines.core.pen
+            x.hatch_line.iter_mut().for_each(|x| {
+                x.lines.iter_mut().for_each(|x| {
+                    x.core.pen = pen.into();
+                })
+            })
+        });
+    }
+}
+
 #[binrw]
 #[derive(Clone, Debug, Diff, PartialEq)]
 #[diff(attr(
@@ -355,12 +369,43 @@ pub struct Hatch {
 
 impl Translate for Hatch {
     fn move_absolute(&mut self, origin: Option<Coordinate>, z: Option<f64>) {
-        self.outline.iter_mut().for_each(|x| x.move_absolute(origin, z));
+        self.outline
+            .iter_mut()
+            .for_each(|x| x.move_absolute(origin, z));
+        origin.map(|origin| {
+            let delta: Coordinate = origin - *self.core.origin;
+            self.hatches.iter_mut().for_each(|x| {
+                // Ignore Hatches.core.origin
+                x.hatch_lines.iter_mut().for_each(|x| {
+                    // Ignore HatchLines.core.origin
+                    x.hatch_line.iter_mut().for_each(|x| {
+                        x.lines
+                            .iter_mut()
+                            .for_each(|x| x.move_relative(Some(delta), None));
+                    })
+                })
+            });
+        });
         self.core.move_absolute(origin, z);
     }
 
     fn move_relative(&mut self, delta: Option<Coordinate>, z: Option<f64>) {
-        self.outline.iter_mut().for_each(|x| x.move_relative(delta, z));
+        self.outline
+            .iter_mut()
+            .for_each(|x| x.move_relative(delta, z));
+        delta.map(|delta| {
+            self.hatches.iter_mut().for_each(|x| {
+                // Ignore Hatches.core.origin
+                x.hatch_lines.iter_mut().for_each(|x| {
+                    // Ignore HatchLines.core.origin
+                    x.hatch_line.iter_mut().for_each(|x| {
+                        x.lines
+                            .iter_mut()
+                            .for_each(|x| x.move_relative(Some(delta), None));
+                    })
+                })
+            });
+        });
         self.core.move_relative(delta, z);
     }
 }

+ 11 - 5
src/ezcad/objects/line.rs

@@ -16,9 +16,15 @@ pub enum LineType {
     #[brw(magic = 0x0001u16)]
     Point { _zero: u32, point: Coordinate },
     #[brw(magic = 0x0100u16)]
-    Line { _zero: u32, points: ArrayOf<Coordinate> },
+    Line {
+        _zero: u32,
+        points: ArrayOf<Coordinate>,
+    },
     #[brw(magic = 0x0300u16)]
-    Bezier { _zero: u32, points: ArrayOf<Coordinate> },
+    Bezier {
+        _zero: u32,
+        points: ArrayOf<Coordinate>,
+    },
 }
 
 // Custom Debug implementation to only print known fields
@@ -40,13 +46,13 @@ impl LineType {
         match self {
             LineType::Point { _zero, point } => {
                 *point += delta;
-            },
+            }
             LineType::Line { _zero, points } => {
                 points.iter_mut().for_each(|pt| *pt += delta);
-            },
+            }
             LineType::Bezier { _zero, points } => {
                 points.iter_mut().for_each(|pt| *pt += delta);
-            },
+            }
         }
     }
 }

+ 17 - 12
src/ezcad/objects/mod.rs

@@ -218,6 +218,7 @@ impl Object {
                 x.legacy_setting.hatch_0_pen = pen.into();
                 x.legacy_setting.hatch_1_pen = pen.into();
                 x.legacy_setting.hatch_2_pen = pen.into();
+                x.hatches.as_mut().map(|x| x.set_pen(pen));
             }
         }
     }
@@ -239,16 +240,23 @@ impl Object {
 #[diff(attr(
     #[derive(Debug, PartialEq)]
 ))]
-pub struct ObjectModified {
+pub struct ObjectModifier {
     pub default: U32, // 0 if values are default, 255 otherwise
-    pub changes: FieldOf<ScaleValues>,
+    pub modifiers: FieldOf<ScaleValues>,
 }
 
-impl Default for ObjectModified {
+impl ObjectModifier {
+    pub fn move_relative(&mut self, delta: Coordinate) {
+        self.default = 255.into();
+        self.modifiers.correction += delta;
+    }
+}
+
+impl Default for ObjectModifier {
     fn default() -> Self {
         Self {
             default: 0.into(),
-            changes: ScaleValues::default().into(),
+            modifiers: ScaleValues::default().into(),
         }
     }
 }
@@ -268,8 +276,7 @@ pub struct ScaleValues {
     pub y_scale: f64, // Y scaled ratio on drawn object
     #[br(assert(_unknown_4 == 0.0))]
     _unknown_4: f64,
-    pub x_correction: f64, // X correction factor due to scaling
-    pub y_correction: f64, // Y correction factor due to scaling
+    correction: Coordinate, // Correction factor due to scaling
     #[br(assert(_unknown_5 == 1.0))]
     _unknown_5: f64,
 }
@@ -283,8 +290,7 @@ impl Default for ScaleValues {
             _unknown_3: 0.0.into(),
             y_scale: 1.0.into(),
             _unknown_4: 0.0.into(),
-            x_correction: 0.0.into(),
-            y_correction: 0.0.into(),
+            correction: (0.0, 0.0).into(),
             _unknown_5: 1.0.into(),
         }
     }
@@ -294,10 +300,9 @@ impl Default for ScaleValues {
 impl Debug for ScaleValues {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         f.debug_struct("ScaleValues")
-            .field("width_scale", &self.x_scale)
-            .field("height_scale", &self.y_scale)
-            .field("origin_x_delta", &self.x_correction)
-            .field("origin_y_delta", &self.y_correction)
+            .field("x_scale", &self.x_scale)
+            .field("y_scale", &self.y_scale)
+            .field("correction", &self.correction)
             .finish()
     }
 }

+ 8 - 29
src/ezcad/objects/polygon.rs

@@ -5,13 +5,12 @@ use diff::Diff;
 
 use crate::{
     field_of::FieldOf,
-    types::{ObjectType, Coordinate, F64, U32},
+    types::{Coordinate, ObjectType, F64, U32},
 };
 
-use super::{ObjectCore, Translate, ObjectModified};
+use super::{ObjectCore, ObjectModifier, Translate};
 
-#[cfg_attr(feature = "default-debug", derive(Debug))]
-#[derive(BinRead, BinWrite, Clone, Diff, PartialEq)]
+#[derive(BinRead, BinWrite, Clone, Debug, Diff, PartialEq)]
 #[diff(attr(
     #[derive(Debug, PartialEq)]
 ))]
@@ -26,25 +25,7 @@ pub struct Polygon {
     pub offset_dx: F64,
     pub offset_dy: F64,
     pub edges: U32,
-    pub modified: ObjectModified,
-}
-
-// Custom Debug implementation to only print known fields
-#[cfg(not(feature = "default-debug"))]
-impl Debug for Polygon {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.debug_struct("Polygon")
-            .field("core", &self.core)
-            .field("invert_shape", &self.invert_shape)
-            .field("corner_a", &self.drawn_corner_a)
-            .field("corner_b", &self.drawn_corner_b)
-            .field("offset_cx", &self.offset_cx)
-            .field("offset_cy", &self.offset_cy)
-            .field("offset_dx", &self.offset_dx)
-            .field("offset_dy", &self.offset_dy)
-            .field("edges", &self.edges)
-            .finish()
-    }
+    pub modifier: ObjectModifier,
 }
 
 impl Default for Polygon {
@@ -59,7 +40,7 @@ impl Default for Polygon {
             offset_dx: 0.0.into(),
             offset_dy: 0.0.into(),
             edges: 6.into(),
-            modified: ObjectModified::default(),
+            modifier: ObjectModifier::default(),
         }
     }
 }
@@ -67,17 +48,15 @@ impl Default for Polygon {
 impl Translate for Polygon {
     fn move_absolute(&mut self, origin: Option<Coordinate>, z: Option<f64>) {
         origin.map(|origin| {
-            let delta: Coordinate = *self.core.origin - origin;
-            *self.drawn_corner_a += delta;
-            *self.drawn_corner_b += delta;
+            let delta: Coordinate = origin - *self.core.origin;
+            self.modifier.move_relative(delta);
         });
         self.core.move_absolute(origin, z);
     }
 
     fn move_relative(&mut self, delta: Option<Coordinate>, z: Option<f64>) {
         delta.map(|delta| {
-            *self.drawn_corner_a += delta;
-            *self.drawn_corner_b += delta;
+            self.modifier.move_relative(delta);
         });
         self.core.move_relative(delta, z);
     }

+ 9 - 28
src/ezcad/objects/rectangle.rs

@@ -8,10 +8,9 @@ use crate::{
     types::{Coordinate, ObjectType, F64},
 };
 
-use super::{ObjectCore, Translate, ObjectModified};
+use super::{ObjectCore, ObjectModifier, Translate};
 
-#[cfg_attr(feature = "default-debug", derive(Debug))]
-#[derive(BinRead, BinWrite, Clone, Diff, PartialEq)]
+#[derive(BinRead, BinWrite, Clone, Debug, Diff, PartialEq)]
 #[diff(attr(
     #[derive(Debug, PartialEq)]
 ))]
@@ -24,25 +23,7 @@ pub struct Rectangle {
     pub round_bottom_right: F64,
     pub round_top_right: F64,
     pub round_top_left: F64,
-    // origin_x = (corner_a.x + corner_b.x) / 2 * width_scale + origin_x_delta
-    pub modified: ObjectModified,
-
-}
-
-// Custom Debug implementation to only print known fields
-#[cfg(not(feature = "default-debug"))]
-impl Debug for Rectangle {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.debug_struct("Rectangle")
-            .field("core", &self.core)
-            .field("corner_a", &self.drawn_corner_a)
-            .field("corner_b", &self.drawn_corner_b)
-            .field("round_bottom_left", &self.round_bottom_left)
-            .field("round_bottom_right", &self.round_bottom_right)
-            .field("round_top_right", &self.round_top_right)
-            .field("round_top_left", &self.round_top_left)
-            .finish()
-    }
+    pub modifier: ObjectModifier,
 }
 
 impl Default for Rectangle {
@@ -55,25 +36,25 @@ impl Default for Rectangle {
             round_bottom_right: 0.0.into(),
             round_top_right: 0.0.into(),
             round_top_left: 0.0.into(),
-            modified: ObjectModified::default(),
+            modifier: ObjectModifier::default(),
         }
     }
 }
 
+// origin_x = x_corretion + (drawn_a.x + drawn_b.x) / 2 * x_scale
+// x_correction = origin_x - (drawn_a.x + drawn_b.x) / 2 * x_scale
 impl Translate for Rectangle {
     fn move_absolute(&mut self, origin: Option<Coordinate>, z: Option<f64>) {
         origin.map(|origin| {
-            let delta: Coordinate = *self.core.origin - origin;
-            *self.drawn_corner_a += delta;
-            *self.drawn_corner_b += delta;
+            let delta: Coordinate = origin - *self.core.origin;
+            self.modifier.move_relative(delta);
         });
         self.core.move_absolute(origin, z);
     }
 
     fn move_relative(&mut self, delta: Option<Coordinate>, z: Option<f64>) {
         delta.map(|delta| {
-            *self.drawn_corner_a += delta;
-            *self.drawn_corner_b += delta;
+            self.modifier.move_relative(delta);
         });
         self.core.move_relative(delta, z);
     }

+ 30 - 1
src/ezcad/types.rs

@@ -1,6 +1,6 @@
 use std::{
     fmt::{Debug, Display},
-    ops::{Add, AddAssign, Sub},
+    ops::{Add, AddAssign, Div, Mul, Sub, SubAssign},
 };
 
 use binrw::{binrw, BinRead, BinWrite};
@@ -153,6 +153,13 @@ impl Sub for Coordinate {
     }
 }
 
+impl SubAssign for Coordinate {
+    fn sub_assign(&mut self, rhs: Self) {
+        self.x -= rhs.x;
+        self.y -= rhs.y;
+    }
+}
+
 impl Add for Coordinate {
     type Output = Coordinate;
 
@@ -171,6 +178,28 @@ impl AddAssign for Coordinate {
     }
 }
 
+impl Mul for Coordinate {
+    type Output = Coordinate;
+
+    fn mul(self, rhs: Self) -> Self::Output {
+        Coordinate {
+            x: self.x * rhs.x,
+            y: self.y * rhs.y,
+        }
+    }
+}
+
+impl Div for Coordinate {
+    type Output = Coordinate;
+
+    fn div(self, rhs: Self) -> Self::Output {
+        Coordinate {
+            x: self.x / rhs.x,
+            y: self.y / rhs.y,
+        }
+    }
+}
+
 impl From<(f64, f64)> for Coordinate {
     fn from(value: (f64, f64)) -> Self {
         Self {