@@ -534,3 +534,118 @@ fn delete_preview(tool_data: &mut SplineToolData, responses: &mut VecDeque<Messa
534
534
tool_data. preview_point = None ;
535
535
tool_data. preview_segment = None ;
536
536
}
537
+
538
+ #[ cfg( test) ]
539
+ mod test_spline_tool {
540
+ use crate :: messages:: tool:: tool_messages:: spline_tool:: find_spline;
541
+ use crate :: test_utils:: test_prelude:: * ;
542
+ use glam:: DAffine2 ;
543
+ use graphene_core:: vector:: VectorData ;
544
+ use graphene_std:: vector:: PointId ;
545
+
546
+ fn assert_point_positions ( vector_data : & VectorData , layer_to_viewport : DAffine2 , expected_points : & [ DVec2 ] , epsilon : f64 ) {
547
+ let points_in_viewport: Vec < DVec2 > = vector_data
548
+ . point_domain
549
+ . ids ( )
550
+ . iter ( )
551
+ . filter_map ( |& point_id| {
552
+ let position = vector_data. point_domain . position_from_id ( point_id) ?;
553
+ Some ( layer_to_viewport. transform_point2 ( position) )
554
+ } )
555
+ . collect ( ) ;
556
+
557
+ // Verify each point position is close to the expected position
558
+ for ( i, expected_point) in expected_points. iter ( ) . enumerate ( ) {
559
+ let actual_point = points_in_viewport[ i] ;
560
+ let distance = ( actual_point - * expected_point) . length ( ) ;
561
+
562
+ assert ! (
563
+ distance < epsilon,
564
+ "Point {} position mismatch: expected {:?}, got {:?} (distance: {})" ,
565
+ i,
566
+ expected_point,
567
+ actual_point,
568
+ distance
569
+ ) ;
570
+ }
571
+ }
572
+
573
+ #[ tokio:: test]
574
+ async fn test_continue_drawing_from_existing_spline ( ) {
575
+ let mut editor = EditorTestUtils :: create ( ) ;
576
+ editor. new_document ( ) . await ;
577
+
578
+ let initial_points = [ DVec2 :: new ( 100. , 100. ) , DVec2 :: new ( 200. , 150. ) , DVec2 :: new ( 300. , 100. ) ] ;
579
+
580
+ editor. select_tool ( ToolType :: Spline ) . await ;
581
+
582
+ for & point in & initial_points {
583
+ editor. click_tool ( ToolType :: Spline , MouseKeys :: LEFT , point, ModifierKeys :: empty ( ) ) . await ;
584
+ }
585
+
586
+ editor. press ( Key :: Enter , ModifierKeys :: empty ( ) ) . await ;
587
+
588
+ let document = editor. active_document ( ) ;
589
+ let spline_layer = document
590
+ . metadata ( )
591
+ . all_layers ( )
592
+ . find ( |layer| find_spline ( document, * layer) . is_some ( ) )
593
+ . expect ( "Failed to find a layer with a spline node" ) ;
594
+
595
+ let first_spline_node = find_spline ( document, spline_layer) . expect ( "Spline node not found in the layer" ) ;
596
+
597
+ let first_vector_data = document. network_interface . compute_modified_vector ( spline_layer) . expect ( "Vector data not found for the spline layer" ) ;
598
+
599
+ // Verify initial spline has correct number of points and segments
600
+ let initial_point_count = first_vector_data. point_domain . ids ( ) . len ( ) ;
601
+ let initial_segment_count = first_vector_data. segment_domain . ids ( ) . len ( ) ;
602
+ assert_eq ! ( initial_point_count, 3 , "Expected 3 points in initial spline, found {}" , initial_point_count) ;
603
+ assert_eq ! ( initial_segment_count, 2 , "Expected 2 segments in initial spline, found {}" , initial_segment_count) ;
604
+
605
+ let layer_to_viewport = document. metadata ( ) . transform_to_viewport ( spline_layer) ;
606
+
607
+ let endpoints: Vec < ( PointId , DVec2 ) > = first_vector_data
608
+ . extendable_points ( false )
609
+ . filter_map ( |point_id| first_vector_data. point_domain . position_from_id ( point_id) . map ( |pos| ( point_id, layer_to_viewport. transform_point2 ( pos) ) ) )
610
+ . collect ( ) ;
611
+
612
+ assert_eq ! ( endpoints. len( ) , 2 , "Expected 2 endpoints in the initial spline" ) ;
613
+
614
+ let ( _, endpoint_position) = endpoints. first ( ) . expect ( "No endpoints found in spline" ) ;
615
+
616
+ editor. select_tool ( ToolType :: Spline ) . await ;
617
+ editor. click_tool ( ToolType :: Spline , MouseKeys :: LEFT , * endpoint_position, ModifierKeys :: empty ( ) ) . await ;
618
+
619
+ let continuation_points = [ DVec2 :: new ( 400. , 150. ) , DVec2 :: new ( 500. , 100. ) ] ;
620
+
621
+ for & point in & continuation_points {
622
+ editor. click_tool ( ToolType :: Spline , MouseKeys :: LEFT , point, ModifierKeys :: empty ( ) ) . await ;
623
+ }
624
+
625
+ editor. press ( Key :: Enter , ModifierKeys :: empty ( ) ) . await ;
626
+
627
+ let document = editor. active_document ( ) ;
628
+ let extended_vector_data = document
629
+ . network_interface
630
+ . compute_modified_vector ( spline_layer)
631
+ . expect ( "Vector data not found for the extended spline layer" ) ;
632
+
633
+ // Verify extended spline has correct number of points and segments
634
+ let extended_point_count = extended_vector_data. point_domain . ids ( ) . len ( ) ;
635
+ let extended_segment_count = extended_vector_data. segment_domain . ids ( ) . len ( ) ;
636
+
637
+ assert_eq ! ( extended_point_count, 5 , "Expected 5 points in extended spline, found {}" , extended_point_count) ;
638
+ assert_eq ! ( extended_segment_count, 4 , "Expected 4 segments in extended spline, found {}" , extended_segment_count) ;
639
+
640
+ // Verify the spline node is still the same
641
+ let extended_spline_node = find_spline ( document, spline_layer) . expect ( "Spline node not found after extension" ) ;
642
+ assert_eq ! ( first_spline_node, extended_spline_node, "Spline node changed after extension" ) ;
643
+
644
+ // Verify the positions of all points in the extended spline
645
+ let layer_to_viewport = document. metadata ( ) . transform_to_viewport ( spline_layer) ;
646
+
647
+ let all_expected_points = [ initial_points[ 0 ] , initial_points[ 1 ] , initial_points[ 2 ] , continuation_points[ 0 ] , continuation_points[ 1 ] ] ;
648
+
649
+ assert_point_positions ( & extended_vector_data, layer_to_viewport, & all_expected_points, 1e-10 ) ;
650
+ }
651
+ }
0 commit comments