Generalize the 'Map Vector' node as 'Map' with support for all graphical types (#3793)

* Rename Map Vector to Map

* Fix compilation errors

* Move to the Graphic module and add Read {Graphic, Raster, Color} nodes

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
Dennis Kobert
2026-02-20 22:33:02 +01:00
committed by GitHub
parent bd1c54907d
commit ba177c4c5d
5 changed files with 74 additions and 37 deletions

View File

@@ -1,10 +1,18 @@
use core_types::ExtractVarArgs;
use core_types::table::Table;
use core_types::{Color, ExtractVarArgs};
use core_types::{Ctx, ExtractIndex, ExtractPosition};
use glam::DVec2;
use graphic_types::Vector;
use graphic_types::{Graphic, Vector};
use raster_types::{CPU, Raster};
#[node_macro::node(category("Context"), path(graphene_core::vector))]
fn read_graphic(ctx: impl Ctx + ExtractVarArgs) -> Table<Graphic> {
let Ok(var_arg) = ctx.vararg(0) else { return Default::default() };
let var_arg = var_arg as &dyn std::any::Any;
var_arg.downcast_ref().cloned().unwrap_or_default()
}
// TODO: Call this "Read Context" once it's fully generic
#[node_macro::node(category("Context"), path(graphene_core::vector))]
fn read_vector(ctx: impl Ctx + ExtractVarArgs) -> Table<Vector> {
let Ok(var_arg) = ctx.vararg(0) else { return Default::default() };
@@ -13,6 +21,22 @@ fn read_vector(ctx: impl Ctx + ExtractVarArgs) -> Table<Vector> {
var_arg.downcast_ref().cloned().unwrap_or_default()
}
#[node_macro::node(category("Context"), path(graphene_core::vector))]
fn read_raster(ctx: impl Ctx + ExtractVarArgs) -> Table<Raster<CPU>> {
let Ok(var_arg) = ctx.vararg(0) else { return Default::default() };
let var_arg = var_arg as &dyn std::any::Any;
var_arg.downcast_ref().cloned().unwrap_or_default()
}
#[node_macro::node(category("Context"), path(graphene_core::vector))]
fn read_color(ctx: impl Ctx + ExtractVarArgs) -> Table<Color> {
let Ok(var_arg) = ctx.vararg(0) else { return Default::default() };
let var_arg = var_arg as &dyn std::any::Any;
var_arg.downcast_ref().cloned().unwrap_or_default()
}
#[node_macro::node(category("Context"), path(core_types::vector))]
async fn read_position(
ctx: impl Ctx + ExtractPosition,

View File

@@ -1,14 +1,46 @@
use core_types::Color;
use core_types::Ctx;
use core_types::registry::types::SignedInteger;
use core_types::table::{Table, TableRow};
use core_types::uuid::NodeId;
use core_types::{AnyHash, CloneVarArgs, Color, Context, Ctx, ExtractAll, OwnedContextImpl};
use glam::{DAffine2, DVec2};
use graphic_types::graphic::{Graphic, IntoGraphicTable};
use graphic_types::{Artboard, Vector};
use raster_types::{CPU, GPU, Raster};
use vector_types::GradientStops;
#[node_macro::node(category("General"), path(graphene_core::vector))]
async fn map<Item: AnyHash + Send + Sync + std::hash::Hash>(
ctx: impl Ctx + CloneVarArgs + ExtractAll,
#[implementations(
Table<Graphic>,
Table<Vector>,
Table<Raster<CPU>>,
Table<Color>,
Table<GradientStops>,
)]
content: Table<Item>,
#[implementations(
Context -> Table<Graphic>,
Context -> Table<Vector>,
Context -> Table<Raster<CPU>>,
Context -> Table<Color>,
Context -> Table<GradientStops>,
)]
mapped: impl Node<Context<'static>, Output = Table<Item>>,
) -> Table<Item> {
let mut rows = Table::new();
for (i, row) in content.into_iter().enumerate() {
let owned_ctx = OwnedContextImpl::from(ctx.clone());
let owned_ctx = owned_ctx.with_vararg(Box::new(Table::new_from_row(row))).with_index(i);
let table = mapped.eval(owned_ctx.into_context()).await;
rows.extend(table);
}
rows
}
/// Performs internal editor record-keeping that enables tools to target this network's layer.
/// This node associates the ID of the network's parent layer to every element of output data.
/// This technical detail may be ignored by users, and will be phased out in the future.

View File

@@ -1325,25 +1325,6 @@ async fn separate_subpaths(_: impl Ctx, content: Table<Vector>) -> Table<Vector>
.collect()
}
// TODO: Call this "Map" once it's fully generic
#[node_macro::node(category("Vector"), path(graphene_core::vector))]
async fn map_vector(ctx: impl Ctx + CloneVarArgs + ExtractAll, content: Table<Vector>, mapped: impl Node<Context<'static>, Output = Table<Vector>>) -> Table<Vector> {
let mut rows = Vec::new();
for (i, row) in content.into_iter().enumerate() {
let owned_ctx = OwnedContextImpl::from(ctx.clone());
let owned_ctx = owned_ctx.with_vararg(Box::new(Table::new_from_row(row))).with_index(i);
let table = mapped.eval(owned_ctx.into_context()).await;
for inner_row in table {
rows.push(inner_row);
}
}
rows.into_iter().collect()
}
// TODO: Call this "Map" once it's fully generic
#[node_macro::node(category("Vector"), path(graphene_core::vector))]
async fn map_points(ctx: impl Ctx + CloneVarArgs + ExtractAll, content: Table<Vector>, mapped: impl Node<Context<'static>, Output = DVec2>) -> Table<Vector> {
let mut content = content;