mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-02 08:58:11 +08:00
Rename graphic subtypes to remove their "data" and "group" suffixes (#2990)
* Rename VectorData to Vector * Rename other VectorData* types to Vector* * Move assorted data types out of vector_data.rs into misc.rs * Rename vector_data.rs to vector_types.rs and remove the vector_types module folder * Rename other references to "vector data" * Remove label widgets for raster/vector/group to use "-" instead * Rename RasterData to Raster * Rename GraphicGroup to Group * Fix migrations and rename graphic_element.rs -> graphic.rs * Rename TaggedValue::ArtboardGroup -> TaggedValue::Artboard
This commit is contained in:
@@ -11,6 +11,7 @@ use crate::messages::tool::common_functionality::snapping::SnapData;
|
||||
use crate::messages::tool::common_functionality::snapping::SnapManager;
|
||||
use crate::messages::tool::common_functionality::transformation_cage::*;
|
||||
use graph_craft::document::NodeId;
|
||||
use graphene_std::Artboard;
|
||||
use graphene_std::renderer::Quad;
|
||||
use graphene_std::table::Table;
|
||||
|
||||
@@ -337,8 +338,8 @@ impl Fsm for ArtboardToolFsmState {
|
||||
|
||||
responses.add(GraphOperationMessage::NewArtboard {
|
||||
id,
|
||||
artboard: graphene_std::Artboard {
|
||||
graphic_group: Table::new(),
|
||||
artboard: Artboard {
|
||||
group: Table::new(),
|
||||
label: String::from("Artboard"),
|
||||
location: start.min(end).round().as_ivec2(),
|
||||
dimensions: (start.round() - end.round()).abs().as_ivec2(),
|
||||
|
||||
@@ -360,9 +360,9 @@ mod test_freehand {
|
||||
use crate::messages::tool::tool_messages::freehand_tool::FreehandOptionsUpdate;
|
||||
use crate::test_utils::test_prelude::*;
|
||||
use glam::{DAffine2, DVec2};
|
||||
use graphene_std::vector::VectorData;
|
||||
use graphene_std::vector::Vector;
|
||||
|
||||
async fn get_vector_data(editor: &mut EditorTestUtils) -> Vec<(VectorData, DAffine2)> {
|
||||
async fn get_vector_and_transform_list(editor: &mut EditorTestUtils) -> Vec<(Vector, DAffine2)> {
|
||||
let document = editor.active_document();
|
||||
let layers = document.metadata().all_layers();
|
||||
|
||||
@@ -372,23 +372,22 @@ mod test_freehand {
|
||||
// Only get layers with path nodes
|
||||
let _ = graph_layer.upstream_visible_node_id_from_name_in_layer("Path")?;
|
||||
|
||||
let vector_data = document.network_interface.compute_modified_vector(layer)?;
|
||||
let vector = document.network_interface.compute_modified_vector(layer)?;
|
||||
let transform = document.metadata().transform_to_viewport(layer);
|
||||
Some((vector_data, transform))
|
||||
Some((vector, transform))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn verify_path_points(vector_data_list: &[(VectorData, DAffine2)], expected_captured_points: &[DVec2], tolerance: f64) -> Result<(), String> {
|
||||
assert_eq!(vector_data_list.len(), 1, "there should be one vector data");
|
||||
fn verify_path_points(vector_and_transform_list: &[(Vector, DAffine2)], expected_captured_points: &[DVec2], tolerance: f64) -> Result<(), String> {
|
||||
assert_eq!(vector_and_transform_list.len(), 1, "There should be one row of Vector geometry");
|
||||
|
||||
let path_data = vector_data_list.iter().find(|(data, _)| data.point_domain.ids().len() > 0).ok_or("Could not find path data")?;
|
||||
let (vector, transform) = vector_and_transform_list.iter().find(|(data, _)| data.point_domain.ids().len() > 0).ok_or("Could not find path data")?;
|
||||
|
||||
let (vector_data, transform) = path_data;
|
||||
let point_count = vector_data.point_domain.ids().len();
|
||||
let segment_count = vector_data.segment_domain.ids().len();
|
||||
let point_count = vector.point_domain.ids().len();
|
||||
let segment_count = vector.segment_domain.ids().len();
|
||||
|
||||
let actual_positions: Vec<DVec2> = vector_data.point_domain.positions().iter().map(|&position| transform.transform_point2(position)).collect();
|
||||
let actual_positions: Vec<DVec2> = vector.point_domain.positions().iter().map(|&position| transform.transform_point2(position)).collect();
|
||||
|
||||
if segment_count != point_count - 1 {
|
||||
return Err(format!("Expected segments to be one less than points, got {} segments for {} points", segment_count, point_count));
|
||||
@@ -435,8 +434,8 @@ mod test_freehand {
|
||||
let expected_captured_points = &mouse_points[1..];
|
||||
editor.drag_path(&mouse_points, ModifierKeys::empty()).await;
|
||||
|
||||
let vector_data_list = get_vector_data(&mut editor).await;
|
||||
verify_path_points(&vector_data_list, expected_captured_points, 1.).expect("Path points verification failed");
|
||||
let vector_and_transform_list = get_vector_and_transform_list(&mut editor).await;
|
||||
verify_path_points(&vector_and_transform_list, expected_captured_points, 1.).expect("Path points verification failed");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -468,12 +467,12 @@ mod test_freehand {
|
||||
)
|
||||
.await;
|
||||
|
||||
let initial_vector_data = get_vector_data(&mut editor).await;
|
||||
assert!(!initial_vector_data.is_empty(), "No vector data found after initial drawing");
|
||||
let initial_vector_and_transform_list = get_vector_and_transform_list(&mut editor).await;
|
||||
assert!(!initial_vector_and_transform_list.is_empty(), "No Vector geometry found after initial drawing");
|
||||
|
||||
let (initial_data, transform) = &initial_vector_data[0];
|
||||
let initial_point_count = initial_data.point_domain.ids().len();
|
||||
let initial_segment_count = initial_data.segment_domain.ids().len();
|
||||
let (initial_vector, initial_transform) = &initial_vector_and_transform_list[0];
|
||||
let initial_point_count = initial_vector.point_domain.ids().len();
|
||||
let initial_segment_count = initial_vector.segment_domain.ids().len();
|
||||
|
||||
assert!(initial_point_count >= 2, "Expected at least 2 points in initial path, found {}", initial_point_count);
|
||||
assert_eq!(
|
||||
@@ -484,15 +483,15 @@ mod test_freehand {
|
||||
initial_segment_count
|
||||
);
|
||||
|
||||
let extendable_points = initial_data.extendable_points(false).collect::<Vec<_>>();
|
||||
let extendable_points = initial_vector.extendable_points(false).collect::<Vec<_>>();
|
||||
assert!(!extendable_points.is_empty(), "No extendable points found in the path");
|
||||
|
||||
let endpoint_id = extendable_points[0];
|
||||
let endpoint_pos_option = initial_data.point_domain.position_from_id(endpoint_id);
|
||||
let endpoint_pos_option = initial_vector.point_domain.position_from_id(endpoint_id);
|
||||
assert!(endpoint_pos_option.is_some(), "Could not find position for endpoint");
|
||||
|
||||
let endpoint_pos = endpoint_pos_option.unwrap();
|
||||
let endpoint_viewport_pos = transform.transform_point2(endpoint_pos);
|
||||
let endpoint_viewport_pos = initial_transform.transform_point2(endpoint_pos);
|
||||
|
||||
assert!(endpoint_viewport_pos.is_finite(), "Endpoint position is not finite");
|
||||
|
||||
@@ -527,12 +526,12 @@ mod test_freehand {
|
||||
)
|
||||
.await;
|
||||
|
||||
let extended_vector_data = get_vector_data(&mut editor).await;
|
||||
assert!(!extended_vector_data.is_empty(), "No vector data found after extension");
|
||||
let extended_vector_and_transform = get_vector_and_transform_list(&mut editor).await;
|
||||
assert!(!extended_vector_and_transform.is_empty(), "No Vector geometry found after extension");
|
||||
|
||||
let (extended_data, _) = &extended_vector_data[0];
|
||||
let extended_point_count = extended_data.point_domain.ids().len();
|
||||
let extended_segment_count = extended_data.segment_domain.ids().len();
|
||||
let (extended_vector, _) = &extended_vector_and_transform[0];
|
||||
let extended_point_count = extended_vector.point_domain.ids().len();
|
||||
let extended_segment_count = extended_vector.segment_domain.ids().len();
|
||||
|
||||
assert!(
|
||||
extended_point_count > initial_point_count,
|
||||
@@ -585,12 +584,12 @@ mod test_freehand {
|
||||
)
|
||||
.await;
|
||||
|
||||
let initial_vector_data = get_vector_data(&mut editor).await;
|
||||
assert!(!initial_vector_data.is_empty(), "No vector data found after initial drawing");
|
||||
let initial_vector_and_transform = get_vector_and_transform_list(&mut editor).await;
|
||||
assert!(!initial_vector_and_transform.is_empty(), "No vector geometry found after initial drawing");
|
||||
|
||||
let (initial_data, _) = &initial_vector_data[0];
|
||||
let initial_point_count = initial_data.point_domain.ids().len();
|
||||
let initial_segment_count = initial_data.segment_domain.ids().len();
|
||||
let (initial_vector, _) = &initial_vector_and_transform[0];
|
||||
let initial_point_count = initial_vector.point_domain.ids().len();
|
||||
let initial_segment_count = initial_vector.segment_domain.ids().len();
|
||||
|
||||
let existing_layer_id = {
|
||||
let document = editor.active_document();
|
||||
@@ -636,8 +635,8 @@ mod test_freehand {
|
||||
)
|
||||
.await;
|
||||
|
||||
let final_vector_data = get_vector_data(&mut editor).await;
|
||||
assert!(!final_vector_data.is_empty(), "No vector data found after second drawing");
|
||||
let final_vector_and_transform = get_vector_and_transform_list(&mut editor).await;
|
||||
assert!(!final_vector_and_transform.is_empty(), "No vector geometry found after second drawing");
|
||||
|
||||
// Verify we still have only one layer
|
||||
let layer_count = {
|
||||
@@ -646,9 +645,9 @@ mod test_freehand {
|
||||
};
|
||||
assert_eq!(layer_count, 1, "Expected only one layer after drawing with Shift key");
|
||||
|
||||
let (final_data, _) = &final_vector_data[0];
|
||||
let final_point_count = final_data.point_domain.ids().len();
|
||||
let final_segment_count = final_data.segment_domain.ids().len();
|
||||
let (final_vector, _) = &final_vector_and_transform[0];
|
||||
let final_point_count = final_vector.point_domain.ids().len();
|
||||
let final_segment_count = final_vector.segment_domain.ids().len();
|
||||
|
||||
assert!(
|
||||
final_point_count > initial_point_count,
|
||||
|
||||
@@ -27,8 +27,8 @@ use graphene_std::renderer::Quad;
|
||||
use graphene_std::transform::ReferencePoint;
|
||||
use graphene_std::uuid::NodeId;
|
||||
use graphene_std::vector::click_target::ClickTargetType;
|
||||
use graphene_std::vector::{HandleExt, HandleId, NoHashBuilder, SegmentId, VectorData};
|
||||
use graphene_std::vector::{ManipulatorPointId, PointId, VectorModificationType};
|
||||
use graphene_std::vector::misc::{HandleId, ManipulatorPointId};
|
||||
use graphene_std::vector::{HandleExt, NoHashBuilder, PointId, SegmentId, Vector, VectorModificationType};
|
||||
use std::vec;
|
||||
|
||||
#[derive(Default, ExtractField)]
|
||||
@@ -285,7 +285,7 @@ impl LayoutHolder for PathTool {
|
||||
.selected_index(Some(self.options.path_overlay_mode as u32))
|
||||
.widget_holder();
|
||||
|
||||
// Works only if a single layer is selected and its type is vectordata
|
||||
// Works only if a single layer is selected and its type is Vector
|
||||
let path_node_button = TextButton::new("Make Path Editable")
|
||||
.icon(Some("NodeShape".into()))
|
||||
.tooltip("Make Path Editable")
|
||||
@@ -619,10 +619,10 @@ impl PathToolData {
|
||||
self.can_toggle_colinearity = match &selection_status {
|
||||
SelectionStatus::None => false,
|
||||
SelectionStatus::One(single_selected_point) => {
|
||||
let vector_data = document.network_interface.compute_modified_vector(single_selected_point.layer).unwrap();
|
||||
if single_selected_point.id.get_handle_pair(&vector_data).is_some() {
|
||||
let anchor = single_selected_point.id.get_anchor(&vector_data).expect("Cannot find connected anchor");
|
||||
vector_data.all_connected(anchor).count() <= 2
|
||||
let vector = document.network_interface.compute_modified_vector(single_selected_point.layer).unwrap();
|
||||
if single_selected_point.id.get_handle_pair(&vector).is_some() {
|
||||
let anchor = single_selected_point.id.get_anchor(&vector).expect("Cannot find connected anchor");
|
||||
vector.all_connected(anchor).count() <= 2
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@@ -761,13 +761,13 @@ impl PathToolData {
|
||||
if handle_drag_from_anchor {
|
||||
if let Some((layer, point)) = shape_editor.find_nearest_point_indices(&document.network_interface, input.mouse.position, SELECTION_THRESHOLD) {
|
||||
// Check that selected point is an anchor
|
||||
if let (Some(point_id), Some(vector_data)) = (point.as_anchor(), document.network_interface.compute_modified_vector(layer)) {
|
||||
let handles = vector_data.all_connected(point_id).collect::<Vec<_>>();
|
||||
if let (Some(point_id), Some(vector)) = (point.as_anchor(), document.network_interface.compute_modified_vector(layer)) {
|
||||
let handles = vector.all_connected(point_id).collect::<Vec<_>>();
|
||||
self.alt_clicked_on_anchor = true;
|
||||
for handle in &handles {
|
||||
let modification_type = handle.set_relative_position(DVec2::ZERO);
|
||||
responses.add(GraphOperationMessage::Vector { layer, modification_type });
|
||||
for &handles in &vector_data.colinear_manipulators {
|
||||
for &handles in &vector.colinear_manipulators {
|
||||
if handles.contains(handle) {
|
||||
let modification_type = VectorModificationType::SetG1Continuous { handles, enabled: false };
|
||||
responses.add(GraphOperationMessage::Vector { layer, modification_type });
|
||||
@@ -783,16 +783,16 @@ impl PathToolData {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some((Some(point), Some(vector_data))) = shape_editor
|
||||
if let Some((Some(point), Some(vector))) = shape_editor
|
||||
.find_nearest_point_indices(&document.network_interface, input.mouse.position, SELECTION_THRESHOLD)
|
||||
.map(|(layer, point)| (point.as_anchor(), document.network_interface.compute_modified_vector(layer)))
|
||||
{
|
||||
let handles = vector_data
|
||||
let handles = vector
|
||||
.all_connected(point)
|
||||
.filter(|handle| handle.length(&vector_data) < 1e-6)
|
||||
.filter(|handle| handle.length(&vector) < 1e-6)
|
||||
.map(|handle| handle.to_manipulator_point())
|
||||
.collect::<Vec<_>>();
|
||||
let endpoint = vector_data.extendable_points(false).any(|anchor| point == anchor);
|
||||
let endpoint = vector.extendable_points(false).any(|anchor| point == anchor);
|
||||
|
||||
if drag_zero_handle && (handles.len() == 1 && !endpoint) {
|
||||
shape_editor.deselect_all_points();
|
||||
@@ -883,27 +883,25 @@ impl PathToolData {
|
||||
let mut manipulators = HashMap::with_hasher(NoHashBuilder);
|
||||
let mut unselected = Vec::new();
|
||||
for (&layer, state) in &shape_editor.selected_shape_state {
|
||||
let Some(vector_data) = document.network_interface.compute_modified_vector(layer) else {
|
||||
continue;
|
||||
};
|
||||
let Some(vector) = document.network_interface.compute_modified_vector(layer) else { continue };
|
||||
let transform = document.metadata().transform_to_document_if_feeds(layer, &document.network_interface);
|
||||
|
||||
let mut layer_manipulators = HashSet::with_hasher(NoHashBuilder);
|
||||
for point in state.selected_points() {
|
||||
let Some(anchor) = point.get_anchor(&vector_data) else { continue };
|
||||
let Some(anchor) = point.get_anchor(&vector) else { continue };
|
||||
layer_manipulators.insert(anchor);
|
||||
let Some([handle1, handle2]) = point.get_handle_pair(&vector_data) else { continue };
|
||||
let Some([handle1, handle2]) = point.get_handle_pair(&vector) else { continue };
|
||||
let Some(handle) = point.as_handle() else { continue };
|
||||
// Check which handle is selected and which is opposite
|
||||
let opposite = if handle == handle1 { handle2 } else { handle1 };
|
||||
|
||||
self.opposite_handle_position = if self.opposite_handle_position.is_none() {
|
||||
opposite.to_manipulator_point().get_position(&vector_data)
|
||||
opposite.to_manipulator_point().get_position(&vector)
|
||||
} else {
|
||||
self.opposite_handle_position
|
||||
};
|
||||
}
|
||||
for (&id, &position) in vector_data.point_domain.ids().iter().zip(vector_data.point_domain.positions()) {
|
||||
for (&id, &position) in vector.point_domain.ids().iter().zip(vector.point_domain.positions()) {
|
||||
if layer_manipulators.contains(&id) {
|
||||
continue;
|
||||
}
|
||||
@@ -956,17 +954,17 @@ impl PathToolData {
|
||||
return false;
|
||||
};
|
||||
|
||||
let Some(vector_data) = document.network_interface.compute_modified_vector(*layer) else {
|
||||
let Some(vector) = document.network_interface.compute_modified_vector(*layer) else {
|
||||
self.opposing_handle_lengths = Some(shape_editor.opposing_handle_lengths(document));
|
||||
return false;
|
||||
};
|
||||
|
||||
// Check if handle has a pair (to ignore handles of edges of open paths)
|
||||
if let Some(handle_pair) = selected_handle_id.get_handle_pair(&vector_data) {
|
||||
if let Some(handle_pair) = selected_handle_id.get_handle_pair(&vector) {
|
||||
let opposite_handle_length = handle_pair.iter().filter(|&&h| h.to_manipulator_point() != selected_handle_id).find_map(|&h| {
|
||||
let opp_handle_pos = h.to_manipulator_point().get_position(&vector_data)?;
|
||||
let opp_anchor_id = h.to_manipulator_point().get_anchor(&vector_data)?;
|
||||
let opp_anchor_pos = vector_data.point_domain.position_from_id(opp_anchor_id)?;
|
||||
let opp_handle_pos = h.to_manipulator_point().get_position(&vector)?;
|
||||
let opp_anchor_id = h.to_manipulator_point().get_anchor(&vector)?;
|
||||
let opp_anchor_pos = vector.point_domain.position_from_id(opp_anchor_id)?;
|
||||
Some((opp_handle_pos - opp_anchor_pos).length())
|
||||
});
|
||||
|
||||
@@ -997,11 +995,11 @@ impl PathToolData {
|
||||
let handle_id = selected_handle.to_manipulator_point();
|
||||
|
||||
let layer_to_document = document.metadata().transform_to_document_if_feeds(*layer, &document.network_interface);
|
||||
let vector_data = document.network_interface.compute_modified_vector(*layer)?;
|
||||
let vector = document.network_interface.compute_modified_vector(*layer)?;
|
||||
|
||||
let handle_position_local = selected_handle.to_manipulator_point().get_position(&vector_data)?;
|
||||
let anchor_id = selected_handle.to_manipulator_point().get_anchor(&vector_data)?;
|
||||
let anchor_position_local = vector_data.point_domain.position_from_id(anchor_id)?;
|
||||
let handle_position_local = selected_handle.to_manipulator_point().get_position(&vector)?;
|
||||
let anchor_id = selected_handle.to_manipulator_point().get_anchor(&vector)?;
|
||||
let anchor_position_local = vector.point_domain.position_from_id(anchor_id)?;
|
||||
|
||||
let handle_position_document = layer_to_document.transform_point2(handle_position_local);
|
||||
let anchor_position_document = layer_to_document.transform_point2(anchor_position_local);
|
||||
@@ -1024,24 +1022,24 @@ impl PathToolData {
|
||||
) -> f64 {
|
||||
let current_angle = -handle_vector.angle_to(DVec2::X);
|
||||
|
||||
if let Some((vector_data, layer)) = shape_editor
|
||||
if let Some((vector, layer)) = shape_editor
|
||||
.selected_shape_state
|
||||
.iter()
|
||||
.next()
|
||||
.and_then(|(layer, _)| document.network_interface.compute_modified_vector(*layer).map(|vector_data| (vector_data, layer)))
|
||||
.and_then(|(layer, _)| document.network_interface.compute_modified_vector(*layer).map(|vector| (vector, layer)))
|
||||
{
|
||||
let adjacent_anchor = check_handle_over_adjacent_anchor(handle_id, &vector_data);
|
||||
let adjacent_anchor = check_handle_over_adjacent_anchor(handle_id, &vector);
|
||||
let mut required_angle = None;
|
||||
|
||||
// If the handle is dragged over one of its adjacent anchors while holding down the Ctrl key, compute the angle based on the tangent formed with the neighboring anchor points.
|
||||
if adjacent_anchor.is_some() && lock_angle && !self.angle_locked {
|
||||
let anchor = handle_id.get_anchor(&vector_data);
|
||||
let (angle, anchor_position) = calculate_adjacent_anchor_tangent(handle_id, anchor, adjacent_anchor, &vector_data);
|
||||
let anchor = handle_id.get_anchor(&vector);
|
||||
let (angle, anchor_position) = calculate_adjacent_anchor_tangent(handle_id, anchor, adjacent_anchor, &vector);
|
||||
|
||||
let layer_to_document = document.metadata().transform_to_document_if_feeds(*layer, &document.network_interface);
|
||||
|
||||
self.adjacent_anchor_offset = handle_id
|
||||
.get_anchor_position(&vector_data)
|
||||
.get_anchor_position(&vector)
|
||||
.and_then(|handle_anchor| anchor_position.map(|adjacent_anchor| layer_to_document.transform_point2(adjacent_anchor) - layer_to_document.transform_point2(handle_anchor)));
|
||||
|
||||
required_angle = angle;
|
||||
@@ -1049,7 +1047,7 @@ impl PathToolData {
|
||||
|
||||
// If the handle is dragged near its adjacent anchors while holding down the Ctrl key, compute the angle using the tangent direction of neighboring segments.
|
||||
if relative_vector.length() < 25. && lock_angle && !self.angle_locked {
|
||||
required_angle = calculate_lock_angle(self, shape_editor, responses, document, &vector_data, handle_id, tangent_to_neighboring_tangents);
|
||||
required_angle = calculate_lock_angle(self, shape_editor, responses, document, &vector, handle_id, tangent_to_neighboring_tangents);
|
||||
}
|
||||
|
||||
// Finalize and apply angle locking if a valid target angle was determined.
|
||||
@@ -1158,17 +1156,17 @@ impl PathToolData {
|
||||
self.snapping_axis = None;
|
||||
}
|
||||
|
||||
fn get_normalized_tangent(&mut self, point: PointId, segment: SegmentId, vector_data: &VectorData) -> Option<DVec2> {
|
||||
let other_point = vector_data.other_point(segment, point)?;
|
||||
let position = ManipulatorPointId::Anchor(point).get_position(vector_data)?;
|
||||
fn get_normalized_tangent(&mut self, point: PointId, segment: SegmentId, vector: &Vector) -> Option<DVec2> {
|
||||
let other_point = vector.other_point(segment, point)?;
|
||||
let position = ManipulatorPointId::Anchor(point).get_position(vector)?;
|
||||
|
||||
let mut handles = vector_data.all_connected(other_point);
|
||||
let mut handles = vector.all_connected(other_point);
|
||||
let other_handle = handles.find(|handle| handle.segment == segment)?;
|
||||
|
||||
let target_position = if other_handle.length(vector_data) == 0. {
|
||||
ManipulatorPointId::Anchor(other_point).get_position(vector_data)?
|
||||
let target_position = if other_handle.length(vector) == 0. {
|
||||
ManipulatorPointId::Anchor(other_point).get_position(vector)?
|
||||
} else {
|
||||
other_handle.to_manipulator_point().get_position(vector_data)?
|
||||
other_handle.to_manipulator_point().get_position(vector)?
|
||||
};
|
||||
|
||||
let tangent_vector = target_position - position;
|
||||
@@ -1207,19 +1205,17 @@ impl PathToolData {
|
||||
let Some(layer) = document.network_interface.selected_nodes().selected_layers(document.metadata()).next() else {
|
||||
return false;
|
||||
};
|
||||
let Some(vector_data) = document.network_interface.compute_modified_vector(layer) else {
|
||||
return false;
|
||||
};
|
||||
let Some(vector) = document.network_interface.compute_modified_vector(layer) else { return false };
|
||||
|
||||
// Check that the handles of anchor point are also colinear
|
||||
if !vector_data.colinear(*anchor) {
|
||||
if !vector.colinear(*anchor) {
|
||||
return false;
|
||||
};
|
||||
|
||||
let Some(point_id) = anchor.as_anchor() else { return false };
|
||||
|
||||
let mut connected_segments = [None, None];
|
||||
for (segment, bezier, start, end) in vector_data.segment_bezier_iter() {
|
||||
for (segment, bezier, start, end) in vector.segment_bezier_iter() {
|
||||
if start == point_id || end == point_id {
|
||||
match (connected_segments[0], connected_segments[1]) {
|
||||
(None, None) => connected_segments[0] = Some(SlidingSegmentData { segment_id: segment, bezier, start }),
|
||||
@@ -1253,7 +1249,7 @@ impl PathToolData {
|
||||
let anchor = sliding_point_info.anchor;
|
||||
let layer = sliding_point_info.layer;
|
||||
|
||||
let Some(vector_data) = network_interface.compute_modified_vector(layer) else { return };
|
||||
let Some(vector) = network_interface.compute_modified_vector(layer) else { return };
|
||||
let transform = network_interface.document_metadata().transform_to_viewport_if_feeds(layer, network_interface);
|
||||
let layer_pos = transform.inverse().transform_point2(target_position);
|
||||
|
||||
@@ -1272,12 +1268,12 @@ impl PathToolData {
|
||||
};
|
||||
|
||||
// Move the anchor to the new position
|
||||
let Some(current_position) = ManipulatorPointId::Anchor(anchor).get_position(&vector_data) else {
|
||||
let Some(current_position) = ManipulatorPointId::Anchor(anchor).get_position(&vector) else {
|
||||
return;
|
||||
};
|
||||
let delta = new_position - current_position;
|
||||
|
||||
shape_editor.move_anchor(anchor, &vector_data, delta, layer, None, responses);
|
||||
shape_editor.move_anchor(anchor, &vector, delta, layer, None, responses);
|
||||
|
||||
// Make a split at the t_value
|
||||
let [first, second] = closer_segment.bezier.split(TValue::Parametric(t_value));
|
||||
@@ -1419,19 +1415,19 @@ impl PathToolData {
|
||||
let Some(layer) = document.network_interface.selected_nodes().selected_layers(document.metadata()).next() else {
|
||||
return;
|
||||
};
|
||||
let Some(vector_data) = document.network_interface.compute_modified_vector(layer) else { return };
|
||||
let Some(point_id) = shape_editor.selected_points().next().unwrap().get_anchor(&vector_data) else {
|
||||
let Some(vector) = document.network_interface.compute_modified_vector(layer) else { return };
|
||||
let Some(point_id) = shape_editor.selected_points().next().unwrap().get_anchor(&vector) else {
|
||||
return;
|
||||
};
|
||||
|
||||
if vector_data.connected_count(point_id) == 2 {
|
||||
let connected_segments: Vec<HandleId> = vector_data.all_connected(point_id).collect();
|
||||
if vector.connected_count(point_id) == 2 {
|
||||
let connected_segments: Vec<HandleId> = vector.all_connected(point_id).collect();
|
||||
let segment1 = connected_segments[0];
|
||||
let Some(tangent1) = self.get_normalized_tangent(point_id, segment1.segment, &vector_data) else {
|
||||
let Some(tangent1) = self.get_normalized_tangent(point_id, segment1.segment, &vector) else {
|
||||
return;
|
||||
};
|
||||
let segment2 = connected_segments[1];
|
||||
let Some(tangent2) = self.get_normalized_tangent(point_id, segment2.segment, &vector_data) else {
|
||||
let Some(tangent2) = self.get_normalized_tangent(point_id, segment2.segment, &vector) else {
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -1565,11 +1561,11 @@ impl Fsm for PathToolFsmState {
|
||||
let selected_layers = shape_editor.selected_layers().cloned().collect::<Vec<_>>();
|
||||
|
||||
for layer in selected_layers {
|
||||
let Some(vector_data) = document.network_interface.compute_modified_vector(layer) else { continue };
|
||||
let Some(vector) = document.network_interface.compute_modified_vector(layer) else { continue };
|
||||
|
||||
let selected_state = shape_editor.selected_shape_state.entry(layer).or_default();
|
||||
|
||||
for (segment, _, start, end) in vector_data.segment_bezier_iter() {
|
||||
for (segment, _, start, end) in vector.segment_bezier_iter() {
|
||||
if selected_state.is_segment_selected(segment) {
|
||||
selected_state.select_point(ManipulatorPointId::Anchor(start));
|
||||
selected_state.select_point(ManipulatorPointId::Anchor(end));
|
||||
@@ -1610,11 +1606,11 @@ impl Fsm for PathToolFsmState {
|
||||
let selected_layers = shape_editor.selected_layers().cloned().collect::<Vec<_>>();
|
||||
|
||||
for layer in selected_layers {
|
||||
let Some(vector_data) = document.network_interface.compute_modified_vector(layer) else { continue };
|
||||
let Some(vector) = document.network_interface.compute_modified_vector(layer) else { continue };
|
||||
|
||||
let selected_state = shape_editor.selected_shape_state.entry(layer).or_default();
|
||||
|
||||
for (segment, _, start, end) in vector_data.segment_bezier_iter() {
|
||||
for (segment, _, start, end) in vector.segment_bezier_iter() {
|
||||
let first_selected = selected_state.is_point_selected(ManipulatorPointId::Anchor(start));
|
||||
let second_selected = selected_state.is_point_selected(ManipulatorPointId::Anchor(end));
|
||||
if first_selected && second_selected {
|
||||
@@ -1663,12 +1659,12 @@ impl Fsm for PathToolFsmState {
|
||||
let mut segment_endpoints: HashMap<SegmentId, Vec<PointId>> = HashMap::new();
|
||||
|
||||
for layer in document.network_interface.selected_nodes().selected_layers(document.metadata()) {
|
||||
let Some(vector_data) = document.network_interface.compute_modified_vector(layer) else { continue };
|
||||
let Some(vector) = document.network_interface.compute_modified_vector(layer) else { continue };
|
||||
|
||||
// The points which are part of only one segment will be rendered
|
||||
let mut selected_segments_by_point: HashMap<PointId, Vec<SegmentId>> = HashMap::new();
|
||||
|
||||
for (segment_id, _bezier, start, end) in vector_data.segment_bezier_iter() {
|
||||
for (segment_id, _bezier, start, end) in vector.segment_bezier_iter() {
|
||||
if selected_segments.contains(&segment_id) {
|
||||
selected_segments_by_point.entry(start).or_default().push(segment_id);
|
||||
selected_segments_by_point.entry(end).or_default().push(segment_id);
|
||||
@@ -1721,8 +1717,8 @@ impl Fsm for PathToolFsmState {
|
||||
);
|
||||
|
||||
let Some((layer, manipulator_point_id)) = nearest_visible_point_indices else { return };
|
||||
let Some(vector_data) = document.network_interface.compute_modified_vector(layer) else { return };
|
||||
let Some(position) = manipulator_point_id.get_position(&vector_data) else {
|
||||
let Some(vector) = document.network_interface.compute_modified_vector(layer) else { return };
|
||||
let Some(position) = manipulator_point_id.get_position(&vector) else {
|
||||
error!("No position for hovered point");
|
||||
return;
|
||||
};
|
||||
@@ -1847,10 +1843,10 @@ impl Fsm for PathToolFsmState {
|
||||
};
|
||||
|
||||
for (layer, points) in points_inside {
|
||||
let Some(vector_data) = document.network_interface.compute_modified_vector(layer) else { continue };
|
||||
let Some(vector) = document.network_interface.compute_modified_vector(layer) else { continue };
|
||||
|
||||
for point in points {
|
||||
let Some(position) = point.get_position(&vector_data) else { continue };
|
||||
let Some(position) = point.get_position(&vector) else { continue };
|
||||
|
||||
let transform = document.metadata().transform_to_viewport(layer);
|
||||
let position = transform.transform_point2(position);
|
||||
@@ -1865,11 +1861,11 @@ impl Fsm for PathToolFsmState {
|
||||
}
|
||||
|
||||
for (layer, segments) in segments_inside {
|
||||
let Some(vector_data) = document.network_interface.compute_modified_vector(layer) else { continue };
|
||||
let Some(vector) = document.network_interface.compute_modified_vector(layer) else { continue };
|
||||
|
||||
let transform = document.metadata().transform_to_viewport_if_feeds(layer, &document.network_interface);
|
||||
|
||||
for (segment, bezier, _, _) in vector_data.segment_bezier_iter() {
|
||||
for (segment, bezier, _, _) in vector.segment_bezier_iter() {
|
||||
if segments.contains(&segment) {
|
||||
overlay_context.outline_overlay_bezier(bezier, transform);
|
||||
}
|
||||
@@ -2392,8 +2388,8 @@ impl Fsm for PathToolFsmState {
|
||||
|
||||
if !drag_occurred && !tool_data.molding_segment && ((point_mode && !segment_mode) || (segment_mode && tool_data.segment_editing_modifier)) {
|
||||
if tool_data.delete_segment_pressed {
|
||||
if let Some(vector_data) = document.network_interface.compute_modified_vector(segment.layer()) {
|
||||
shape_editor.dissolve_segment(responses, segment.layer(), &vector_data, segment.segment(), segment.points());
|
||||
if let Some(vector) = document.network_interface.compute_modified_vector(segment.layer()) {
|
||||
shape_editor.dissolve_segment(responses, segment.layer(), &vector, segment.segment(), segment.points());
|
||||
}
|
||||
} else {
|
||||
let is_segment_selected = shape_editor
|
||||
@@ -2580,17 +2576,15 @@ impl Fsm for PathToolFsmState {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Some(old_vector_data) = document.network_interface.compute_modified_vector(layer) else {
|
||||
continue;
|
||||
};
|
||||
let Some(old_vector) = document.network_interface.compute_modified_vector(layer) else { continue };
|
||||
|
||||
// Also get the transform node that is applied on the layer if it exists
|
||||
let transform = document.metadata().transform_to_document(layer);
|
||||
|
||||
let mut new_vector_data = VectorData::default();
|
||||
let mut new_vector = Vector::default();
|
||||
|
||||
let mut selected_points_by_segment = HashSet::new();
|
||||
old_vector_data
|
||||
old_vector
|
||||
.segment_bezier_iter()
|
||||
.filter(|(segment, _, _, _)| layer_selection_state.is_segment_selected(*segment))
|
||||
.for_each(|(_, _, start, end)| {
|
||||
@@ -2599,16 +2593,16 @@ impl Fsm for PathToolFsmState {
|
||||
});
|
||||
|
||||
// Add all the selected points
|
||||
for (point, position) in old_vector_data.point_domain.iter() {
|
||||
for (point, position) in old_vector.point_domain.iter() {
|
||||
if layer_selection_state.is_point_selected(ManipulatorPointId::Anchor(point)) || selected_points_by_segment.contains(&point) {
|
||||
new_vector_data.point_domain.push(point, position);
|
||||
new_vector.point_domain.push(point, position);
|
||||
}
|
||||
}
|
||||
|
||||
let find_index = |id: PointId| new_vector_data.point_domain.iter().enumerate().find(|(_, (point_id, _))| *point_id == id).map(|(index, _)| index);
|
||||
let find_index = |id: PointId| new_vector.point_domain.iter().enumerate().find(|(_, (point_id, _))| *point_id == id).map(|(index, _)| index);
|
||||
|
||||
// Add segments which have selected ends
|
||||
for ((segment_id, bezier, start, end), stroke) in old_vector_data.segment_bezier_iter().zip(old_vector_data.segment_domain.stroke().iter()) {
|
||||
for ((segment_id, bezier, start, end), stroke) in old_vector.segment_bezier_iter().zip(old_vector.segment_domain.stroke().iter()) {
|
||||
let both_ends_selected = layer_selection_state.is_point_selected(ManipulatorPointId::Anchor(start)) && layer_selection_state.is_point_selected(ManipulatorPointId::Anchor(end));
|
||||
|
||||
let segment_selected = layer_selection_state.is_segment_selected(segment_id);
|
||||
@@ -2618,17 +2612,17 @@ impl Fsm for PathToolFsmState {
|
||||
error!("Point does not exist in point domain");
|
||||
return PathToolFsmState::Ready;
|
||||
};
|
||||
new_vector_data.segment_domain.push(segment_id, start_index, end_index, bezier.handles, *stroke);
|
||||
new_vector.segment_domain.push(segment_id, start_index, end_index, bezier.handles, *stroke);
|
||||
}
|
||||
}
|
||||
|
||||
for handles in old_vector_data.colinear_manipulators {
|
||||
if new_vector_data.segment_domain.ids().contains(&handles[0].segment) && new_vector_data.segment_domain.ids().contains(&handles[1].segment) {
|
||||
new_vector_data.colinear_manipulators.push(handles);
|
||||
for handles in old_vector.colinear_manipulators {
|
||||
if new_vector.segment_domain.ids().contains(&handles[0].segment) && new_vector.segment_domain.ids().contains(&handles[1].segment) {
|
||||
new_vector.colinear_manipulators.push(handles);
|
||||
}
|
||||
}
|
||||
|
||||
buffer.push((layer, new_vector_data, transform));
|
||||
buffer.push((layer, new_vector, transform));
|
||||
}
|
||||
|
||||
if clipboard == Clipboard::Device {
|
||||
@@ -2650,7 +2644,7 @@ impl Fsm for PathToolFsmState {
|
||||
}
|
||||
(_, PathToolMessage::Paste { data }) => {
|
||||
// Deserialize the data
|
||||
if let Ok(data) = serde_json::from_str::<Vec<(LayerNodeIdentifier, VectorData, DAffine2)>>(&data) {
|
||||
if let Ok(data) = serde_json::from_str::<Vec<(LayerNodeIdentifier, Vector, DAffine2)>>(&data) {
|
||||
shape_editor.deselect_all_points();
|
||||
responses.add(DocumentMessage::AddTransaction);
|
||||
let mut new_layers = Vec::new();
|
||||
@@ -2690,7 +2684,7 @@ impl Fsm for PathToolFsmState {
|
||||
layer
|
||||
};
|
||||
|
||||
// Create new point ids and add those into the existing vector data
|
||||
// Create new point ids and add those into the existing vector content
|
||||
let mut points_map = HashMap::new();
|
||||
for (point, position) in new_vector.point_domain.iter() {
|
||||
let new_point_id = PointId::generate();
|
||||
@@ -2701,7 +2695,7 @@ impl Fsm for PathToolFsmState {
|
||||
responses.add(GraphOperationMessage::Vector { layer, modification_type });
|
||||
}
|
||||
|
||||
// Create new segment ids and add the segments into the existing vector data
|
||||
// Create new segment ids and add the segments into the existing vector content
|
||||
let mut segments_map = HashMap::new();
|
||||
for (segment_id, bezier, start, end) in new_vector.segment_bezier_iter() {
|
||||
let new_segment_id = SegmentId::generate();
|
||||
@@ -2777,13 +2771,13 @@ impl Fsm for PathToolFsmState {
|
||||
if layer_selection_state.is_empty() {
|
||||
continue;
|
||||
}
|
||||
let Some(old_vector_data) = document.network_interface.compute_modified_vector(layer) else {
|
||||
let Some(old_vector) = document.network_interface.compute_modified_vector(layer) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// Add all the selected points
|
||||
let mut selected_points_by_segment = HashSet::new();
|
||||
old_vector_data
|
||||
old_vector
|
||||
.segment_bezier_iter()
|
||||
.filter(|(segment, _, _, _)| layer_selection_state.is_segment_selected(*segment))
|
||||
.for_each(|(_, _, start, end)| {
|
||||
@@ -2792,7 +2786,7 @@ impl Fsm for PathToolFsmState {
|
||||
});
|
||||
|
||||
let mut points_map = HashMap::new();
|
||||
for (point, position) in old_vector_data.point_domain.iter() {
|
||||
for (point, position) in old_vector.point_domain.iter() {
|
||||
// TODO: Either the point is selected or it is an endpoint of a selected segment
|
||||
|
||||
if layer_selection_state.is_point_selected(ManipulatorPointId::Anchor(point)) || selected_points_by_segment.contains(&point) {
|
||||
@@ -2808,7 +2802,7 @@ impl Fsm for PathToolFsmState {
|
||||
|
||||
let mut segments_map = HashMap::new();
|
||||
|
||||
for (segment_id, bezier, start, end) in old_vector_data.segment_bezier_iter() {
|
||||
for (segment_id, bezier, start, end) in old_vector.segment_bezier_iter() {
|
||||
let both_ends_selected = layer_selection_state.is_point_selected(ManipulatorPointId::Anchor(start)) && layer_selection_state.is_point_selected(ManipulatorPointId::Anchor(end));
|
||||
|
||||
let segment_selected = layer_selection_state.is_segment_selected(segment_id);
|
||||
@@ -2830,7 +2824,7 @@ impl Fsm for PathToolFsmState {
|
||||
}
|
||||
}
|
||||
|
||||
for handles in old_vector_data.colinear_manipulators {
|
||||
for handles in old_vector.colinear_manipulators {
|
||||
let to_new_handle = |handle: HandleId| -> HandleId {
|
||||
HandleId {
|
||||
ty: handle.ty,
|
||||
@@ -3104,13 +3098,13 @@ fn get_selection_status(network_interface: &NodeNetworkInterface, shape_state: &
|
||||
let Some(layer) = selection_layers.find(|(_, v)| *v > 0).map(|(k, _)| k) else {
|
||||
return SelectionStatus::None;
|
||||
};
|
||||
let Some(vector_data) = network_interface.compute_modified_vector(layer) else {
|
||||
let Some(vector) = network_interface.compute_modified_vector(layer) else {
|
||||
return SelectionStatus::None;
|
||||
};
|
||||
let Some(&point) = shape_state.selected_points().next() else {
|
||||
return SelectionStatus::None;
|
||||
};
|
||||
let Some(local_position) = point.get_position(&vector_data) else {
|
||||
let Some(local_position) = point.get_position(&vector) else {
|
||||
return SelectionStatus::None;
|
||||
};
|
||||
|
||||
@@ -3118,7 +3112,7 @@ fn get_selection_status(network_interface: &NodeNetworkInterface, shape_state: &
|
||||
.document_metadata()
|
||||
.transform_to_document_if_feeds(layer, network_interface)
|
||||
.transform_point2(local_position);
|
||||
let manipulator_angle = if vector_data.colinear(point) { ManipulatorAngle::Colinear } else { ManipulatorAngle::Free };
|
||||
let manipulator_angle = if vector.colinear(point) { ManipulatorAngle::Colinear } else { ManipulatorAngle::Free };
|
||||
|
||||
return SelectionStatus::One(SingleSelectedPoint {
|
||||
coordinates,
|
||||
@@ -3143,40 +3137,40 @@ fn calculate_lock_angle(
|
||||
shape_state: &mut ShapeState,
|
||||
responses: &mut VecDeque<Message>,
|
||||
document: &DocumentMessageHandler,
|
||||
vector_data: &VectorData,
|
||||
vector: &Vector,
|
||||
handle_id: ManipulatorPointId,
|
||||
tangent_to_neighboring_tangents: bool,
|
||||
) -> Option<f64> {
|
||||
let anchor = handle_id.get_anchor(vector_data)?;
|
||||
let anchor_position = vector_data.point_domain.position_from_id(anchor);
|
||||
let anchor = handle_id.get_anchor(vector)?;
|
||||
let anchor_position = vector.point_domain.position_from_id(anchor);
|
||||
let current_segment = handle_id.get_segment();
|
||||
let points_connected = vector_data.connected_count(anchor);
|
||||
let points_connected = vector.connected_count(anchor);
|
||||
|
||||
let (anchor_position, segment) = anchor_position.zip(current_segment)?;
|
||||
if points_connected == 1 {
|
||||
calculate_segment_angle(anchor, segment, vector_data, false)
|
||||
calculate_segment_angle(anchor, segment, vector, false)
|
||||
} else {
|
||||
let opposite_handle = handle_id
|
||||
.get_handle_pair(vector_data)
|
||||
.get_handle_pair(vector)
|
||||
.iter()
|
||||
.flatten()
|
||||
.find(|&h| h.to_manipulator_point() != handle_id)
|
||||
.copied()
|
||||
.map(|h| h.to_manipulator_point());
|
||||
let opposite_handle_position = opposite_handle.and_then(|h| h.get_position(vector_data)).filter(|pos| (pos - anchor_position).length() > 1e-6);
|
||||
let opposite_handle_position = opposite_handle.and_then(|h| h.get_position(vector)).filter(|pos| (pos - anchor_position).length() > 1e-6);
|
||||
|
||||
if let Some(opposite_pos) = opposite_handle_position {
|
||||
if !vector_data.colinear_manipulators.iter().flatten().map(|h| h.to_manipulator_point()).any(|h| h == handle_id) {
|
||||
if !vector.colinear_manipulators.iter().flatten().map(|h| h.to_manipulator_point()).any(|h| h == handle_id) {
|
||||
shape_state.convert_selected_manipulators_to_colinear_handles(responses, document);
|
||||
tool_data.temporary_colinear_handles = true;
|
||||
}
|
||||
Some(-(opposite_pos - anchor_position).angle_to(DVec2::X))
|
||||
} else {
|
||||
let angle_1 = vector_data
|
||||
let angle_1 = vector
|
||||
.adjacent_segment(&handle_id)
|
||||
.and_then(|(_, adjacent_segment)| calculate_segment_angle(anchor, adjacent_segment, vector_data, false));
|
||||
.and_then(|(_, adjacent_segment)| calculate_segment_angle(anchor, adjacent_segment, vector, false));
|
||||
|
||||
let angle_2 = calculate_segment_angle(anchor, segment, vector_data, false);
|
||||
let angle_2 = calculate_segment_angle(anchor, segment, vector, false);
|
||||
|
||||
match (angle_1, angle_2) {
|
||||
(Some(angle_1), Some(angle_2)) => {
|
||||
@@ -3195,37 +3189,32 @@ fn calculate_lock_angle(
|
||||
}
|
||||
}
|
||||
|
||||
fn check_handle_over_adjacent_anchor(handle_id: ManipulatorPointId, vector_data: &VectorData) -> Option<PointId> {
|
||||
let (anchor, handle_position) = handle_id.get_anchor(vector_data).zip(handle_id.get_position(vector_data))?;
|
||||
fn check_handle_over_adjacent_anchor(handle_id: ManipulatorPointId, vector: &Vector) -> Option<PointId> {
|
||||
let (anchor, handle_position) = handle_id.get_anchor(vector).zip(handle_id.get_position(vector))?;
|
||||
|
||||
let check_if_close = |point_id: &PointId| {
|
||||
let Some(anchor_position) = vector_data.point_domain.position_from_id(*point_id) else {
|
||||
let Some(anchor_position) = vector.point_domain.position_from_id(*point_id) else {
|
||||
return false;
|
||||
};
|
||||
(anchor_position - handle_position).length() < 10.
|
||||
};
|
||||
|
||||
vector_data.connected_points(anchor).find(check_if_close)
|
||||
vector.connected_points(anchor).find(check_if_close)
|
||||
}
|
||||
fn calculate_adjacent_anchor_tangent(
|
||||
currently_dragged_handle: ManipulatorPointId,
|
||||
anchor: Option<PointId>,
|
||||
adjacent_anchor: Option<PointId>,
|
||||
vector_data: &VectorData,
|
||||
) -> (Option<f64>, Option<DVec2>) {
|
||||
fn calculate_adjacent_anchor_tangent(currently_dragged_handle: ManipulatorPointId, anchor: Option<PointId>, adjacent_anchor: Option<PointId>, vector: &Vector) -> (Option<f64>, Option<DVec2>) {
|
||||
// Early return if no anchor or no adjacent anchors
|
||||
|
||||
let Some((dragged_handle_anchor, adjacent_anchor)) = anchor.zip(adjacent_anchor) else {
|
||||
return (None, None);
|
||||
};
|
||||
let adjacent_anchor_position = vector_data.point_domain.position_from_id(adjacent_anchor);
|
||||
let adjacent_anchor_position = vector.point_domain.position_from_id(adjacent_anchor);
|
||||
|
||||
let handles: Vec<_> = vector_data.all_connected(adjacent_anchor).filter(|handle| handle.length(vector_data) > 1e-6).collect();
|
||||
let handles: Vec<_> = vector.all_connected(adjacent_anchor).filter(|handle| handle.length(vector) > 1e-6).collect();
|
||||
|
||||
match handles.len() {
|
||||
0 => {
|
||||
// Find non-shared segments
|
||||
let non_shared_segment: Vec<_> = vector_data
|
||||
let non_shared_segment: Vec<_> = vector
|
||||
.segment_bezier_iter()
|
||||
.filter_map(|(segment_id, _, start, end)| {
|
||||
let touches_adjacent = start == adjacent_anchor || end == adjacent_anchor;
|
||||
@@ -3237,7 +3226,7 @@ fn calculate_adjacent_anchor_tangent(
|
||||
|
||||
match non_shared_segment.first() {
|
||||
Some(&segment) => {
|
||||
let angle = calculate_segment_angle(adjacent_anchor, segment, vector_data, true);
|
||||
let angle = calculate_segment_angle(adjacent_anchor, segment, vector, true);
|
||||
(angle, adjacent_anchor_position)
|
||||
}
|
||||
None => (None, None),
|
||||
@@ -3246,7 +3235,7 @@ fn calculate_adjacent_anchor_tangent(
|
||||
|
||||
1 => {
|
||||
let segment = handles[0].segment;
|
||||
let angle = calculate_segment_angle(adjacent_anchor, segment, vector_data, true);
|
||||
let angle = calculate_segment_angle(adjacent_anchor, segment, vector, true);
|
||||
(angle, adjacent_anchor_position)
|
||||
}
|
||||
|
||||
@@ -3261,7 +3250,7 @@ fn calculate_adjacent_anchor_tangent(
|
||||
};
|
||||
|
||||
let angle = shared_segment_handle
|
||||
.get_position(vector_data)
|
||||
.get_position(vector)
|
||||
.zip(adjacent_anchor_position)
|
||||
.map(|(handle, anchor)| -(handle - anchor).angle_to(DVec2::X));
|
||||
|
||||
@@ -3296,8 +3285,8 @@ fn update_dynamic_hints(
|
||||
shape_editor.selected_points().next(),
|
||||
document.network_interface.selected_nodes().selected_layers(document.metadata()).next(),
|
||||
) {
|
||||
if let Some(vector_data) = document.network_interface.compute_modified_vector(layer) {
|
||||
single_colinear_anchor_selected = vector_data.colinear(*anchor)
|
||||
if let Some(vector) = document.network_interface.compute_modified_vector(layer) {
|
||||
single_colinear_anchor_selected = vector.colinear(*anchor)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3448,9 +3437,9 @@ fn update_dynamic_hints(
|
||||
let handle1 = HandleId::primary(segment.segment());
|
||||
let handle2 = HandleId::end(segment.segment());
|
||||
|
||||
if let Some(vector_data) = document.network_interface.compute_modified_vector(segment.layer()) {
|
||||
let other_handle1 = vector_data.other_colinear_handle(handle1);
|
||||
let other_handle2 = vector_data.other_colinear_handle(handle2);
|
||||
if let Some(vector) = document.network_interface.compute_modified_vector(segment.layer()) {
|
||||
let other_handle1 = vector.other_colinear_handle(handle1);
|
||||
let other_handle2 = vector.other_colinear_handle(handle2);
|
||||
if other_handle1.is_some() || other_handle2.is_some() {
|
||||
has_colinear_anchors = true;
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@ use crate::messages::tool::common_functionality::utility_functions::{calculate_s
|
||||
use bezier_rs::{Bezier, BezierHandles};
|
||||
use graph_craft::document::NodeId;
|
||||
use graphene_std::Color;
|
||||
use graphene_std::vector::{HandleId, ManipulatorPointId, NoHashBuilder, SegmentId, StrokeId, VectorData};
|
||||
use graphene_std::vector::{PointId, VectorModificationType};
|
||||
use graphene_std::vector::misc::{HandleId, ManipulatorPointId};
|
||||
use graphene_std::vector::{NoHashBuilder, PointId, SegmentId, StrokeId, Vector, VectorModificationType};
|
||||
|
||||
#[derive(Default, ExtractField)]
|
||||
pub struct PenTool {
|
||||
@@ -395,11 +395,11 @@ impl PenToolData {
|
||||
}
|
||||
|
||||
/// Check whether target handle is primary, end, or `self.handle_end`
|
||||
fn check_end_handle_type(&self, vector_data: &VectorData) -> TargetHandle {
|
||||
fn check_end_handle_type(&self, vector: &Vector) -> TargetHandle {
|
||||
match (self.handle_end, self.prior_segment_endpoint, self.prior_segment, self.path_closed) {
|
||||
(Some(_), _, _, false) => TargetHandle::PreviewInHandle,
|
||||
(None, Some(point), Some(segment), false) | (Some(_), Some(point), Some(segment), true) => {
|
||||
if vector_data.segment_start_from_id(segment) == Some(point) {
|
||||
if vector.segment_start_from_id(segment) == Some(point) {
|
||||
TargetHandle::PriorOutHandle(segment)
|
||||
} else {
|
||||
TargetHandle::PriorInHandle(segment)
|
||||
@@ -409,23 +409,23 @@ impl PenToolData {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_grs_end_handle(&self, vector_data: &VectorData) -> TargetHandle {
|
||||
fn check_grs_end_handle(&self, vector: &Vector) -> TargetHandle {
|
||||
let Some(point) = self.latest_point().map(|point| point.id) else { return TargetHandle::None };
|
||||
let Some(segment) = self.prior_segment else { return TargetHandle::None };
|
||||
|
||||
if vector_data.segment_start_from_id(segment) == Some(point) {
|
||||
if vector.segment_start_from_id(segment) == Some(point) {
|
||||
TargetHandle::PriorOutHandle(segment)
|
||||
} else {
|
||||
TargetHandle::PriorInHandle(segment)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_opposite_handle_type(&self, handle_type: TargetHandle, vector_data: &VectorData) -> TargetHandle {
|
||||
fn get_opposite_handle_type(&self, handle_type: TargetHandle, vector: &Vector) -> TargetHandle {
|
||||
match handle_type {
|
||||
TargetHandle::FuturePreviewOutHandle => self.check_end_handle_type(vector_data),
|
||||
TargetHandle::FuturePreviewOutHandle => self.check_end_handle_type(vector),
|
||||
TargetHandle::PreviewInHandle => match (self.path_closed, self.prior_segment_endpoint, self.prior_segment) {
|
||||
(true, Some(point), Some(segment)) => {
|
||||
if vector_data.segment_start_from_id(segment) == Some(point) {
|
||||
if vector.segment_start_from_id(segment) == Some(point) {
|
||||
TargetHandle::PriorOutHandle(segment)
|
||||
} else {
|
||||
TargetHandle::PriorInHandle(segment)
|
||||
@@ -472,10 +472,10 @@ impl PenToolData {
|
||||
}
|
||||
}
|
||||
|
||||
fn target_handle_position(&self, handle_type: TargetHandle, vector_data: &VectorData) -> Option<DVec2> {
|
||||
fn target_handle_position(&self, handle_type: TargetHandle, vector: &Vector) -> Option<DVec2> {
|
||||
match handle_type {
|
||||
TargetHandle::PriorOutHandle(segment) => ManipulatorPointId::PrimaryHandle(segment).get_position(vector_data),
|
||||
TargetHandle::PriorInHandle(segment) => ManipulatorPointId::EndHandle(segment).get_position(vector_data),
|
||||
TargetHandle::PriorOutHandle(segment) => ManipulatorPointId::PrimaryHandle(segment).get_position(vector),
|
||||
TargetHandle::PriorInHandle(segment) => ManipulatorPointId::EndHandle(segment).get_position(vector),
|
||||
TargetHandle::PreviewInHandle => self.handle_end,
|
||||
TargetHandle::FuturePreviewOutHandle => Some(self.next_handle_start),
|
||||
TargetHandle::None => None,
|
||||
@@ -488,11 +488,11 @@ impl PenToolData {
|
||||
return;
|
||||
};
|
||||
|
||||
let Some(vector_data) = layer.and_then(|layer| document.network_interface.compute_modified_vector(layer)) else {
|
||||
let Some(vector) = layer.and_then(|layer| document.network_interface.compute_modified_vector(layer)) else {
|
||||
return;
|
||||
};
|
||||
|
||||
match self.check_end_handle_type(&vector_data) {
|
||||
match self.check_end_handle_type(&vector) {
|
||||
TargetHandle::PriorInHandle(segment) => shape_state.deselect_point(ManipulatorPointId::EndHandle(segment)),
|
||||
TargetHandle::PriorOutHandle(segment) => shape_state.deselect_point(ManipulatorPointId::PrimaryHandle(segment)),
|
||||
_ => {}
|
||||
@@ -518,18 +518,14 @@ impl PenToolData {
|
||||
self.latest_points.len() == 1 && self.latest_point().is_some_and(|point| point.pos == self.next_point)
|
||||
}
|
||||
|
||||
// When the vector data transform changes, the positions of the points must be recalculated.
|
||||
// When the vector transform changes, the positions of the points must be recalculated.
|
||||
fn recalculate_latest_points_position(&mut self, document: &DocumentMessageHandler) {
|
||||
let selected_nodes = document.network_interface.selected_nodes();
|
||||
let mut selected_layers = selected_nodes.selected_layers(document.metadata());
|
||||
if let (Some(layer), None) = (selected_layers.next(), selected_layers.next()) {
|
||||
let Some(vector_data) = document.network_interface.compute_modified_vector(layer) else {
|
||||
return;
|
||||
};
|
||||
let Some(vector) = document.network_interface.compute_modified_vector(layer) else { return };
|
||||
for point in &mut self.latest_points {
|
||||
let Some(pos) = vector_data.point_domain.position_from_id(point.id) else {
|
||||
continue;
|
||||
};
|
||||
let Some(pos) = vector.point_domain.position_from_id(point.id) else { continue };
|
||||
point.pos = pos;
|
||||
point.handle_start = point.pos;
|
||||
}
|
||||
@@ -549,7 +545,7 @@ impl PenToolData {
|
||||
self.g1_continuous = true;
|
||||
let document = snap_data.document;
|
||||
self.next_handle_start = self.next_point;
|
||||
let vector_data = document.network_interface.compute_modified_vector(layer).unwrap();
|
||||
let vector = document.network_interface.compute_modified_vector(layer).unwrap();
|
||||
self.update_handle_type(TargetHandle::FuturePreviewOutHandle);
|
||||
self.handle_mode = HandleMode::ColinearLocked;
|
||||
|
||||
@@ -565,7 +561,7 @@ impl PenToolData {
|
||||
self.store_clicked_endpoint(document, &transform, snap_data.input, preferences);
|
||||
|
||||
if self.modifiers.lock_angle {
|
||||
self.set_lock_angle(&vector_data, id, self.prior_segment);
|
||||
self.set_lock_angle(&vector, id, self.prior_segment);
|
||||
let last_segment = self.prior_segment;
|
||||
let Some(point) = self.latest_point_mut() else { return };
|
||||
point.in_segment = last_segment;
|
||||
@@ -579,7 +575,7 @@ impl PenToolData {
|
||||
}
|
||||
|
||||
// Closing path
|
||||
let closing_path_on_point = self.close_path_on_point(snap_data, &vector_data, document, preferences, id, &transform);
|
||||
let closing_path_on_point = self.close_path_on_point(snap_data, &vector, document, preferences, id, &transform);
|
||||
if !closing_path_on_point && preferences.vector_meshes {
|
||||
// Attempt to find nearest segment and close path on segment by creating an anchor point on it
|
||||
let tolerance = crate::consts::SNAP_POINT_TOLERANCE;
|
||||
@@ -600,24 +596,16 @@ impl PenToolData {
|
||||
|
||||
self.handle_mode = HandleMode::Free;
|
||||
if let (true, Some(prior_endpoint)) = (self.modifiers.lock_angle, self.prior_segment_endpoint) {
|
||||
self.set_lock_angle(&vector_data, prior_endpoint, self.prior_segment);
|
||||
self.set_lock_angle(&vector, prior_endpoint, self.prior_segment);
|
||||
self.switch_to_free_on_ctrl_release = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn close_path_on_point(
|
||||
&mut self,
|
||||
snap_data: SnapData,
|
||||
vector_data: &VectorData,
|
||||
document: &DocumentMessageHandler,
|
||||
preferences: &PreferencesMessageHandler,
|
||||
id: PointId,
|
||||
transform: &DAffine2,
|
||||
) -> bool {
|
||||
for id in vector_data.extendable_points(preferences.vector_meshes).filter(|&point| point != id) {
|
||||
let Some(pos) = vector_data.point_domain.position_from_id(id) else { continue };
|
||||
fn close_path_on_point(&mut self, snap_data: SnapData, vector: &Vector, document: &DocumentMessageHandler, preferences: &PreferencesMessageHandler, id: PointId, transform: &DAffine2) -> bool {
|
||||
for id in vector.extendable_points(preferences.vector_meshes).filter(|&point| point != id) {
|
||||
let Some(pos) = vector.point_domain.position_from_id(id) else { continue };
|
||||
let transformed_distance_between_squared = transform.transform_point2(pos).distance_squared(transform.transform_point2(self.next_point));
|
||||
let snap_point_tolerance_squared = crate::consts::SNAP_POINT_TOLERANCE.powi(2);
|
||||
|
||||
@@ -629,7 +617,7 @@ impl PenToolData {
|
||||
self.store_clicked_endpoint(document, transform, snap_data.input, preferences);
|
||||
self.handle_mode = HandleMode::Free;
|
||||
if let (true, Some(prior_endpoint)) = (self.modifiers.lock_angle, self.prior_segment_endpoint) {
|
||||
self.set_lock_angle(vector_data, prior_endpoint, self.prior_segment);
|
||||
self.set_lock_angle(vector, prior_endpoint, self.prior_segment);
|
||||
self.switch_to_free_on_ctrl_release = true;
|
||||
}
|
||||
return true;
|
||||
@@ -662,11 +650,11 @@ impl PenToolData {
|
||||
let selected_nodes = document.network_interface.selected_nodes();
|
||||
let mut selected_layers = selected_nodes.selected_layers(document.metadata());
|
||||
let layer = selected_layers.next().filter(|_| selected_layers.next().is_none()).or(self.current_layer)?;
|
||||
let vector_data = document.network_interface.compute_modified_vector(layer)?;
|
||||
let vector = document.network_interface.compute_modified_vector(layer)?;
|
||||
let start = self.latest_point()?.id;
|
||||
let transform = document.metadata().document_to_viewport * transform;
|
||||
for id in vector_data.extendable_points(preferences.vector_meshes).filter(|&point| point != start) {
|
||||
let Some(pos) = vector_data.point_domain.position_from_id(id) else { continue };
|
||||
for id in vector.extendable_points(preferences.vector_meshes).filter(|&point| point != start) {
|
||||
let Some(pos) = vector.point_domain.position_from_id(id) else { continue };
|
||||
let transformed_distance_between_squared = transform.transform_point2(pos).distance_squared(transform.transform_point2(next_point));
|
||||
let snap_point_tolerance_squared = crate::consts::SNAP_POINT_TOLERANCE.powi(2);
|
||||
if transformed_distance_between_squared < snap_point_tolerance_squared {
|
||||
@@ -687,15 +675,15 @@ impl PenToolData {
|
||||
// Store the segment
|
||||
let id = SegmentId::generate();
|
||||
if self.path_closed {
|
||||
if let Some((handles, handle1_pos)) = match self.get_opposite_handle_type(TargetHandle::PreviewInHandle, &vector_data) {
|
||||
if let Some((handles, handle1_pos)) = match self.get_opposite_handle_type(TargetHandle::PreviewInHandle, &vector) {
|
||||
TargetHandle::PriorOutHandle(segment) => {
|
||||
let handles = [HandleId::end(id), HandleId::primary(segment)];
|
||||
let handle1_pos = handles[1].to_manipulator_point().get_position(&vector_data);
|
||||
let handle1_pos = handles[1].to_manipulator_point().get_position(&vector);
|
||||
handle1_pos.map(|pos| (handles, pos))
|
||||
}
|
||||
TargetHandle::PriorInHandle(segment) => {
|
||||
let handles = [HandleId::end(id), HandleId::end(segment)];
|
||||
let handle1_pos = handles[1].to_manipulator_point().get_position(&vector_data);
|
||||
let handle1_pos = handles[1].to_manipulator_point().get_position(&vector);
|
||||
handle1_pos.map(|pos| (handles, pos))
|
||||
}
|
||||
_ => None,
|
||||
@@ -719,14 +707,14 @@ impl PenToolData {
|
||||
|
||||
// Mirror
|
||||
if let Some((last_segment, last_point)) = self.latest_point().and_then(|point| point.in_segment).zip(self.latest_point()) {
|
||||
let end = vector_data.segment_end_from_id(last_segment) == Some(last_point.id);
|
||||
let end = vector.segment_end_from_id(last_segment) == Some(last_point.id);
|
||||
let handles = if end {
|
||||
[HandleId::end(last_segment), HandleId::primary(id)]
|
||||
} else {
|
||||
[HandleId::primary(last_segment), HandleId::primary(id)]
|
||||
};
|
||||
|
||||
if let Some(h1) = handles[0].to_manipulator_point().get_position(&vector_data) {
|
||||
if let Some(h1) = handles[0].to_manipulator_point().get_position(&vector) {
|
||||
let angle = (h1 - last_point.pos).angle_to(last_point.handle_start - last_point.pos);
|
||||
let pi = std::f64::consts::PI;
|
||||
let colinear = (angle - pi).abs() < 1e-6 || (angle + pi).abs() < 1e-6;
|
||||
@@ -758,13 +746,13 @@ impl PenToolData {
|
||||
transform: &DAffine2,
|
||||
snap_data: &SnapData<'_>,
|
||||
mouse: &DVec2,
|
||||
vector_data: &VectorData,
|
||||
vector: &Vector,
|
||||
input: &InputPreprocessorMessageHandler,
|
||||
) -> Option<DVec2> {
|
||||
let reference_handle = if self.path_closed { TargetHandle::PreviewInHandle } else { TargetHandle::FuturePreviewOutHandle };
|
||||
let end_handle = self.get_opposite_handle_type(reference_handle, vector_data);
|
||||
let end_handle_pos = self.target_handle_position(end_handle, vector_data);
|
||||
let ref_pos = self.target_handle_position(reference_handle, vector_data)?;
|
||||
let end_handle = self.get_opposite_handle_type(reference_handle, vector);
|
||||
let end_handle_pos = self.target_handle_position(end_handle, vector);
|
||||
let ref_pos = self.target_handle_position(reference_handle, vector)?;
|
||||
let snap = &mut self.snap_manager;
|
||||
let snap_data = SnapData::new_snap_cache(snap_data.document, input, &self.snap_cache);
|
||||
|
||||
@@ -826,7 +814,7 @@ impl PenToolData {
|
||||
responses: &mut VecDeque<Message>,
|
||||
) {
|
||||
// Validate necessary data exists
|
||||
let Some(vector_data) = layer.and_then(|layer| document.network_interface.compute_modified_vector(layer)) else {
|
||||
let Some(vector) = layer.and_then(|layer| document.network_interface.compute_modified_vector(layer)) else {
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -842,9 +830,9 @@ impl PenToolData {
|
||||
let should_swap_to_start = !self.path_closed && !matches!(self.handle_type, TargetHandle::None | TargetHandle::FuturePreviewOutHandle);
|
||||
|
||||
if should_swap_to_opposite {
|
||||
let opposite_type = self.get_opposite_handle_type(self.handle_type, &vector_data);
|
||||
let opposite_type = self.get_opposite_handle_type(self.handle_type, &vector);
|
||||
// Update offset
|
||||
let Some(handle_pos) = self.target_handle_position(opposite_type, &vector_data) else {
|
||||
let Some(handle_pos) = self.target_handle_position(opposite_type, &vector) else {
|
||||
self.handle_swapped = false;
|
||||
return;
|
||||
};
|
||||
@@ -894,7 +882,7 @@ impl PenToolData {
|
||||
Some(PenToolFsmState::DraggingHandle(self.handle_mode))
|
||||
}
|
||||
|
||||
fn move_anchor_and_handles(&mut self, delta: DVec2, layer: LayerNodeIdentifier, responses: &mut VecDeque<Message>, vector_data: &VectorData) {
|
||||
fn move_anchor_and_handles(&mut self, delta: DVec2, layer: LayerNodeIdentifier, responses: &mut VecDeque<Message>, vector: &Vector) {
|
||||
if self.handle_end.is_none() {
|
||||
if let Some(latest_pt) = self.latest_point_mut() {
|
||||
latest_pt.pos += delta;
|
||||
@@ -912,10 +900,10 @@ impl PenToolData {
|
||||
let reference_handle = if self.path_closed { TargetHandle::PreviewInHandle } else { TargetHandle::FuturePreviewOutHandle };
|
||||
|
||||
// Move the end handle
|
||||
let end_handle_type = self.get_opposite_handle_type(reference_handle, vector_data);
|
||||
let end_handle_type = self.get_opposite_handle_type(reference_handle, vector);
|
||||
match end_handle_type {
|
||||
TargetHandle::PriorInHandle(..) | TargetHandle::PriorOutHandle(..) => {
|
||||
let Some(handle_pos) = self.target_handle_position(end_handle_type, vector_data) else { return };
|
||||
let Some(handle_pos) = self.target_handle_position(end_handle_type, vector) else { return };
|
||||
self.update_target_handle_pos(end_handle_type, self.next_point, responses, handle_pos + delta, layer);
|
||||
}
|
||||
_ => {}
|
||||
@@ -934,13 +922,13 @@ impl PenToolData {
|
||||
let colinear = (self.handle_mode == HandleMode::ColinearEquidistant && self.modifiers.break_handle) || (self.handle_mode == HandleMode::ColinearLocked && !self.modifiers.break_handle);
|
||||
let document = snap_data.document;
|
||||
let Some(layer) = layer else { return Some(PenToolFsmState::DraggingHandle(self.handle_mode)) };
|
||||
let vector_data = document.network_interface.compute_modified_vector(layer)?;
|
||||
let vector = document.network_interface.compute_modified_vector(layer)?;
|
||||
let viewport_to_document = document.metadata().document_to_viewport.inverse();
|
||||
let mut mouse_pos = mouse;
|
||||
|
||||
// Handles pressing Space to drag anchor and its handles
|
||||
if self.modifiers.move_anchor_with_handles {
|
||||
let Some(delta) = self.space_anchor_handle_snap(&viewport_to_document, &transform, &snap_data, &mouse, &vector_data, input) else {
|
||||
let Some(delta) = self.space_anchor_handle_snap(&viewport_to_document, &transform, &snap_data, &mouse, &vector, input) else {
|
||||
return Some(PenToolFsmState::DraggingHandle(self.handle_mode));
|
||||
};
|
||||
|
||||
@@ -959,7 +947,7 @@ impl PenToolData {
|
||||
};
|
||||
}
|
||||
|
||||
self.move_anchor_and_handles(delta, layer, responses, &vector_data);
|
||||
self.move_anchor_and_handles(delta, layer, responses, &vector);
|
||||
|
||||
responses.add(OverlaysMessage::Draw);
|
||||
return Some(PenToolFsmState::DraggingHandle(self.handle_mode));
|
||||
@@ -994,8 +982,8 @@ impl PenToolData {
|
||||
match self.handle_mode {
|
||||
HandleMode::ColinearLocked | HandleMode::ColinearEquidistant => {
|
||||
self.g1_continuous = true;
|
||||
self.apply_colinear_constraint(responses, layer, self.next_point, &vector_data);
|
||||
self.adjust_handle_length(responses, layer, &vector_data);
|
||||
self.apply_colinear_constraint(responses, layer, self.next_point, &vector);
|
||||
self.adjust_handle_length(responses, layer, &vector);
|
||||
}
|
||||
HandleMode::Free => {
|
||||
self.g1_continuous = false;
|
||||
@@ -1006,7 +994,7 @@ impl PenToolData {
|
||||
let Some(endpoint) = self.prior_segment_endpoint else {
|
||||
return Some(PenToolFsmState::DraggingHandle(self.handle_mode));
|
||||
};
|
||||
self.set_lock_angle(&vector_data, endpoint, self.prior_segment);
|
||||
self.set_lock_angle(&vector, endpoint, self.prior_segment);
|
||||
self.switch_to_free_on_ctrl_release = true;
|
||||
let last_segment = self.prior_segment;
|
||||
if let Some(latest) = self.latest_point_mut() {
|
||||
@@ -1020,19 +1008,19 @@ impl PenToolData {
|
||||
}
|
||||
|
||||
/// Makes the opposite handle equidistant or locks its length.
|
||||
fn adjust_handle_length(&mut self, responses: &mut VecDeque<Message>, layer: LayerNodeIdentifier, vector_data: &VectorData) {
|
||||
let opposite_handle_type = self.get_opposite_handle_type(self.handle_type, vector_data);
|
||||
fn adjust_handle_length(&mut self, responses: &mut VecDeque<Message>, layer: LayerNodeIdentifier, vector: &Vector) {
|
||||
let opposite_handle_type = self.get_opposite_handle_type(self.handle_type, vector);
|
||||
match self.handle_mode {
|
||||
HandleMode::ColinearEquidistant => {
|
||||
if self.modifiers.break_handle {
|
||||
// Store handle for later restoration only when Alt is first pressed
|
||||
if !self.alt_pressed {
|
||||
self.previous_handle_end_pos = self.target_handle_position(opposite_handle_type, vector_data);
|
||||
self.previous_handle_end_pos = self.target_handle_position(opposite_handle_type, vector);
|
||||
self.alt_pressed = true;
|
||||
}
|
||||
|
||||
// Set handle to opposite position of the other handle
|
||||
let Some(new_position) = self.target_handle_position(self.handle_type, vector_data).map(|handle| self.next_point * 2. - handle) else {
|
||||
let Some(new_position) = self.target_handle_position(self.handle_type, vector).map(|handle| self.next_point * 2. - handle) else {
|
||||
return;
|
||||
};
|
||||
self.update_target_handle_pos(opposite_handle_type, self.next_point, responses, new_position, layer);
|
||||
@@ -1047,7 +1035,7 @@ impl PenToolData {
|
||||
}
|
||||
HandleMode::ColinearLocked => {
|
||||
if !self.modifiers.break_handle {
|
||||
let Some(new_position) = self.target_handle_position(self.handle_type, vector_data).map(|handle| self.next_point * 2. - handle) else {
|
||||
let Some(new_position) = self.target_handle_position(self.handle_type, vector).map(|handle| self.next_point * 2. - handle) else {
|
||||
return;
|
||||
};
|
||||
self.update_target_handle_pos(opposite_handle_type, self.next_point, responses, new_position, layer);
|
||||
@@ -1057,23 +1045,23 @@ impl PenToolData {
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_colinear_constraint(&mut self, responses: &mut VecDeque<Message>, layer: LayerNodeIdentifier, anchor_pos: DVec2, vector_data: &VectorData) {
|
||||
let Some(handle) = self.target_handle_position(self.handle_type, vector_data) else {
|
||||
return;
|
||||
};
|
||||
fn apply_colinear_constraint(&mut self, responses: &mut VecDeque<Message>, layer: LayerNodeIdentifier, anchor_pos: DVec2, vector: &Vector) {
|
||||
let Some(handle) = self.target_handle_position(self.handle_type, vector) else { return };
|
||||
|
||||
if (anchor_pos - handle).length() < 1e-6 && self.modifiers.lock_angle {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(direction) = (anchor_pos - handle).try_normalize() else {
|
||||
return;
|
||||
};
|
||||
let opposite_handle = self.get_opposite_handle_type(self.handle_type, vector_data);
|
||||
let Some(handle_offset) = self.target_handle_position(opposite_handle, vector_data).map(|handle| (handle - anchor_pos).length()) else {
|
||||
let Some(direction) = (anchor_pos - handle).try_normalize() else { return };
|
||||
|
||||
let opposite_handle = self.get_opposite_handle_type(self.handle_type, vector);
|
||||
|
||||
let Some(handle_offset) = self.target_handle_position(opposite_handle, vector).map(|handle| (handle - anchor_pos).length()) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let new_handle_position = anchor_pos + handle_offset * direction;
|
||||
|
||||
self.update_target_handle_pos(opposite_handle, self.next_point, responses, new_handle_position, layer);
|
||||
}
|
||||
|
||||
@@ -1086,10 +1074,10 @@ impl PenToolData {
|
||||
let selected_nodes = document.network_interface.selected_nodes();
|
||||
let mut selected_layers = selected_nodes.selected_layers(document.metadata());
|
||||
let layer = selected_layers.next().filter(|_| selected_layers.next().is_none()).or(self.current_layer)?;
|
||||
let vector_data = document.network_interface.compute_modified_vector(layer)?;
|
||||
let vector = document.network_interface.compute_modified_vector(layer)?;
|
||||
let transform = document.metadata().document_to_viewport * transform;
|
||||
for point in vector_data.extendable_points(preferences.vector_meshes) {
|
||||
let Some(pos) = vector_data.point_domain.position_from_id(point) else { continue };
|
||||
for point in vector.extendable_points(preferences.vector_meshes) {
|
||||
let Some(pos) = vector.point_domain.position_from_id(point) else { continue };
|
||||
let transformed_distance_between_squared = transform.transform_point2(pos).distance_squared(transform.transform_point2(self.next_point));
|
||||
let snap_point_tolerance_squared = crate::consts::SNAP_POINT_TOLERANCE.powi(2);
|
||||
if transformed_distance_between_squared < snap_point_tolerance_squared {
|
||||
@@ -1217,11 +1205,11 @@ impl PenToolData {
|
||||
|
||||
if append {
|
||||
if let Some((layer, point, _)) = closest_point(document, viewport, tolerance, document.metadata().all_layers(), |_| false, preferences) {
|
||||
let vector_data = document.network_interface.compute_modified_vector(layer).unwrap();
|
||||
let segment = vector_data.all_connected(point).collect::<Vec<_>>().first().map(|s| s.segment);
|
||||
let vector = document.network_interface.compute_modified_vector(layer).unwrap();
|
||||
let segment = vector.all_connected(point).collect::<Vec<_>>().first().map(|s| s.segment);
|
||||
|
||||
if self.modifiers.lock_angle {
|
||||
self.set_lock_angle(&vector_data, point, segment);
|
||||
self.set_lock_angle(&vector, point, segment);
|
||||
self.switch_to_free_on_ctrl_release = true;
|
||||
}
|
||||
}
|
||||
@@ -1235,11 +1223,11 @@ impl PenToolData {
|
||||
}
|
||||
|
||||
if let Some((layer, point, _position)) = closest_point(document, viewport, tolerance, document.metadata().all_layers(), |_| false, preferences) {
|
||||
let vector_data = document.network_interface.compute_modified_vector(layer).unwrap();
|
||||
let segment = vector_data.all_connected(point).collect::<Vec<_>>().first().map(|s| s.segment);
|
||||
let vector = document.network_interface.compute_modified_vector(layer).unwrap();
|
||||
let segment = vector.all_connected(point).collect::<Vec<_>>().first().map(|s| s.segment);
|
||||
self.handle_mode = HandleMode::Free;
|
||||
if self.modifiers.lock_angle {
|
||||
self.set_lock_angle(&vector_data, point, segment);
|
||||
self.set_lock_angle(&vector, point, segment);
|
||||
self.switch_to_free_on_ctrl_release = true;
|
||||
}
|
||||
}
|
||||
@@ -1265,9 +1253,9 @@ impl PenToolData {
|
||||
|
||||
/// Perform extension of an existing path
|
||||
fn extend_existing_path(&mut self, document: &DocumentMessageHandler, layer: LayerNodeIdentifier, point: PointId, position: DVec2) {
|
||||
let vector_data = document.network_interface.compute_modified_vector(layer);
|
||||
let (handle_start, in_segment) = if let Some(vector_data) = &vector_data {
|
||||
vector_data
|
||||
let vector = document.network_interface.compute_modified_vector(layer);
|
||||
let (handle_start, in_segment) = if let Some(vector) = &vector {
|
||||
vector
|
||||
.segment_bezier_iter()
|
||||
.find_map(|(segment_id, bezier, start, end)| {
|
||||
let is_end = point == end;
|
||||
@@ -1310,12 +1298,12 @@ impl PenToolData {
|
||||
|
||||
self.next_point = position;
|
||||
self.next_handle_start = handle_start;
|
||||
let vector_data = document.network_interface.compute_modified_vector(layer).unwrap();
|
||||
let segment = vector_data.all_connected(point).collect::<Vec<_>>().first().map(|s| s.segment);
|
||||
let vector = document.network_interface.compute_modified_vector(layer).unwrap();
|
||||
let segment = vector.all_connected(point).collect::<Vec<_>>().first().map(|s| s.segment);
|
||||
self.handle_mode = HandleMode::Free;
|
||||
|
||||
if self.modifiers.lock_angle {
|
||||
self.set_lock_angle(&vector_data, point, segment);
|
||||
self.set_lock_angle(&vector, point, segment);
|
||||
self.switch_to_free_on_ctrl_release = true;
|
||||
}
|
||||
}
|
||||
@@ -1340,11 +1328,11 @@ impl PenToolData {
|
||||
if let Some((layer, point, _position)) = closest_point(document, viewport, tolerance, document.metadata().all_layers(), |_| false, preferences) {
|
||||
self.prior_segment_endpoint = Some(point);
|
||||
self.prior_segment_layer = Some(layer);
|
||||
let vector_data = document.network_interface.compute_modified_vector(layer).unwrap();
|
||||
let segment = vector_data.all_connected(point).collect::<Vec<_>>().first().map(|s| s.segment);
|
||||
let vector = document.network_interface.compute_modified_vector(layer).unwrap();
|
||||
let segment = vector.all_connected(point).collect::<Vec<_>>().first().map(|s| s.segment);
|
||||
self.prior_segment = segment;
|
||||
layer_manipulators.insert(point);
|
||||
for (&id, &position) in vector_data.point_domain.ids().iter().zip(vector_data.point_domain.positions()) {
|
||||
for (&id, &position) in vector.point_domain.ids().iter().zip(vector.point_domain.positions()) {
|
||||
if id == point {
|
||||
continue;
|
||||
}
|
||||
@@ -1355,8 +1343,8 @@ impl PenToolData {
|
||||
}
|
||||
}
|
||||
|
||||
fn set_lock_angle(&mut self, vector_data: &VectorData, anchor: PointId, segment: Option<SegmentId>) {
|
||||
let anchor_position = vector_data.point_domain.position_from_id(anchor);
|
||||
fn set_lock_angle(&mut self, vector: &Vector, anchor: PointId, segment: Option<SegmentId>) {
|
||||
let anchor_position = vector.point_domain.position_from_id(anchor);
|
||||
|
||||
let Some((anchor_position, segment)) = anchor_position.zip(segment) else {
|
||||
self.handle_mode = HandleMode::Free;
|
||||
@@ -1365,7 +1353,7 @@ impl PenToolData {
|
||||
|
||||
match (self.handle_type, self.path_closed) {
|
||||
(TargetHandle::FuturePreviewOutHandle, _) | (TargetHandle::PreviewInHandle, true) => {
|
||||
if let Some(required_handle) = calculate_segment_angle(anchor, segment, vector_data, true) {
|
||||
if let Some(required_handle) = calculate_segment_angle(anchor, segment, vector, true) {
|
||||
self.angle = required_handle;
|
||||
self.handle_mode = HandleMode::ColinearEquidistant;
|
||||
}
|
||||
@@ -1460,12 +1448,12 @@ impl Fsm for PenToolFsmState {
|
||||
responses.add(TransformLayerMessage::BeginScalePen { last_point, handle });
|
||||
}
|
||||
|
||||
let vector_data = document.network_interface.compute_modified_vector(layer).unwrap();
|
||||
let vector = document.network_interface.compute_modified_vector(layer).unwrap();
|
||||
tool_data.previous_handle_start_pos = latest.handle_start;
|
||||
let opposite_handle = tool_data.check_grs_end_handle(&vector_data);
|
||||
tool_data.previous_handle_end_pos = tool_data.target_handle_position(opposite_handle, &vector_data);
|
||||
let opposite_handle = tool_data.check_grs_end_handle(&vector);
|
||||
tool_data.previous_handle_end_pos = tool_data.target_handle_position(opposite_handle, &vector);
|
||||
let handle1 = latest_handle_start - latest_pos;
|
||||
let Some(opposite_handle_pos) = tool_data.target_handle_position(opposite_handle, &vector_data) else {
|
||||
let Some(opposite_handle_pos) = tool_data.target_handle_position(opposite_handle, &vector) else {
|
||||
return PenToolFsmState::GRSHandle;
|
||||
};
|
||||
let handle2 = opposite_handle_pos - latest_pos;
|
||||
@@ -1476,8 +1464,8 @@ impl Fsm for PenToolFsmState {
|
||||
}
|
||||
(PenToolFsmState::GRSHandle, PenToolMessage::FinalPosition { final_position }) => {
|
||||
let Some(layer) = layer else { return PenToolFsmState::GRSHandle };
|
||||
let vector_data = document.network_interface.compute_modified_vector(layer);
|
||||
let Some(vector_data) = vector_data else { return PenToolFsmState::GRSHandle };
|
||||
let vector = document.network_interface.compute_modified_vector(layer);
|
||||
let Some(vector) = vector else { return PenToolFsmState::GRSHandle };
|
||||
|
||||
if let Some(latest_pt) = tool_data.latest_point_mut() {
|
||||
let layer_space_to_viewport = document.metadata().transform_to_viewport(layer);
|
||||
@@ -1489,8 +1477,8 @@ impl Fsm for PenToolFsmState {
|
||||
let Some(latest) = tool_data.latest_point() else {
|
||||
return PenToolFsmState::GRSHandle;
|
||||
};
|
||||
let opposite_handle = tool_data.check_grs_end_handle(&vector_data);
|
||||
let Some(opposite_handle_pos) = tool_data.target_handle_position(opposite_handle, &vector_data) else {
|
||||
let opposite_handle = tool_data.check_grs_end_handle(&vector);
|
||||
let Some(opposite_handle_pos) = tool_data.target_handle_position(opposite_handle, &vector) else {
|
||||
return PenToolFsmState::GRSHandle;
|
||||
};
|
||||
|
||||
@@ -1531,8 +1519,8 @@ impl Fsm for PenToolFsmState {
|
||||
tool_data.next_handle_start = input.mouse.position;
|
||||
|
||||
let Some(layer) = layer else { return PenToolFsmState::GRSHandle };
|
||||
let vector_data = document.network_interface.compute_modified_vector(layer).unwrap();
|
||||
let opposite_handle = tool_data.check_grs_end_handle(&vector_data);
|
||||
let vector = document.network_interface.compute_modified_vector(layer).unwrap();
|
||||
let opposite_handle = tool_data.check_grs_end_handle(&vector);
|
||||
|
||||
let previous = tool_data.previous_handle_start_pos;
|
||||
if let Some(latest) = tool_data.latest_point_mut() {
|
||||
@@ -1722,10 +1710,10 @@ impl Fsm for PenToolFsmState {
|
||||
let start = latest_point.id;
|
||||
|
||||
if let Some(layer) = layer
|
||||
&& let Some(mut vector_data) = document.network_interface.compute_modified_vector(layer)
|
||||
&& let Some(mut vector) = document.network_interface.compute_modified_vector(layer)
|
||||
{
|
||||
let closest_point = vector_data.extendable_points(preferences.vector_meshes).filter(|&id| id != start).find(|&id| {
|
||||
vector_data.point_domain.position_from_id(id).map_or(false, |pos| {
|
||||
let closest_point = vector.extendable_points(preferences.vector_meshes).filter(|&id| id != start).find(|&id| {
|
||||
vector.point_domain.position_from_id(id).is_some_and(|pos| {
|
||||
let dist_sq = transform.transform_point2(pos).distance_squared(transform.transform_point2(next_point));
|
||||
dist_sq < crate::consts::SNAP_POINT_TOLERANCE.powi(2)
|
||||
})
|
||||
@@ -1734,21 +1722,21 @@ impl Fsm for PenToolFsmState {
|
||||
// We have the point. Join the 2 vertices and check if any path is closed.
|
||||
if let Some(end) = closest_point {
|
||||
let segment_id = SegmentId::generate();
|
||||
vector_data.push(segment_id, start, end, BezierHandles::Cubic { handle_start, handle_end }, StrokeId::ZERO);
|
||||
vector.push(segment_id, start, end, BezierHandles::Cubic { handle_start, handle_end }, StrokeId::ZERO);
|
||||
|
||||
let grouped_segments = vector_data.auto_join_paths();
|
||||
let grouped_segments = vector.auto_join_paths();
|
||||
let closed_paths = grouped_segments.iter().filter(|path| path.is_closed() && path.contains(segment_id));
|
||||
|
||||
let subpaths: Vec<_> = closed_paths
|
||||
.filter_map(|path| {
|
||||
let segments = path.edges.iter().filter_map(|edge| {
|
||||
vector_data
|
||||
vector
|
||||
.segment_domain
|
||||
.iter()
|
||||
.find(|(id, _, _, _)| id == &edge.id)
|
||||
.map(|(_, start, end, bezier)| if start == edge.start { (bezier, start, end) } else { (bezier.reversed(), end, start) })
|
||||
});
|
||||
vector_data.subpath_from_segments_ignore_discontinuities(segments)
|
||||
vector.subpath_from_segments_ignore_discontinuities(segments)
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -1817,7 +1805,8 @@ impl Fsm for PenToolFsmState {
|
||||
}
|
||||
// Merge two layers if the point is connected to the end point of another path
|
||||
|
||||
// This might not be the correct solution to artboards being included as the other layer, which occurs due to the compute_modified_vector call in should_extend using the click targets for a layer instead of vector data.
|
||||
// This might not be the correct solution to artboards being included as the other layer,
|
||||
// which occurs due to the `compute_modified_vector` call in `should_extend` using the click targets for a layer instead of vector.
|
||||
let layers = LayerNodeIdentifier::ROOT_PARENT
|
||||
.descendants(document.metadata())
|
||||
.filter(|layer| !document.network_interface.is_artboard(&layer.to_node(), &[]));
|
||||
@@ -1887,7 +1876,7 @@ impl Fsm for PenToolFsmState {
|
||||
tool_data.toggle_colinear_debounce = true;
|
||||
}
|
||||
|
||||
let Some(vector_data) = layer.and_then(|layer| document.network_interface.compute_modified_vector(layer)) else {
|
||||
let Some(vector) = layer.and_then(|layer| document.network_interface.compute_modified_vector(layer)) else {
|
||||
return self;
|
||||
};
|
||||
|
||||
@@ -1901,7 +1890,7 @@ impl Fsm for PenToolFsmState {
|
||||
document
|
||||
.metadata()
|
||||
.transform_to_viewport(layer)
|
||||
.transform_point2(tool_data.target_handle_position(reference_handle, &vector_data).unwrap())
|
||||
.transform_point2(tool_data.target_handle_position(reference_handle, &vector).unwrap())
|
||||
});
|
||||
tool_data.handle_start_offset = handle_start.map(|start| start - input.mouse.position);
|
||||
tool_data.space_pressed = true;
|
||||
@@ -2075,8 +2064,8 @@ impl Fsm for PenToolFsmState {
|
||||
}
|
||||
(PenToolFsmState::DraggingHandle(..), PenToolMessage::Confirm) => {
|
||||
// Confirm to end path
|
||||
if let Some((vector_data, layer)) = layer.and_then(|layer| document.network_interface.compute_modified_vector(layer)).zip(layer) {
|
||||
let single_point_in_layer = vector_data.point_domain.ids().len() == 1;
|
||||
if let Some((vector, layer)) = layer.and_then(|layer| document.network_interface.compute_modified_vector(layer)).zip(layer) {
|
||||
let single_point_in_layer = vector.point_domain.ids().len() == 1;
|
||||
tool_data.finish_placing_handle(SnapData::new(document, input), transform, preferences, responses);
|
||||
let latest_points = tool_data.latest_points.len() == 1;
|
||||
|
||||
@@ -2129,8 +2118,8 @@ impl Fsm for PenToolFsmState {
|
||||
}
|
||||
}
|
||||
(PenToolFsmState::PlacingAnchor, PenToolMessage::Abort) => {
|
||||
let should_delete_layer = if let Some(vector_data) = layer.and_then(|layer| document.network_interface.compute_modified_vector(layer)) {
|
||||
vector_data.point_domain.ids().len() == 1
|
||||
let should_delete_layer = if let Some(vector) = layer.and_then(|layer| document.network_interface.compute_modified_vector(layer)) {
|
||||
vector.point_domain.ids().len() == 1
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
@@ -548,15 +548,15 @@ mod test_spline_tool {
|
||||
use crate::test_utils::test_prelude::*;
|
||||
use glam::DAffine2;
|
||||
use graphene_std::vector::PointId;
|
||||
use graphene_std::vector::VectorData;
|
||||
use graphene_std::vector::Vector;
|
||||
|
||||
fn assert_point_positions(vector_data: &VectorData, layer_to_viewport: DAffine2, expected_points: &[DVec2], epsilon: f64) {
|
||||
let points_in_viewport: Vec<DVec2> = vector_data
|
||||
fn assert_point_positions(vector: &Vector, layer_to_viewport: DAffine2, expected_points: &[DVec2], epsilon: f64) {
|
||||
let points_in_viewport: Vec<DVec2> = vector
|
||||
.point_domain
|
||||
.ids()
|
||||
.iter()
|
||||
.filter_map(|&point_id| {
|
||||
let position = vector_data.point_domain.position_from_id(point_id)?;
|
||||
let position = vector.point_domain.position_from_id(point_id)?;
|
||||
Some(layer_to_viewport.transform_point2(position))
|
||||
})
|
||||
.collect();
|
||||
@@ -601,19 +601,19 @@ mod test_spline_tool {
|
||||
|
||||
let first_spline_node = find_spline(document, spline_layer).expect("Spline node not found in the layer");
|
||||
|
||||
let first_vector_data = document.network_interface.compute_modified_vector(spline_layer).expect("Vector data not found for the spline layer");
|
||||
let first_vector = document.network_interface.compute_modified_vector(spline_layer).expect("Vector not found for the spline layer");
|
||||
|
||||
// Verify initial spline has correct number of points and segments
|
||||
let initial_point_count = first_vector_data.point_domain.ids().len();
|
||||
let initial_segment_count = first_vector_data.segment_domain.ids().len();
|
||||
let initial_point_count = first_vector.point_domain.ids().len();
|
||||
let initial_segment_count = first_vector.segment_domain.ids().len();
|
||||
assert_eq!(initial_point_count, 3, "Expected 3 points in initial spline, found {}", initial_point_count);
|
||||
assert_eq!(initial_segment_count, 2, "Expected 2 segments in initial spline, found {}", initial_segment_count);
|
||||
|
||||
let layer_to_viewport = document.metadata().transform_to_viewport(spline_layer);
|
||||
|
||||
let endpoints: Vec<(PointId, DVec2)> = first_vector_data
|
||||
let endpoints: Vec<(PointId, DVec2)> = first_vector
|
||||
.extendable_points(false)
|
||||
.filter_map(|point_id| first_vector_data.point_domain.position_from_id(point_id).map(|pos| (point_id, layer_to_viewport.transform_point2(pos))))
|
||||
.filter_map(|point_id| first_vector.point_domain.position_from_id(point_id).map(|pos| (point_id, layer_to_viewport.transform_point2(pos))))
|
||||
.collect();
|
||||
|
||||
assert_eq!(endpoints.len(), 2, "Expected 2 endpoints in the initial spline");
|
||||
@@ -632,14 +632,14 @@ mod test_spline_tool {
|
||||
editor.press(Key::Enter, ModifierKeys::empty()).await;
|
||||
|
||||
let document = editor.active_document();
|
||||
let extended_vector_data = document
|
||||
let extended_vector = document
|
||||
.network_interface
|
||||
.compute_modified_vector(spline_layer)
|
||||
.expect("Vector data not found for the extended spline layer");
|
||||
.expect("Vector not found for the extended spline layer");
|
||||
|
||||
// Verify extended spline has correct number of points and segments
|
||||
let extended_point_count = extended_vector_data.point_domain.ids().len();
|
||||
let extended_segment_count = extended_vector_data.segment_domain.ids().len();
|
||||
let extended_point_count = extended_vector.point_domain.ids().len();
|
||||
let extended_segment_count = extended_vector.segment_domain.ids().len();
|
||||
|
||||
assert_eq!(extended_point_count, 5, "Expected 5 points in extended spline, found {}", extended_point_count);
|
||||
assert_eq!(extended_segment_count, 4, "Expected 4 segments in extended spline, found {}", extended_segment_count);
|
||||
@@ -653,7 +653,7 @@ mod test_spline_tool {
|
||||
|
||||
let all_expected_points = [initial_points[0], initial_points[1], initial_points[2], continuation_points[0], continuation_points[1]];
|
||||
|
||||
assert_point_positions(&extended_vector_data, layer_to_viewport, &all_expected_points, 1e-10);
|
||||
assert_point_positions(&extended_vector, layer_to_viewport, &all_expected_points, 1e-10);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -688,14 +688,14 @@ mod test_spline_tool {
|
||||
.selected_visible_and_unlocked_layers(network_interface)
|
||||
.next()
|
||||
.expect("Should have a selected layer");
|
||||
let vector_data = network_interface.compute_modified_vector(layer).expect("Should have vector data");
|
||||
let vector = network_interface.compute_modified_vector(layer).expect("Should have vector data");
|
||||
let layer_to_viewport = document.metadata().transform_to_viewport(layer);
|
||||
|
||||
// Expected points in viewport coordinates
|
||||
let expected_points = vec![DVec2::new(50., 50.), DVec2::new(100., 50.), DVec2::new(150., 100.)];
|
||||
|
||||
// Assert all points are correctly positioned
|
||||
assert_point_positions(&vector_data, layer_to_viewport, &expected_points, 1e-10);
|
||||
assert_point_positions(&vector, layer_to_viewport, &expected_points, 1e-10);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -728,14 +728,14 @@ mod test_spline_tool {
|
||||
.selected_visible_and_unlocked_layers(network_interface)
|
||||
.next()
|
||||
.expect("Should have a selected layer");
|
||||
let vector_data = network_interface.compute_modified_vector(layer).expect("Should have vector data");
|
||||
let vector = network_interface.compute_modified_vector(layer).expect("Should have vector data");
|
||||
let layer_to_viewport = document.metadata().transform_to_viewport(layer);
|
||||
|
||||
// Expected points in viewport coordinates
|
||||
let expected_points = vec![DVec2::new(50., 50.), DVec2::new(100., 50.), DVec2::new(150., 100.)];
|
||||
|
||||
// Assert all points are correctly positioned
|
||||
assert_point_positions(&vector_data, layer_to_viewport, &expected_points, 1e-10);
|
||||
assert_point_positions(&vector, layer_to_viewport, &expected_points, 1e-10);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -766,14 +766,14 @@ mod test_spline_tool {
|
||||
.selected_visible_and_unlocked_layers(network_interface)
|
||||
.next()
|
||||
.expect("Should have a selected layer");
|
||||
let vector_data = network_interface.compute_modified_vector(layer).expect("Should have vector data");
|
||||
let vector = network_interface.compute_modified_vector(layer).expect("Should have vector data");
|
||||
let layer_to_viewport = document.metadata().transform_to_viewport(layer);
|
||||
|
||||
// Expected points in viewport coordinates
|
||||
let expected_points = vec![DVec2::new(50., 50.), DVec2::new(100., 50.), DVec2::new(150., 100.)];
|
||||
|
||||
// Assert all points are correctly positioned
|
||||
assert_point_positions(&vector_data, layer_to_viewport, &expected_points, 1e-10);
|
||||
assert_point_positions(&vector, layer_to_viewport, &expected_points, 1e-10);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -805,14 +805,14 @@ mod test_spline_tool {
|
||||
.selected_visible_and_unlocked_layers(network_interface)
|
||||
.next()
|
||||
.expect("Should have a selected layer");
|
||||
let vector_data = network_interface.compute_modified_vector(layer).expect("Should have vector data");
|
||||
let vector = network_interface.compute_modified_vector(layer).expect("Should have vector data");
|
||||
let layer_to_viewport = document.metadata().transform_to_viewport(layer);
|
||||
|
||||
// Expected points in viewport coordinates
|
||||
let expected_points = vec![DVec2::new(50., 50.), DVec2::new(100., 50.), DVec2::new(150., 100.)];
|
||||
|
||||
// Assert all points are correctly positioned
|
||||
assert_point_positions(&vector_data, layer_to_viewport, &expected_points, 1e-10);
|
||||
assert_point_positions(&vector, layer_to_viewport, &expected_points, 1e-10);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -845,17 +845,17 @@ mod test_spline_tool {
|
||||
let spline_layer = layers.next().expect("Failed to find the spline layer");
|
||||
assert!(find_spline(document, spline_layer).is_some(), "Spline node not found in the layer");
|
||||
|
||||
let vector_data = document.network_interface.compute_modified_vector(spline_layer).expect("Vector data not found for the spline layer");
|
||||
let vector = document.network_interface.compute_modified_vector(spline_layer).expect("Vector not found for the spline layer");
|
||||
|
||||
// Verify we have the correct number of points and segments
|
||||
let point_count = vector_data.point_domain.ids().len();
|
||||
let segment_count = vector_data.segment_domain.ids().len();
|
||||
let point_count = vector.point_domain.ids().len();
|
||||
let segment_count = vector.segment_domain.ids().len();
|
||||
|
||||
assert_eq!(point_count, 3, "Expected 3 points in the spline, found {}", point_count);
|
||||
assert_eq!(segment_count, 2, "Expected 2 segments in the spline, found {}", segment_count);
|
||||
|
||||
let layer_to_viewport = document.metadata().transform_to_viewport(spline_layer);
|
||||
|
||||
assert_point_positions(&vector_data, layer_to_viewport, &spline_points, 1e-10);
|
||||
assert_point_positions(&vector, layer_to_viewport, &spline_points, 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user