diff --git a/node-graph/libraries/rendering/src/renderer.rs b/node-graph/libraries/rendering/src/renderer.rs index fc51b50093..f87e78598c 100644 --- a/node-graph/libraries/rendering/src/renderer.rs +++ b/node-graph/libraries/rendering/src/renderer.rs @@ -825,8 +825,20 @@ impl Render for Table { (id, mask_type, vector_row) }); - if vector.is_branching() { - for mut face_path in vector.construct_faces().filter(|face| !(face.area() < 0.0)) { + if !vector.region_domain.is_empty() || vector.is_branching() { + let regions = vector.region_manipulator_groups(); + let region_count = regions.count(); + if region_count > 0 { + log::trace!("Rendering {} mesh regions", region_count); + } + + let faces: Box> = if region_count > 0 { + Box::new(vector.region_manipulator_groups().map(|(_, face)| graphic_types::vector_types::vector::misc::bezpath_from_manipulator_groups(&face, true))) + } else { + Box::new(vector.construct_faces().filter(|face| !(face.area() < 0.0))) + }; + + for mut face_path in faces { face_path.apply_affine(Affine::new(applied_stroke_transform.to_cols_array())); let face_d = face_path.to_svg(); @@ -1059,9 +1071,20 @@ impl Render for Table { }; let do_fill = |scene: &mut Scene| { - if row.element.is_branching() { - // For branching paths, fill each face separately - for mut face_path in row.element.construct_faces().filter(|face| !(face.area() < 0.0)) { + if !row.element.region_domain.is_empty() || row.element.is_branching() { + let regions = row.element.region_manipulator_groups(); + let region_count = regions.count(); + if region_count > 0 { + log::trace!("Rendering {} mesh regions (Vello)", region_count); + } + + let faces: Box> = if region_count > 0 { + Box::new(row.element.region_manipulator_groups().map(|(_, face)| graphic_types::vector_types::vector::misc::bezpath_from_manipulator_groups(&face, true))) + } else { + Box::new(row.element.construct_faces().filter(|face| !(face.area() < 0.0))) + }; + + for mut face_path in faces { face_path.apply_affine(Affine::new(applied_stroke_transform.to_cols_array())); let mut kurbo_path = kurbo::BezPath::new(); for element in face_path { diff --git a/node-graph/libraries/vector-types/src/vector/vector_types.rs b/node-graph/libraries/vector-types/src/vector/vector_types.rs index e504bb7199..f27eab5282 100644 --- a/node-graph/libraries/vector-types/src/vector/vector_types.rs +++ b/node-graph/libraries/vector-types/src/vector/vector_types.rs @@ -564,4 +564,18 @@ mod tests { let generated = vector.stroke_bezier_paths().collect::>(); assert_subpath_eq(&generated, &[curve, circle]); } + + #[test] + fn construct_disconnected_regions() { + let mut vector: Vector<()> = Vector::default(); + // First region (square) + vector.append_subpath(Subpath::new_rect(DVec2::ZERO, DVec2::splat(10.)), false); + // Second region (offset square) + vector.append_subpath(Subpath::new_rect(DVec2::splat(20.), DVec2::splat(30.)), false); + + assert_eq!(vector.region_domain.ids().len(), 2, "Should have 2 regions"); + + let regions = vector.region_manipulator_groups().collect::>(); + assert_eq!(regions.len(), 2, "Should extract 2 independent region manipulator groups"); + } }