From 2b56e3cbf473563a6a791c3e752b73ac749edc48 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 16 Jan 2024 12:29:54 +0100 Subject: [PATCH 1/8] Add `Presentation` --- crates/fj-core/src/lib.rs | 1 + crates/fj-core/src/presentation.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 crates/fj-core/src/presentation.rs diff --git a/crates/fj-core/src/lib.rs b/crates/fj-core/src/lib.rs index 6118c0b6d..1d26548fd 100644 --- a/crates/fj-core/src/lib.rs +++ b/crates/fj-core/src/lib.rs @@ -86,6 +86,7 @@ pub mod geometry; pub mod layers; pub mod objects; pub mod operations; +pub mod presentation; pub mod queries; pub mod storage; pub mod validate; diff --git a/crates/fj-core/src/presentation.rs b/crates/fj-core/src/presentation.rs new file mode 100644 index 000000000..7def409cb --- /dev/null +++ b/crates/fj-core/src/presentation.rs @@ -0,0 +1,26 @@ +//! Presentation data for the object graph +//! +//! See [`Presentation`]. + +use std::collections::BTreeMap; + +use fj_interop::Color; + +use crate::{objects::Region, storage::Handle}; + +/// Presentation data for the object graph +/// +/// Assigns attributes relating to the presentation of objects (currently just a +/// color) to those objects (currently only to regions). +/// +/// This data is made available through [`Layers`]. +/// +/// [`Layers`]: crate::layers::Layers +#[derive(Default)] +pub struct Presentation { + /// Color assigned to regions + /// + /// Having a color is optional, so map does not necessarily contain + /// assignments for all existing regions. + pub color: BTreeMap, Color>, +} From 4e75c5bf62e8fbe4b0d79d7642f7fa6621d94f55 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 14 Feb 2024 12:51:51 +0100 Subject: [PATCH 2/8] Add layer infrastructure for `Presentation` --- crates/fj-core/src/layers/mod.rs | 1 + crates/fj-core/src/layers/presentation.rs | 104 ++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 crates/fj-core/src/layers/presentation.rs diff --git a/crates/fj-core/src/layers/mod.rs b/crates/fj-core/src/layers/mod.rs index d18457b73..b442d0819 100644 --- a/crates/fj-core/src/layers/mod.rs +++ b/crates/fj-core/src/layers/mod.rs @@ -3,6 +3,7 @@ //! See [`Layers`]. pub mod objects; +pub mod presentation; pub mod validation; mod layer; diff --git a/crates/fj-core/src/layers/presentation.rs b/crates/fj-core/src/layers/presentation.rs new file mode 100644 index 000000000..1717279d0 --- /dev/null +++ b/crates/fj-core/src/layers/presentation.rs @@ -0,0 +1,104 @@ +//! Layer infrastructure for [`Presentation`] + +use fj_interop::Color; + +use crate::{ + objects::{AnyObject, Region, Stored}, + presentation::Presentation, + storage::Handle, +}; + +use super::{Command, Event, Layer}; + +impl Layer { + /// Set the color of a region + pub fn set_color(&mut self, region: Handle, color: Color) { + let mut events = Vec::new(); + self.process(SetColor { region, color }, &mut events); + } + + /// Mark an object as being derived from another + pub fn derive_object( + &mut self, + original: AnyObject, + derived: AnyObject, + ) { + let mut events = Vec::new(); + self.process(DeriveObject { original, derived }, &mut events); + } +} + +/// Set the color of a region +pub struct SetColor { + /// The region to set the color for + region: Handle, + + /// The color to set + color: Color, +} + +impl Command for SetColor { + type Result = (); + type Event = Self; + + fn decide( + self, + _: &Presentation, + events: &mut Vec, + ) -> Self::Result { + events.push(self); + } +} + +impl Event for SetColor { + fn evolve(&self, state: &mut Presentation) { + state.color.insert(self.region.clone(), self.color); + } +} + +/// Handle an object being derived from another +pub struct DeriveObject { + /// The original object + original: AnyObject, + + /// The derived object + derived: AnyObject, +} + +impl Command for DeriveObject { + type Result = (); + type Event = SetColor; + + fn decide( + self, + state: &Presentation, + events: &mut Vec, + ) -> Self::Result { + if let (AnyObject::Region(original), AnyObject::Region(derived)) = + (self.original, self.derived) + { + if let Some(color) = state.color.get(&original.0).cloned() { + events.push(SetColor { + region: derived.into(), + color, + }); + } + } + } +} + +/// Command for `Layer` +pub enum PresentationCommand {} + +/// Event produced by `Layer` +#[derive(Clone)] +pub enum PresentationEvent { + /// The color of a region is being set + SetColor { + /// The region the color is being set for + region: Handle, + + /// The color being set + color: Color, + }, +} From 3f761bb8f25734b73230b3ba130ec550916dde42 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 14 Feb 2024 13:00:20 +0100 Subject: [PATCH 3/8] Add presentation layer to `Layers` --- crates/fj-core/src/layers/layers.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/fj-core/src/layers/layers.rs b/crates/fj-core/src/layers/layers.rs index 200fd4529..e449cc15e 100644 --- a/crates/fj-core/src/layers/layers.rs +++ b/crates/fj-core/src/layers/layers.rs @@ -1,5 +1,6 @@ use crate::{ objects::Objects, + presentation::Presentation, validate::{Validation, ValidationConfig}, }; @@ -31,6 +32,11 @@ pub struct Layers { /// /// Monitors objects and validates them, as they are inserted. pub validation: Layer, + + /// The presentation layer + /// + /// Stores data concerning the presentation of objects. + pub presentation: Layer, } impl Layers { From 181788378c73c540fd10b7848150eb1221472e69 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 14 Feb 2024 12:56:25 +0100 Subject: [PATCH 4/8] Refactor to prepare for follow-on change --- crates/fj-core/src/operations/presentation.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/operations/presentation.rs b/crates/fj-core/src/operations/presentation.rs index e58323531..1ea9ffe96 100644 --- a/crates/fj-core/src/operations/presentation.rs +++ b/crates/fj-core/src/operations/presentation.rs @@ -15,10 +15,12 @@ pub trait SetColor: IsObject { impl SetColor for Handle { fn set_color(&self, color: impl Into) -> Self::BareObject { + let color = color.into(); + Region::new( self.exterior().clone(), self.interiors().into_iter().cloned(), - Some(color.into()), + Some(color), ) } } From 00b8e261e23b8c519d396eeaa80dfe41ddb2c908 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 14 Feb 2024 13:02:39 +0100 Subject: [PATCH 5/8] Expect `&mut Core` in `SetColor::set_color` --- crates/fj-core/src/operations/presentation.rs | 13 +++++++++++-- crates/fj-core/src/operations/split/face.rs | 4 ++-- models/color/src/lib.rs | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/crates/fj-core/src/operations/presentation.rs b/crates/fj-core/src/operations/presentation.rs index 1ea9ffe96..4c61eef1d 100644 --- a/crates/fj-core/src/operations/presentation.rs +++ b/crates/fj-core/src/operations/presentation.rs @@ -5,16 +5,25 @@ use fj_interop::Color; use crate::{ objects::{IsObject, Region}, storage::Handle, + Core, }; /// Set the color of an object pub trait SetColor: IsObject { /// Set the color of the object - fn set_color(&self, color: impl Into) -> Self::BareObject; + fn set_color( + &self, + color: impl Into, + core: &mut Core, + ) -> Self::BareObject; } impl SetColor for Handle { - fn set_color(&self, color: impl Into) -> Self::BareObject { + fn set_color( + &self, + color: impl Into, + _core: &mut Core, + ) -> Self::BareObject { let color = color.into(); Region::new( diff --git a/crates/fj-core/src/operations/split/face.rs b/crates/fj-core/src/operations/split/face.rs index ee1b93aa9..e1413f99a 100644 --- a/crates/fj-core/src/operations/split/face.rs +++ b/crates/fj-core/src/operations/split/face.rs @@ -151,7 +151,7 @@ impl SplitFace for Shell { if let Some(color) = face.region().color() { region = region - .set_color(color) + .set_color(color, core) .insert(core) .derive_from(®ion, core); } @@ -194,7 +194,7 @@ impl SplitFace for Shell { if let Some(color) = face.region().color() { region = region - .set_color(color) + .set_color(color, core) .insert(core) .derive_from(®ion, core); } diff --git a/models/color/src/lib.rs b/models/color/src/lib.rs index 0e32e7186..5071e486b 100644 --- a/models/color/src/lib.rs +++ b/models/color/src/lib.rs @@ -18,7 +18,7 @@ pub fn model(core: &mut fj::core::Core) -> Solid { shell.faces().first(), |face, core| { [face.update_region( - |region, _| region.set_color([0., 1., 0.]), + |region, core| region.set_color([0., 1., 0.], core), core, )] }, From 6decab41b3a0f1509565507ca76caf394e381049 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 14 Feb 2024 13:03:44 +0100 Subject: [PATCH 6/8] Update presentation layer in `SetColor::set_color` --- crates/fj-core/src/operations/presentation.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/fj-core/src/operations/presentation.rs b/crates/fj-core/src/operations/presentation.rs index 4c61eef1d..84912d436 100644 --- a/crates/fj-core/src/operations/presentation.rs +++ b/crates/fj-core/src/operations/presentation.rs @@ -22,10 +22,12 @@ impl SetColor for Handle { fn set_color( &self, color: impl Into, - _core: &mut Core, + core: &mut Core, ) -> Self::BareObject { let color = color.into(); + core.layers.presentation.set_color(self.clone(), color); + Region::new( self.exterior().clone(), self.interiors().into_iter().cloned(), From 8a1d378c5dea6821cc8a0d279ffb5798b71151d7 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 16 Feb 2024 13:19:21 +0100 Subject: [PATCH 7/8] Add trait bound to prepare for follow-on change --- crates/fj-core/src/operations/derive.rs | 11 +++++++++-- crates/fj-core/src/operations/transform/mod.rs | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/crates/fj-core/src/operations/derive.rs b/crates/fj-core/src/operations/derive.rs index 5063b214c..8e57ff73e 100644 --- a/crates/fj-core/src/operations/derive.rs +++ b/crates/fj-core/src/operations/derive.rs @@ -2,7 +2,11 @@ //! //! See [`DeriveFrom`]. -use crate::{storage::Handle, Core}; +use crate::{ + objects::{AnyObject, Stored}, + storage::Handle, + Core, +}; /// Mark a store object as derived from another pub trait DeriveFrom { @@ -10,7 +14,10 @@ pub trait DeriveFrom { fn derive_from(self, other: &Self, core: &mut Core) -> Self; } -impl DeriveFrom for Handle { +impl DeriveFrom for Handle +where + Self: Into>, +{ fn derive_from(self, _other: &Self, _core: &mut Core) -> Self { // This is currently a no-op. Eventually, it will trigger a command to // the layers that this information is relevant for. diff --git a/crates/fj-core/src/operations/transform/mod.rs b/crates/fj-core/src/operations/transform/mod.rs index 538e00b68..6f6bc8c05 100644 --- a/crates/fj-core/src/operations/transform/mod.rs +++ b/crates/fj-core/src/operations/transform/mod.rs @@ -16,6 +16,7 @@ use fj_math::{Transform, Vector}; use type_map::TypeMap; use crate::{ + objects::{AnyObject, Stored}, operations::insert::Insert, storage::{Handle, ObjectId}, Core, @@ -69,6 +70,7 @@ pub trait TransformObject: Sized { impl TransformObject for Handle where T: Clone + Insert> + TransformObject + 'static, + Handle: Into>, { fn transform_with_cache( &self, From a9bf98aa934d9b98af0c8317807a177eaddd8cb9 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 16 Feb 2024 13:20:32 +0100 Subject: [PATCH 8/8] Update presentation layer when deriving object --- crates/fj-core/src/operations/derive.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/fj-core/src/operations/derive.rs b/crates/fj-core/src/operations/derive.rs index 8e57ff73e..67bc005d4 100644 --- a/crates/fj-core/src/operations/derive.rs +++ b/crates/fj-core/src/operations/derive.rs @@ -18,9 +18,10 @@ impl DeriveFrom for Handle where Self: Into>, { - fn derive_from(self, _other: &Self, _core: &mut Core) -> Self { - // This is currently a no-op. Eventually, it will trigger a command to - // the layers that this information is relevant for. + fn derive_from(self, other: &Self, core: &mut Core) -> Self { + core.layers + .presentation + .derive_object(other.clone().into(), self.clone().into()); self } }