diff --git a/packages/cadmium-macros/src/lib.rs b/packages/cadmium-macros/src/lib.rs index c8df9500..2237a87e 100644 --- a/packages/cadmium-macros/src/lib.rs +++ b/packages/cadmium-macros/src/lib.rs @@ -116,6 +116,7 @@ pub fn derive_step_data(input: TokenStream) -> TokenStream { let step_ = Step { name, + id: result_id_, operation: StepOperation::Add, unique_id: format!(concat!("Add:", stringify!(#name), "-{}"), result_id_), suppressed: false, diff --git a/packages/cadmium/src/isketch.rs b/packages/cadmium/src/isketch.rs index 686d3b8d..f5de1e8c 100644 --- a/packages/cadmium/src/isketch.rs +++ b/packages/cadmium/src/isketch.rs @@ -5,7 +5,7 @@ use std::rc::Rc; use isotope::decompose::face::Face; use isotope::primitives::line::Line; use isotope::primitives::point2::Point2 as ISOPoint2; -use isotope::primitives::{Primitive, PrimitiveCell}; +use isotope::primitives::PrimitiveCell; use isotope::sketch::Sketch; use serde::{Deserialize, Serialize}; use tsify::Tsify; diff --git a/packages/cadmium/src/lib.rs b/packages/cadmium/src/lib.rs index 93cbae84..3e50932d 100644 --- a/packages/cadmium/src/lib.rs +++ b/packages/cadmium/src/lib.rs @@ -114,12 +114,12 @@ impl Realization { } #[wasm_bindgen] - pub fn solid_to_obj(&self, solid_name: String, tolerance: f64) -> String { - self.native.solid_to_obj(&solid_name, tolerance) + pub fn solid_to_obj(&self, solid_name: IDType, tolerance: f64) -> String { + self.native.solid_to_obj(solid_name, tolerance) } #[wasm_bindgen] - pub fn solid_to_step(&self, solid_name: String) -> String { - self.native.solid_to_step(&solid_name) + pub fn solid_to_step(&self, solid_name: IDType) -> String { + self.native.solid_to_step(solid_name) } } diff --git a/packages/cadmium/src/message.rs b/packages/cadmium/src/message.rs index fcce9b79..e24e18a0 100644 --- a/packages/cadmium/src/message.rs +++ b/packages/cadmium/src/message.rs @@ -35,6 +35,7 @@ impl From> for MessageResult { #[derive(Tsify, Debug, Serialize, Deserialize)] #[tsify(into_wasm_abi, from_wasm_abi)] pub enum Message { + StepAction(StepData), RenameWorkbench { workbench_id: u64, new_name: String, @@ -138,6 +139,9 @@ impl Message { pub fn handle(&self, project: &mut Project) -> Result { match self { + Message::StepAction(data) => { + + } Message::RenameProject { new_name } => { project.name = new_name.to_owned(); Ok(format!("\"name\": \"{}\"", new_name)) @@ -164,16 +168,6 @@ impl Message { Ok(format!("\"name\": \"{}\"", new_name)) } - Message::NewSketchOnPlane { - workbench_id, - sketch_name, - plane_id, - } => { - let workbench = project.get_workbench_by_id_mut(*workbench_id)?; - - let new_sketch_id = workbench.add_sketch_to_plane(&sketch_name, &plane_id); - Ok(format!("\"sketch_id\": \"{}\"", new_sketch_id)) - } Message::SetSketchPlane { workbench_id, sketch_id, diff --git a/packages/cadmium/src/realization.rs b/packages/cadmium/src/realization.rs index 0b5dc457..77e960ae 100644 --- a/packages/cadmium/src/realization.rs +++ b/packages/cadmium/src/realization.rs @@ -5,48 +5,49 @@ use wasm_bindgen::prelude::*; use crate::archetypes::Point3; use crate::isketch::{IPlane, ISketch}; use crate::solid::Solid; -use std::collections::HashMap; +use crate::IDType; +use std::collections::BTreeMap; #[derive(Tsify, Debug, Serialize, Deserialize)] #[tsify(into_wasm_abi, from_wasm_abi)] pub struct Realization { // a Realization is what you get if you apply the steps in a Workbench's // history and build a bunch of geometry - pub planes: HashMap, - pub points: HashMap, - pub sketches: HashMap, - pub solids: HashMap, + pub planes: BTreeMap, + pub points: BTreeMap, + pub sketches: BTreeMap, + pub solids: BTreeMap, } impl Realization { pub fn new() -> Self { Realization { - planes: HashMap::new(), - points: HashMap::new(), - sketches: HashMap::new(), - solids: HashMap::new(), + planes: BTreeMap::new(), + points: BTreeMap::new(), + sketches: BTreeMap::new(), + solids: BTreeMap::new(), } } - pub fn solid_to_obj(&self, solid_name: &str, tolerance: f64) -> String { - let solid = &self.solids[solid_name]; + pub fn solid_to_obj(&self, solid_name: IDType, tolerance: f64) -> String { + let solid = &self.solids[&solid_name]; let obj_text = solid.to_obj_string(tolerance); obj_text } - pub fn save_solid_as_obj_file(&self, solid_name: &str, filename: &str, tolerance: f64) { - let solid = &self.solids[solid_name]; + pub fn save_solid_as_obj_file(&self, solid_name: IDType, filename: &str, tolerance: f64) { + let solid = &self.solids[&solid_name]; solid.save_as_obj(filename, tolerance); } - pub fn solid_to_step(&self, solid_name: &str) -> String { - let solid = &self.solids[solid_name]; + pub fn solid_to_step(&self, solid_name: IDType) -> String { + let solid = &self.solids[&solid_name]; let step_text = solid.to_step_string(); step_text } - pub fn save_solid_as_step_file(&self, solid_name: &str, filename: &str) { - let solid = &self.solids[solid_name]; + pub fn save_solid_as_step_file(&self, solid_name: IDType, filename: &str) { + let solid = &self.solids[&solid_name]; solid.save_as_step(filename) } } diff --git a/packages/cadmium/src/step.rs b/packages/cadmium/src/step.rs index 635130f2..c1509635 100644 --- a/packages/cadmium/src/step.rs +++ b/packages/cadmium/src/step.rs @@ -18,9 +18,10 @@ pub enum StepOperation { #[derive(Tsify, Debug, Serialize, Deserialize)] #[tsify(into_wasm_abi, from_wasm_abi)] pub struct Step { + pub(crate) id: IDType, pub(crate) operation: StepOperation, pub(crate) name: String, - pub(crate) unique_id: String, + pub(crate) unique_id: String, // TODO: remove this field, it's not needed pub(crate) suppressed: bool, pub(crate) data: StepData, } diff --git a/packages/cadmium/src/workbench.rs b/packages/cadmium/src/workbench.rs index f8a771d5..e7bec81b 100644 --- a/packages/cadmium/src/workbench.rs +++ b/packages/cadmium/src/workbench.rs @@ -55,10 +55,10 @@ impl Workbench { solids_next_id: 0, }; - wb.add_point(Point3::new(0.0, 0.0, 0.0)).unwrap(); - wb.add_plane(Plane::front(), 100.0, 100.0).unwrap(); - wb.add_plane(Plane::right(), 100.0, 100.0).unwrap(); - wb.add_plane(Plane::top(), 100.0, 100.0).unwrap(); + wb.add_workbench_point(Point3::new(0.0, 0.0, 0.0)).unwrap(); + wb.add_workbench_plane(Plane::front(), 100.0, 100.0).unwrap(); + wb.add_workbench_plane(Plane::right(), 100.0, 100.0).unwrap(); + wb.add_workbench_plane(Plane::top(), 100.0, 100.0).unwrap(); wb } @@ -95,19 +95,19 @@ impl Workbench { self.history[index].data = new_step_data; } - pub fn add_extrusion(&mut self, name: &str, extrusion: Extrusion) -> u64 { - // If the extrusion name is empty string, then we need to generate a new name - // Let's use "Extrusion n" where n is the number of extrusions - let extrusion_name = if name == "" { - format!("Extrusion {}", *counter + 1) - } else { - name.to_owned() - }; - self.history - .push(Step::new_extrusion(&extrusion_name, extrusion, *counter)); - } - - pub fn realize(&self, max_steps: u64) -> Realization { + // pub fn add_extrusion(&mut self, name: &str, extrusion: Extrusion) -> u64 { + // // If the extrusion name is empty string, then we need to generate a new name + // // Let's use "Extrusion n" where n is the number of extrusions + // let extrusion_name = if name == "" { + // format!("Extrusion {}", *counter + 1) + // } else { + // name.to_owned() + // }; + // self.history + // .push(Step::new_extrusion(&extrusion_name, extrusion, *counter)); + // } + + pub fn realize(&self, max_steps: u64) -> Result { let mut realized = Realization::new(); let max_steps = max_steps as usize; // just coerce the type once @@ -120,98 +120,93 @@ impl Workbench { let step_data = &step.data; // println!("{:?}", step_data); match step_data { - StepData::Point { point } => { + StepData::WorkbenchPoint { point, .. } => { realized .points - .insert(step.unique_id.to_owned(), point.clone()); + .insert(step.id, point.clone()); } - StepData::Plane { + StepData::WorkbenchPlane { plane, width, height, + .. } => { + // Do we need to store the IPlane or just the Plane? let rp = IPlane { plane: plane.clone(), width: *width, height: *height, name: step.name.clone(), }; - realized.planes.insert(step.unique_id.to_owned(), rp); + realized.planes.insert(step.id, rp); } - StepData::Sketch { - width: _, - height: _, + StepData::WorkbenchSketch { plane_description, - sketch, + // sketch_id, + // width: _, + // height: _, + .. } => match plane_description { PlaneDescription::PlaneId(plane_id) => { - if plane_id == "" { - println!("Sketch {} has no plane", step.name); - continue; - } - - let plane = &realized.planes[&plane_id]; - let sketch_ref = Rc::new(RefCell::new(sketch.clone())); + let plane = &realized.planes.get(&plane_id).ok_or(anyhow::anyhow!("Failed to find plane with id {}", plane_id))?; + let sketch = self.get_sketch_by_id(step.id)?.borrow().clone(); realized.sketches.insert( - step.unique_id.to_owned(), + step.id, ( - ISketch::new(&plane_id, &plane, sketch_ref.clone()), - ISketch::new( - &plane_id, - &plane, - sketch_ref, - ), + sketch.clone(), + sketch.clone(), step.name.clone(), ), ); } PlaneDescription::SolidFace { solid_id, normal } => { - let solid = &realized.solids[&solid_id]; - let face = solid.get_face_by_normal(&normal).unwrap(); - let oriented_surface = face.oriented_surface(); - - println!("Surface: {:?}", oriented_surface); - let sketch_plane; - match oriented_surface { - truck_modeling::geometry::Surface::Plane(p) => { - let plane = Plane::from_truck(p); - println!("Plane: {:?}", plane); - sketch_plane = plane; - } - _ => { - panic!("I only know how to put sketches on planes"); - } - } - - let new_plane_id = format!("derived_plane_for:{}", step.name); - - let rp = IPlane { - plane: sketch_plane.clone(), - width: 90.0, - height: 60.0, - name: new_plane_id.clone(), - }; - realized.planes.insert(new_plane_id.clone(), rp); - let rp = &realized.planes[&new_plane_id]; - let sketch_ref = Rc::new(RefCell::new(sketch.clone())); - - // TODO: There's no way this is correct. Also a lot of prelude is the same fo Plane case - realized.sketches.insert( - step.unique_id.to_owned(), - ( - ISketch::new(&new_plane_id, &rp, sketch_ref.clone()), - ISketch::new( - &new_plane_id, - &rp, - // TODO: &sketch.split_intersections(false), - sketch_ref, - ), - step.name.clone(), - ), - ); + // let solid = &realized.solids[&solid_id]; + // let face = solid.get_face_by_normal(&normal).unwrap(); + // let oriented_surface = face.oriented_surface(); + + // println!("Surface: {:?}", oriented_surface); + // let sketch_plane; + // match oriented_surface { + // truck_modeling::geometry::Surface::Plane(p) => { + // let plane = Plane::from_truck(p); + // println!("Plane: {:?}", plane); + // sketch_plane = plane; + // } + // _ => { + // panic!("I only know how to put sketches on planes"); + // } + // } + + // let new_plane_id = format!("derived_plane_for:{}", step.name); + + // let rp = IPlane { + // plane: sketch_plane.clone(), + // width: 90.0, + // height: 60.0, + // name: new_plane_id.clone(), + // }; + // realized.planes.insert(new_plane_id.clone(), rp); + // let rp = &realized.planes[&new_plane_id]; + // let sketch_ref = Rc::new(RefCell::new(sketch.clone())); + + // // TODO: There's no way this is correct. Also a lot of prelude is the same fo Plane case + // realized.sketches.insert( + // step.unique_id.to_owned(), + // ( + // ISketch::new(&new_plane_id, &rp, sketch_ref.clone()), + // ISketch::new( + // &new_plane_id, + // &rp, + // // TODO: &sketch.split_intersections(false), + // sketch_ref, + // ), + // step.name.clone(), + // ), + // ); } }, + /* StepData::Extrusion { extrusion } => { let (_sketch, split_sketch, _name) = &realized.sketches[&extrusion.sketch_id]; let plane = &realized.planes[&split_sketch.plane_id]; @@ -357,10 +352,11 @@ impl Workbench { } } } + */ } } - realized + Ok(realized) } } @@ -388,8 +384,12 @@ impl Workbench { PlaneDescription::SolidFace { solid_id, normal } => todo!("Implement SolidFace"), }; - let sketch = ISketch::new(plane); - self.sketches.insert(self.sketches_next_id, sketch).ok_or(anyhow::anyhow!("Failed to insert sketch")); + let plane_cell = Rc::new(RefCell::new(plane.clone())); + + let sketch = ISketch::new(plane_cell); + self.sketches + .insert(self.sketches_next_id, Rc::new(RefCell::new(sketch))) + .ok_or(anyhow::anyhow!("Failed to insert sketch")); self.sketches_next_id += 1; Ok(self.sketches_next_id - 1) }