From f0075a645c28161817d1a21ee4622e395999ec1a Mon Sep 17 00:00:00 2001 From: Tom Date: Sun, 5 Nov 2023 22:11:26 -0800 Subject: [PATCH] Add metafield for features --- detailer/src/lib.rs | 4 ++-- drawing/src/feature.rs | 46 ++++++++++++++++++++++++++++-------------- drawing/src/handler.rs | 9 +++++---- drawing/src/lib.rs | 2 +- drawing/src/tools.rs | 4 ++-- liquid-cad/src/app.rs | 18 +++++++++++------ 6 files changed, 53 insertions(+), 30 deletions(-) diff --git a/detailer/src/lib.rs b/detailer/src/lib.rs index a6388ba..d6db676 100644 --- a/detailer/src/lib.rs +++ b/detailer/src/lib.rs @@ -72,10 +72,10 @@ impl<'a> Widget<'a> { for k in selected { if let Some(v) = self.drawing.features.get_mut(k) { match v { - Feature::Point(x, y) => { + Feature::Point(_, x, y) => { Widget::show_selection_entry_point(ui, &mut commands, &k, x, y) } - Feature::LineSegment(p1, p2) => { + Feature::LineSegment(_, p1, p2) => { Widget::show_selection_entry_line(ui, &mut commands, &k) } } diff --git a/drawing/src/feature.rs b/drawing/src/feature.rs index a5325e4..a2390c7 100644 --- a/drawing/src/feature.rs +++ b/drawing/src/feature.rs @@ -39,37 +39,53 @@ impl LineSegment { } } -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, PartialEq)] +#[derive(Debug, Clone, Default, serde::Deserialize, serde::Serialize, PartialEq)] +pub struct FeatureMeta {} + +#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] pub enum Feature { - Point(f32, f32), - LineSegment(K, K), + Point(FeatureMeta, f32, f32), + LineSegment(FeatureMeta, K, K), } impl Default for Feature { fn default() -> Self { - Feature::Point(0., 0.) + Feature::Point(FeatureMeta::default(), 0., 0.) + } +} + +impl PartialEq for Feature { + fn eq(&self, other: &Feature) -> bool { + use Feature::{LineSegment, Point}; + match (self, other) { + (Point(_, x1, y1), Point(_, x2, y2)) => x1 == x2 && y1 == y2, + (LineSegment(_, p00, p01), LineSegment(_, p10, p11)) => { + (p00 == p10 && p01 == p11) || (p00 == p11 && p01 == p10) + } + _ => false, + } } } impl Feature { pub fn is_point(&self) -> bool { - matches!(self, Feature::Point(_, _)) + matches!(self, Feature::Point(_, _, _)) } pub fn depends_on(&self) -> [Option; 2] { match self { - Feature::Point(_, _) => [None, None], - Feature::LineSegment(p1, p2) => [Some(*p1), Some(*p2)], + Feature::Point(_, _, _) => [None, None], + Feature::LineSegment(_, p1, p2) => [Some(*p1), Some(*p2)], } } pub fn bb(&self, drawing: &Data) -> egui::Rect { match self { - Feature::Point(x, y) => egui::Rect { + Feature::Point(_, x, y) => egui::Rect { min: egui::Pos2 { x: *x, y: *y }, max: egui::Pos2 { x: *x, y: *y }, }, - Feature::LineSegment(p1, p2) => { + Feature::LineSegment(_, p1, p2) => { let (p1, p2) = ( drawing.features.get(*p1).unwrap(), drawing.features.get(*p2).unwrap(), @@ -82,17 +98,17 @@ impl Feature { pub fn screen_dist(&self, drawing: &Data, hp: egui::Pos2, vp: &Viewport) -> f32 { match self { - Feature::Point(x, y) => vp + Feature::Point(_, x, y) => vp .translate_point(egui::Pos2 { x: *x, y: *y }) .distance_sq(hp), - Feature::LineSegment(p1, p2) => { + Feature::LineSegment(_, p1, p2) => { let (f1, f2) = ( drawing.features.get(*p1).unwrap(), drawing.features.get(*p2).unwrap(), ); let (p1, p2) = match (f1, f2) { - (Feature::Point(x1, y1), Feature::Point(x2, y2)) => ( + (Feature::Point(_, x1, y1), Feature::Point(_, x2, y2)) => ( vp.translate_point(egui::Pos2 { x: *x1, y: *y1 }), vp.translate_point(egui::Pos2 { x: *x2, y: *y2 }), ), @@ -112,7 +128,7 @@ impl Feature { painter: &egui::Painter, ) { match self { - Feature::Point(_, _) => { + Feature::Point(_, _, _) => { painter.rect_filled( params .vp @@ -131,13 +147,13 @@ impl Feature { ); } - Feature::LineSegment(p1, p2) => { + Feature::LineSegment(_, p1, p2) => { let (f1, f2) = ( drawing.features.get(*p1).unwrap(), drawing.features.get(*p2).unwrap(), ); let (p1, p2) = match (f1, f2) { - (Feature::Point(x1, y1), Feature::Point(x2, y2)) => ( + (Feature::Point(_, x1, y1), Feature::Point(_, x2, y2)) => ( params.vp.translate_point(egui::Pos2 { x: *x1, y: *y1 }), params.vp.translate_point(egui::Pos2 { x: *x2, y: *y2 }), ), diff --git a/drawing/src/handler.rs b/drawing/src/handler.rs index 12f19fe..7c9cb10 100644 --- a/drawing/src/handler.rs +++ b/drawing/src/handler.rs @@ -1,4 +1,4 @@ -use super::{Data, Feature}; +use super::{Data, Feature, FeatureMeta}; use crate::tools::ToolResponse; #[derive(Debug, Default)] @@ -10,7 +10,7 @@ impl Handler { ToolResponse::Handled => {} ToolResponse::NewPoint(pos) => { let pos = drawing.vp.screen_to_point(pos); - let p = Feature::Point(pos.x, pos.y); + let p = Feature::Point(FeatureMeta::default(), pos.x, pos.y); // Make sure it doesnt already exist for v in drawing.features.values() { @@ -28,15 +28,16 @@ impl Handler { drawing.find_point_at(p1).unwrap(), drawing.find_point_at(p2).unwrap(), ); + let l = Feature::LineSegment(FeatureMeta::default(), f2, f1); // Make sure it doesnt already exist for v in drawing.features.values() { - if v == &Feature::LineSegment(f1, f2) || v == &Feature::LineSegment(f2, f1) { + if v == &l { return; } } - drawing.features.insert(Feature::LineSegment(f1, f2)); + drawing.features.insert(l); } ToolResponse::Delete(k) => { diff --git a/drawing/src/lib.rs b/drawing/src/lib.rs index 0a15d07..328349d 100644 --- a/drawing/src/lib.rs +++ b/drawing/src/lib.rs @@ -3,7 +3,7 @@ mod data; pub use data::{Data, Viewport}; mod feature; -pub use feature::Feature; +pub use feature::{Feature, FeatureMeta}; mod handler; pub use handler::Handler; pub mod tools; diff --git a/drawing/src/tools.rs b/drawing/src/tools.rs index 1c25e78..16cabaa 100644 --- a/drawing/src/tools.rs +++ b/drawing/src/tools.rs @@ -127,12 +127,12 @@ impl Tool { Tool::Line(p1) => { let c = match (hf, &p1, response.clicked()) { // No first point, clicked on a point - (Some((_, crate::Feature::Point(x, y))), None, true) => { + (Some((_, crate::Feature::Point(_, x, y))), None, true) => { *p1 = Some(egui::Pos2 { x: *x, y: *y }); Some(ToolResponse::Handled) } // Has first point, clicked on a point - (Some((_, crate::Feature::Point(x2, y2))), Some(starting_point), true) => { + (Some((_, crate::Feature::Point(_, x2, y2))), Some(starting_point), true) => { let starting_point = starting_point.clone(); *p1 = Some(egui::Pos2 { x: *x2, y: *y2 }); Some(ToolResponse::NewLineSegment( diff --git a/liquid-cad/src/app.rs b/liquid-cad/src/app.rs index ff81fc3..e5094e1 100644 --- a/liquid-cad/src/app.rs +++ b/liquid-cad/src/app.rs @@ -1,5 +1,5 @@ use detailer; -use drawing; +use drawing::{self, Feature, FeatureMeta}; #[derive(serde::Deserialize, serde::Serialize)] #[serde(default)] // if we add new fields, give them default values when deserializing old state @@ -22,15 +22,21 @@ impl Default for App { // drawing.features.insert(drawing::Feature::Point(188., 188.)); // drawing.features.insert(drawing::Feature::Point(-88., 188.)); - let p1 = drawing.features.insert(drawing::Feature::Point(-88., 0.)); - let p2 = drawing.features.insert(drawing::Feature::Point(0., 0.)); - let p3 = drawing.features.insert(drawing::Feature::Point(88., 0.)); + let p1 = drawing + .features + .insert(Feature::Point(FeatureMeta::default(), -88., 0.)); + let p2 = drawing + .features + .insert(Feature::Point(FeatureMeta::default(), 0., 0.)); + let p3 = drawing + .features + .insert(Feature::Point(FeatureMeta::default(), 88., 0.)); drawing .features - .insert(drawing::Feature::LineSegment(p1, p2)); + .insert(Feature::LineSegment(FeatureMeta::default(), p1, p2)); drawing .features - .insert(drawing::Feature::LineSegment(p2, p3)); + .insert(Feature::LineSegment(FeatureMeta::default(), p2, p3)); let tools = drawing::tools::Toolbar::default(); let handler = drawing::Handler::default();