| 
					
				 | 
			
			
				@@ -1,10 +1,5 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-use std::{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    fs::File, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    io::{Cursor, Read, Write}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    path::PathBuf, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+use std::path::PathBuf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-use binrw::{BinRead, BinWriterExt}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 use ezcad::{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     array_of::ArrayOf, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     layer::Layer, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -15,11 +10,11 @@ use ezcad::{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Object, ObjectCore, Translate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     pen::Pen, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    types::{ObjectType, Point}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    types::{ObjectType, Coordinate}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-use log::{debug, warn}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+use log::{debug, error, warn}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 use rand::{seq::SliceRandom, thread_rng}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-use serde::{de, Deserialize, Serialize}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+use serde::{Deserialize, Serialize}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #[derive(Debug, Serialize, Deserialize)] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #[serde(rename_all = "PascalCase")] 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -56,6 +51,7 @@ impl DeleteObjects { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 pub struct HatchConfig { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     line_spacing: f64, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pen: Option<u32>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     count: Option<u32>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     edge_offset: Option<f64>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     start_offset: Option<f64>, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -90,6 +86,7 @@ impl From<HatchConfig> for HatchSetting { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let mut ret = Self::default(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         *ret.line_spacing = value.line_spacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        value.pen.map(|x| *ret.pen = x.into()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         value.count.map(|x| *ret.count = x.into()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         value.edge_offset.map(|x| *ret.edge_offset = x.into()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         value.start_offset.map(|x| *ret.start_offset = x.into()); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -120,21 +117,18 @@ pub struct ArrayConfig { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #[derive(Debug, Serialize, Deserialize, strum::Display)] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #[serde(rename_all = "PascalCase")] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 pub enum InputObject { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[serde(rename_all = "PascalCase")] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     Rectangle { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         width: f64, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         height: f64, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         round_corner: Option<f64>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Circle { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        radius: f64, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Import { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        path: PathBuf, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Existing { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        layer: usize, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        object: usize, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[serde(rename_all = "PascalCase")] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Circle { radius: f64 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[serde(rename_all = "PascalCase")] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Import { path: PathBuf }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[serde(rename_all = "PascalCase")] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Existing { layer: usize, object: usize }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 impl InputObject { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -145,8 +139,8 @@ impl InputObject { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 height, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 round_corner, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } => Object::Rectangle(Rectangle { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                corner_a: Point::from((-width / 2.0, -height / 2.0)).into(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                corner_b: Point::from((width / 2.0, height / 2.0)).into(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                corner_a: Coordinate::from((-width / 2.0, -height / 2.0)).into(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                corner_b: Coordinate::from((width / 2.0, height / 2.0)).into(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 round_bottom_left: round_corner.unwrap_or(0.0).into(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 round_bottom_right: round_corner.unwrap_or(0.0).into(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 round_top_left: round_corner.unwrap_or(0.0).into(), 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -175,7 +169,7 @@ impl InputObject { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 pub struct ObjectOperation { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     input: InputObject, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     z: Option<f64>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    origin: Option<Point>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    origin: Option<Coordinate>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     pen: Option<u32>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     layer: Option<usize>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     array: Option<ArrayConfig>, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -186,19 +180,81 @@ pub struct ObjectOperation { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 impl ObjectOperation { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     pub fn process(&self, pens: &Vec<Pen>, layers: &mut ArrayOf<Layer>) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        debug!("Processing object {}", self.input); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        debug!("Begin processing of object {:?}", self.input); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let mut object: Object = self.input.new(layers); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // Process basic transformation 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        object.translate(self.origin, self.z); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        self.pen.map(|pen| object.set_pen(pen)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if self.origin.is_some() || self.z.is_some() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            debug!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                "Translating object to origin {:?} and Z {:?}", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.origin, self.z 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            object.move_absolute(self.origin, self.z); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.pen.map(|pen| { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if self.array.is_some() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                warn!("Ignoring pen setting as values will be overridden by array setting"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                assert!(pen < pens.len().try_into().unwrap(), "Invalid pen index"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                debug!("Setting object pen to #{}", pen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                object.set_pen(pen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // Process conversion to hatch object 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let object = self.hatch.as_ref().map_or(object.clone(), |hatch| { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if self.array.is_some() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                warn!("Ignoring hatch pen setting as values will be overridden by array setting"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let hatch_setting: HatchSetting = (*hatch).into(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            match object { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Object::Curve(_) | Object::Point(_) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    error!("Points, lines, and curves cannot be hatched"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    object 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Object::Rectangle(_) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                | Object::Circle(_) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                | Object::Ellipse(_) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                | Object::Polygon(_) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    debug!("Converting to hatch object"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // Build new hatch object (no hatch lines) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Object::Hatch(Hatch { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        core: ObjectCore { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            origin: object.core().origin, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            z: object.core().z, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            ..ObjectCore::default(ObjectType::Hatch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        outline: vec![object].into(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        legacy_setting: vec![hatch_setting.clone()].into(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        hatch_settings: vec![hatch_setting.clone()].into(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        hatches: Some(Hatches { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            core: ObjectCore::default(ObjectType::HatchLine), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            hatch_lines: vec![].into(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Object::Hatch(hatch) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    debug!("Modifying existing hatch settings"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // Modify existing hatch (delete existing hatch lines) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Object::Hatch(Hatch { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        legacy_setting: vec![hatch_setting.clone()].into(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        hatch_settings: vec![hatch_setting.clone()].into(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        hatches: Some(Hatches { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            core: ObjectCore::default(ObjectType::HatchLine), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            hatch_lines: vec![].into(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        ..hatch 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // Process array generation of object 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let new_objects = self.array.as_ref().map_or(vec![object.clone()], |array| { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let bottom_left: Point = Point { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let bottom_left: Coordinate = Coordinate { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 x: (array.columns - 1) as f64 * array.spacing / -2.0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 y: (array.rows - 1) as f64 * array.spacing / -2.0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -209,7 +265,7 @@ impl ObjectOperation { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 let x_pos: f64 = (index % array.columns) as f64; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 let y_pos: f64 = (index / array.columns) as f64; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Point { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Coordinate { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     x: bottom_left.x + array.spacing * x_pos, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     y: bottom_left.y + array.spacing * y_pos, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -225,142 +281,50 @@ impl ObjectOperation { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             let mut new_obj: Vec<Object> = vec![]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             for obj_idx in seq.into_iter() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let delta: Coordinate = calc_pt(obj_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let pen: u32 = array.starting_pen + u32::try_from(obj_idx).unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 let mut object: Object = object.clone(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                object.translate(Some(calc_pt(obj_idx)), None); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                object.set_pen(array.starting_pen + u32::try_from(obj_idx).unwrap()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                object.move_relative(Some(delta), None); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                object.set_pen(pen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                debug!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    "Adding new array instance at {} with pen #{}", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    object.core().origin, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    pen 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 new_obj.push(object); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             new_obj 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Process export of object 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        self.export.as_ref().map(|path| { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let layer_id: usize = self.layer.unwrap_or(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let layer: &mut Layer = layers.get_mut(layer_id).expect("Invalid layer index"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Either export the object, replace an existing object, or append if neither 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if let Some(path) = &self.export { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if new_objects.len() > 1 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 warn!("Exporting only the first object in list of objects"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 debug!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    "Exporting object {} to '{}'", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    "Exporting object {} in layer #{} to '{}'", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     new_objects[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    layer_id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     path.to_string_lossy() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             new_objects[0].write_to_file(path); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Append or replace object in layer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let layer: &mut Layer = layers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            .get_mut(self.layer.unwrap_or(0)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            .expect("Invalid layer index"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        match self.replace_object { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            Some(object) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // debug!("Replacing object #{} with {}", object, new_objects); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                layer.objects.splice(object..=object, new_objects); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            None => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                layer.objects.extend(new_objects); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if let Some(object) = self.replace_object { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            assert!(object < layer.objects.len(), "Invalid object index"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            debug!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                "Replacing object #{} in layer #{} with new objects", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                object, layer_id 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            layer.objects.splice(object..=object, new_objects); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            debug!("Extending layer #{} with new objects", layer_id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            layer.objects.extend(new_objects); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// #[derive(Debug, Serialize, Deserialize)] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// #[serde(rename_all = "PascalCase")] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// pub struct Array { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//     layer: usize, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//     z: f64, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//     columns: usize, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//     rows: usize, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//     spacing: f64, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//     starting_pen: usize, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//     object: InputObject, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//     hatch: Option<HatchConfig>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// impl Array { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//     pub fn generate(&self, pens: &Vec<Pen>, layers: &mut ArrayOf<Layer>) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         debug!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             "Generating {} x {} array of {:?} with spacing of {} starting from pen #{} on layer #{}", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             self.columns, self.rows, self.object, self.spacing, self.starting_pen, self.layer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         assert!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             self.rows >= 1 && self.columns >= 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             "Invalid row/column value" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         assert!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             self.starting_pen + (self.rows * self.columns) < pens.len(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             "Invalid starting pen" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         let layer: &mut Layer = layers.get_mut(self.layer).expect("Invalid layer index"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         let bottom_left: Point = Point { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             x: (self.columns - 1) as f64 * self.spacing / -2.0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             y: (self.rows - 1) as f64 * self.spacing / -2.0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         // Closure that returns origin point of given index in array, where index starts 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         // from bottom left and increments to the right and wraps around to the row above 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         let calc_pt = |index: usize| { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             let x_pos: f64 = (index % self.columns) as f64; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             let y_pos: f64 = (index / self.columns) as f64; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             Point { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                 x: bottom_left.x + self.spacing * x_pos, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                 y: bottom_left.y + self.spacing * y_pos, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         // Randomize draw order 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         let mut seq: Vec<usize> = (0..(self.rows * self.columns)).collect(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         seq.shuffle(&mut thread_rng()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         // Generate objects and append to layer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         for obj_idx in seq.into_iter() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             let pen: u32 = (self.starting_pen + obj_idx).try_into().unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //     // Build outline object 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //     let mut rect: Rectangle = Rectangle::default(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //     let origin: Point = calc_pt(obj_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //     *rect.corner_a = Point { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //         x: origin.x - self.width / 2.0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //         y: origin.y - self.height / 2.0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //     *rect.corner_b = Point { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //         x: origin.x + self.width / 2.0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //         y: origin.y + self.height / 2.0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //     *rect.core.origin = origin; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //     *rect.core.pen = pen; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //     *rect.core.z = self.z; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //     debug!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //         "Adding hatched rectangle with pen #{} at {} (from {} to {})", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //         *rect.core.pen, *rect.core.origin, *rect.corner_a, *rect.corner_b 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //     ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //     let mut hatch_setting: HatchSetting = self.hatch.into(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //     *hatch_setting.pen = pen; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //     // Build hatch object 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //     let hatch: Hatch = Hatch { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //         core: ObjectCore { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //             origin: origin.into(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //             z: self.z.into(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //             ..ObjectCore::default(ObjectType::Hatch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //         }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //         outline: vec![Object::Rectangle(rect)].into(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //         legacy_setting: vec![hatch_setting.clone()].into(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //         hatch_settings: vec![hatch_setting.clone()].into(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //         hatches: Some(Hatches { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //             core: ObjectCore::default(ObjectType::HatchLine), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //             hatch_lines: vec![].into(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //         }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//             //     layer.objects.push(Object::Hatch(hatch)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// } 
			 |