Skip to content

Commit cf2a071

Browse files
4adexKeavon
andauthored
Make the Pen tool extend an endpoint by starting with a colinear, equidistant handle (#2295)
* Fixed Pen extension having collienar handles * Reformat a little * handles being colinear for GRS --------- Co-authored-by: Keavon Chambers <[email protected]>
1 parent 38e542e commit cf2a071

File tree

1 file changed

+61
-19
lines changed

1 file changed

+61
-19
lines changed

editor/src/messages/tool/tool_messages/pen_tool.rs

+61-19
Original file line numberDiff line numberDiff line change
@@ -690,25 +690,9 @@ impl PenToolData {
690690
self.handle_end = None;
691691

692692
let tolerance = crate::consts::SNAP_POINT_TOLERANCE;
693-
if let Some((layer, point, position)) = should_extend(document, viewport, tolerance, selected_nodes.selected_layers(document.metadata()), preferences) {
694-
// Perform extension of an existing path
695-
let in_segment = if self.modifiers.lock_angle { self.end_point_segment } else { None };
696-
self.add_point(LastPoint {
697-
id: point,
698-
pos: position,
699-
in_segment,
700-
handle_start: position,
701-
});
702-
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![layer.to_node()] });
703-
self.next_point = position;
704-
self.next_handle_start = position;
705-
let vector_data = document.network_interface.compute_modified_vector(layer).unwrap();
706-
let segment = vector_data.all_connected(point).collect::<Vec<_>>().first().map(|s| s.segment);
707-
708-
if self.modifiers.lock_angle {
709-
self.set_lock_angle(&vector_data, point, segment);
710-
}
711-
693+
let extension_choice = should_extend(document, viewport, tolerance, selected_nodes.selected_layers(document.metadata()), preferences);
694+
if let Some((layer, point, position)) = extension_choice {
695+
self.extend_existing_path(document, layer, point, position, responses);
712696
return;
713697
}
714698

@@ -759,6 +743,64 @@ impl PenToolData {
759743
responses.add(PenToolMessage::AddPointLayerPosition { layer, viewport });
760744
}
761745

746+
/// Perform extension of an existing path
747+
fn extend_existing_path(&mut self, document: &DocumentMessageHandler, layer: LayerNodeIdentifier, point: PointId, position: DVec2, responses: &mut VecDeque<Message>) {
748+
let vector_data = document.network_interface.compute_modified_vector(layer);
749+
let (handle_start, in_segment) = if let Some(vector_data) = &vector_data {
750+
vector_data
751+
.segment_bezier_iter()
752+
.find_map(|(segment_id, bezier, start, end)| {
753+
let is_end = point == end;
754+
let is_start = point == start;
755+
if !is_end && !is_start {
756+
return None;
757+
}
758+
759+
let handle = match bezier.handles {
760+
BezierHandles::Cubic { handle_start, handle_end, .. } => {
761+
if is_start {
762+
handle_start
763+
} else {
764+
handle_end
765+
}
766+
}
767+
BezierHandles::Quadratic { handle } => handle,
768+
_ => return None,
769+
};
770+
Some((segment_id, is_end, handle))
771+
})
772+
.map(|(segment_id, is_end, handle)| {
773+
let mirrored_handle = position * 2. - handle;
774+
let in_segment = if is_end { Some(segment_id) } else { None };
775+
(mirrored_handle, in_segment)
776+
})
777+
.unwrap_or_else(|| (position, None))
778+
} else {
779+
(position, None)
780+
};
781+
782+
let in_segment = if self.modifiers.lock_angle { self.end_point_segment } else { in_segment };
783+
784+
self.add_point(LastPoint {
785+
id: point,
786+
pos: position,
787+
in_segment,
788+
handle_start,
789+
});
790+
791+
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![layer.to_node()] });
792+
793+
self.next_point = position;
794+
self.next_handle_start = handle_start;
795+
let vector_data = document.network_interface.compute_modified_vector(layer).unwrap();
796+
let segment = vector_data.all_connected(point).collect::<Vec<_>>().first().map(|s| s.segment);
797+
798+
if self.modifiers.lock_angle {
799+
self.set_lock_angle(&vector_data, point, segment);
800+
}
801+
self.handle_mode = HandleMode::ColinearEquidistant;
802+
}
803+
762804
// Stores the segment and point ID of the clicked endpoint
763805
fn store_clicked_endpoint(&mut self, document: &DocumentMessageHandler, input: &InputPreprocessorMessageHandler, preferences: &PreferencesMessageHandler) {
764806
let point = SnapCandidatePoint::handle(document.metadata().document_to_viewport.inverse().transform_point2(input.mouse.position));

0 commit comments

Comments
 (0)