Skip to content

Fix min and max macro not enforcing limits when data flows #2464

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
6fc79b1
Fix min and max macro not enforcing limits when data flows
mTvare6 Mar 18, 2025
7a631e8
Use trait based clamping
TrueDoctor Mar 18, 2025
b4354ed
Remove min/max from testing
mTvare6 Mar 18, 2025
20305b4
cargo fmt
mTvare6 Mar 18, 2025
9da8e64
Resolve into min, and hard_min
mTvare6 Mar 22, 2025
b785868
Merge branch 'master' into fix-min-max-macro
mTvare6 Mar 22, 2025
abdc29f
cargo fmt
mTvare6 Mar 22, 2025
a89263b
fix traits
mTvare6 Mar 22, 2025
affa876
cargo fmt
mTvare6 Mar 22, 2025
5c57f42
fix tests
mTvare6 Mar 22, 2025
8931efd
rename as soft_x
mTvare6 Mar 24, 2025
fc7c6e1
Merge branch 'master' into fix-min-max-macro
mTvare6 Mar 24, 2025
ad7a721
Merge branch 'master' into fix-min-max-macro
mTvare6 Apr 1, 2025
2a99d60
Merge branch 'master' into fix-min-max-macro
mTvare6 Apr 4, 2025
cdf7180
Merge branch 'master' into fix-min-max-macro
mTvare6 Apr 8, 2025
bcd32dd
Merge branch 'master' into fix-min-max-macro
mTvare6 Apr 9, 2025
76cd8e5
Merge branch 'master' into fix-min-max-macro
mTvare6 Apr 11, 2025
599256a
Merge branch 'master' into fix-min-max-macro
mTvare6 Apr 19, 2025
ce36a23
Merge branch 'master' into fix-min-max-macro
mTvare6 Apr 19, 2025
6ace7f6
Add validation code
mTvare6 Apr 19, 2025
c9f1bf1
Merge branch 'master' into fix-min-max-macro
mTvare6 Apr 19, 2025
f45db63
Merge branch 'master' into fix-min-max-macro
mTvare6 Apr 20, 2025
cbd7967
Merge branch 'master' into fix-min-max-macro
mTvare6 Apr 20, 2025
51e12e0
Merge branch 'master' into fix-min-max-macro
Keavon Apr 30, 2025
c764e55
Clean up (not compiling because of DVec2 clamping)
Keavon Apr 30, 2025
1d361c0
Avoid needing to add trait bounds to node definitions
Keavon Apr 30, 2025
fe15134
Replace a bunch of `quote!` with `quote_spanned!`
Keavon Apr 30, 2025
44f34bc
Use idiomatic formatting
Keavon Apr 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion node-graph/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ Instead of manually implementing the `Node` trait with complex generics, one can

