Skip to content

Attribute-based vector format refactor #1624

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Mar 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use crate::messages::prelude::Message;

use bezier_rs::Subpath;
use graphene_core::renderer::Quad;
use graphene_core::uuid::ManipulatorGroupId;

use core::f64::consts::PI;
use glam::{DAffine2, DVec2};
Expand Down Expand Up @@ -114,7 +113,7 @@ impl OverlayContext {
self.render_context.stroke();
}

pub fn outline<'a>(&mut self, subpaths: impl Iterator<Item = &'a Subpath<ManipulatorGroupId>>, transform: DAffine2) {
pub fn outline<'a, Id: bezier_rs::Identifier>(&mut self, subpaths: impl Iterator<Item = &'a Subpath<Id>>, transform: DAffine2) {
self.render_context.begin_path();
for subpath in subpaths {
let mut curves = subpath.iter().peekable();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use graph_craft::document::{DocumentNode, NodeId, NodeNetwork};
use graphene_core::renderer::ClickTarget;
use graphene_core::renderer::Quad;
use graphene_core::transform::Footprint;
use graphene_core::uuid::ManipulatorGroupId;

use glam::{DAffine2, DVec2};
use graphene_std::vector::PointId;
use std::collections::{HashMap, HashSet};
use std::num::NonZeroU64;

Expand Down Expand Up @@ -287,7 +287,7 @@ impl DocumentMetadata {
.reduce(Quad::combine_bounds)
}

pub fn layer_outline(&self, layer: LayerNodeIdentifier) -> impl Iterator<Item = &bezier_rs::Subpath<ManipulatorGroupId>> {
pub fn layer_outline(&self, layer: LayerNodeIdentifier) -> impl Iterator<Item = &bezier_rs::Subpath<PointId>> {
static EMPTY: Vec<ClickTarget> = Vec::new();
let click_targets = self.click_targets.get(&layer).unwrap_or(&EMPTY);
click_targets.iter().map(|click_target| &click_target.subpath)
Expand Down
8 changes: 3 additions & 5 deletions editor/src/messages/tool/common_functionality/shape_editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ impl ClosestSegment {
}

fn t_min_max(bezier: &Bezier, layer_scale: DVec2) -> (f64, f64) {
let length = bezier.apply_transformation(|point| point * layer_scale).length(Some(100));
let length = bezier.apply_transformation(|point| point * layer_scale).length(None);
let too_close_t = (INSERT_POINT_ON_SEGMENT_TOO_CLOSE_DISTANCE / length).min(0.5);

let t_min_euclidean = too_close_t;
Expand All @@ -148,7 +148,7 @@ impl ClosestSegment {
// Linear approximation of parametric t-value ranges:
let t_min = self.t_min / self.scale;
let t_max = 1. - ((1. - self.t_max) / self.scale);
let t = self.bezier.project(layer_m_pos, None).max(t_min).min(t_max);
let t = self.bezier.project(layer_m_pos).max(t_min).min(t_max);
self.t = t;

let bezier_point = self.bezier.evaluate(TValue::Parametric(t));
Expand Down Expand Up @@ -1099,8 +1099,6 @@ impl ShapeState {

let scale = document_metadata.document_to_viewport.decompose_scale().x;
let tolerance = tolerance + 0.5 * scale; // make more talerance at large scale
let lut_size = ((5. + scale) as usize).min(20); // need more precision at large scale
let projection_options = bezier_rs::ProjectionOptions { lut_size, ..Default::default() };

let mut closest = None;
let mut closest_distance_squared: f64 = tolerance * tolerance;
Expand All @@ -1109,7 +1107,7 @@ impl ShapeState {

for (subpath_index, subpath) in subpaths.iter().enumerate() {
for (manipulator_index, bezier) in subpath.iter().enumerate() {
let t = bezier.project(layer_pos, Some(projection_options));
let t = bezier.project(layer_pos);
let layerspace = bezier.evaluate(TValue::Parametric(t));

let screenspace = transform.transform_point2(layerspace);
Expand Down
6 changes: 3 additions & 3 deletions editor/src/messages/tool/common_functionality/snapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ impl<'a> SnapData<'a> {
fn ignore_bounds(&self, layer: LayerNodeIdentifier) -> bool {
self.manipulators.iter().any(|&(ignore, _)| ignore == layer)
}
fn ignore_manipulator(&self, layer: LayerNodeIdentifier, manipulator: ManipulatorGroupId) -> bool {
self.manipulators.contains(&(layer, manipulator))
fn ignore_manipulator(&self, layer: LayerNodeIdentifier, manipulator: impl Into<ManipulatorGroupId>) -> bool {
self.manipulators.contains(&(layer, manipulator.into()))
}
}
impl SnapManager {
Expand Down Expand Up @@ -327,7 +327,7 @@ impl SnapManager {
if let Some(ind) = &self.indicator {
for curve in &ind.curves {
let Some(curve) = curve else { continue };
overlay_context.outline([Subpath::from_bezier(curve)].iter(), to_viewport);
overlay_context.outline::<ManipulatorGroupId>([Subpath::from_bezier(curve)].iter(), to_viewport);
}
if let Some(quad) = ind.target_bounds {
overlay_context.quad(to_viewport * quad);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use bezier_rs::{Bezier, Identifier, Subpath, TValue};
use glam::{DAffine2, DVec2};
use graphene_core::renderer::Quad;
use graphene_core::uuid::ManipulatorGroupId;
use graphene_std::vector::PointId;

#[derive(Clone, Debug, Default)]
pub struct LayerSnapper {
Expand Down Expand Up @@ -62,7 +63,7 @@ impl LayerSnapper {
for subpath in document.metadata.layer_outline(layer) {
for (start_index, curve) in subpath.iter().enumerate() {
let document_curve = curve.apply_transformation(|p| transform.transform_point2(p));
let start = subpath.manipulator_groups()[start_index].id;
let start = subpath.manipulator_groups()[start_index].id.into();
if snap_data.ignore_manipulator(layer, start) || snap_data.ignore_manipulator(layer, subpath.manipulator_groups()[(start_index + 1) % subpath.len()].id) {
continue;
}
Expand Down Expand Up @@ -94,7 +95,7 @@ impl LayerSnapper {
if path.document_curve.start.distance_squared(path.document_curve.end) < tolerance * tolerance * 2. {
continue;
}
let time = path.document_curve.project(point.document_point, None);
let time = path.document_curve.project(point.document_point);
let snapped_point_document = path.document_curve.evaluate(bezier_rs::TValue::Parametric(time));

let distance = snapped_point_document.distance(point.document_point);
Expand Down Expand Up @@ -372,7 +373,7 @@ pub fn get_bbox_points(quad: Quad, points: &mut Vec<SnapCandidatePoint>, values:
fn handle_not_under(to_document: DAffine2) -> impl Fn(&DVec2) -> bool {
move |&offset: &DVec2| to_document.transform_vector2(offset).length_squared() >= HIDE_HANDLE_DISTANCE * HIDE_HANDLE_DISTANCE
}
fn subpath_anchor_snap_points(layer: LayerNodeIdentifier, subpath: &Subpath<ManipulatorGroupId>, snap_data: &SnapData, points: &mut Vec<SnapCandidatePoint>, to_document: DAffine2) {
fn subpath_anchor_snap_points(layer: LayerNodeIdentifier, subpath: &Subpath<PointId>, snap_data: &SnapData, points: &mut Vec<SnapCandidatePoint>, to_document: DAffine2) {
let document = snap_data.document;
// Midpoints of linear segments
if document.snapping_state.target_enabled(SnapTarget::Geometry(GeometrySnapTarget::LineMidpoint)) {
Expand Down Expand Up @@ -418,7 +419,7 @@ fn subpath_anchor_snap_points(layer: LayerNodeIdentifier, subpath: &Subpath<Mani
}
}

pub fn group_smooth(group: &bezier_rs::ManipulatorGroup<ManipulatorGroupId>, to_document: DAffine2, subpath: &Subpath<ManipulatorGroupId>, index: usize) -> bool {
pub fn group_smooth<Id: bezier_rs::Identifier>(group: &bezier_rs::ManipulatorGroup<Id>, to_document: DAffine2, subpath: &Subpath<Id>, index: usize) -> bool {
let anchor = group.anchor;
let handle_in = group.in_handle.map(|handle| anchor - handle).filter(handle_not_under(to_document));
let handle_out = group.out_handle.map(|handle| handle - anchor).filter(handle_not_under(to_document));
Expand Down
Loading