From 09ec20d70d712c76261ca3cf74381de835759d08 Mon Sep 17 00:00:00 2001 From: phailhaus Date: Fri, 27 Jun 2025 23:10:40 -0500 Subject: [PATCH 1/6] Add from_cmyka function to color.rs Adds a function to convert CMYKA values into RGBA. --- node-graph/gcore/src/color/color.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/node-graph/gcore/src/color/color.rs b/node-graph/gcore/src/color/color.rs index 69edc39e87..b1c35cf9ad 100644 --- a/node-graph/gcore/src/color/color.rs +++ b/node-graph/gcore/src/color/color.rs @@ -454,6 +454,28 @@ impl Color { Color { red, green, blue, alpha } } + /// Create a [Color] from Return a `Color` from given `f32` CMYKA channels (all between 0 and 1) + /// + /// # Examples + /// ``` + /// use graphene_core::color::Color; + /// let color = Color::from_cmyka(0.5, 0.2, 0.3, 0.5, 1.0); + /// ``` + // From https://graphicdesign.stackexchange.com/questions/114260/alternative-formulae-for-cmyk-to-rgb-conversion-for-display-on-screen + pub fn from_cmyka(cyan: f32, magenta: f32, yellow: f32, key: f32, alpha: f32) -> Color { + let cyan_temp: f32 = (1. - cyan) * 255.; + let magenta_temp: f32 = (1. - magenta) * 255.; + let yellow_temp: f32 = (1. - yellow) * 255.; + let red: f32 = (80. + 0.5882 * cyan_temp - 0.3529 * magenta_temp - 0.1373 * yellow_temp + 0.00185 * cyan_temp * magenta_temp + 0.00046 * yellow_temp * cyan_temp) / 255. * key; + let green: f32 = + (66. - 0.1961 * cyan_temp + 0.2745 * magenta_temp - 0.0627 * yellow_temp + 0.00215 * cyan_temp * magenta_temp + 0.00008 * yellow_temp * cyan_temp + 0.00062 * yellow_temp * magenta_temp) + / 255. * key; + let blue: f32 = + (86. - 0.3255 * cyan_temp - 0.1569 * magenta_temp + 0.1647 * yellow_temp + 0.00046 * cyan_temp * magenta_temp + 0.00123 * yellow_temp * cyan_temp + 0.00215 * yellow_temp * magenta_temp) + / 255. * key; + Color { red, green, blue, alpha } + } + /// Return the `red` component. /// /// # Examples From 0ac4c65648f64aeea3384f151465d50ce7f9450a Mon Sep 17 00:00:00 2001 From: phailhaus Date: Fri, 27 Jun 2025 23:12:02 -0500 Subject: [PATCH 2/6] Add construct_color_... nodes Adds nodes to construct colors in the following formats: RGBA, HSLA, Grayscale, CMYKA --- node-graph/gmath-nodes/src/lib.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/node-graph/gmath-nodes/src/lib.rs b/node-graph/gmath-nodes/src/lib.rs index 37a7ed3644..68fb21056a 100644 --- a/node-graph/gmath-nodes/src/lib.rs +++ b/node-graph/gmath-nodes/src/lib.rs @@ -462,6 +462,30 @@ fn dot_product(_: impl Ctx, vector_a: DVec2, vector_b: DVec2) -> f64 { vector_a.dot(vector_b) } +/// Constructs a color from RGBA components. Clamped to 0 -> 1. +#[node_macro::node(category("Color"))] +fn construct_color_rgba(_: impl Ctx, _primary: (), red: f32, green: f32, blue: f32, alpha: f32) -> Color { + Color::from_rgbaf32_unchecked(red.clamp(0.0, 1.0), green.clamp(0.0, 1.0), blue.clamp(0.0, 1.0), alpha.clamp(0.0, 1.0)) +} + +/// Constructs a color from HSLA components. Clamped to 0 -> 1. +#[node_macro::node(category("Color"))] +fn construct_color_hsla(_: impl Ctx, _primary: (), hue: f32, saturation: f32, lightness: f32, alpha: f32) -> Color { + Color::from_hsla(hue.clamp(0.0, 1.0), saturation.clamp(0.0, 1.0), lightness.clamp(0.0, 1.0), alpha.clamp(0.0, 1.0)) +} + +/// Constructs a color from a single grayscale value. Clamped to 0 -> 1. +#[node_macro::node(category("Color"))] +fn construct_color_grayscale(_: impl Ctx, _primary: (), luminance: f32) -> Color { + Color::from_luminance(luminance.clamp(0.0, 1.0)) +} + +/// Constructs a color from CMYKA components. Clamped to 0 -> 1. +#[node_macro::node(category("Color"))] +fn construct_color_cmyka(_: impl Ctx, _primary: (), cyan: f32, magenta: f32, yellow: f32, key: f32, alpha: f32) -> Color { + Color::from_cmyka(cyan.clamp(0.0, 1.0), magenta.clamp(0.0, 1.0), yellow.clamp(0.0, 1.0), key.clamp(0.0, 1.0), alpha.clamp(0.0, 1.0)) +} + #[cfg(test)] mod test { use super::*; From 2627bc877af0dde4811f02a1b0d3c72717b90923 Mon Sep 17 00:00:00 2001 From: phailhaus Date: Fri, 27 Jun 2025 23:14:02 -0500 Subject: [PATCH 3/6] Fix typo in from_cmyka docs Fixed duplicated text in documentation --- node-graph/gcore/src/color/color.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node-graph/gcore/src/color/color.rs b/node-graph/gcore/src/color/color.rs index b1c35cf9ad..69e97afa42 100644 --- a/node-graph/gcore/src/color/color.rs +++ b/node-graph/gcore/src/color/color.rs @@ -454,7 +454,7 @@ impl Color { Color { red, green, blue, alpha } } - /// Create a [Color] from Return a `Color` from given `f32` CMYKA channels (all between 0 and 1) + /// Create a [Color] from given `f32` CMYKA channels (all between 0 and 1) /// /// # Examples /// ``` From 1e75e829cefb2d72224ab1f0cc11a5992ae49b99 Mon Sep 17 00:00:00 2001 From: phailhaus Date: Fri, 27 Jun 2025 23:36:07 -0500 Subject: [PATCH 4/6] Updated Whole Number Floats Updated a bunch of whole number floats to match style guide --- node-graph/gmath-nodes/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/node-graph/gmath-nodes/src/lib.rs b/node-graph/gmath-nodes/src/lib.rs index 68fb21056a..10d9c64292 100644 --- a/node-graph/gmath-nodes/src/lib.rs +++ b/node-graph/gmath-nodes/src/lib.rs @@ -465,25 +465,25 @@ fn dot_product(_: impl Ctx, vector_a: DVec2, vector_b: DVec2) -> f64 { /// Constructs a color from RGBA components. Clamped to 0 -> 1. #[node_macro::node(category("Color"))] fn construct_color_rgba(_: impl Ctx, _primary: (), red: f32, green: f32, blue: f32, alpha: f32) -> Color { - Color::from_rgbaf32_unchecked(red.clamp(0.0, 1.0), green.clamp(0.0, 1.0), blue.clamp(0.0, 1.0), alpha.clamp(0.0, 1.0)) + Color::from_rgbaf32_unchecked(red.clamp(0., 1.), green.clamp(0., 1.), blue.clamp(0., 1.), alpha.clamp(0., 1.)) } /// Constructs a color from HSLA components. Clamped to 0 -> 1. #[node_macro::node(category("Color"))] fn construct_color_hsla(_: impl Ctx, _primary: (), hue: f32, saturation: f32, lightness: f32, alpha: f32) -> Color { - Color::from_hsla(hue.clamp(0.0, 1.0), saturation.clamp(0.0, 1.0), lightness.clamp(0.0, 1.0), alpha.clamp(0.0, 1.0)) + Color::from_hsla(hue.clamp(0.0, 1.0), saturation.clamp(0., 1.), lightness.clamp(0., 1.), alpha.clamp(0., 1.)) } /// Constructs a color from a single grayscale value. Clamped to 0 -> 1. #[node_macro::node(category("Color"))] fn construct_color_grayscale(_: impl Ctx, _primary: (), luminance: f32) -> Color { - Color::from_luminance(luminance.clamp(0.0, 1.0)) + Color::from_luminance(luminance.clamp(0., 1.)) } /// Constructs a color from CMYKA components. Clamped to 0 -> 1. #[node_macro::node(category("Color"))] fn construct_color_cmyka(_: impl Ctx, _primary: (), cyan: f32, magenta: f32, yellow: f32, key: f32, alpha: f32) -> Color { - Color::from_cmyka(cyan.clamp(0.0, 1.0), magenta.clamp(0.0, 1.0), yellow.clamp(0.0, 1.0), key.clamp(0.0, 1.0), alpha.clamp(0.0, 1.0)) + Color::from_cmyka(cyan.clamp(0., 1.), magenta.clamp(0., 1.), yellow.clamp(0., 1.), key.clamp(0., 1.), alpha.clamp(0., 1.)) } #[cfg(test)] From db82040eb6c04b1f734229a1b1ad209cd2b38fb8 Mon Sep 17 00:00:00 2001 From: phailhaus Date: Tue, 8 Jul 2025 18:51:25 -0500 Subject: [PATCH 5/6] Fix Node Properties by converting from f64 Made nodes accept f64 arguments and convert them to f32 internally so that node properties work. --- node-graph/gmath-nodes/src/lib.rs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/node-graph/gmath-nodes/src/lib.rs b/node-graph/gmath-nodes/src/lib.rs index 10d9c64292..34d55e4b83 100644 --- a/node-graph/gmath-nodes/src/lib.rs +++ b/node-graph/gmath-nodes/src/lib.rs @@ -464,26 +464,32 @@ fn dot_product(_: impl Ctx, vector_a: DVec2, vector_b: DVec2) -> f64 { /// Constructs a color from RGBA components. Clamped to 0 -> 1. #[node_macro::node(category("Color"))] -fn construct_color_rgba(_: impl Ctx, _primary: (), red: f32, green: f32, blue: f32, alpha: f32) -> Color { - Color::from_rgbaf32_unchecked(red.clamp(0., 1.), green.clamp(0., 1.), blue.clamp(0., 1.), alpha.clamp(0., 1.)) +fn construct_color_rgba(_: impl Ctx, _primary: (), red: f64, green: f64, blue: f64, alpha: f64) -> Color { + Color::from_rgbaf32_unchecked(red.clamp(0., 1.) as f32, green.clamp(0., 1.) as f32, blue.clamp(0., 1.) as f32, alpha.clamp(0., 1.) as f32) } /// Constructs a color from HSLA components. Clamped to 0 -> 1. #[node_macro::node(category("Color"))] -fn construct_color_hsla(_: impl Ctx, _primary: (), hue: f32, saturation: f32, lightness: f32, alpha: f32) -> Color { - Color::from_hsla(hue.clamp(0.0, 1.0), saturation.clamp(0., 1.), lightness.clamp(0., 1.), alpha.clamp(0., 1.)) +fn construct_color_hsla(_: impl Ctx, _primary: (), hue: f64, saturation: f64, lightness: f64, alpha: f64) -> Color { + Color::from_hsla(hue.clamp(0.0, 1.0) as f32, saturation.clamp(0., 1.) as f32, lightness.clamp(0., 1.) as f32, alpha.clamp(0., 1.) as f32) } /// Constructs a color from a single grayscale value. Clamped to 0 -> 1. #[node_macro::node(category("Color"))] -fn construct_color_grayscale(_: impl Ctx, _primary: (), luminance: f32) -> Color { - Color::from_luminance(luminance.clamp(0., 1.)) +fn construct_color_grayscale(_: impl Ctx, _primary: (), luminance: f64) -> Color { + Color::from_luminance(luminance.clamp(0., 1.) as f32) } /// Constructs a color from CMYKA components. Clamped to 0 -> 1. #[node_macro::node(category("Color"))] -fn construct_color_cmyka(_: impl Ctx, _primary: (), cyan: f32, magenta: f32, yellow: f32, key: f32, alpha: f32) -> Color { - Color::from_cmyka(cyan.clamp(0., 1.), magenta.clamp(0., 1.), yellow.clamp(0., 1.), key.clamp(0., 1.), alpha.clamp(0., 1.)) +fn construct_color_cmyka(_: impl Ctx, _primary: (), cyan: f64, magenta: f64, yellow: f64, key: f64, alpha: f64) -> Color { + Color::from_cmyka( + cyan.clamp(0., 1.) as f32, + magenta.clamp(0., 1.) as f32, + yellow.clamp(0., 1.) as f32, + key.clamp(0., 1.) as f32, + alpha.clamp(0., 1.) as f32, + ) } #[cfg(test)] From 541ec145e7e1fd858a397f68f07cd54f27cacbda Mon Sep 17 00:00:00 2001 From: phailhaus Date: Tue, 8 Jul 2025 19:05:39 -0500 Subject: [PATCH 6/6] Renamed Color nodes to be shorter Changed names from 'construct_color_xxx' to 'xxx_to_color' --- node-graph/gmath-nodes/src/lib.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/node-graph/gmath-nodes/src/lib.rs b/node-graph/gmath-nodes/src/lib.rs index 34d55e4b83..0cd2201e0c 100644 --- a/node-graph/gmath-nodes/src/lib.rs +++ b/node-graph/gmath-nodes/src/lib.rs @@ -463,26 +463,26 @@ fn dot_product(_: impl Ctx, vector_a: DVec2, vector_b: DVec2) -> f64 { } /// Constructs a color from RGBA components. Clamped to 0 -> 1. -#[node_macro::node(category("Color"))] -fn construct_color_rgba(_: impl Ctx, _primary: (), red: f64, green: f64, blue: f64, alpha: f64) -> Color { +#[node_macro::node(category("Color"), name("RGBA to Color"))] +fn rgba_to_color(_: impl Ctx, _primary: (), red: f64, green: f64, blue: f64, alpha: f64) -> Color { Color::from_rgbaf32_unchecked(red.clamp(0., 1.) as f32, green.clamp(0., 1.) as f32, blue.clamp(0., 1.) as f32, alpha.clamp(0., 1.) as f32) } /// Constructs a color from HSLA components. Clamped to 0 -> 1. -#[node_macro::node(category("Color"))] -fn construct_color_hsla(_: impl Ctx, _primary: (), hue: f64, saturation: f64, lightness: f64, alpha: f64) -> Color { +#[node_macro::node(category("Color"), name("HSLA to Color"))] +fn hsla_to_color(_: impl Ctx, _primary: (), hue: f64, saturation: f64, lightness: f64, alpha: f64) -> Color { Color::from_hsla(hue.clamp(0.0, 1.0) as f32, saturation.clamp(0., 1.) as f32, lightness.clamp(0., 1.) as f32, alpha.clamp(0., 1.) as f32) } /// Constructs a color from a single grayscale value. Clamped to 0 -> 1. #[node_macro::node(category("Color"))] -fn construct_color_grayscale(_: impl Ctx, _primary: (), luminance: f64) -> Color { +fn gray_to_color(_: impl Ctx, _primary: (), luminance: f64) -> Color { Color::from_luminance(luminance.clamp(0., 1.) as f32) } /// Constructs a color from CMYKA components. Clamped to 0 -> 1. -#[node_macro::node(category("Color"))] -fn construct_color_cmyka(_: impl Ctx, _primary: (), cyan: f64, magenta: f64, yellow: f64, key: f64, alpha: f64) -> Color { +#[node_macro::node(category("Color"), name("CMYKA to Color"))] +fn cmyka_to_color(_: impl Ctx, _primary: (), cyan: f64, magenta: f64, yellow: f64, key: f64, alpha: f64) -> Color { Color::from_cmyka( cyan.clamp(0., 1.) as f32, magenta.clamp(0., 1.) as f32,