@@ -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
346347where
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