Use f64 not f32 throughout graph; add Vector2 value node (#1618)

* Use doubles in graph

* Format .graphite files onto one line

* Rename new node to Vector2

* No primary input

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
0HyperCube 2024-02-18 22:16:37 +00:00 committed by GitHub
parent 0e0e347435
commit 229b5dbb20
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 477 additions and 445 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -764,7 +764,7 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
}
SetOpacityForSelectedLayers { opacity } => {
self.backup(responses);
let opacity = opacity.clamp(0., 1.) as f32;
let opacity = opacity.clamp(0., 1.);
for layer in self.selected_nodes.selected_layers_except_artboards(self.metadata()) {
responses.add(GraphOperationMessage::OpacitySet { layer, opacity });
@ -1365,7 +1365,7 @@ impl DocumentMessageHandler {
let mut blend_mode_identical = true;
for (opacity, blend_mode) in result_opacity_and_blend_mode {
if (opacity - first_opacity).abs() > (f32::EPSILON * 100.) {
if (opacity - first_opacity).abs() > (f64::EPSILON * 100.) {
opacity_identical = false;
}
if blend_mode != first_blend_mode {

View File

@ -24,7 +24,7 @@ pub enum GraphOperationMessage {
},
OpacitySet {
layer: LayerNodeIdentifier,
opacity: f32,
opacity: f64,
},
BlendModeSet {
layer: LayerNodeIdentifier,
@ -92,7 +92,7 @@ pub enum GraphOperationMessage {
id: NodeId,
text: String,
font: Font,
size: f32,
size: f64,
parent: LayerNodeIdentifier,
insert_index: isize,
},

View File

@ -206,13 +206,13 @@ impl<'a> ModifyInputsContext<'a> {
self.responses.add(NodeGraphMessage::RunDocumentGraph);
}
fn insert_text(&mut self, text: String, font: Font, size: f32, layer: NodeId) {
fn insert_text(&mut self, text: String, font: Font, size: f64, layer: NodeId) {
let text = resolve_document_node_type("Text").expect("Text node does not exist").to_document_node(
[
NodeInput::Network(graph_craft::concrete!(graphene_std::wasm_application_io::WasmEditorApi)),
NodeInput::value(TaggedValue::String(text), false),
NodeInput::value(TaggedValue::Font(font), false),
NodeInput::value(TaggedValue::F32(size), false),
NodeInput::value(TaggedValue::F64(size), false),
],
Default::default(),
);
@ -367,9 +367,9 @@ impl<'a> ModifyInputsContext<'a> {
});
}
fn opacity_set(&mut self, opacity: f32) {
fn opacity_set(&mut self, opacity: f64) {
self.modify_inputs("Opacity", false, |inputs, _node_id, _metadata| {
inputs[1] = NodeInput::value(TaggedValue::F32(opacity * 100.), false);
inputs[1] = NodeInput::value(TaggedValue::F64(opacity * 100.), false);
});
}
@ -382,12 +382,12 @@ impl<'a> ModifyInputsContext<'a> {
fn stroke_set(&mut self, stroke: Stroke) {
self.modify_inputs("Stroke", false, |inputs, _node_id, _metadata| {
inputs[1] = NodeInput::value(TaggedValue::OptionalColor(stroke.color), false);
inputs[2] = NodeInput::value(TaggedValue::F32(stroke.weight as f32), false);
inputs[3] = NodeInput::value(TaggedValue::VecF32(stroke.dash_lengths), false);
inputs[4] = NodeInput::value(TaggedValue::F32(stroke.dash_offset as f32), false);
inputs[2] = NodeInput::value(TaggedValue::F64(stroke.weight), false);
inputs[3] = NodeInput::value(TaggedValue::VecF64(stroke.dash_lengths), false);
inputs[4] = NodeInput::value(TaggedValue::F64(stroke.dash_offset), false);
inputs[5] = NodeInput::value(TaggedValue::LineCap(stroke.line_cap), false);
inputs[6] = NodeInput::value(TaggedValue::LineJoin(stroke.line_join), false);
inputs[7] = NodeInput::value(TaggedValue::F32(stroke.line_join_miter_limit as f32), false);
inputs[7] = NodeInput::value(TaggedValue::F64(stroke.line_join_miter_limit), false);
});
}
@ -851,7 +851,7 @@ fn apply_usvg_stroke(stroke: &Option<usvg::Stroke>, modify_inputs: &mut ModifyIn
modify_inputs.stroke_set(Stroke {
color: Some(usvg_color(*color, stroke.opacity.get())),
weight: stroke.width.get() as f64,
dash_lengths: stroke.dasharray.clone().unwrap_or_default(),
dash_lengths: stroke.dasharray.as_ref().map(|lengths| lengths.iter().map(|&length| length as f64).collect()).unwrap_or_default(),
dash_offset: stroke.dashoffset as f64,
line_cap: match stroke.linecap {
usvg::LineCap::Butt => LineCap::Butt,

View File

@ -38,7 +38,7 @@ pub fn update_transform(inputs: &mut [NodeInput], transform: DAffine2) {
let (scale, angle, translation, shear) = compute_scale_angle_translation_shear(transform);
inputs[1] = NodeInput::value(TaggedValue::DVec2(translation), false);
inputs[2] = NodeInput::value(TaggedValue::F32(angle as f32), false);
inputs[2] = NodeInput::value(TaggedValue::F64(angle), false);
inputs[3] = NodeInput::value(TaggedValue::DVec2(scale), false);
inputs[4] = NodeInput::value(TaggedValue::DVec2(shear), false);
}
@ -82,7 +82,7 @@ pub fn get_current_transform(inputs: &[NodeInput]) -> DAffine2 {
};
let angle = if let NodeInput::Value {
tagged_value: TaggedValue::F32(angle),
tagged_value: TaggedValue::F64(angle),
..
} = inputs[2]
{
@ -111,7 +111,7 @@ pub fn get_current_transform(inputs: &[NodeInput]) -> DAffine2 {
DVec2::ZERO
};
DAffine2::from_scale_angle_translation(scale, angle as f64, translation) * DAffine2::from_cols_array(&[1., shear.y, shear.x, 1., 0., 0.])
DAffine2::from_scale_angle_translation(scale, angle, translation) * DAffine2::from_cols_array(&[1., shear.y, shear.x, 1., 0., 0.])
}
/// Extract the current normalized pivot from the layer

View File

@ -159,7 +159,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
name: "Number",
category: "Inputs",
implementation: NodeImplementation::proto("graphene_core::ops::IdentityNode"),
inputs: vec![DocumentInputType::value("Number", TaggedValue::F32(0.), false)],
inputs: vec![DocumentInputType::value("Number", TaggedValue::F64(0.), false)],
outputs: vec![DocumentOutputType::new("Out", FrontendGraphDataType::Number)],
properties: node_properties::number_properties,
..Default::default()
@ -173,6 +173,19 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
properties: node_properties::color_properties,
..Default::default()
},
DocumentNodeDefinition {
name: "Vector2",
category: "Inputs",
implementation: NodeImplementation::proto("graphene_core::ops::ConstructVector2<_, _>"),
inputs: vec![
DocumentInputType::none(),
DocumentInputType::value("X", TaggedValue::F64(0.), false),
DocumentInputType::value("Y", TaggedValue::F64(0.), false),
],
outputs: vec![DocumentOutputType::new("Out", FrontendGraphDataType::Number)],
properties: node_properties::vector2_properties,
..Default::default()
},
DocumentNodeDefinition {
name: "Identity",
category: "Structural",
@ -632,19 +645,19 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
NodeInput::Network(concrete!(())),
NodeInput::Network(concrete!(UVec2)),
NodeInput::Network(concrete!(u32)),
NodeInput::Network(concrete!(f32)),
NodeInput::Network(concrete!(f64)),
NodeInput::Network(concrete!(graphene_core::raster::NoiseType)),
NodeInput::Network(concrete!(graphene_core::raster::FractalType)),
NodeInput::Network(concrete!(f32)),
NodeInput::Network(concrete!(f64)),
NodeInput::Network(concrete!(graphene_core::raster::FractalType)),
NodeInput::Network(concrete!(u32)),
NodeInput::Network(concrete!(f32)),
NodeInput::Network(concrete!(f32)),
NodeInput::Network(concrete!(f32)),
NodeInput::Network(concrete!(f32)),
NodeInput::Network(concrete!(f64)),
NodeInput::Network(concrete!(f64)),
NodeInput::Network(concrete!(f64)),
NodeInput::Network(concrete!(f64)),
NodeInput::Network(concrete!(graphene_core::raster::CellularDistanceFunction)),
NodeInput::Network(concrete!(graphene_core::raster::CellularReturnType)),
NodeInput::Network(concrete!(f32)),
NodeInput::Network(concrete!(f64)),
],
implementation: DocumentNodeImplementation::Unresolved(ProtoNodeIdentifier::new("graphene_std::raster::NoisePatternNode<_, _, _, _, _, _, _, _, _, _, _, _, _, _, _>")),
..Default::default()
@ -668,22 +681,22 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
// All
DocumentInputType::value("Dimensions", TaggedValue::UVec2((512, 512).into()), false),
DocumentInputType::value("Seed", TaggedValue::U32(0), false),
DocumentInputType::value("Scale", TaggedValue::F32(10.), false),
DocumentInputType::value("Scale", TaggedValue::F64(10.), false),
DocumentInputType::value("Noise Type", TaggedValue::NoiseType(NoiseType::Perlin), false),
// Domain Warp
DocumentInputType::value("Domain Warp Type", TaggedValue::DomainWarpType(DomainWarpType::None), false),
DocumentInputType::value("Domain Warp Amplitude", TaggedValue::F32(100.), false),
DocumentInputType::value("Domain Warp Amplitude", TaggedValue::F64(100.), false),
// Fractal
DocumentInputType::value("Fractal Type", TaggedValue::FractalType(FractalType::None), false),
DocumentInputType::value("Fractal Octaves", TaggedValue::U32(3), false),
DocumentInputType::value("Fractal Lacunarity", TaggedValue::F32(2.), false),
DocumentInputType::value("Fractal Gain", TaggedValue::F32(0.5), false),
DocumentInputType::value("Fractal Weighted Strength", TaggedValue::F32(0.), false), // 0-1 range
DocumentInputType::value("Fractal Ping Pong Strength", TaggedValue::F32(2.), false),
DocumentInputType::value("Fractal Lacunarity", TaggedValue::F64(2.), false),
DocumentInputType::value("Fractal Gain", TaggedValue::F64(0.5), false),
DocumentInputType::value("Fractal Weighted Strength", TaggedValue::F64(0.), false), // 0-1 range
DocumentInputType::value("Fractal Ping Pong Strength", TaggedValue::F64(2.), false),
// Cellular
DocumentInputType::value("Cellular Distance Function", TaggedValue::CellularDistanceFunction(CellularDistanceFunction::Euclidean), false),
DocumentInputType::value("Cellular Return Type", TaggedValue::CellularReturnType(CellularReturnType::Nearest), false),
DocumentInputType::value("Cellular Jitter", TaggedValue::F32(1.), false),
DocumentInputType::value("Cellular Jitter", TaggedValue::F64(1.), false),
],
outputs: vec![DocumentOutputType::new("Image", FrontendGraphDataType::Raster)],
properties: node_properties::noise_pattern_properties,
@ -743,7 +756,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
DocumentInputType::value("Image", TaggedValue::ImageFrame(ImageFrame::empty()), true),
DocumentInputType::value("Second", TaggedValue::ImageFrame(ImageFrame::empty()), true),
DocumentInputType::value("BlendMode", TaggedValue::BlendMode(BlendMode::Normal), false),
DocumentInputType::value("Opacity", TaggedValue::F32(100.), false),
DocumentInputType::value("Opacity", TaggedValue::F64(100.), false),
],
outputs: vec![DocumentOutputType::new("Image", FrontendGraphDataType::Raster)],
properties: node_properties::blend_properties,
@ -762,27 +775,27 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
DocumentInputType {
name: "Shadows",
data_type: FrontendGraphDataType::Number,
default: NodeInput::value(TaggedValue::F32(0.), false),
default: NodeInput::value(TaggedValue::F64(0.), false),
},
DocumentInputType {
name: "Midtones",
data_type: FrontendGraphDataType::Number,
default: NodeInput::value(TaggedValue::F32(50.), false),
default: NodeInput::value(TaggedValue::F64(50.), false),
},
DocumentInputType {
name: "Highlights",
data_type: FrontendGraphDataType::Number,
default: NodeInput::value(TaggedValue::F32(100.), false),
default: NodeInput::value(TaggedValue::F64(100.), false),
},
DocumentInputType {
name: "Output Minimums",
data_type: FrontendGraphDataType::Number,
default: NodeInput::value(TaggedValue::F32(0.), false),
default: NodeInput::value(TaggedValue::F64(0.), false),
},
DocumentInputType {
name: "Output Maximums",
data_type: FrontendGraphDataType::Number,
default: NodeInput::value(TaggedValue::F32(100.), false),
default: NodeInput::value(TaggedValue::F64(100.), false),
},
],
outputs: vec![DocumentOutputType::new("Image", FrontendGraphDataType::Raster)],
@ -807,32 +820,32 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
DocumentInputType {
name: "Reds",
data_type: FrontendGraphDataType::Number,
default: NodeInput::value(TaggedValue::F32(40.), false),
default: NodeInput::value(TaggedValue::F64(40.), false),
},
DocumentInputType {
name: "Yellows",
data_type: FrontendGraphDataType::Number,
default: NodeInput::value(TaggedValue::F32(60.), false),
default: NodeInput::value(TaggedValue::F64(60.), false),
},
DocumentInputType {
name: "Greens",
data_type: FrontendGraphDataType::Number,
default: NodeInput::value(TaggedValue::F32(40.), false),
default: NodeInput::value(TaggedValue::F64(40.), false),
},
DocumentInputType {
name: "Cyans",
data_type: FrontendGraphDataType::Number,
default: NodeInput::value(TaggedValue::F32(60.), false),
default: NodeInput::value(TaggedValue::F64(60.), false),
},
DocumentInputType {
name: "Blues",
data_type: FrontendGraphDataType::Number,
default: NodeInput::value(TaggedValue::F32(20.), false),
default: NodeInput::value(TaggedValue::F64(20.), false),
},
DocumentInputType {
name: "Magentas",
data_type: FrontendGraphDataType::Number,
default: NodeInput::value(TaggedValue::F32(80.), false),
default: NodeInput::value(TaggedValue::F64(80.), false),
},
],
outputs: vec![DocumentOutputType::new("Image", FrontendGraphDataType::Raster)],
@ -1103,7 +1116,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
DocumentInputType {
name: "In",
data_type: FrontendGraphDataType::General,
default: NodeInput::value(TaggedValue::F32(0.), true),
default: NodeInput::value(TaggedValue::F64(0.), true),
},
DocumentInputType {
name: "In",
@ -1608,7 +1621,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
DocumentInputType::value("Image", TaggedValue::ImageFrame(ImageFrame::empty()), true),
DocumentInputType::value("Second", TaggedValue::ImageFrame(ImageFrame::empty()), true),
DocumentInputType::value("Blend Mode", TaggedValue::BlendMode(BlendMode::Normal), false),
DocumentInputType::value("Opacity", TaggedValue::F32(100.), false),
DocumentInputType::value("Opacity", TaggedValue::F64(100.), false),
],
outputs: vec![DocumentOutputType::new("Image", FrontendGraphDataType::Raster)],
properties: node_properties::blend_properties,
@ -1708,9 +1721,9 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
implementation: NodeImplementation::proto("graphene_core::raster::HueSaturationNode<_, _, _>"),
inputs: vec![
DocumentInputType::value("Image", TaggedValue::ImageFrame(ImageFrame::empty()), true),
DocumentInputType::value("Hue Shift", TaggedValue::F32(0.), false),
DocumentInputType::value("Saturation Shift", TaggedValue::F32(0.), false),
DocumentInputType::value("Lightness Shift", TaggedValue::F32(0.), false),
DocumentInputType::value("Hue Shift", TaggedValue::F64(0.), false),
DocumentInputType::value("Saturation Shift", TaggedValue::F64(0.), false),
DocumentInputType::value("Lightness Shift", TaggedValue::F64(0.), false),
],
outputs: vec![DocumentOutputType::new("Image", FrontendGraphDataType::Raster)],
properties: node_properties::adjust_hsl_properties,
@ -1722,8 +1735,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
implementation: NodeImplementation::proto("graphene_core::raster::BrightnessContrastNode<_, _, _>"),
inputs: vec![
DocumentInputType::value("Image", TaggedValue::ImageFrame(ImageFrame::empty()), true),
DocumentInputType::value("Brightness", TaggedValue::F32(0.), false),
DocumentInputType::value("Contrast", TaggedValue::F32(0.), false),
DocumentInputType::value("Brightness", TaggedValue::F64(0.), false),
DocumentInputType::value("Contrast", TaggedValue::F64(0.), false),
DocumentInputType::value("Use Legacy", TaggedValue::Bool(false), false),
],
outputs: vec![DocumentOutputType::new("Image", FrontendGraphDataType::Raster)],
@ -1748,8 +1761,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
implementation: NodeImplementation::proto("graphene_core::raster::ThresholdNode<_, _, _>"),
inputs: vec![
DocumentInputType::value("Image", TaggedValue::ImageFrame(ImageFrame::empty()), true),
DocumentInputType::value("Min Luminance", TaggedValue::F32(50.), false),
DocumentInputType::value("Max Luminance", TaggedValue::F32(100.), false),
DocumentInputType::value("Min Luminance", TaggedValue::F64(50.), false),
DocumentInputType::value("Max Luminance", TaggedValue::F64(100.), false),
DocumentInputType::value("Luminance Calc", TaggedValue::LuminanceCalculation(LuminanceCalculation::SRGB), false),
],
outputs: vec![DocumentOutputType::new("Image", FrontendGraphDataType::Raster)],
@ -1762,7 +1775,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
implementation: NodeImplementation::proto("graphene_core::raster::VibranceNode<_>"),
inputs: vec![
DocumentInputType::value("Image", TaggedValue::ImageFrame(ImageFrame::empty()), true),
DocumentInputType::value("Vibrance", TaggedValue::F32(0.), false),
DocumentInputType::value("Vibrance", TaggedValue::F64(0.), false),
],
outputs: vec![DocumentOutputType::new("Image", FrontendGraphDataType::Raster)],
properties: node_properties::adjust_vibrance_properties,
@ -1777,25 +1790,25 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
// Monochrome toggle
DocumentInputType::value("Monochrome", TaggedValue::Bool(false), false),
// Monochrome
DocumentInputType::value("Red", TaggedValue::F32(40.), false),
DocumentInputType::value("Green", TaggedValue::F32(40.), false),
DocumentInputType::value("Blue", TaggedValue::F32(20.), false),
DocumentInputType::value("Constant", TaggedValue::F32(0.), false),
DocumentInputType::value("Red", TaggedValue::F64(40.), false),
DocumentInputType::value("Green", TaggedValue::F64(40.), false),
DocumentInputType::value("Blue", TaggedValue::F64(20.), false),
DocumentInputType::value("Constant", TaggedValue::F64(0.), false),
// Red output channel
DocumentInputType::value("(Red) Red", TaggedValue::F32(100.), false),
DocumentInputType::value("(Red) Green", TaggedValue::F32(0.), false),
DocumentInputType::value("(Red) Blue", TaggedValue::F32(0.), false),
DocumentInputType::value("(Red) Constant", TaggedValue::F32(0.), false),
DocumentInputType::value("(Red) Red", TaggedValue::F64(100.), false),
DocumentInputType::value("(Red) Green", TaggedValue::F64(0.), false),
DocumentInputType::value("(Red) Blue", TaggedValue::F64(0.), false),
DocumentInputType::value("(Red) Constant", TaggedValue::F64(0.), false),
// Green output channel
DocumentInputType::value("(Green) Red", TaggedValue::F32(0.), false),
DocumentInputType::value("(Green) Green", TaggedValue::F32(100.), false),
DocumentInputType::value("(Green) Blue", TaggedValue::F32(0.), false),
DocumentInputType::value("(Green) Constant", TaggedValue::F32(0.), false),
DocumentInputType::value("(Green) Red", TaggedValue::F64(0.), false),
DocumentInputType::value("(Green) Green", TaggedValue::F64(100.), false),
DocumentInputType::value("(Green) Blue", TaggedValue::F64(0.), false),
DocumentInputType::value("(Green) Constant", TaggedValue::F64(0.), false),
// Blue output channel
DocumentInputType::value("(Blue) Red", TaggedValue::F32(0.), false),
DocumentInputType::value("(Blue) Green", TaggedValue::F32(0.), false),
DocumentInputType::value("(Blue) Blue", TaggedValue::F32(100.), false),
DocumentInputType::value("(Blue) Constant", TaggedValue::F32(0.), false),
DocumentInputType::value("(Blue) Red", TaggedValue::F64(0.), false),
DocumentInputType::value("(Blue) Green", TaggedValue::F64(0.), false),
DocumentInputType::value("(Blue) Blue", TaggedValue::F64(100.), false),
DocumentInputType::value("(Blue) Constant", TaggedValue::F64(0.), false),
// Display-only properties (not used within the node)
DocumentInputType::value("Output Channel", TaggedValue::RedGreenBlue(RedGreenBlue::Red), false),
],
@ -1814,50 +1827,50 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
// Mode
DocumentInputType::value("Mode", TaggedValue::RelativeAbsolute(RelativeAbsolute::Relative), false),
// Reds
DocumentInputType::value("(Reds) Cyan", TaggedValue::F32(0.), false),
DocumentInputType::value("(Reds) Magenta", TaggedValue::F32(0.), false),
DocumentInputType::value("(Reds) Yellow", TaggedValue::F32(0.), false),
DocumentInputType::value("(Reds) Black", TaggedValue::F32(0.), false),
DocumentInputType::value("(Reds) Cyan", TaggedValue::F64(0.), false),
DocumentInputType::value("(Reds) Magenta", TaggedValue::F64(0.), false),
DocumentInputType::value("(Reds) Yellow", TaggedValue::F64(0.), false),
DocumentInputType::value("(Reds) Black", TaggedValue::F64(0.), false),
// Yellows
DocumentInputType::value("(Yellows) Cyan", TaggedValue::F32(0.), false),
DocumentInputType::value("(Yellows) Magenta", TaggedValue::F32(0.), false),
DocumentInputType::value("(Yellows) Yellow", TaggedValue::F32(0.), false),
DocumentInputType::value("(Yellows) Black", TaggedValue::F32(0.), false),
DocumentInputType::value("(Yellows) Cyan", TaggedValue::F64(0.), false),
DocumentInputType::value("(Yellows) Magenta", TaggedValue::F64(0.), false),
DocumentInputType::value("(Yellows) Yellow", TaggedValue::F64(0.), false),
DocumentInputType::value("(Yellows) Black", TaggedValue::F64(0.), false),
// Greens
DocumentInputType::value("(Greens) Cyan", TaggedValue::F32(0.), false),
DocumentInputType::value("(Greens) Magenta", TaggedValue::F32(0.), false),
DocumentInputType::value("(Greens) Yellow", TaggedValue::F32(0.), false),
DocumentInputType::value("(Greens) Black", TaggedValue::F32(0.), false),
DocumentInputType::value("(Greens) Cyan", TaggedValue::F64(0.), false),
DocumentInputType::value("(Greens) Magenta", TaggedValue::F64(0.), false),
DocumentInputType::value("(Greens) Yellow", TaggedValue::F64(0.), false),
DocumentInputType::value("(Greens) Black", TaggedValue::F64(0.), false),
// Cyans
DocumentInputType::value("(Cyans) Cyan", TaggedValue::F32(0.), false),
DocumentInputType::value("(Cyans) Magenta", TaggedValue::F32(0.), false),
DocumentInputType::value("(Cyans) Yellow", TaggedValue::F32(0.), false),
DocumentInputType::value("(Cyans) Black", TaggedValue::F32(0.), false),
DocumentInputType::value("(Cyans) Cyan", TaggedValue::F64(0.), false),
DocumentInputType::value("(Cyans) Magenta", TaggedValue::F64(0.), false),
DocumentInputType::value("(Cyans) Yellow", TaggedValue::F64(0.), false),
DocumentInputType::value("(Cyans) Black", TaggedValue::F64(0.), false),
// Blues
DocumentInputType::value("(Blues) Cyan", TaggedValue::F32(0.), false),
DocumentInputType::value("(Blues) Magenta", TaggedValue::F32(0.), false),
DocumentInputType::value("(Blues) Yellow", TaggedValue::F32(0.), false),
DocumentInputType::value("(Blues) Black", TaggedValue::F32(0.), false),
DocumentInputType::value("(Blues) Cyan", TaggedValue::F64(0.), false),
DocumentInputType::value("(Blues) Magenta", TaggedValue::F64(0.), false),
DocumentInputType::value("(Blues) Yellow", TaggedValue::F64(0.), false),
DocumentInputType::value("(Blues) Black", TaggedValue::F64(0.), false),
// Magentas
DocumentInputType::value("(Magentas) Cyan", TaggedValue::F32(0.), false),
DocumentInputType::value("(Magentas) Magenta", TaggedValue::F32(0.), false),
DocumentInputType::value("(Magentas) Yellow", TaggedValue::F32(0.), false),
DocumentInputType::value("(Magentas) Black", TaggedValue::F32(0.), false),
DocumentInputType::value("(Magentas) Cyan", TaggedValue::F64(0.), false),
DocumentInputType::value("(Magentas) Magenta", TaggedValue::F64(0.), false),
DocumentInputType::value("(Magentas) Yellow", TaggedValue::F64(0.), false),
DocumentInputType::value("(Magentas) Black", TaggedValue::F64(0.), false),
// Whites
DocumentInputType::value("(Whites) Cyan", TaggedValue::F32(0.), false),
DocumentInputType::value("(Whites) Magenta", TaggedValue::F32(0.), false),
DocumentInputType::value("(Whites) Yellow", TaggedValue::F32(0.), false),
DocumentInputType::value("(Whites) Black", TaggedValue::F32(0.), false),
DocumentInputType::value("(Whites) Cyan", TaggedValue::F64(0.), false),
DocumentInputType::value("(Whites) Magenta", TaggedValue::F64(0.), false),
DocumentInputType::value("(Whites) Yellow", TaggedValue::F64(0.), false),
DocumentInputType::value("(Whites) Black", TaggedValue::F64(0.), false),
// Neutrals
DocumentInputType::value("(Neutrals) Cyan", TaggedValue::F32(0.), false),
DocumentInputType::value("(Neutrals) Magenta", TaggedValue::F32(0.), false),
DocumentInputType::value("(Neutrals) Yellow", TaggedValue::F32(0.), false),
DocumentInputType::value("(Neutrals) Black", TaggedValue::F32(0.), false),
DocumentInputType::value("(Neutrals) Cyan", TaggedValue::F64(0.), false),
DocumentInputType::value("(Neutrals) Magenta", TaggedValue::F64(0.), false),
DocumentInputType::value("(Neutrals) Yellow", TaggedValue::F64(0.), false),
DocumentInputType::value("(Neutrals) Black", TaggedValue::F64(0.), false),
// Blacks
DocumentInputType::value("(Blacks) Cyan", TaggedValue::F32(0.), false),
DocumentInputType::value("(Blacks) Magenta", TaggedValue::F32(0.), false),
DocumentInputType::value("(Blacks) Yellow", TaggedValue::F32(0.), false),
DocumentInputType::value("(Blacks) Black", TaggedValue::F32(0.), false),
DocumentInputType::value("(Blacks) Cyan", TaggedValue::F64(0.), false),
DocumentInputType::value("(Blacks) Magenta", TaggedValue::F64(0.), false),
DocumentInputType::value("(Blacks) Yellow", TaggedValue::F64(0.), false),
DocumentInputType::value("(Blacks) Black", TaggedValue::F64(0.), false),
// Display-only properties (not used within the node)
DocumentInputType::value("Colors", TaggedValue::SelectiveColorChoice(SelectiveColorChoice::Reds), false),
],
@ -1871,7 +1884,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
implementation: NodeImplementation::proto("graphene_core::raster::OpacityNode<_>"),
inputs: vec![
DocumentInputType::value("Image", TaggedValue::ImageFrame(ImageFrame::empty()), true),
DocumentInputType::value("Factor", TaggedValue::F32(100.), false),
DocumentInputType::value("Factor", TaggedValue::F64(100.), false),
],
outputs: vec![DocumentOutputType::new("Image", FrontendGraphDataType::Raster)],
properties: node_properties::opacity_properties,
@ -1895,7 +1908,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
implementation: NodeImplementation::proto("graphene_core::raster::PosterizeNode<_>"),
inputs: vec![
DocumentInputType::value("Image", TaggedValue::ImageFrame(ImageFrame::empty()), true),
DocumentInputType::value("Levels", TaggedValue::F32(4.), false),
DocumentInputType::value("Levels", TaggedValue::F64(4.), false),
],
outputs: vec![DocumentOutputType::new("Image", FrontendGraphDataType::Raster)],
properties: node_properties::posterize_properties,
@ -1907,9 +1920,9 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
implementation: NodeImplementation::proto("graphene_core::raster::ExposureNode<_, _, _>"),
inputs: vec![
DocumentInputType::value("Image", TaggedValue::ImageFrame(ImageFrame::empty()), true),
DocumentInputType::value("Exposure", TaggedValue::F32(0.), false),
DocumentInputType::value("Offset", TaggedValue::F32(0.), false),
DocumentInputType::value("Gamma Correction", TaggedValue::F32(1.), false),
DocumentInputType::value("Exposure", TaggedValue::F64(0.), false),
DocumentInputType::value("Offset", TaggedValue::F64(0.), false),
DocumentInputType::value("Gamma Correction", TaggedValue::F64(1.), false),
],
outputs: vec![DocumentOutputType::new("Image", FrontendGraphDataType::Raster)],
properties: node_properties::exposure_properties,
@ -1920,8 +1933,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
category: "Math",
implementation: NodeImplementation::proto("graphene_core::ops::AddNode<_>"),
inputs: vec![
DocumentInputType::value("Primary", TaggedValue::F32(0.), true),
DocumentInputType::value("Addend", TaggedValue::F32(0.), false),
DocumentInputType::value("Primary", TaggedValue::F64(0.), true),
DocumentInputType::value("Addend", TaggedValue::F64(0.), false),
],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::add_properties,
@ -1932,8 +1945,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
category: "Math",
implementation: NodeImplementation::proto("graphene_core::ops::SubtractNode<_>"),
inputs: vec![
DocumentInputType::value("Primary", TaggedValue::F32(0.), true),
DocumentInputType::value("Subtrahend", TaggedValue::F32(0.), false),
DocumentInputType::value("Primary", TaggedValue::F64(0.), true),
DocumentInputType::value("Subtrahend", TaggedValue::F64(0.), false),
],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::subtract_properties,
@ -1944,8 +1957,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
category: "Math",
implementation: NodeImplementation::proto("graphene_core::ops::DivideNode<_>"),
inputs: vec![
DocumentInputType::value("Primary", TaggedValue::F32(0.), true),
DocumentInputType::value("Divisor", TaggedValue::F32(1.), false),
DocumentInputType::value("Primary", TaggedValue::F64(0.), true),
DocumentInputType::value("Divisor", TaggedValue::F64(1.), false),
],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::divide_properties,
@ -1956,8 +1969,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
category: "Math",
implementation: NodeImplementation::proto("graphene_core::ops::MultiplyNode<_>"),
inputs: vec![
DocumentInputType::value("Primary", TaggedValue::F32(0.), true),
DocumentInputType::value("Multiplicand", TaggedValue::F32(1.), false),
DocumentInputType::value("Primary", TaggedValue::F64(0.), true),
DocumentInputType::value("Multiplicand", TaggedValue::F64(1.), false),
],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::multiply_properties,
@ -1968,8 +1981,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
category: "Math",
implementation: NodeImplementation::proto("graphene_core::ops::ExponentNode<_>"),
inputs: vec![
DocumentInputType::value("Primary", TaggedValue::F32(0.), true),
DocumentInputType::value("Power", TaggedValue::F32(2.), false),
DocumentInputType::value("Primary", TaggedValue::F64(0.), true),
DocumentInputType::value("Power", TaggedValue::F64(2.), false),
],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::exponent_properties,
@ -1979,7 +1992,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
name: "Floor",
category: "Math",
implementation: NodeImplementation::proto("graphene_core::ops::FloorNode"),
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F32(0.), true)],
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F64(0.), true)],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::node_no_properties,
..Default::default()
@ -1988,7 +2001,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
name: "Ceil",
category: "Math",
implementation: NodeImplementation::proto("graphene_core::ops::CeilingNode"),
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F32(0.), true)],
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F64(0.), true)],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::node_no_properties,
..Default::default()
@ -1997,7 +2010,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
name: "Round",
category: "Math",
implementation: NodeImplementation::proto("graphene_core::ops::RoundNode"),
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F32(0.), true)],
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F64(0.), true)],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::node_no_properties,
..Default::default()
@ -2006,7 +2019,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
name: "Absolute Value",
category: "Math",
implementation: NodeImplementation::proto("graphene_core::ops::AbsoluteValue"),
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F32(0.), true)],
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F64(0.), true)],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::node_no_properties,
..Default::default()
@ -2016,8 +2029,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
category: "Math",
implementation: NodeImplementation::proto("graphene_core::ops::LogarithmNode<_>"),
inputs: vec![
DocumentInputType::value("Primary", TaggedValue::F32(0.), true),
DocumentInputType::value("Base", TaggedValue::F32(0.), true),
DocumentInputType::value("Primary", TaggedValue::F64(0.), true),
DocumentInputType::value("Base", TaggedValue::F64(0.), true),
],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::log_properties,
@ -2027,7 +2040,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
name: "Natural Logarithm",
category: "Math",
implementation: NodeImplementation::proto("graphene_core::ops::NaturalLogarithmNode"),
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F32(0.), true)],
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F64(0.), true)],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::node_no_properties,
..Default::default()
@ -2036,7 +2049,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
name: "Sine",
category: "Math",
implementation: NodeImplementation::proto("graphene_core::ops::SineNode"),
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F32(0.), true)],
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F64(0.), true)],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::node_no_properties,
..Default::default()
@ -2045,7 +2058,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
name: "Cosine",
category: "Math",
implementation: NodeImplementation::proto("graphene_core::ops::CosineNode"),
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F32(0.), true)],
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F64(0.), true)],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::node_no_properties,
..Default::default()
@ -2054,7 +2067,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
name: "Tangent",
category: "Math",
implementation: NodeImplementation::proto("graphene_core::ops::TangentNode"),
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F32(0.), true)],
inputs: vec![DocumentInputType::value("Primary", TaggedValue::F64(0.), true)],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::node_no_properties,
..Default::default()
@ -2064,8 +2077,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
category: "Math",
implementation: NodeImplementation::proto("graphene_core::ops::MaximumNode<_>"),
inputs: vec![
DocumentInputType::value("Operand A", TaggedValue::F32(0.), true),
DocumentInputType::value("Operand B", TaggedValue::F32(0.), true),
DocumentInputType::value("Operand A", TaggedValue::F64(0.), true),
DocumentInputType::value("Operand B", TaggedValue::F64(0.), true),
],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::max_properties,
@ -2076,8 +2089,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
category: "Math",
implementation: NodeImplementation::proto("graphene_core::ops::MinimumNode<_>"),
inputs: vec![
DocumentInputType::value("Operand A", TaggedValue::F32(0.), true),
DocumentInputType::value("Operand B", TaggedValue::F32(0.), true),
DocumentInputType::value("Operand A", TaggedValue::F64(0.), true),
DocumentInputType::value("Operand B", TaggedValue::F64(0.), true),
],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::min_properties,
@ -2088,8 +2101,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
category: "Math",
implementation: NodeImplementation::proto("graphene_core::ops::EqualsNode<_>"),
inputs: vec![
DocumentInputType::value("Operand A", TaggedValue::F32(0.), true),
DocumentInputType::value("Operand B", TaggedValue::F32(0.), true),
DocumentInputType::value("Operand A", TaggedValue::F64(0.), true),
DocumentInputType::value("Operand B", TaggedValue::F64(0.), true),
],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::eq_properties,
@ -2100,8 +2113,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
category: "Math",
implementation: NodeImplementation::proto("graphene_core::ops::ModuloNode<_>"),
inputs: vec![
DocumentInputType::value("Primary", TaggedValue::F32(0.), true),
DocumentInputType::value("Modulus", TaggedValue::F32(0.), false),
DocumentInputType::value("Primary", TaggedValue::F64(0.), true),
DocumentInputType::value("Modulus", TaggedValue::F64(0.), false),
],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::modulo_properties,
@ -2171,7 +2184,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
nodes: vec![
DocumentNode {
name: "Circle Generator".to_string(),
inputs: vec![NodeInput::Network(concrete!(())), NodeInput::Network(concrete!(f32))],
inputs: vec![NodeInput::Network(concrete!(())), NodeInput::Network(concrete!(f64))],
implementation: DocumentNodeImplementation::Unresolved(ProtoNodeIdentifier::new("graphene_core::vector::generator_nodes::CircleGenerator<_>")),
..Default::default()
},
@ -2189,7 +2202,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
.collect(),
..Default::default()
}),
inputs: vec![DocumentInputType::none(), DocumentInputType::value("Radius", TaggedValue::F32(50.), false)],
inputs: vec![DocumentInputType::none(), DocumentInputType::value("Radius", TaggedValue::F64(50.), false)],
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
properties: node_properties::circle_properties,
..Default::default()
@ -2203,7 +2216,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
nodes: vec![
DocumentNode {
name: "Ellipse Generator".to_string(),
inputs: vec![NodeInput::Network(concrete!(())), NodeInput::Network(concrete!(f32)), NodeInput::Network(concrete!(f32))],
inputs: vec![NodeInput::Network(concrete!(())), NodeInput::Network(concrete!(f64)), NodeInput::Network(concrete!(f64))],
implementation: DocumentNodeImplementation::Unresolved(ProtoNodeIdentifier::new("graphene_core::vector::generator_nodes::EllipseGenerator<_, _>")),
..Default::default()
},
@ -2223,8 +2236,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
}),
inputs: vec![
DocumentInputType::none(),
DocumentInputType::value("Radius X", TaggedValue::F32(50.), false),
DocumentInputType::value("Radius Y", TaggedValue::F32(25.), false),
DocumentInputType::value("Radius X", TaggedValue::F64(50.), false),
DocumentInputType::value("Radius Y", TaggedValue::F64(25.), false),
],
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
properties: node_properties::ellipse_properties,
@ -2239,7 +2252,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
nodes: vec![
DocumentNode {
name: "Rectangle Generator".to_string(),
inputs: vec![NodeInput::Network(concrete!(())), NodeInput::Network(concrete!(f32)), NodeInput::Network(concrete!(f32))],
inputs: vec![NodeInput::Network(concrete!(())), NodeInput::Network(concrete!(f64)), NodeInput::Network(concrete!(f64))],
implementation: DocumentNodeImplementation::Unresolved(ProtoNodeIdentifier::new("graphene_core::vector::generator_nodes::RectangleGenerator<_, _>")),
..Default::default()
},
@ -2259,8 +2272,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
}),
inputs: vec![
DocumentInputType::none(),
DocumentInputType::value("Size X", TaggedValue::F32(100.), false),
DocumentInputType::value("Size Y", TaggedValue::F32(100.), false),
DocumentInputType::value("Size X", TaggedValue::F64(100.), false),
DocumentInputType::value("Size Y", TaggedValue::F64(100.), false),
],
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
properties: node_properties::rectangle_properties,
@ -2275,7 +2288,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
nodes: vec![
DocumentNode {
name: "Regular Polygon Generator".to_string(),
inputs: vec![NodeInput::Network(concrete!(())), NodeInput::Network(concrete!(u32)), NodeInput::Network(concrete!(f32))],
inputs: vec![NodeInput::Network(concrete!(())), NodeInput::Network(concrete!(u32)), NodeInput::Network(concrete!(f64))],
implementation: DocumentNodeImplementation::Unresolved(ProtoNodeIdentifier::new("graphene_core::vector::generator_nodes::RegularPolygonGenerator<_, _>")),
..Default::default()
},
@ -2296,7 +2309,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
inputs: vec![
DocumentInputType::none(),
DocumentInputType::value("Sides", TaggedValue::U32(6), false),
DocumentInputType::value("Radius", TaggedValue::F32(50.), false),
DocumentInputType::value("Radius", TaggedValue::F64(50.), false),
],
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
properties: node_properties::regular_polygon_properties,
@ -2314,8 +2327,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
inputs: vec![
NodeInput::Network(concrete!(())),
NodeInput::Network(concrete!(u32)),
NodeInput::Network(concrete!(f32)),
NodeInput::Network(concrete!(f32)),
NodeInput::Network(concrete!(f64)),
NodeInput::Network(concrete!(f64)),
],
implementation: DocumentNodeImplementation::Unresolved(ProtoNodeIdentifier::new("graphene_core::vector::generator_nodes::StarGenerator<_, _, _>")),
..Default::default()
@ -2337,8 +2350,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
inputs: vec![
DocumentInputType::none(),
DocumentInputType::value("Sides", TaggedValue::U32(5), false),
DocumentInputType::value("Radius", TaggedValue::F32(50.), false),
DocumentInputType::value("Inner Radius", TaggedValue::F32(25.), false),
DocumentInputType::value("Radius", TaggedValue::F64(50.), false),
DocumentInputType::value("Inner Radius", TaggedValue::F64(25.), false),
],
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
properties: node_properties::star_properties,
@ -2492,7 +2505,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
NodeInput::Network(concrete!(application_io::EditorApi<graphene_std::wasm_application_io::WasmApplicationIo>)),
NodeInput::Network(concrete!(String)),
NodeInput::Network(concrete!(graphene_core::text::Font)),
NodeInput::Network(concrete!(f32)),
NodeInput::Network(concrete!(f64)),
],
implementation: DocumentNodeImplementation::Unresolved(ProtoNodeIdentifier::new("graphene_core::text::TextGeneratorNode<_, _, _>")),
..Default::default()
@ -2515,7 +2528,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
DocumentInputType::none(),
DocumentInputType::value("Text", TaggedValue::String("Lorem ipsum".to_string()), false),
DocumentInputType::value("Font", TaggedValue::Font(Font::new(DEFAULT_FONT_FAMILY.into(), DEFAULT_FONT_STYLE.into())), false),
DocumentInputType::value("Size", TaggedValue::F32(24.), false),
DocumentInputType::value("Size", TaggedValue::F64(24.), false),
],
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
properties: node_properties::node_section_font,
@ -2537,7 +2550,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
inputs: vec![
NodeInput::node(NodeId(0), 0),
NodeInput::Network(concrete!(DVec2)),
NodeInput::Network(concrete!(f32)),
NodeInput::Network(concrete!(f64)),
NodeInput::Network(concrete!(DVec2)),
NodeInput::Network(concrete!(DVec2)),
NodeInput::Network(concrete!(DVec2)),
@ -2557,7 +2570,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
inputs: vec![
DocumentInputType::value("Vector Data", TaggedValue::VectorData(VectorData::empty()), true),
DocumentInputType::value("Translation", TaggedValue::DVec2(DVec2::ZERO), false),
DocumentInputType::value("Rotation", TaggedValue::F32(0.), false),
DocumentInputType::value("Rotation", TaggedValue::F64(0.), false),
DocumentInputType::value("Scale", TaggedValue::DVec2(DVec2::ONE), false),
DocumentInputType::value("Skew", TaggedValue::DVec2(DVec2::ZERO), false),
DocumentInputType::value("Pivot", TaggedValue::DVec2(DVec2::splat(0.5)), false),
@ -2602,12 +2615,12 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
inputs: vec![
DocumentInputType::value("Vector Data", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
DocumentInputType::value("Color", TaggedValue::OptionalColor(Some(Color::BLACK)), false),
DocumentInputType::value("Weight", TaggedValue::F32(0.), false),
DocumentInputType::value("Dash Lengths", TaggedValue::VecF32(Vec::new()), false),
DocumentInputType::value("Dash Offset", TaggedValue::F32(0.), false),
DocumentInputType::value("Weight", TaggedValue::F64(0.), false),
DocumentInputType::value("Dash Lengths", TaggedValue::VecF64(Vec::new()), false),
DocumentInputType::value("Dash Offset", TaggedValue::F64(0.), false),
DocumentInputType::value("Line Cap", TaggedValue::LineCap(graphene_core::vector::style::LineCap::Butt), false),
DocumentInputType::value("Line Join", TaggedValue::LineJoin(graphene_core::vector::style::LineJoin::Miter), false),
DocumentInputType::value("Miter Limit", TaggedValue::F32(4.), false),
DocumentInputType::value("Miter Limit", TaggedValue::F64(4.), false),
],
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
properties: node_properties::stroke_properties,
@ -2641,8 +2654,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
implementation: NodeImplementation::proto("graphene_core::vector::CircularRepeatNode<_, _, _>"),
inputs: vec![
DocumentInputType::value("Instance", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
DocumentInputType::value("Angle Offset", TaggedValue::F32(0.), false),
DocumentInputType::value("Radius", TaggedValue::F32(5.), false),
DocumentInputType::value("Angle Offset", TaggedValue::F64(0.), false),
DocumentInputType::value("Radius", TaggedValue::F64(5.), false),
DocumentInputType::value("Count", TaggedValue::U32(10), false),
],
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
@ -2658,10 +2671,10 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
inputs: vec![
DocumentInputType::value("Points", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
DocumentInputType::value("Instance", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
DocumentInputType::value("Random Scale Min", TaggedValue::F32(1.), false),
DocumentInputType::value("Random Scale Max", TaggedValue::F32(1.), false),
DocumentInputType::value("Random Scale Bias", TaggedValue::F32(1.), false),
DocumentInputType::value("Random Rotation", TaggedValue::F32(0.), false),
DocumentInputType::value("Random Scale Min", TaggedValue::F64(1.), false),
DocumentInputType::value("Random Scale Max", TaggedValue::F64(1.), false),
DocumentInputType::value("Random Scale Bias", TaggedValue::F64(1.), false),
DocumentInputType::value("Random Rotation", TaggedValue::F64(0.), false),
],
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
properties: node_properties::copy_to_points_properties,
@ -2690,9 +2703,9 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
name: "Sample Points".to_string(),
inputs: vec![
NodeInput::node(NodeId(0), 0), // From output 0 of Identity
NodeInput::Network(concrete!(f32)), // From the document node's parameters
NodeInput::Network(concrete!(f32)), // From the document node's parameters
NodeInput::Network(concrete!(f32)), // From the document node's parameters
NodeInput::Network(concrete!(f64)), // From the document node's parameters
NodeInput::Network(concrete!(f64)), // From the document node's parameters
NodeInput::Network(concrete!(f64)), // From the document node's parameters
NodeInput::Network(concrete!(bool)), // From the document node's parameters
NodeInput::node(NodeId(1), 0), // From output 0 of Lengths of Segments of Subpaths
],
@ -2710,9 +2723,9 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
}),
inputs: vec![
DocumentInputType::value("Vector Data", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
DocumentInputType::value("Spacing", TaggedValue::F32(100.), false),
DocumentInputType::value("Start Offset", TaggedValue::F32(0.), false),
DocumentInputType::value("Stop Offset", TaggedValue::F32(0.), false),
DocumentInputType::value("Spacing", TaggedValue::F64(100.), false),
DocumentInputType::value("Start Offset", TaggedValue::F64(0.), false),
DocumentInputType::value("Stop Offset", TaggedValue::F64(0.), false),
DocumentInputType::value("Adaptive Spacing", TaggedValue::Bool(false), false),
],
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
@ -2725,7 +2738,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
implementation: NodeImplementation::proto("graphene_core::vector::PoissonDiskPoints<_>"),
inputs: vec![
DocumentInputType::value("Vector Data", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
DocumentInputType::value("Separation Disk Diameter", TaggedValue::F32(10.), false),
DocumentInputType::value("Separation Disk Diameter", TaggedValue::F64(10.), false),
],
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
properties: node_properties::poisson_disk_points_properties,
@ -2748,7 +2761,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
DocumentInputType::value("Source", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
DocumentInputType::value("Target", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
DocumentInputType::value("Start Index", TaggedValue::U32(0), false),
DocumentInputType::value("Time", TaggedValue::F32(0.5), false),
DocumentInputType::value("Time", TaggedValue::F64(0.5), false),
],
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
manual_composition: Some(concrete!(Footprint)),
@ -2800,7 +2813,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
DocumentInputType::value("Image", TaggedValue::ImageFrame(ImageFrame::empty()), true),
DocumentInputType::value("Color", TaggedValue::Color(Color::BLACK), false),
DocumentInputType::value("Blend Mode", TaggedValue::BlendMode(BlendMode::Normal), false),
DocumentInputType::value("Opacity", TaggedValue::F32(100.), false),
DocumentInputType::value("Opacity", TaggedValue::F64(100.), false),
],
outputs: vec![DocumentOutputType::new("Image", FrontendGraphDataType::Raster)],
properties: node_properties::color_overlay_properties,
@ -2865,13 +2878,13 @@ pub static IMAGINATE_NODE: Lazy<DocumentNodeDefinition> = Lazy::new(|| DocumentN
NodeInput::Network(concrete!(Option<DVec2>)),
NodeInput::Network(concrete!(u32)),
NodeInput::Network(concrete!(ImaginateSamplingMethod)),
NodeInput::Network(concrete!(f32)),
NodeInput::Network(concrete!(f64)),
NodeInput::Network(concrete!(String)),
NodeInput::Network(concrete!(String)),
NodeInput::Network(concrete!(bool)),
NodeInput::Network(concrete!(f32)),
NodeInput::Network(concrete!(f64)),
NodeInput::Network(concrete!(bool)),
NodeInput::Network(concrete!(f32)),
NodeInput::Network(concrete!(f64)),
NodeInput::Network(concrete!(ImaginateMaskStartingFill)),
NodeInput::Network(concrete!(bool)),
NodeInput::Network(concrete!(bool)),
@ -2896,13 +2909,13 @@ pub static IMAGINATE_NODE: Lazy<DocumentNodeDefinition> = Lazy::new(|| DocumentN
DocumentInputType::value("Resolution", TaggedValue::OptionalDVec2(None), false),
DocumentInputType::value("Samples", TaggedValue::U32(30), false),
DocumentInputType::value("Sampling Method", TaggedValue::ImaginateSamplingMethod(ImaginateSamplingMethod::EulerA), false),
DocumentInputType::value("Prompt Guidance", TaggedValue::F32(7.5), false),
DocumentInputType::value("Prompt Guidance", TaggedValue::F64(7.5), false),
DocumentInputType::value("Prompt", TaggedValue::String(String::new()), false),
DocumentInputType::value("Negative Prompt", TaggedValue::String(String::new()), false),
DocumentInputType::value("Adapt Input Image", TaggedValue::Bool(false), false),
DocumentInputType::value("Image Creativity", TaggedValue::F32(66.), false),
DocumentInputType::value("Image Creativity", TaggedValue::F64(66.), false),
DocumentInputType::value("Inpaint", TaggedValue::Bool(true), false),
DocumentInputType::value("Mask Blur", TaggedValue::F32(4.), false),
DocumentInputType::value("Mask Blur", TaggedValue::F64(4.), false),
DocumentInputType::value("Mask Starting Fill", TaggedValue::ImaginateMaskStartingFill(ImaginateMaskStartingFill::Fill), false),
DocumentInputType::value("Improve Faces", TaggedValue::Bool(false), false),
DocumentInputType::value("Tiling", TaggedValue::Bool(false), false),
@ -3085,7 +3098,7 @@ pub fn new_text_network(text: String, font: Font, size: f64) -> NodeNetwork {
NodeInput::Network(concrete!(WasmEditorApi)),
NodeInput::value(TaggedValue::String(text), false),
NodeInput::value(TaggedValue::Font(font), false),
NodeInput::value(TaggedValue::F32(size as f32), false),
NodeInput::value(TaggedValue::F64(size), false),
],
DocumentNodeMetadata::position((0, 4)),
));

View File

@ -226,21 +226,21 @@ fn vec2_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name
LayoutGroup::Row { widgets }
}
fn vec_f32_input(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, text_props: TextInput, blank_assist: bool) -> Vec<WidgetHolder> {
fn vec_f64_input(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, text_props: TextInput, blank_assist: bool) -> Vec<WidgetHolder> {
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::Vector, blank_assist);
let from_string = |string: &str| {
string
.split(&[',', ' '])
.filter(|x| !x.is_empty())
.map(str::parse::<f32>)
.map(str::parse::<f64>)
.collect::<Result<Vec<_>, _>>()
.ok()
.map(TaggedValue::VecF32)
.map(TaggedValue::VecF64)
};
if let NodeInput::Value {
tagged_value: TaggedValue::VecF32(x),
tagged_value: TaggedValue::VecF64(x),
exposed: false,
} = &document_node.inputs[index]
{
@ -905,6 +905,13 @@ pub fn number_properties(document_node: &DocumentNode, node_id: NodeId, _context
vec![LayoutGroup::Row { widgets }]
}
pub fn vector2_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let x = number_widget(document_node, node_id, 1, "X", NumberInput::default(), true);
let y = number_widget(document_node, node_id, 2, "Y", NumberInput::default(), true);
vec![LayoutGroup::Row { widgets: x }, LayoutGroup::Row { widgets: y }]
}
pub fn boolean_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let widgets = bool_widget(document_node, node_id, 0, "Bool", true);
@ -1541,7 +1548,7 @@ pub fn transform_properties(document_node: &DocumentNode, node_id: NodeId, _cont
let mut widgets = start_widgets(document_node, node_id, index, "Rotation", FrontendGraphDataType::Number, true);
if let NodeInput::Value {
tagged_value: TaggedValue::F32(val),
tagged_value: TaggedValue::F64(val),
exposed: false,
} = document_node.inputs[index]
{
@ -1553,7 +1560,7 @@ pub fn transform_properties(document_node: &DocumentNode, node_id: NodeId, _cont
.range_min(Some(-180.))
.range_max(Some(180.))
.on_update(update_value(
|number_input: &NumberInput| TaggedValue::F32((number_input.value.unwrap() as f32).to_radians()),
|number_input: &NumberInput| TaggedValue::F64((number_input.value.unwrap() as f64).to_radians()),
node_id,
index,
))
@ -2100,7 +2107,7 @@ pub fn stroke_properties(document_node: &DocumentNode, node_id: NodeId, _context
let color = color_widget(document_node, node_id, color_index, "Color", ColorButton::default(), true);
let weight = number_widget(document_node, node_id, weight_index, "Weight", NumberInput::default().unit("px").min(0.), true);
let dash_lengths = vec_f32_input(document_node, node_id, dash_lengths_index, "Dash Lengths", TextInput::default().centered(true), true);
let dash_lengths = vec_f64_input(document_node, node_id, dash_lengths_index, "Dash Lengths", TextInput::default().centered(true), true);
let dash_offset = number_widget(document_node, node_id, dash_offset_index, "Dash Offset", NumberInput::default().unit("px").min(0.), true);
let line_cap = line_cap_widget(document_node, node_id, line_cap_index, "Line Cap", true);
let line_join = line_join_widget(document_node, node_id, line_join_index, "Line Join", true);

View File

@ -148,9 +148,9 @@ pub fn get_blend_mode(layer: LayerNodeIdentifier, document_network: &NodeNetwork
/// - Already factored into the pixel alpha channel of an image
/// - The default value of 100% if no Opacity node is present, but this function returns None in that case
/// With those limitations in mind, the intention of this function is to show just the value already present in an upstream Opacity node so that value can be directly edited.
pub fn get_opacity(layer: LayerNodeIdentifier, document_network: &NodeNetwork) -> Option<f32> {
pub fn get_opacity(layer: LayerNodeIdentifier, document_network: &NodeNetwork) -> Option<f64> {
let inputs = NodeGraphLayer::new(layer, document_network)?.find_node_inputs("Opacity")?;
let TaggedValue::F32(opacity) = inputs.get(1)?.as_value()? else {
let TaggedValue::F64(opacity) = inputs.get(1)?.as_value()? else {
return None;
};
Some(*opacity)
@ -165,7 +165,7 @@ pub fn get_text_id(layer: LayerNodeIdentifier, document_network: &NodeNetwork) -
}
/// Gets properties from the Text node
pub fn get_text(layer: LayerNodeIdentifier, document_network: &NodeNetwork) -> Option<(&String, &Font, f32)> {
pub fn get_text(layer: LayerNodeIdentifier, document_network: &NodeNetwork) -> Option<(&String, &Font, f64)> {
let inputs = NodeGraphLayer::new(layer, document_network)?.find_node_inputs("Text")?;
let NodeInput::Value {
tagged_value: TaggedValue::String(text),
@ -184,7 +184,7 @@ pub fn get_text(layer: LayerNodeIdentifier, document_network: &NodeNetwork) -> O
};
let NodeInput::Value {
tagged_value: TaggedValue::F32(font_size),
tagged_value: TaggedValue::F64(font_size),
..
} = inputs[3]
else {
@ -194,8 +194,8 @@ pub fn get_text(layer: LayerNodeIdentifier, document_network: &NodeNetwork) -> O
Some((text, font, font_size))
}
pub fn get_stroke_width(layer: LayerNodeIdentifier, network: &NodeNetwork) -> Option<f32> {
if let TaggedValue::F32(width) = NodeGraphLayer::new(layer, network)?.find_input("Stroke", 2)? {
pub fn get_stroke_width(layer: LayerNodeIdentifier, network: &NodeNetwork) -> Option<f64> {
if let TaggedValue::F64(width) = NodeGraphLayer::new(layer, network)?.find_input("Stroke", 2)? {
Some(*width)
} else {
None

View File

@ -209,7 +209,7 @@ enum TextToolFsmState {
pub struct EditingText {
text: String,
font: Font,
font_size: f32,
font_size: f64,
color: Option<Color>,
transform: DAffine2,
}
@ -406,7 +406,7 @@ impl Fsm for TextToolFsmState {
tool_data.editing_text = Some(EditingText {
text: String::new(),
transform: DAffine2::from_translation(input.mouse.position),
font_size: tool_options.font_size as f32,
font_size: tool_options.font_size as f64,
font: Font::new(tool_options.font_name.clone(), tool_options.font_style.clone()),
color: tool_options.fill.active_color(),
});

View File

@ -85,28 +85,28 @@ where
// Floor
pub struct FloorNode;
#[node_macro::node_fn(FloorNode)]
fn floor(input: f32) -> f32 {
fn floor(input: f64) -> f64 {
input.floor()
}
// Ceil
pub struct CeilingNode;
#[node_macro::node_fn(CeilingNode)]
fn ceil(input: f32) -> f32 {
fn ceil(input: f64) -> f64 {
input.ceil()
}
// Round
pub struct RoundNode;
#[node_macro::node_fn(RoundNode)]
fn round(input: f32) -> f32 {
fn round(input: f64) -> f64 {
input.round()
}
// Absolute Value
pub struct AbsoluteValue;
#[node_macro::node_fn(AbsoluteValue)]
fn abs(input: f32) -> f32 {
fn abs(input: f64) -> f64 {
input.abs()
}
@ -122,28 +122,28 @@ fn ln<U: num_traits::float::Float>(first: U, second: U) -> U {
// Natural Log
pub struct NaturalLogarithmNode;
#[node_macro::node_fn(NaturalLogarithmNode)]
fn ln(input: f32) -> f32 {
fn ln(input: f64) -> f64 {
input.ln()
}
// Sine
pub struct SineNode;
#[node_macro::node_fn(SineNode)]
fn ln(input: f32) -> f32 {
fn ln(input: f64) -> f64 {
input.sin()
}
// Cosine
pub struct CosineNode;
#[node_macro::node_fn(CosineNode)]
fn ln(input: f32) -> f32 {
fn ln(input: f64) -> f64 {
input.cos()
}
// Tangent
pub struct TangentNode;
#[node_macro::node_fn(TangentNode)]
fn ln(input: f32) -> f32 {
fn ln(input: f64) -> f64 {
input.tan()
}
@ -192,6 +192,15 @@ where
first % second
}
pub struct ConstructVector2<X, Y> {
x: X,
y: Y,
}
#[node_macro::node_fn(ConstructVector2)]
fn construct_vector2(_primary: (), x: f64, y: f64) -> glam::DVec2 {
glam::DVec2::new(x, y)
}
// Size Of
#[cfg(feature = "std")]
struct SizeOfNode;

View File

@ -297,17 +297,17 @@ pub struct LevelsNode<InputStart, InputMid, InputEnd, OutputStart, OutputEnd> {
// From https://stackoverflow.com/questions/39510072/algorithm-for-adjustment-of-image-levels
#[node_macro::node_fn(LevelsNode)]
fn levels_node(color: Color, input_start: f32, input_mid: f32, input_end: f32, output_start: f32, output_end: f32) -> Color {
fn levels_node(color: Color, input_start: f64, input_mid: f64, input_end: f64, output_start: f64, output_end: f64) -> Color {
let color = color.to_gamma_srgb();
// Input Range (Range: 0-1)
let input_shadows = input_start / 100.;
let input_midtones = input_mid / 100.;
let input_highlights = input_end / 100.;
let input_shadows = (input_start / 100.) as f32;
let input_midtones = (input_mid / 100.) as f32;
let input_highlights = (input_end / 100.) as f32;
// Output Range (Range: 0-1)
let output_minimums = output_start / 100.;
let output_maximums = output_end / 100.;
let output_minimums = (output_start / 100.) as f32;
let output_maximums = (output_end / 100.) as f32;
// Midtones interpolation factor between minimums and maximums (Range: 0-1)
let midtones = output_minimums + (output_maximums - output_minimums) * input_midtones;
@ -354,15 +354,15 @@ pub struct BlackAndWhiteNode<Tint, Reds, Yellows, Greens, Cyans, Blues, Magentas
// From <https://stackoverflow.com/a/55233732/775283>
// Works the same for gamma and linear color
#[node_macro::node_fn(BlackAndWhiteNode)]
fn black_and_white_color_node(color: Color, tint: Color, reds: f32, yellows: f32, greens: f32, cyans: f32, blues: f32, magentas: f32) -> Color {
fn black_and_white_color_node(color: Color, tint: Color, reds: f64, yellows: f64, greens: f64, cyans: f64, blues: f64, magentas: f64) -> Color {
let color = color.to_gamma_srgb();
let reds = reds / 100.;
let yellows = yellows / 100.;
let greens = greens / 100.;
let cyans = cyans / 100.;
let blues = blues / 100.;
let magentas = magentas / 100.;
let reds = reds as f32 / 100.;
let yellows = yellows as f32 / 100.;
let greens = greens as f32 / 100.;
let cyans = cyans as f32 / 100.;
let blues = blues as f32 / 100.;
let magentas = magentas as f32 / 100.;
let gray_base = color.r().min(color.g()).min(color.b());
@ -400,17 +400,17 @@ pub struct HueSaturationNode<Hue, Saturation, Lightness> {
}
#[node_macro::node_fn(HueSaturationNode)]
fn hue_shift_color_node(color: Color, hue_shift: f32, saturation_shift: f32, lightness_shift: f32) -> Color {
fn hue_shift_color_node(color: Color, hue_shift: f64, saturation_shift: f64, lightness_shift: f64) -> Color {
let color = color.to_gamma_srgb();
let [hue, saturation, lightness, alpha] = color.to_hsla();
let color = Color::from_hsla(
(hue + hue_shift / 360.) % 1.,
(hue + hue_shift as f32 / 360.) % 1.,
// TODO: Improve the way saturation works (it's slightly off)
(saturation + saturation_shift / 100.).clamp(0., 1.),
(saturation + saturation_shift as f32 / 100.).clamp(0., 1.),
// TODO: Fix the way lightness works (it's very off)
(lightness + lightness_shift / 100.).clamp(0., 1.),
(lightness + lightness_shift as f32 / 100.).clamp(0., 1.),
alpha,
);
@ -450,9 +450,9 @@ pub struct ThresholdNode<MinLuminance, MaxLuminance, LuminanceCalc> {
}
#[node_macro::node_fn(ThresholdNode)]
fn threshold_node(color: Color, min_luminance: f32, max_luminance: f32, luminance_calc: LuminanceCalculation) -> Color {
let min_luminance = Color::srgb_to_linear(min_luminance / 100.);
let max_luminance = Color::srgb_to_linear(max_luminance / 100.);
fn threshold_node(color: Color, min_luminance: f64, max_luminance: f64, luminance_calc: LuminanceCalculation) -> Color {
let min_luminance = Color::srgb_to_linear(min_luminance as f32 / 100.);
let max_luminance = Color::srgb_to_linear(max_luminance as f32 / 100.);
let luminance = match luminance_calc {
LuminanceCalculation::SRGB => color.luminance_srgb(),
@ -476,8 +476,8 @@ pub struct BlendNode<BlendMode, Opacity> {
}
#[node_macro::node_fn(BlendNode)]
fn blend_node(input: (Color, Color), blend_mode: BlendMode, opacity: f32) -> Color {
blend_colors(input.0, input.1, blend_mode, opacity / 100.)
fn blend_node(input: (Color, Color), blend_mode: BlendMode, opacity: f64) -> Color {
blend_colors(input.0, input.1, blend_mode, opacity as f32 / 100.)
}
pub fn apply_blend_mode(foreground: Color, background: Color, blend_mode: BlendMode) -> Color {
@ -540,8 +540,8 @@ pub struct VibranceNode<Vibrance> {
// Modified from https://stackoverflow.com/questions/33966121/what-is-the-algorithm-for-vibrance-filters
// The results of this implementation are very close to correct, but not quite perfect
#[node_macro::node_fn(VibranceNode)]
fn vibrance_node(color: Color, vibrance: f32) -> Color {
let vibrance = vibrance / 100.;
fn vibrance_node(color: Color, vibrance: f64) -> Color {
let vibrance = vibrance as f32 / 100.;
// Slow the effect down by half when it's negative, since artifacts begin appearing past -50%.
// So this scales the 0% to -50% range to 0% to -100%.
let slowed_vibrance = if vibrance >= 0. { vibrance } else { vibrance * 0.5 };
@ -811,37 +811,37 @@ pub struct ChannelMixerNode<Monochrome, MonochromeR, MonochromeG, MonochromeB, M
fn channel_mixer_node(
color: Color,
monochrome: bool,
monochrome_r: f32,
monochrome_g: f32,
monochrome_b: f32,
monochrome_c: f32,
red_r: f32,
red_g: f32,
red_b: f32,
red_c: f32,
green_r: f32,
green_g: f32,
green_b: f32,
green_c: f32,
blue_r: f32,
blue_g: f32,
blue_b: f32,
blue_c: f32,
monochrome_r: f64,
monochrome_g: f64,
monochrome_b: f64,
monochrome_c: f64,
red_r: f64,
red_g: f64,
red_b: f64,
red_c: f64,
green_r: f64,
green_g: f64,
green_b: f64,
green_c: f64,
blue_r: f64,
blue_g: f64,
blue_b: f64,
blue_c: f64,
) -> Color {
let color = color.to_gamma_srgb();
let (r, g, b, a) = color.components();
let color = if monochrome {
let (monochrome_r, monochrome_g, monochrome_b, monochrome_c) = (monochrome_r / 100., monochrome_g / 100., monochrome_b / 100., monochrome_c / 100.);
let (monochrome_r, monochrome_g, monochrome_b, monochrome_c) = (monochrome_r as f32 / 100., monochrome_g as f32 / 100., monochrome_b as f32 / 100., monochrome_c as f32 / 100.);
let gray = (r * monochrome_r + g * monochrome_g + b * monochrome_b + monochrome_c).clamp(0., 1.);
Color::from_rgbaf32_unchecked(gray, gray, gray, a)
} else {
let (red_r, red_g, red_b, red_c) = (red_r / 100., red_g / 100., red_b / 100., red_c / 100.);
let (green_r, green_g, green_b, green_c) = (green_r / 100., green_g / 100., green_b / 100., green_c / 100.);
let (blue_r, blue_g, blue_b, blue_c) = (blue_r / 100., blue_g / 100., blue_b / 100., blue_c / 100.);
let (red_r, red_g, red_b, red_c) = (red_r as f32 / 100., red_g as f32 / 100., red_b as f32 / 100., red_c as f32 / 100.);
let (green_r, green_g, green_b, green_c) = (green_r as f32 / 100., green_g as f32 / 100., green_b as f32 / 100., green_c as f32 / 100.);
let (blue_r, blue_g, blue_b, blue_c) = (blue_r as f32 / 100., blue_g as f32 / 100., blue_b as f32 / 100., blue_c as f32 / 100.);
let red = (r * red_r + g * red_g + b * red_b + red_c).clamp(0., 1.);
let green = (r * green_r + g * green_g + b * green_b + green_c).clamp(0., 1.);
@ -948,42 +948,42 @@ pub struct SelectiveColorNode<Absolute, RC, RM, RY, RK, YC, YM, YY, YK, GC, GM,
fn selective_color_node(
color: Color,
mode: RelativeAbsolute,
r_c: f32,
r_m: f32,
r_y: f32,
r_k: f32,
y_c: f32,
y_m: f32,
y_y: f32,
y_k: f32,
g_c: f32,
g_m: f32,
g_y: f32,
g_k: f32,
c_c: f32,
c_m: f32,
c_y: f32,
c_k: f32,
b_c: f32,
b_m: f32,
b_y: f32,
b_k: f32,
m_c: f32,
m_m: f32,
m_y: f32,
m_k: f32,
w_c: f32,
w_m: f32,
w_y: f32,
w_k: f32,
n_c: f32,
n_m: f32,
n_y: f32,
n_k: f32,
k_c: f32,
k_m: f32,
k_y: f32,
k_k: f32,
r_c: f64,
r_m: f64,
r_y: f64,
r_k: f64,
y_c: f64,
y_m: f64,
y_y: f64,
y_k: f64,
g_c: f64,
g_m: f64,
g_y: f64,
g_k: f64,
c_c: f64,
c_m: f64,
c_y: f64,
c_k: f64,
b_c: f64,
b_m: f64,
b_y: f64,
b_k: f64,
m_c: f64,
m_m: f64,
m_y: f64,
m_k: f64,
w_c: f64,
w_m: f64,
w_y: f64,
w_k: f64,
n_c: f64,
n_m: f64,
n_y: f64,
n_k: f64,
k_c: f64,
k_m: f64,
k_y: f64,
k_k: f64,
) -> Color {
let color = color.to_gamma_srgb();
@ -1018,15 +1018,15 @@ fn selective_color_node(
};
let (sum_r, sum_g, sum_b) = [
(SelectiveColorChoice::Reds, (r_c, r_m, r_y, r_k)),
(SelectiveColorChoice::Yellows, (y_c, y_m, y_y, y_k)),
(SelectiveColorChoice::Greens, (g_c, g_m, g_y, g_k)),
(SelectiveColorChoice::Cyans, (c_c, c_m, c_y, c_k)),
(SelectiveColorChoice::Blues, (b_c, b_m, b_y, b_k)),
(SelectiveColorChoice::Magentas, (m_c, m_m, m_y, m_k)),
(SelectiveColorChoice::Whites, (w_c, w_m, w_y, w_k)),
(SelectiveColorChoice::Neutrals, (n_c, n_m, n_y, n_k)),
(SelectiveColorChoice::Blacks, (k_c, k_m, k_y, k_k)),
(SelectiveColorChoice::Reds, (r_c as f32, r_m as f32, r_y as f32, r_k as f32)),
(SelectiveColorChoice::Yellows, (y_c as f32, y_m as f32, y_y as f32, y_k as f32)),
(SelectiveColorChoice::Greens, (g_c as f32, g_m as f32, g_y as f32, g_k as f32)),
(SelectiveColorChoice::Cyans, (c_c as f32, c_m as f32, c_y as f32, c_k as f32)),
(SelectiveColorChoice::Blues, (b_c as f32, b_m as f32, b_y as f32, b_k as f32)),
(SelectiveColorChoice::Magentas, (m_c as f32, m_m as f32, m_y as f32, m_k as f32)),
(SelectiveColorChoice::Whites, (w_c as f32, w_m as f32, w_y as f32, w_k as f32)),
(SelectiveColorChoice::Neutrals, (n_c as f32, n_m as f32, n_y as f32, n_k as f32)),
(SelectiveColorChoice::Blacks, (k_c as f32, k_m as f32, k_y as f32, k_k as f32)),
]
.into_iter()
.fold((0., 0., 0.), |acc, (color_parameter_group, (c, m, y, k))| {
@ -1065,21 +1065,21 @@ pub struct OpacityNode<O> {
}
#[node_macro::node_fn(OpacityNode)]
fn opacity_node(color: Color, opacity_multiplier: f32) -> Color {
let opacity_multiplier = opacity_multiplier / 100.;
fn opacity_node(color: Color, 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)
}
#[node_macro::node_impl(OpacityNode)]
fn opacity_node(mut vector_data: VectorData, opacity_multiplier: f32) -> VectorData {
let opacity_multiplier = opacity_multiplier / 100.;
fn opacity_node(mut vector_data: VectorData, opacity_multiplier: f64) -> VectorData {
let opacity_multiplier = opacity_multiplier as f32 / 100.;
vector_data.alpha_blending.opacity *= opacity_multiplier;
vector_data
}
#[node_macro::node_impl(OpacityNode)]
fn opacity_node(mut graphic_group: GraphicGroup, opacity_multiplier: f32) -> GraphicGroup {
let opacity_multiplier = opacity_multiplier / 100.;
fn opacity_node(mut graphic_group: GraphicGroup, opacity_multiplier: f64) -> GraphicGroup {
let opacity_multiplier = opacity_multiplier as f32 / 100.;
graphic_group.alpha_blending.opacity *= opacity_multiplier;
graphic_group
}
@ -1115,11 +1115,11 @@ pub struct PosterizeNode<P> {
// Based on http://www.axiomx.com/posterize.htm
// This algorithm produces fully accurate output in relation to the industry standard.
#[node_macro::node_fn(PosterizeNode)]
fn posterize(color: Color, posterize_value: f32) -> Color {
fn posterize(color: Color, posterize_value: f64) -> Color {
let color = color.to_gamma_srgb();
let number_of_areas = posterize_value.recip();
let size_of_areas = (posterize_value - 1.).recip();
let number_of_areas = posterize_value.recip() as f32;
let size_of_areas = (posterize_value - 1.).recip() as f32;
let channel = |channel: f32| (channel / number_of_areas).floor() * size_of_areas;
let color = color.map_rgb(channel);
@ -1135,14 +1135,14 @@ pub struct ExposureNode<Exposure, Offset, GammaCorrection> {
// Based on https://geraldbakker.nl/psnumbers/exposure.html
#[node_macro::node_fn(ExposureNode)]
fn exposure(color: Color, exposure: f32, offset: f32, gamma_correction: f32) -> Color {
fn exposure(color: Color, exposure: f64, offset: f64, gamma_correction: f64) -> Color {
let adjusted = color
// Exposure
.map_rgb(|c: f32| c * 2_f32.powf(exposure))
.map_rgb(|c: f32| c * 2_f32.powf(exposure as f32))
// Offset
.map_rgb(|c: f32| c + offset)
.map_rgb(|c: f32| c + offset as f32)
// Gamma correction
.gamma(gamma_correction);
.gamma(gamma_correction as f32);
adjusted.map_rgb(|c: f32| c.clamp(0., 1.))
}
@ -1224,8 +1224,8 @@ pub struct ColorOverlayNode<Color, BlendMode, Opacity> {
#[cfg(feature = "alloc")]
#[node_macro::node_fn(ColorOverlayNode)]
pub fn color_overlay_node(mut image: ImageFrame<Color>, color: Color, blend_mode: BlendMode, opacity: f32) -> ImageFrame<Color> {
let opacity = (opacity / 100.).clamp(0., 1.);
pub fn color_overlay_node(mut image: ImageFrame<Color>, color: Color, blend_mode: BlendMode, opacity: f64) -> ImageFrame<Color> {
let opacity = (opacity as f32 / 100.).clamp(0., 1.);
for pixel in &mut image.image.data {
let image = pixel.map_rgb(|channel| channel * (1. - opacity));
@ -1254,7 +1254,7 @@ fn color_overlay_multiply() {
let overlay_color = Color::GREEN;
// 100% of the output should come from the multiplied value
let opacity = 100_f32;
let opacity = 100_f64;
let result = ColorOverlayNode {
color: ClonedNode(overlay_color),

View File

@ -27,10 +27,10 @@ pub struct GenerateBrightnessContrastLegacyMapperNode<Brightness, Contrast> {
}
#[node_macro::node_fn(GenerateBrightnessContrastLegacyMapperNode)]
fn brightness_contrast_legacy_node(_primary: (), brightness: f32, contrast: f32) -> BrightnessContrastLegacyMapperNode {
let brightness = brightness / 255.;
fn brightness_contrast_legacy_node(_primary: (), brightness: f64, contrast: f64) -> BrightnessContrastLegacyMapperNode {
let brightness = brightness as f32 / 255.;
let contrast = contrast / 100.;
let contrast = contrast as f32 / 100.;
let contrast = if contrast > 0. { (contrast * core::f32::consts::FRAC_PI_2 - 0.01).tan() } else { contrast };
let combined = brightness * contrast + brightness - contrast / 2.;
@ -68,10 +68,10 @@ pub struct GenerateBrightnessContrastMapperNode<Brightness, Contrast> {
// TODO: Replace this node implementation with one that reuses the more generalized Curves adjustment node.
// TODO: It will be necessary to ensure the tests below are faithfully translated in a way that ensures identical results.
#[node_macro::node_fn(GenerateBrightnessContrastMapperNode)]
fn brightness_contrast_node(_primary: (), brightness: f32, contrast: f32) -> BrightnessContrastMapperNode {
fn brightness_contrast_node(_primary: (), brightness: f64, contrast: f64) -> BrightnessContrastMapperNode {
// Brightness LUT
let brightness_is_negative = brightness < 0.;
let brightness = brightness.abs() / 100.;
let brightness = brightness.abs() as f32 / 100.;
let brightness_curve_points = CubicSplines {
x: [0., 130. - brightness * 26., 233. - brightness * 48., 255.].map(|x| x / 255.),
y: [0., 130. + brightness * 51., 233. + brightness * 10., 255.].map(|x| x / 255.),
@ -93,7 +93,7 @@ fn brightness_contrast_node(_primary: (), brightness: f32, contrast: f32) -> Bri
}
// Contrast LUT
let contrast = contrast / 100.;
let contrast = contrast as f32 / 100.;
let contrast_curve_points = CubicSplines {
x: [0., 64., 192., 255.].map(|x| x / 255.),
y: [0., 64. - contrast * 30., 192. + contrast * 30., 255.].map(|x| x / 255.),

View File

@ -15,7 +15,7 @@ pub struct TextGeneratorNode<Text, FontName, Size> {
}
#[node_fn(TextGeneratorNode)]
fn generate_text<'a: 'input, T>(editor: EditorApi<'a, T>, text: String, font_name: Font, font_size: f32) -> crate::vector::VectorData {
fn generate_text<'a: 'input, T>(editor: EditorApi<'a, T>, text: String, font_name: Font, font_size: f64) -> crate::vector::VectorData {
let buzz_face = editor.font_cache.get(&font_name).map(|data| load_face(data));
crate::vector::VectorData::from_subpaths(to_path(&text, buzz_face, font_size as f64, None))
}

View File

@ -236,7 +236,7 @@ pub(crate) async fn transform_vector_data<Fut: Future>(
mut footprint: Footprint,
transform_target: impl Node<Footprint, Output = Fut>,
translate: DVec2,
rotate: f32,
rotate: f64,
scale: DVec2,
shear: DVec2,
pivot: DVec2,
@ -245,7 +245,7 @@ where
Fut::Output: TransformMut,
{
// TODO: This is hack and might break for Vector data because the pivot may be incorrect
let transform = DAffine2::from_scale_angle_translation(scale, rotate as f64, translate) * DAffine2::from_cols_array(&[1., shear.y, shear.x, 1., 0., 0.]);
let transform = DAffine2::from_scale_angle_translation(scale, rotate, translate) * DAffine2::from_cols_array(&[1., shear.y, shear.x, 1., 0., 0.]);
if !footprint.ignore_modifications {
let pivot_transform = DAffine2::from_translation(pivot);
let modification = pivot_transform * transform * pivot_transform.inverse();

View File

@ -12,7 +12,7 @@ pub struct CircleGenerator<Radius> {
}
#[node_macro::node_fn(CircleGenerator)]
fn circle_generator(_input: (), radius: f32) -> VectorData {
fn circle_generator(_input: (), radius: f64) -> VectorData {
let radius: f64 = radius.into();
super::VectorData::from_subpath(Subpath::new_ellipse(DVec2::splat(-radius), DVec2::splat(radius)))
}
@ -24,7 +24,7 @@ pub struct EllipseGenerator<RadiusX, RadiusY> {
}
#[node_macro::node_fn(EllipseGenerator)]
fn ellipse_generator(_input: (), radius_x: f32, radius_y: f32) -> VectorData {
fn ellipse_generator(_input: (), radius_x: f64, radius_y: f64) -> VectorData {
let radius = DVec2::new(radius_x as f64, radius_y as f64);
let corner1 = -radius;
let corner2 = radius;
@ -38,7 +38,7 @@ pub struct RectangleGenerator<SizeX, SizeY> {
}
#[node_macro::node_fn(RectangleGenerator)]
fn square_generator(_input: (), size_x: f32, size_y: f32) -> VectorData {
fn square_generator(_input: (), size_x: f64, size_y: f64) -> VectorData {
let size = DVec2::new(size_x as f64, size_y as f64);
let corner1 = -size / 2.;
let corner2 = size / 2.;
@ -53,7 +53,7 @@ pub struct RegularPolygonGenerator<Points, Radius> {
}
#[node_macro::node_fn(RegularPolygonGenerator)]
fn regular_polygon_generator(_input: (), points: u32, radius: f32) -> VectorData {
fn regular_polygon_generator(_input: (), points: u32, radius: f64) -> VectorData {
let points = points.into();
let radius: f64 = (radius * 2.).into();
super::VectorData::from_subpath(Subpath::new_regular_polygon(DVec2::splat(-radius), points, radius))
@ -67,7 +67,7 @@ pub struct StarGenerator<Points, Radius, InnerRadius> {
}
#[node_macro::node_fn(StarGenerator)]
fn star_generator(_input: (), points: u32, radius: f32, inner_radius: f32) -> VectorData {
fn star_generator(_input: (), points: u32, radius: f64, inner_radius: f64) -> VectorData {
let points = points.into();
let diameter: f64 = (radius * 2.).into();
let inner_diameter = (inner_radius * 2.).into();

View File

@ -307,7 +307,7 @@ pub struct Stroke {
pub color: Option<Color>,
/// Line thickness
pub weight: f64,
pub dash_lengths: Vec<f32>,
pub dash_lengths: Vec<f64>,
pub dash_offset: f64,
pub line_cap: LineCap,
pub line_join: LineJoin,
@ -344,7 +344,7 @@ impl Stroke {
Self {
color: self.color.map(|color| color.lerp(&other.color.unwrap_or(color), time as f32)),
weight: self.weight + (other.weight - self.weight) * time,
dash_lengths: self.dash_lengths.iter().zip(other.dash_lengths.iter()).map(|(a, b)| a + (b - a) * time as f32).collect(),
dash_lengths: self.dash_lengths.iter().zip(other.dash_lengths.iter()).map(|(a, b)| a + (b - a) * time).collect(),
dash_offset: self.dash_offset + (other.dash_offset - self.dash_offset) * time,
line_cap: if time < 0.5 { self.line_cap } else { other.line_cap },
line_join: if time < 0.5 { self.line_join } else { other.line_join },
@ -420,7 +420,7 @@ impl Stroke {
dash_lengths
.split(&[',', ' '])
.filter(|x| !x.is_empty())
.map(str::parse::<f32>)
.map(str::parse::<f64>)
.collect::<Result<Vec<_>, _>>()
.ok()
.map(|lengths| {

View File

@ -59,21 +59,21 @@ pub struct SetStrokeNode<Color, Weight, DashLengths, DashOffset, LineCap, LineJo
fn set_vector_data_stroke(
mut vector_data: VectorData,
color: Option<Color>,
weight: f32,
dash_lengths: Vec<f32>,
dash_offset: f32,
weight: f64,
dash_lengths: Vec<f64>,
dash_offset: f64,
line_cap: super::style::LineCap,
line_join: super::style::LineJoin,
miter_limit: f32,
miter_limit: f64,
) -> VectorData {
vector_data.style.set_stroke(Stroke {
color,
weight: weight as f64,
weight,
dash_lengths,
dash_offset: dash_offset as f64,
dash_offset,
line_cap,
line_join,
line_join_miter_limit: miter_limit as f64,
line_join_miter_limit: miter_limit,
});
vector_data
}
@ -112,16 +112,16 @@ pub struct CircularRepeatNode<AngleOffset, Radius, Count> {
}
#[node_macro::node_fn(CircularRepeatNode)]
fn circular_repeat_vector_data(mut vector_data: VectorData, angle_offset: f32, radius: f32, count: u32) -> VectorData {
fn circular_repeat_vector_data(mut vector_data: VectorData, angle_offset: f64, radius: f64, count: u32) -> VectorData {
let mut new_subpaths: Vec<Subpath<_>> = Vec::with_capacity(vector_data.subpaths.len() * count as usize);
let Some(bounding_box) = vector_data.bounding_box() else { return vector_data };
let center = (bounding_box[0] + bounding_box[1]) / 2.;
let base_transform = DVec2::new(0., radius as f64) - center;
let base_transform = DVec2::new(0., radius) - center;
for i in 0..count {
let angle = (2. * std::f64::consts::PI / count as f64) * i as f64 + angle_offset.to_radians() as f64;
let angle = (2. * std::f64::consts::PI / count as f64) * i as f64 + angle_offset.to_radians();
let rotation = DAffine2::from_angle(angle);
let transform = DAffine2::from_translation(center) * rotation * DAffine2::from_translation(base_transform);
for mut subpath in vector_data.subpaths.clone() {
@ -189,18 +189,14 @@ async fn copy_to_points<I: GraphicElementRendered + Default + ConcatElement + Tr
footprint: Footprint,
points: impl Node<Footprint, Output = FP>,
instance: impl Node<Footprint, Output = FI>,
random_scale_min: f32,
random_scale_max: f32,
random_scale_bias: f32,
random_rotation: f32,
random_scale_min: f64,
random_scale_max: f64,
random_scale_bias: f64,
random_rotation: f64,
) -> I {
let points = self.points.eval(footprint).await;
let instance = self.instance.eval(footprint).await;
let random_scale_min = random_scale_min as f64;
let random_scale_max = random_scale_max as f64;
let random_scale_difference = random_scale_max - random_scale_min;
let random_scale_bias = random_scale_bias as f64;
let random_rotation = random_rotation as f64;
let points_list = points.subpaths.iter().flat_map(|s| s.anchors());
@ -260,17 +256,14 @@ pub struct SamplePoints<VectorData, Spacing, StartOffset, StopOffset, AdaptiveSp
async fn sample_points<FV: Future<Output = VectorData>, FL: Future<Output = Vec<Vec<f64>>>>(
footprint: Footprint,
mut vector_data: impl Node<Footprint, Output = FV>,
spacing: f32,
start_offset: f32,
stop_offset: f32,
spacing: f64,
start_offset: f64,
stop_offset: f64,
adaptive_spacing: bool,
lengths_of_segments_of_subpaths: impl Node<Footprint, Output = FL>,
) -> VectorData {
let mut vector_data = self.vector_data.eval(footprint).await;
let lengths_of_segments_of_subpaths = self.lengths_of_segments_of_subpaths.eval(footprint).await;
let spacing = spacing as f64;
let start_offset = start_offset as f64;
let stop_offset = stop_offset as f64;
for (index, subpath) in &mut vector_data.subpaths.iter_mut().enumerate() {
if subpath.is_empty() || !spacing.is_finite() || spacing <= 0. {
@ -326,7 +319,7 @@ pub struct PoissonDiskPoints<SeparationDiskDiameter> {
}
#[node_macro::node_fn(PoissonDiskPoints)]
fn poisson_disk_points(mut vector_data: VectorData, separation_disk_diameter: f32) -> VectorData {
fn poisson_disk_points(mut vector_data: VectorData, separation_disk_diameter: f64) -> VectorData {
let mut rng = rand::rngs::StdRng::seed_from_u64(0);
for subpath in &mut vector_data.subpaths.iter_mut() {
if subpath.manipulator_groups().len() < 3 {
@ -335,7 +328,7 @@ fn poisson_disk_points(mut vector_data: VectorData, separation_disk_diameter: f3
subpath.apply_transform(vector_data.transform);
let points = subpath.poisson_disk_points(separation_disk_diameter as f64, || rng.gen::<f64>()).into_iter().map(|point| point.into());
let points = subpath.poisson_disk_points(separation_disk_diameter, || rng.gen::<f64>()).into_iter().map(|point| point.into());
*subpath = Subpath::from_anchors(points, false);
subpath.apply_transform(vector_data.transform.inverse());
@ -391,10 +384,8 @@ async fn morph<SourceFuture: Future<Output = VectorData>, TargetFuture: Future<O
source: impl Node<Footprint, Output = SourceFuture>,
target: impl Node<Footprint, Output = TargetFuture>,
start_index: u32,
time: f32,
time: f64,
) -> VectorData {
let time = time as f64;
let mut source = self.source.eval(footprint).await;
let mut target = self.target.eval(footprint).await;

View File

@ -42,7 +42,7 @@ pub enum TaggedValue {
VectorData(graphene_core::vector::VectorData),
Fill(graphene_core::vector::style::Fill),
Stroke(graphene_core::vector::style::Stroke),
VecF32(Vec<f32>),
VecF64(Vec<f64>),
VecDVec2(Vec<DVec2>),
RedGreenBlue(graphene_core::raster::RedGreenBlue),
NoiseType(graphene_core::raster::NoiseType),
@ -109,7 +109,7 @@ impl Hash for TaggedValue {
Self::VectorData(x) => x.hash(state),
Self::Fill(x) => x.hash(state),
Self::Stroke(x) => x.hash(state),
Self::VecF32(x) => x.iter().for_each(|val| val.to_bits().hash(state)),
Self::VecF64(x) => x.iter().for_each(|val| val.to_bits().hash(state)),
Self::VecDVec2(x) => x.iter().for_each(|val| val.to_array().iter().for_each(|x| x.to_bits().hash(state))),
Self::RedGreenBlue(x) => x.hash(state),
Self::NoiseType(x) => x.hash(state),
@ -183,7 +183,7 @@ impl<'a> TaggedValue {
TaggedValue::VectorData(x) => Box::new(x),
TaggedValue::Fill(x) => Box::new(x),
TaggedValue::Stroke(x) => Box::new(x),
TaggedValue::VecF32(x) => Box::new(x),
TaggedValue::VecF64(x) => Box::new(x),
TaggedValue::VecDVec2(x) => Box::new(x),
TaggedValue::RedGreenBlue(x) => Box::new(x),
TaggedValue::NoiseType(x) => Box::new(x),
@ -259,7 +259,7 @@ impl<'a> TaggedValue {
TaggedValue::VectorData(_) => concrete!(graphene_core::vector::VectorData),
TaggedValue::Fill(_) => concrete!(graphene_core::vector::style::Fill),
TaggedValue::Stroke(_) => concrete!(graphene_core::vector::style::Stroke),
TaggedValue::VecF32(_) => concrete!(Vec<f32>),
TaggedValue::VecF64(_) => concrete!(Vec<f64>),
TaggedValue::VecDVec2(_) => concrete!(Vec<DVec2>),
TaggedValue::RedGreenBlue(_) => concrete!(graphene_core::raster::RedGreenBlue),
TaggedValue::NoiseType(_) => concrete!(graphene_core::raster::NoiseType),
@ -323,7 +323,7 @@ impl<'a> TaggedValue {
x if x == TypeId::of::<graphene_core::vector::VectorData>() => Ok(TaggedValue::VectorData(*downcast(input).unwrap())),
x if x == TypeId::of::<graphene_core::vector::style::Fill>() => Ok(TaggedValue::Fill(*downcast(input).unwrap())),
x if x == TypeId::of::<graphene_core::vector::style::Stroke>() => Ok(TaggedValue::Stroke(*downcast(input).unwrap())),
x if x == TypeId::of::<Vec<f32>>() => Ok(TaggedValue::VecF32(*downcast(input).unwrap())),
x if x == TypeId::of::<Vec<f64>>() => Ok(TaggedValue::VecF64(*downcast(input).unwrap())),
x if x == TypeId::of::<Vec<DVec2>>() => Ok(TaggedValue::VecDVec2(*downcast(input).unwrap())),
x if x == TypeId::of::<graphene_core::raster::RedGreenBlue>() => Ok(TaggedValue::RedGreenBlue(*downcast(input).unwrap())),
x if x == TypeId::of::<graphene_core::raster::NoiseType>() => Ok(TaggedValue::NoiseType(*downcast(input).unwrap())),

View File

@ -269,13 +269,13 @@ pub async fn imaginate<'a, P: Pixel>(
res: impl Future<Output = Option<DVec2>>,
samples: impl Future<Output = u32>,
sampling_method: impl Future<Output = ImaginateSamplingMethod>,
prompt_guidance: impl Future<Output = f32>,
prompt_guidance: impl Future<Output = f64>,
prompt: impl Future<Output = String>,
negative_prompt: impl Future<Output = String>,
adapt_input_image: impl Future<Output = bool>,
image_creativity: impl Future<Output = f32>,
image_creativity: impl Future<Output = f64>,
inpaint: impl Future<Output = bool>,
mask_blur: impl Future<Output = f32>,
mask_blur: impl Future<Output = f64>,
mask_starting_fill: impl Future<Output = ImaginateMaskStartingFill>,
improve_faces: impl Future<Output = bool>,
tiling: impl Future<Output = bool>,
@ -336,13 +336,13 @@ async fn imaginate_maybe_fail<'a, P: Pixel, F: Fn(ImaginateStatus)>(
res: impl Future<Output = Option<DVec2>>,
samples: impl Future<Output = u32>,
sampling_method: impl Future<Output = ImaginateSamplingMethod>,
prompt_guidance: impl Future<Output = f32>,
prompt_guidance: impl Future<Output = f64>,
prompt: impl Future<Output = String>,
negative_prompt: impl Future<Output = String>,
adapt_input_image: impl Future<Output = bool>,
image_creativity: impl Future<Output = f32>,
image_creativity: impl Future<Output = f64>,
_inpaint: impl Future<Output = bool>,
_mask_blur: impl Future<Output = f32>,
_mask_blur: impl Future<Output = f64>,
_mask_starting_fill: impl Future<Output = ImaginateMaskStartingFill>,
improve_faces: impl Future<Output = bool>,
tiling: impl Future<Output = bool>,

View File

@ -529,13 +529,13 @@ generate_imaginate_node! {
res: Res: Option<DVec2>,
samples: Samples: u32,
sampling_method: SamplingMethod: ImaginateSamplingMethod,
prompt_guidance: PromptGuidance: f32,
prompt_guidance: PromptGuidance: f64,
prompt: Prompt: String,
negative_prompt: NegativePrompt: String,
adapt_input_image: AdaptInputImage: bool,
image_creativity: ImageCreativity: f32,
image_creativity: ImageCreativity: f64,
inpaint: Inpaint: bool,
mask_blur: MaskBlur: f32,
mask_blur: MaskBlur: f64,
mask_starting_fill: MaskStartingFill: ImaginateMaskStartingFill,
improve_faces: ImproveFaces: bool,
tiling: Tiling: bool,
@ -596,25 +596,25 @@ fn noise_pattern(
_no_primary_input: (),
dimensions: UVec2,
seed: u32,
scale: f32,
scale: f64,
noise_type: NoiseType,
domain_warp_type: DomainWarpType,
domain_warp_amplitude: f32,
domain_warp_amplitude: f64,
fractal_type: FractalType,
fractal_octaves: u32,
fractal_lacunarity: f32,
fractal_gain: f32,
fractal_weighted_strength: f32,
fractal_ping_pong_strength: f32,
fractal_lacunarity: f64,
fractal_gain: f64,
fractal_weighted_strength: f64,
fractal_ping_pong_strength: f64,
cellular_distance_function: CellularDistanceFunction,
cellular_return_type: CellularReturnType,
cellular_jitter: f32,
cellular_jitter: f64,
) -> graphene_core::raster::ImageFrame<Color> {
// All
let [width, height] = dimensions.to_array();
let mut image = Image::new(width, height, Color::from_luminance(0.5));
let mut noise = fastnoise_lite::FastNoiseLite::with_seed(seed as i32);
noise.set_frequency(Some(scale / 1000.));
noise.set_frequency(Some(scale as f32 / 1000.));
// Domain Warp
let domain_warp_type = match domain_warp_type {
@ -625,7 +625,7 @@ fn noise_pattern(
};
let domain_warp_active = domain_warp_type.is_some();
noise.set_domain_warp_type(domain_warp_type);
noise.set_domain_warp_amp(Some(domain_warp_amplitude));
noise.set_domain_warp_amp(Some(domain_warp_amplitude as f32));
// Fractal
let noise_type = match noise_type {
@ -664,10 +664,10 @@ fn noise_pattern(
};
noise.set_fractal_type(Some(fractal_type));
noise.set_fractal_octaves(Some(fractal_octaves as i32));
noise.set_fractal_lacunarity(Some(fractal_lacunarity));
noise.set_fractal_gain(Some(fractal_gain));
noise.set_fractal_weighted_strength(Some(fractal_weighted_strength));
noise.set_fractal_ping_pong_strength(Some(fractal_ping_pong_strength));
noise.set_fractal_lacunarity(Some(fractal_lacunarity as f32));
noise.set_fractal_gain(Some(fractal_gain as f32));
noise.set_fractal_weighted_strength(Some(fractal_weighted_strength as f32));
noise.set_fractal_ping_pong_strength(Some(fractal_ping_pong_strength as f32));
// Cellular
let cellular_distance_function = match cellular_distance_function {
@ -687,7 +687,7 @@ fn noise_pattern(
};
noise.set_cellular_distance_function(Some(cellular_distance_function));
noise.set_cellular_return_type(Some(cellular_return_type));
noise.set_cellular_jitter(Some(cellular_jitter));
noise.set_cellular_jitter(Some(cellular_jitter as f32));
// Calculate the noise for every pixel
for y in 0..height {

View File

@ -203,6 +203,8 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
register_node!(graphene_core::ops::AddNode<_>, input: &f32, params: [f32]),
register_node!(graphene_core::ops::AddNode<_>, input: f32, params: [&f32]),
register_node!(graphene_core::ops::AddNode<_>, input: &f32, params: [&f32]),
register_node!(graphene_core::ops::AddNode<_>, input: f64, params: [f64]),
register_node!(graphene_core::ops::AddNode<_>, input: glam::DVec2, params: [glam::DVec2]),
register_node!(graphene_core::ops::SubtractNode<_>, input: u32, params: [u32]),
register_node!(graphene_core::ops::SubtractNode<_>, input: &u32, params: [u32]),
register_node!(graphene_core::ops::SubtractNode<_>, input: u32, params: [&u32]),
@ -211,6 +213,8 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
register_node!(graphene_core::ops::SubtractNode<_>, input: &f32, params: [f32]),
register_node!(graphene_core::ops::SubtractNode<_>, input: f32, params: [&f32]),
register_node!(graphene_core::ops::SubtractNode<_>, input: &f32, params: [&f32]),
register_node!(graphene_core::ops::SubtractNode<_>, input: f64, params: [f64]),
register_node!(graphene_core::ops::SubtractNode<_>, input: glam::DVec2, params: [glam::DVec2]),
register_node!(graphene_core::ops::DivideNode<_>, input: u32, params: [u32]),
register_node!(graphene_core::ops::DivideNode<_>, input: &u32, params: [u32]),
register_node!(graphene_core::ops::DivideNode<_>, input: u32, params: [&u32]),
@ -219,6 +223,9 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
register_node!(graphene_core::ops::DivideNode<_>, input: &f32, params: [f32]),
register_node!(graphene_core::ops::DivideNode<_>, input: f32, params: [&f32]),
register_node!(graphene_core::ops::DivideNode<_>, input: &f32, params: [&f32]),
register_node!(graphene_core::ops::DivideNode<_>, input: f64, params: [f64]),
register_node!(graphene_core::ops::DivideNode<_>, input: glam::DVec2, params: [f64]),
register_node!(graphene_core::ops::DivideNode<_>, input: glam::DVec2, params: [glam::DVec2]),
register_node!(graphene_core::ops::MultiplyNode<_>, input: u32, params: [u32]),
register_node!(graphene_core::ops::MultiplyNode<_>, input: &u32, params: [u32]),
register_node!(graphene_core::ops::MultiplyNode<_>, input: u32, params: [&u32]),
@ -227,6 +234,9 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
register_node!(graphene_core::ops::MultiplyNode<_>, input: &f32, params: [f32]),
register_node!(graphene_core::ops::MultiplyNode<_>, input: f32, params: [&f32]),
register_node!(graphene_core::ops::MultiplyNode<_>, input: &f32, params: [&f32]),
register_node!(graphene_core::ops::MultiplyNode<_>, input: f64, params: [f64]),
register_node!(graphene_core::ops::MultiplyNode<_>, input: glam::DVec2, params: [f64]),
register_node!(graphene_core::ops::MultiplyNode<_>, input: glam::DVec2, params: [glam::DVec2]),
register_node!(graphene_core::ops::ExponentNode<_>, input: u32, params: [u32]),
register_node!(graphene_core::ops::ExponentNode<_>, input: &u32, params: [u32]),
register_node!(graphene_core::ops::ExponentNode<_>, input: u32, params: [&u32]),
@ -234,32 +244,34 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
register_node!(graphene_core::ops::ExponentNode<_>, input: f32, params: [f32]),
register_node!(graphene_core::ops::ExponentNode<_>, input: &f32, params: [f32]),
register_node!(graphene_core::ops::ExponentNode<_>, input: f32, params: [&f32]),
register_node!(graphene_core::ops::FloorNode, input: f32, params: []),
register_node!(graphene_core::ops::CeilingNode, input: f32, params: []),
register_node!(graphene_core::ops::RoundNode, input: f32, params: []),
register_node!(graphene_core::ops::AbsoluteValue, input: f32, params: []),
register_node!(graphene_core::ops::LogarithmNode<_>, input: f32, params: [f32]),
register_node!(graphene_core::ops::NaturalLogarithmNode, input: f32, params: []),
register_node!(graphene_core::ops::SineNode, input: f32, params: []),
register_node!(graphene_core::ops::CosineNode, input: f32, params: []),
register_node!(graphene_core::ops::TangentNode, input: f32, params: []),
register_node!(graphene_core::ops::ExponentNode<_>, input: f64, params: [f64]),
register_node!(graphene_core::ops::FloorNode, input: f64, params: []),
register_node!(graphene_core::ops::CeilingNode, input: f64, params: []),
register_node!(graphene_core::ops::RoundNode, input: f64, params: []),
register_node!(graphene_core::ops::AbsoluteValue, input: f64, params: []),
register_node!(graphene_core::ops::LogarithmNode<_>, input: f64, params: [f64]),
register_node!(graphene_core::ops::NaturalLogarithmNode, input: f64, params: []),
register_node!(graphene_core::ops::SineNode, input: f64, params: []),
register_node!(graphene_core::ops::CosineNode, input: f64, params: []),
register_node!(graphene_core::ops::TangentNode, input: f64, params: []),
register_node!(graphene_core::ops::MaximumNode<_>, input: u32, params: [u32]),
register_node!(graphene_core::ops::MaximumNode<_>, input: f32, params: [f32]),
register_node!(graphene_core::ops::MaximumNode<_>, input: f64, params: [f64]),
register_node!(graphene_core::ops::MinimumNode<_>, input: u32, params: [u32]),
register_node!(graphene_core::ops::MinimumNode<_>, input: f32, params: [f32]),
register_node!(graphene_core::ops::MinimumNode<_>, input: f64, params: [f64]),
register_node!(graphene_core::ops::EqualsNode<_>, input: u32, params: [u32]),
register_node!(graphene_core::ops::EqualsNode<_>, input: f32, params: [f32]),
register_node!(graphene_core::ops::EqualsNode<_>, input: f64, params: [f64]),
register_node!(graphene_core::ops::ModuloNode<_>, input: u32, params: [u32]),
register_node!(graphene_core::ops::ModuloNode<_>, input: &u32, params: [u32]),
register_node!(graphene_core::ops::ModuloNode<_>, input: u32, params: [&u32]),
register_node!(graphene_core::ops::ModuloNode<_>, input: &u32, params: [&u32]),
register_node!(graphene_core::ops::ModuloNode<_>, input: f32, params: [f32]),
register_node!(graphene_core::ops::ModuloNode<_>, input: &f32, params: [f32]),
register_node!(graphene_core::ops::ModuloNode<_>, input: f32, params: [&f32]),
register_node!(graphene_core::ops::ModuloNode<_>, input: &f32, params: [&f32]),
register_node!(graphene_core::ops::ModuloNode<_>, input: f64, params: [f64]),
register_node!(graphene_core::ops::ModuloNode<_>, input: &f64, params: [f64]),
register_node!(graphene_core::ops::ModuloNode<_>, input: f64, params: [&f64]),
register_node!(graphene_core::ops::ModuloNode<_>, input: &f64, params: [&f64]),
register_node!(graphene_core::ops::ConstructVector2<_, _>, input: (), params: [f64, f64]),
register_node!(graphene_core::ops::SomeNode, input: WasmEditorApi, params: []),
register_node!(graphene_core::logic::LogToConsoleNode, input: bool, params: []),
register_node!(graphene_core::logic::LogToConsoleNode, input: f32, params: []),
register_node!(graphene_core::logic::LogToConsoleNode, input: f64, params: []),
register_node!(graphene_core::logic::LogToConsoleNode, input: f64, params: []),
register_node!(graphene_core::logic::LogToConsoleNode, input: u32, params: []),
register_node!(graphene_core::logic::LogToConsoleNode, input: u64, params: []),
@ -442,12 +454,12 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
raster_node!(graphene_core::raster::ExtractChannelNode<_>, params: [RedGreenBlue]),
raster_node!(graphene_core::raster::ExtractAlphaNode<>, params: []),
raster_node!(graphene_core::raster::ExtractOpaqueNode<>, params: []),
raster_node!(graphene_core::raster::LevelsNode<_, _, _, _, _>, params: [f32, f32, f32, f32, f32]),
raster_node!(graphene_core::raster::LevelsNode<_, _, _, _, _>, params: [f64, f64, f64, f64, f64]),
register_node!(graphene_std::image_segmentation::ImageSegmentationNode<_>, input: ImageFrame<Color>, params: [ImageFrame<Color>]),
register_node!(graphene_std::image_color_palette::ImageColorPaletteNode<_>, input: ImageFrame<Color>, params: [u32]),
register_node!(graphene_core::raster::IndexNode<_>, input: Vec<ImageFrame<Color>>, params: [u32]),
register_node!(graphene_core::raster::adjustments::ColorFillNode<_>, input: ImageFrame<Color>, params: [Color]),
register_node!(graphene_core::raster::adjustments::ColorOverlayNode<_, _, _>, input: ImageFrame<Color>, params: [Color, BlendMode, f32]),
register_node!(graphene_core::raster::adjustments::ColorOverlayNode<_, _, _>, input: ImageFrame<Color>, params: [Color, BlendMode, f64]),
register_node!(graphene_core::raster::IndexNode<_>, input: Vec<Color>, params: [u32]),
vec![(
ProtoNodeIdentifier::new("graphene_core::raster::BlendNode<_, _, _, _>"),
@ -455,7 +467,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
Box::pin(async move {
let image: DowncastBothNode<(), ImageFrame<Color>> = DowncastBothNode::new(args[0].clone());
let blend_mode: DowncastBothNode<(), BlendMode> = DowncastBothNode::new(args[1].clone());
let opacity: DowncastBothNode<(), f32> = DowncastBothNode::new(args[2].clone());
let opacity: DowncastBothNode<(), f64> = DowncastBothNode::new(args[2].clone());
let blend_node = graphene_core::raster::BlendNode::new(CopiedNode::new(blend_mode.eval(()).await), CopiedNode::new(opacity.eval(()).await));
let node = graphene_std::raster::BlendImageNode::new(image, blend_node);
let any: DynAnyNode<ImageFrame<Color>, _, _> = graphene_std::any::DynAnyNode::new(node);
@ -465,21 +477,21 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
NodeIOTypes::new(
concrete!(ImageFrame<Color>),
concrete!(ImageFrame<Color>),
vec![fn_type!(ImageFrame<Color>), fn_type!(BlendMode), fn_type!(f32)],
vec![fn_type!(ImageFrame<Color>), fn_type!(BlendMode), fn_type!(f64)],
),
)],
raster_node!(graphene_core::raster::BlackAndWhiteNode<_, _, _, _, _, _, _>, params: [Color, f32, f32, f32, f32, f32, f32]),
raster_node!(graphene_core::raster::HueSaturationNode<_, _, _>, params: [f32, f32, f32]),
raster_node!(graphene_core::raster::BlackAndWhiteNode<_, _, _, _, _, _, _>, params: [Color, f64, f64, f64, f64, f64, f64]),
raster_node!(graphene_core::raster::HueSaturationNode<_, _, _>, params: [f64, f64, f64]),
raster_node!(graphene_core::raster::InvertRGBNode, params: []),
raster_node!(graphene_core::raster::ThresholdNode<_, _, _>, params: [f32, f32, LuminanceCalculation]),
raster_node!(graphene_core::raster::VibranceNode<_>, params: [f32]),
raster_node!(graphene_core::raster::ThresholdNode<_, _, _>, params: [f64, f64, LuminanceCalculation]),
raster_node!(graphene_core::raster::VibranceNode<_>, params: [f64]),
raster_node!(
graphene_core::raster::ChannelMixerNode<_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _>,
params: [bool, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32]
params: [bool, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64]
),
raster_node!(
graphene_core::raster::SelectiveColorNode<_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _>,
params: [RelativeAbsolute, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32]
params: [RelativeAbsolute, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64]
),
vec![(
ProtoNodeIdentifier::new("graphene_core::raster::BrightnessContrastNode<_, _, _>"),
@ -487,9 +499,9 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
Box::pin(async move {
use graphene_core::raster::brightness_contrast::*;
let brightness: DowncastBothNode<(), f32> = DowncastBothNode::new(args[0].clone());
let brightness: DowncastBothNode<(), f64> = DowncastBothNode::new(args[0].clone());
let brightness = ClonedNode::new(brightness.eval(()).await);
let contrast: DowncastBothNode<(), f32> = DowncastBothNode::new(args[1].clone());
let contrast: DowncastBothNode<(), f64> = DowncastBothNode::new(args[1].clone());
let contrast = ClonedNode::new(contrast.eval(()).await);
let use_legacy: DowncastBothNode<(), bool> = DowncastBothNode::new(args[2].clone());
@ -547,14 +559,14 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
NodeIOTypes::new(concrete!(ImageFrame<Color>), concrete!(ImageFrame<Color>), vec![fn_type!(graphene_core::raster::curve::Curve)]),
),
],
raster_node!(graphene_core::raster::OpacityNode<_>, params: [f32]),
register_node!(graphene_core::raster::OpacityNode<_>, input: VectorData, params: [f32]),
register_node!(graphene_core::raster::OpacityNode<_>, input: GraphicGroup, params: [f32]),
raster_node!(graphene_core::raster::OpacityNode<_>, params: [f64]),
register_node!(graphene_core::raster::OpacityNode<_>, input: VectorData, params: [f64]),
register_node!(graphene_core::raster::OpacityNode<_>, input: GraphicGroup, params: [f64]),
register_node!(graphene_core::raster::BlendModeNode<_>, input: VectorData, params: [BlendMode]),
register_node!(graphene_core::raster::BlendModeNode<_>, input: GraphicGroup, params: [BlendMode]),
register_node!(graphene_core::raster::BlendModeNode<_>, input: ImageFrame<Color>, params: [BlendMode]),
raster_node!(graphene_core::raster::PosterizeNode<_>, params: [f32]),
raster_node!(graphene_core::raster::ExposureNode<_, _, _>, params: [f32, f32, f32]),
raster_node!(graphene_core::raster::PosterizeNode<_>, params: [f64]),
raster_node!(graphene_core::raster::ExposureNode<_, _, _>, params: [f64, f64, f64]),
register_node!(graphene_core::memo::LetNode<_>, input: Option<ImageFrame<Color>>, params: []),
register_node!(graphene_core::memo::LetNode<_>, input: Option<WasmEditorApi>, params: []),
async_node!(graphene_core::memo::EndLetNode<_, _>, input: WasmEditorApi, output: ImageFrame<Color>, params: [ImageFrame<Color>]),
@ -628,13 +640,13 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
fn_type!(Option<DVec2>),
fn_type!(u32),
fn_type!(ImaginateSamplingMethod),
fn_type!(f32),
fn_type!(f64),
fn_type!(String),
fn_type!(String),
fn_type!(bool),
fn_type!(f32),
fn_type!(f64),
fn_type!(bool),
fn_type!(f32),
fn_type!(f64),
fn_type!(ImaginateMaskStartingFill),
fn_type!(bool),
fn_type!(bool),
@ -657,7 +669,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
async_node!(graphene_core::memo::ImpureMemoNode<_, _, _>, input: Footprint, output: VectorData, fn_params: [Footprint => VectorData]),
register_node!(graphene_core::structural::ConsNode<_, _>, input: Image<Color>, params: [&str]),
register_node!(graphene_std::raster::ImageFrameNode<_, _>, input: Image<Color>, params: [DAffine2]),
register_node!(graphene_std::raster::NoisePatternNode<_, _, _, _, _, _, _, _, _, _, _, _, _, _, _>, input: (), params: [UVec2, u32, f32, NoiseType, DomainWarpType, f32, FractalType, u32, f32, f32, f32, f32, CellularDistanceFunction, CellularReturnType, f32]),
register_node!(graphene_std::raster::NoisePatternNode<_, _, _, _, _, _, _, _, _, _, _, _, _, _, _>, input: (), params: [UVec2, u32, f64, NoiseType, DomainWarpType, f64, FractalType, u32, f64, f64, f64, f64, CellularDistanceFunction, CellularReturnType, f64]),
#[cfg(feature = "quantization")]
register_node!(graphene_std::quantization::GenerateQuantizationNode<_, _>, input: ImageFrame<Color>, params: [u32, u32]),
register_node!(graphene_core::quantization::QuantizeNode<_>, input: Color, params: [QuantizationChannels]),
@ -679,20 +691,20 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, fn_params: [Footprint => Option<Color>, () => Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, fn_params: [() => Vec<Color>, () => Arc<WasmSurfaceHandle>]),
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, fn_params: [Footprint => Vec<Color>, () => Arc<WasmSurfaceHandle>]),
async_node!(graphene_core::transform::TransformNode<_, _, _, _, _, _>, input: Footprint, output: VectorData, fn_params: [Footprint => VectorData, () => DVec2, () => f32, () => DVec2, () => DVec2, () => DVec2]),
async_node!(graphene_core::transform::TransformNode<_, _, _, _, _, _>, input: Footprint, output: WasmSurfaceHandleFrame, fn_params: [Footprint => WasmSurfaceHandleFrame, () => DVec2, () => f32, () => DVec2, () => DVec2, () => DVec2]),
async_node!(graphene_core::transform::TransformNode<_, _, _, _, _, _>, input: Footprint, output: WasmSurfaceHandleFrame, fn_params: [Footprint => WasmSurfaceHandleFrame, () => DVec2, () => f32, () => DVec2, () => DVec2, () => DVec2]),
async_node!(graphene_core::transform::TransformNode<_, _, _, _, _, _>, input: Footprint, output: ImageFrame<Color>, fn_params: [Footprint => ImageFrame<Color>, () => DVec2, () => f32, () => DVec2, () => DVec2, () => DVec2]),
async_node!(graphene_core::transform::TransformNode<_, _, _, _, _, _>, input: Footprint, output: GraphicGroup, fn_params: [Footprint => GraphicGroup, () => DVec2, () => f32, () => DVec2, () => DVec2, () => DVec2]),
async_node!(graphene_core::transform::TransformNode<_, _, _, _, _, _>, input: Footprint, output: VectorData, fn_params: [Footprint => VectorData, () => DVec2, () => f64, () => DVec2, () => DVec2, () => DVec2]),
async_node!(graphene_core::transform::TransformNode<_, _, _, _, _, _>, input: Footprint, output: WasmSurfaceHandleFrame, fn_params: [Footprint => WasmSurfaceHandleFrame, () => DVec2, () => f64, () => DVec2, () => DVec2, () => DVec2]),
async_node!(graphene_core::transform::TransformNode<_, _, _, _, _, _>, input: Footprint, output: WasmSurfaceHandleFrame, fn_params: [Footprint => WasmSurfaceHandleFrame, () => DVec2, () => f64, () => DVec2, () => DVec2, () => DVec2]),
async_node!(graphene_core::transform::TransformNode<_, _, _, _, _, _>, input: Footprint, output: ImageFrame<Color>, fn_params: [Footprint => ImageFrame<Color>, () => DVec2, () => f64, () => DVec2, () => DVec2, () => DVec2]),
async_node!(graphene_core::transform::TransformNode<_, _, _, _, _, _>, input: Footprint, output: GraphicGroup, fn_params: [Footprint => GraphicGroup, () => DVec2, () => f64, () => DVec2, () => DVec2, () => DVec2]),
register_node!(graphene_core::transform::SetTransformNode<_>, input: VectorData, params: [VectorData]),
register_node!(graphene_core::transform::SetTransformNode<_>, input: ImageFrame<Color>, params: [ImageFrame<Color>]),
register_node!(graphene_core::transform::SetTransformNode<_>, input: VectorData, params: [DAffine2]),
register_node!(graphene_core::transform::SetTransformNode<_>, input: ImageFrame<Color>, params: [DAffine2]),
register_node!(graphene_core::vector::SetFillNode<_, _, _, _, _, _, _>, input: VectorData, params: [graphene_core::vector::style::FillType, Option<graphene_core::Color>, graphene_core::vector::style::GradientType, DVec2, DVec2, DAffine2, Vec<(f64, graphene_core::Color)>]),
register_node!(graphene_core::vector::SetStrokeNode<_, _, _, _, _, _, _>, input: VectorData, params: [Option<graphene_core::Color>, f32, Vec<f32>, f32, graphene_core::vector::style::LineCap, graphene_core::vector::style::LineJoin, f32]),
register_node!(graphene_core::vector::SetStrokeNode<_, _, _, _, _, _, _>, input: VectorData, params: [Option<graphene_core::Color>, f64, Vec<f64>, f64, graphene_core::vector::style::LineCap, graphene_core::vector::style::LineJoin, f64]),
register_node!(graphene_core::vector::RepeatNode<_, _>, input: VectorData, params: [DVec2, u32]),
register_node!(graphene_core::vector::BoundingBoxNode, input: VectorData, params: []),
register_node!(graphene_core::vector::CircularRepeatNode<_, _, _>, input: VectorData, params: [f32, f32, u32]),
register_node!(graphene_core::vector::CircularRepeatNode<_, _, _>, input: VectorData, params: [f64, f64, u32]),
vec![(
ProtoNodeIdentifier::new("graphene_core::transform::CullNode<_>"),
|args| {
@ -735,18 +747,18 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
)],
register_node!(graphene_std::raster::SampleNode<_>, input: Footprint, params: [ImageFrame<Color>]),
register_node!(graphene_std::raster::MandelbrotNode, input: Footprint, params: []),
async_node!(graphene_core::vector::CopyToPoints<_, _, _, _, _, _>, input: Footprint, output: VectorData, fn_params: [Footprint => VectorData, Footprint => VectorData, () => f32, () => f32, () => f32, () => f32]),
async_node!(graphene_core::vector::CopyToPoints<_, _, _, _, _, _>, input: Footprint, output: GraphicGroup, fn_params: [Footprint => VectorData, Footprint => GraphicGroup, () => f32, () => f32, () => f32, () => f32]),
async_node!(graphene_core::vector::SamplePoints<_, _, _, _, _, _>, input: Footprint, output: VectorData, fn_params: [Footprint => VectorData, () => f32, () => f32, () => f32, () => bool, Footprint => Vec<Vec<f64>>]),
register_node!(graphene_core::vector::PoissonDiskPoints<_>, input: VectorData, params: [f32]),
async_node!(graphene_core::vector::CopyToPoints<_, _, _, _, _, _>, input: Footprint, output: VectorData, fn_params: [Footprint => VectorData, Footprint => VectorData, () => f64, () => f64, () => f64, () => f64]),
async_node!(graphene_core::vector::CopyToPoints<_, _, _, _, _, _>, input: Footprint, output: GraphicGroup, fn_params: [Footprint => VectorData, Footprint => GraphicGroup, () => f64, () => f64, () => f64, () => f64]),
async_node!(graphene_core::vector::SamplePoints<_, _, _, _, _, _>, input: Footprint, output: VectorData, fn_params: [Footprint => VectorData, () => f64, () => f64, () => f64, () => bool, Footprint => Vec<Vec<f64>>]),
register_node!(graphene_core::vector::PoissonDiskPoints<_>, input: VectorData, params: [f64]),
register_node!(graphene_core::vector::LengthsOfSegmentsOfSubpaths, input: VectorData, params: []),
register_node!(graphene_core::vector::SplinesFromPointsNode, input: VectorData, params: []),
async_node!(graphene_core::vector::MorphNode<_, _, _, _>, input: Footprint, output: VectorData, fn_params: [Footprint => VectorData, Footprint => VectorData, () => u32, () => f32]),
register_node!(graphene_core::vector::generator_nodes::CircleGenerator<_>, input: (), params: [f32]),
register_node!(graphene_core::vector::generator_nodes::EllipseGenerator<_, _>, input: (), params: [f32, f32]),
register_node!(graphene_core::vector::generator_nodes::RectangleGenerator<_, _>, input: (), params: [f32, f32]),
register_node!(graphene_core::vector::generator_nodes::RegularPolygonGenerator<_, _>, input: (), params: [u32, f32]),
register_node!(graphene_core::vector::generator_nodes::StarGenerator<_, _, _>, input: (), params: [u32, f32, f32]),
async_node!(graphene_core::vector::MorphNode<_, _, _, _>, input: Footprint, output: VectorData, fn_params: [Footprint => VectorData, Footprint => VectorData, () => u32, () => f64]),
register_node!(graphene_core::vector::generator_nodes::CircleGenerator<_>, input: (), params: [f64]),
register_node!(graphene_core::vector::generator_nodes::EllipseGenerator<_, _>, input: (), params: [f64, f64]),
register_node!(graphene_core::vector::generator_nodes::RectangleGenerator<_, _>, input: (), params: [f64, f64]),
register_node!(graphene_core::vector::generator_nodes::RegularPolygonGenerator<_, _>, input: (), params: [u32, f64]),
register_node!(graphene_core::vector::generator_nodes::StarGenerator<_, _, _>, input: (), params: [u32, f64, f64]),
register_node!(graphene_core::vector::generator_nodes::LineGenerator<_, _>, input: (), params: [DVec2, DVec2]),
register_node!(graphene_core::vector::generator_nodes::SplineGenerator<_>, input: (), params: [Vec<DVec2>]),
register_node!(
@ -754,7 +766,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
input: Vec<graphene_core::vector::bezier_rs::Subpath<graphene_core::uuid::ManipulatorGroupId>>,
params: [Vec<graphene_core::uuid::ManipulatorGroupId>]
),
register_node!(graphene_core::text::TextGeneratorNode<_, _, _>, input: WasmEditorApi, params: [String, graphene_core::text::Font, f32]),
register_node!(graphene_core::text::TextGeneratorNode<_, _, _>, input: WasmEditorApi, params: [String, graphene_core::text::Font, f64]),
register_node!(graphene_std::brush::VectorPointsNode, input: VectorData, params: []),
register_node!(graphene_core::ExtractImageFrame, input: WasmEditorApi, params: []),
async_node!(graphene_core::ConstructLayerNode<_, _>, input: Footprint, output: GraphicGroup, fn_params: [Footprint => graphene_core::GraphicElement, Footprint => GraphicGroup]),
@ -780,5 +792,5 @@ pub static NODE_REGISTRY: Lazy<HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes,
#[cfg(test)]
mod protograph_testing {
// TODO: adde tests testing the node registry
// TODO: add tests testing the node registry
}