```rs
#[node_macro::node(category("Raster: Adjustments"))]
fn opacity(_input: (), #[default(424242)] color: Color,#[min(0.1)] opacity_multiplier: f64) -> Color {
fn opacity(_input: (), #[default(424242)] color: Color,#[soft_min(0.1)] opacity_multiplier: f64) -> Color {
let opacity_multiplier = opacity_multiplier as f32 / 100.;
Color::from_rgbaf32_unchecked(color.r(), color.g(), color.b(), color.a() * opacity_multiplier)
}
Expand Down
2 changes: 2 additions & 0 deletions node-graph/gcore/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use core::future::Future;
#[cfg(feature = "log")]
extern crate log;
pub use crate as graphene_core;
pub use num_traits;

#[cfg(feature = "reflections")]
pub use ctor;
Expand All @@ -19,6 +20,7 @@ pub mod context;
pub mod generic;
pub mod instances;
pub mod logic;
pub mod misc;
pub mod ops;
pub mod structural;
#[cfg(feature = "std")]
Expand Down
60 changes: 60 additions & 0 deletions node-graph/gcore/src/misc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/// A trait for types that can be clamped within a min/max range defined by f64.
pub trait Clampable: Sized {
/// Clamps the value to be no less than `min`.
fn clamp_hard_min(self, min: f64) -> Self;
/// Clamps the value to be no more than `max`.
fn clamp_hard_max(self, max: f64) -> Self;
}

// Implement for common numeric types
macro_rules! impl_clampable_float {
($($ty:ty),*) => {
$(
impl Clampable for $ty {
#[inline(always)]
fn clamp_hard_min(self, min: f64) -> Self {
self.max(min as $ty)
}
#[inline(always)]
fn clamp_hard_max(self, max: f64) -> Self {
self.min(max as $ty)
}
}
)*
};
}
impl_clampable_float!(f32, f64);

macro_rules! impl_clampable_int {
($($ty:ty),*) => {
$(
impl Clampable for $ty {
#[inline(always)]
fn clamp_hard_min(self, min: f64) -> Self {
// Using try_from to handle potential range issues safely, though min should ideally be valid.
// Consider using a different approach if f64 precision vs integer range is a concern.
<$ty>::try_from(min.ceil() as i64).ok().map_or(self, |min_val| self.max(min_val))
}
#[inline(always)]
fn clamp_hard_max(self, max: f64) -> Self {
<$ty>::try_from(max.floor() as i64).ok().map_or(self, |max_val| self.min(max_val))
}
}
)*
};
}
// Add relevant integer types (adjust as needed)
impl_clampable_int!(u32, u64, i32, i64);

// Implement for DVec2 (component-wise clamping)
use glam::DVec2;
impl Clampable for DVec2 {
#[inline(always)]
fn clamp_hard_min(self, min: f64) -> Self {
self.max(DVec2::splat(min))
}
#[inline(always)]
fn clamp_hard_max(self, max: f64) -> Self {
self.min(DVec2::splat(max))
}
}
2 changes: 1 addition & 1 deletion node-graph/gcore/src/raster/adjustments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1399,7 +1399,7 @@ async fn posterize<T: Adjust<Color>>(
)]
mut input: T,
#[default(4)]
#[min(2.)]
#[hard_min(2.)]
levels: u32,
) -> T {
input.adjust(|color| {
Expand Down
6 changes: 3 additions & 3 deletions node-graph/gcore/src/vector/generator_nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ fn regular_polygon<T: AsU64>(
_: impl Ctx,
_primary: (),
#[default(6)]
#[min(3.)]
#[hard_min(3.)]
#[implementations(u32, u64, f64)]
sides: T,
#[default(50)] radius: f64,
Expand All @@ -116,7 +116,7 @@ fn star<T: AsU64>(
_: impl Ctx,
_primary: (),
#[default(5)]
#[min(2.)]
#[hard_min(2.)]
#[implementations(u32, u64, f64)]
sides: T,
#[default(50)] radius: f64,
Expand Down Expand Up @@ -153,7 +153,7 @@ fn grid<T: GridSpacing>(
_: impl Ctx,
_primary: (),
grid_type: GridType,
#[min(0.)]
#[hard_min(0.)]
#[default(10)]
#[implementations(f64, DVec2)]
spacing: T,
Expand Down
12 changes: 6 additions & 6 deletions node-graph/gcore/src/vector/vector_nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ where
async fn round_corners(
_: impl Ctx,
source: VectorDataTable,
#[min(0.)]
#[hard_min(0.)]
#[default(10.)]
radius: PixelLength,
#[range((0., 1.))]
Expand Down Expand Up @@ -538,7 +538,7 @@ async fn spatial_merge_by_distance(
_: impl Ctx,
vector_data: VectorDataTable,
#[default(0.1)]
#[min(0.0001)]
#[hard_min(0.0001)]
distance: f64,
) -> VectorDataTable {
let vector_data_transform = vector_data.transform();
Expand Down Expand Up @@ -748,7 +748,7 @@ async fn remove_handles(
_: impl Ctx,
vector_data: VectorDataTable,
#[default(10.)]
#[min(0.)]
#[soft_min(0.)]
max_handle_distance: f64,
) -> VectorDataTable {
let vector_data_transform = vector_data.transform();
Expand Down Expand Up @@ -879,8 +879,8 @@ async fn generate_handles(
// _: impl Ctx,
// source: VectorDataTable,
// #[default(1.)]
// #[min(1.)]
// #[max(8.)]
// #[hard_min(1.)]
// #[soft_max(8.)]
// subdivisions: f64,
// ) -> VectorDataTable {
// let source_transform = source.transform();
Expand Down Expand Up @@ -1367,7 +1367,7 @@ async fn poisson_disk_points(
_: impl Ctx,
vector_data: VectorDataTable,
#[default(10.)]
#[min(0.01)]
#[hard_min(0.01)]
separation_disk_diameter: f64,
seed: SeedValue,
) -> VectorDataTable {
Expand Down
4 changes: 2 additions & 2 deletions node-graph/gstd/src/image_color_palette.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use graphene_core::{Color, Ctx};
async fn image_color_palette(
_: impl Ctx,
image: ImageFrameTable<Color>,
#[min(1.)]
#[max(28.)]
#[hard_min(1.)]
#[hard_max(28.)]
max_size: u32,
) -> Vec<Color> {
const GRID: f32 = 3.;
Expand Down
Loading
Loading