@@ -1133,16 +1133,22 @@ impl PenToolData {
11331133 let selected_nodes = document. network_interface . selected_nodes ( ) ;
11341134 let mut selected_layers = selected_nodes. selected_layers ( document. metadata ( ) ) ;
11351135 let layer = selected_layers. next ( ) . filter ( |_| selected_layers. next ( ) . is_none ( ) ) . or ( self . current_layer ) ?;
1136- let vector = document. network_interface . compute_modified_vector ( layer) ?;
1137- let transform = document. metadata ( ) . document_to_viewport * transform;
1138- for point in vector. anchor_points ( ) {
1139- let Some ( pos) = vector. point_domain . position_from_id ( point) else { continue } ;
1140- let transformed_distance_between_squared = transform. transform_point2 ( pos) . distance_squared ( transform. transform_point2 ( self . next_point ) ) ;
1141- let snap_point_tolerance_squared = crate :: consts:: SNAP_POINT_TOLERANCE . powi ( 2 ) ;
1142- if transformed_distance_between_squared < snap_point_tolerance_squared {
1143- self . next_point = pos;
1136+
1137+ // The modified vector can be momentarily unavailable while the node graph re-evaluates after a document undo.
1138+ // Snapping onto an existing point is only a convenience, so skip it when the vector is missing rather than
1139+ // returning `None`, which would let a caller like PointerMove's `unwrap_or(Ready)` end the session.
1140+ if let Some ( vector) = document. network_interface . compute_modified_vector ( layer) {
1141+ let transform = document. metadata ( ) . document_to_viewport * transform;
1142+ for point in vector. anchor_points ( ) {
1143+ let Some ( pos) = vector. point_domain . position_from_id ( point) else { continue } ;
1144+ let transformed_distance_between_squared = transform. transform_point2 ( pos) . distance_squared ( transform. transform_point2 ( self . next_point ) ) ;
1145+ let snap_point_tolerance_squared = crate :: consts:: SNAP_POINT_TOLERANCE . powi ( 2 ) ;
1146+ if transformed_distance_between_squared < snap_point_tolerance_squared {
1147+ self . next_point = pos;
1148+ }
11441149 }
11451150 }
1151+
11461152 if let Some ( handle_end) = self . handle_end . as_mut ( ) {
11471153 * handle_end = self . next_point ;
11481154 self . next_handle_start = self . next_point ;
@@ -1979,9 +1985,9 @@ impl Fsm for PenToolFsmState {
19791985 tool_data. angle_locked = false ;
19801986 }
19811987
1982- let state = tool_data
1983- . drag_handle ( snap_data , transform , input . mouse . position , responses , layer , input , viewport )
1984- . unwrap_or ( PenToolFsmState :: Ready ) ;
1988+ // A pointer move must never end the path: keep dragging if the handle can't be resolved this frame
1989+ // (the vector is briefly unavailable while the graph re-evaluates after an undo )
1990+ let state = tool_data . drag_handle ( snap_data , transform , input . mouse . position , responses , layer , input , viewport ) . unwrap_or ( self ) ;
19851991
19861992 if tool_data. handle_swapped {
19871993 responses. add ( FrontendMessage :: UpdateMouseCursor { cursor : MouseCursorIcon :: None } ) ;
@@ -2029,9 +2035,10 @@ impl Fsm for PenToolFsmState {
20292035 colinear : input. keyboard . key ( colinear) ,
20302036 move_anchor_with_handles : input. keyboard . key ( move_anchor_with_handles) ,
20312037 } ;
2038+ // A pointer move must never end the path: keep placing if the anchor can't be resolved this frame
20322039 let state = tool_data
20332040 . place_anchor ( SnapData :: new ( document, input, viewport) , transform, input. mouse . position , responses)
2034- . unwrap_or ( PenToolFsmState :: Ready ) ;
2041+ . unwrap_or ( self ) ;
20352042
20362043 // Auto-panning
20372044 let messages = [
0 commit comments