Skip to content

Commit 81db769

Browse files
otdaviesKeavon
andauthored
Minor fixes for 'Round Corners' and 'Mirror' nodes (#2510)
* Fix round corners node not properly maintaing click targets, added keep_original bool to mirror node * Fixed fix for the theta angle * Add upgrade script for Mirror node --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
1 parent 412dfc2 commit 81db769

File tree

2 files changed

+44
-13
lines changed

2 files changed

+44
-13
lines changed

editor/src/messages/portfolio/portfolio_message_handler.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,22 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
806806
.set_input(&InputConnector::node(*node_id, 2), NodeInput::value(TaggedValue::Bool(false), false), network_path);
807807
}
808808

809+
// Upgrade the Mirror node to add the `keep_original` boolean input
810+
if reference == "Mirror" && inputs_count == 3 {
811+
let node_definition = resolve_document_node_type(reference).unwrap();
812+
let document_node = node_definition.default_node_template().document_node;
813+
document.network_interface.replace_implementation(node_id, network_path, document_node.implementation.clone());
814+
815+
let old_inputs = document.network_interface.replace_inputs(node_id, document_node.inputs.clone(), network_path);
816+
817+
document.network_interface.set_input(&InputConnector::node(*node_id, 0), old_inputs[0].clone(), network_path);
818+
document.network_interface.set_input(&InputConnector::node(*node_id, 1), old_inputs[1].clone(), network_path);
819+
document.network_interface.set_input(&InputConnector::node(*node_id, 2), old_inputs[2].clone(), network_path);
820+
document
821+
.network_interface
822+
.set_input(&InputConnector::node(*node_id, 3), NodeInput::value(TaggedValue::Bool(true), false), network_path);
823+
}
824+
809825
// Upgrade artboard name being passed as hidden value input to "To Artboard"
810826
if reference == "Artboard" && upgrade_from_before_returning_nested_click_targets {
811827
let label = document.network_interface.frontend_display_name(node_id, network_path);

node-graph/gcore/src/vector/vector_nodes.rs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -342,33 +342,42 @@ async fn mirror<I: 'n + Send>(
342342
#[implementations(VectorDataTable, GraphicGroupTable)] instance: Instances<I>,
343343
#[default(0., 0.)] center: DVec2,
344344
#[range((-90., 90.))] angle: Angle,
345+
#[default(true)] keep_original: bool,
345346
) -> GraphicGroupTable
346347
where
347348
Instances<I>: GraphicElementRendered,
348349
{
349350
let mut result_table = GraphicGroupTable::default();
350-
let Some(bounding_box) = instance.bounding_box(DAffine2::IDENTITY) else { return result_table };
351+
351352
// The mirror center is based on the bounding box for now
353+
let Some(bounding_box) = instance.bounding_box(DAffine2::IDENTITY) else { return result_table };
352354
let mirror_center = (bounding_box[0] + bounding_box[1]) / 2. + center;
353-
// Normalize direction vector
355+
356+
// Normalize the direction vector
354357
let normal = DVec2::from_angle(angle.to_radians());
355-
// Create reflection matrix
358+
359+
// Create the reflection matrix
356360
let reflection = DAffine2::from_mat2_translation(
357361
glam::DMat2::from_cols(
358362
DVec2::new(1. - 2. * normal.x * normal.x, -2. * normal.y * normal.x),
359363
DVec2::new(-2. * normal.x * normal.y, 1. - 2. * normal.y * normal.y),
360364
),
361365
DVec2::ZERO,
362366
);
367+
363368
// Apply reflection around the center point
364369
let modification = DAffine2::from_translation(mirror_center) * reflection * DAffine2::from_translation(-mirror_center);
365-
// Add original instance to result
366-
let original_element = instance.to_graphic_element().clone();
367-
result_table.push(original_element);
370+
371+
// Add original instance depending on the keep_original flag
372+
if keep_original {
373+
result_table.push(instance.to_graphic_element());
374+
}
375+
368376
// Create and add mirrored instance
369-
let mut mirrored_element = instance.to_graphic_element().clone();
377+
let mut mirrored_element = instance.to_graphic_element();
370378
mirrored_element.new_ids_from_hash(None);
371-
// Finally, apply the transformation to the mirrored instance
379+
380+
// Apply the transformation to the mirrored instance
372381
let mirrored_instance = result_table.push(mirrored_element);
373382
*mirrored_instance.transform = modification;
374383

@@ -393,6 +402,7 @@ async fn round_corners(
393402
let source_transform = source.transform();
394403
let source_transform_inverse = source_transform.inverse();
395404
let source = source.one_instance().instance;
405+
let upstream_graphics_group = source.upstream_graphic_group.clone();
396406

397407
// Flip the roundness to help with user intuition
398408
let roundness = 1. - roundness;
@@ -402,11 +412,14 @@ async fn round_corners(
402412
let mut result = VectorData::empty();
403413
result.style = source.style.clone();
404414

415+
// Grab the initial point ID as a stable starting point
416+
let mut initial_point_id = source.point_domain.ids().first().copied().unwrap_or(PointId::generate());
417+
405418
for mut subpath in source.stroke_bezier_paths() {
406419
subpath.apply_transform(source_transform);
407420

421+
// End if not enough points for corner rounding
408422
if subpath.manipulator_groups().len() < 3 {
409-
// Not enough points for corner rounding
410423
result.append_subpath(subpath, false);
411424
continue;
412425
}
@@ -450,28 +463,30 @@ async fn round_corners(
450463
let p1 = curr - dir1 * distance_along_edge;
451464
let p2 = curr + dir2 * distance_along_edge;
452465

453-
// Add first point with out handle
466+
// Add first point (coming into the rounded corner)
454467
new_groups.push(ManipulatorGroup {
455468
anchor: p1,
456469
in_handle: None,
457470
out_handle: Some(curr - dir1 * distance_along_edge * roundness),
458-
id: PointId::generate(),
471+
id: initial_point_id.next_id(),
459472
});
460473

461-
// Add second point with in handle
474+
// Add second point (coming out of the rounded corner)
462475
new_groups.push(ManipulatorGroup {
463476
anchor: p2,
464477
in_handle: Some(curr + dir2 * distance_along_edge * roundness),
465478
out_handle: None,
466-
id: PointId::generate(),
479+
id: initial_point_id.next_id(),
467480
});
468481
}
469482

483+
// One subpath for each shape
470484
let mut rounded_subpath = Subpath::new(new_groups, is_closed);
471485
rounded_subpath.apply_transform(source_transform_inverse);
472486
result.append_subpath(rounded_subpath, false);
473487
}
474488

489+
result.upstream_graphic_group = upstream_graphics_group;
475490
let mut result_table = VectorDataTable::new(result);
476491
*result_table.transform_mut() = source_transform;
477492
result_table

0 commit comments

Comments
 (0)