mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 14:18:04 +08:00
Bezier-rs: Add lookup table function for subpath and make it support euclidean parameterization (#1082)
* Add euclidean option for lut * Add lut for subpath * Fix rust formatting * Fixed breakages caused by UI updates * Code cleanup * Make ProjectionOptions optional --------- Co-authored-by: Rob Nadal <robnadal44@gmail.com> Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
committed by
Keavon Chambers
parent
d0ac86b713
commit
3733804d18
@@ -76,10 +76,11 @@ const bezierFeatures = {
|
||||
},
|
||||
"lookup-table": {
|
||||
name: "Lookup Table",
|
||||
callback: (bezier: WasmBezierInstance, options: Record<string, number>): string => bezier.compute_lookup_table(options.steps),
|
||||
callback: (bezier: WasmBezierInstance, options: Record<string, number>, _: undefined): string => bezier.compute_lookup_table(options.steps, BEZIER_T_VALUE_VARIANTS[options.TVariant]),
|
||||
demoOptions: {
|
||||
Quadratic: {
|
||||
inputOptions: [
|
||||
bezierTValueVariantOptions,
|
||||
{
|
||||
min: 2,
|
||||
max: 15,
|
||||
|
||||
@@ -20,6 +20,20 @@ const subpathFeatures = {
|
||||
callback: (subpath: WasmSubpathInstance, options: Record<string, number>, _: undefined): string => subpath.evaluate(options.t, SUBPATH_T_VALUE_VARIANTS[options.TVariant]),
|
||||
inputOptions: [subpathTValueVariantOptions, tSliderOptions],
|
||||
},
|
||||
"lookup-table": {
|
||||
name: "Lookup Table",
|
||||
callback: (subpath: WasmSubpathInstance, options: Record<string, number>, _: undefined): string => subpath.compute_lookup_table(options.steps, SUBPATH_T_VALUE_VARIANTS[options.TVariant]),
|
||||
inputOptions: [
|
||||
subpathTValueVariantOptions,
|
||||
{
|
||||
min: 2,
|
||||
max: 30,
|
||||
step: 1,
|
||||
default: 5,
|
||||
variable: "steps",
|
||||
},
|
||||
],
|
||||
},
|
||||
project: {
|
||||
name: "Project",
|
||||
callback: (subpath: WasmSubpathInstance, _: Record<string, number>, mouseLocation?: [number, number]): string =>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::svg_drawing::*;
|
||||
use crate::utils::parse_cap;
|
||||
|
||||
use bezier_rs::{ArcStrategy, ArcsOptions, Bezier, Identifier, ProjectionOptions, TValue};
|
||||
use bezier_rs::{ArcStrategy, ArcsOptions, Bezier, Identifier, TValue, TValueType};
|
||||
use glam::DVec2;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use wasm_bindgen::prelude::*;
|
||||
@@ -156,9 +156,14 @@ impl WasmBezier {
|
||||
wrap_svg_tag(content)
|
||||
}
|
||||
|
||||
pub fn compute_lookup_table(&self, steps: usize) -> String {
|
||||
pub fn compute_lookup_table(&self, steps: usize, t_variant: String) -> String {
|
||||
let bezier = self.get_bezier_path();
|
||||
let table_values: Vec<DVec2> = self.0.compute_lookup_table(Some(steps));
|
||||
let tvalue_type = match t_variant.as_str() {
|
||||
"Parametric" => TValueType::Parametric,
|
||||
"Euclidean" => TValueType::Euclidean,
|
||||
_ => panic!("Unexpected TValue string: '{}'", t_variant),
|
||||
};
|
||||
let table_values: Vec<DVec2> = self.0.compute_lookup_table(Some(steps), Some(tvalue_type));
|
||||
let circles: String = table_values
|
||||
.iter()
|
||||
.map(|point| draw_circle(*point, 3., RED, 1.5, WHITE))
|
||||
@@ -287,7 +292,7 @@ impl WasmBezier {
|
||||
}
|
||||
|
||||
pub fn project(&self, x: f64, y: f64) -> String {
|
||||
let projected_t_value = self.0.project(DVec2::new(x, y), ProjectionOptions::default());
|
||||
let projected_t_value = self.0.project(DVec2::new(x, y), None);
|
||||
let projected_point = self.0.evaluate(TValue::Parametric(projected_t_value));
|
||||
|
||||
let bezier = self.get_bezier_path();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::svg_drawing::*;
|
||||
use crate::utils::{parse_cap, parse_join};
|
||||
|
||||
use bezier_rs::{Bezier, ManipulatorGroup, ProjectionOptions, Subpath, SubpathTValue};
|
||||
use bezier_rs::{Bezier, ManipulatorGroup, Subpath, SubpathTValue, TValueType};
|
||||
|
||||
use glam::DVec2;
|
||||
use std::fmt::Write;
|
||||
@@ -99,6 +99,22 @@ impl WasmSubpath {
|
||||
wrap_svg_tag(format!("{}{}", self.to_default_svg(), point_text))
|
||||
}
|
||||
|
||||
pub fn compute_lookup_table(&self, steps: usize, t_variant: String) -> String {
|
||||
let subpath = self.to_default_svg();
|
||||
let tvalue_type = match t_variant.as_str() {
|
||||
"GlobalParametric" => TValueType::Parametric,
|
||||
"GlobalEuclidean" => TValueType::Euclidean,
|
||||
_ => panic!("Unexpected TValue string: '{}'", t_variant),
|
||||
};
|
||||
let table_values: Vec<DVec2> = self.0.compute_lookup_table(Some(steps), Some(tvalue_type));
|
||||
let circles: String = table_values
|
||||
.iter()
|
||||
.map(|point| draw_circle(*point, 3., RED, 1.5, WHITE))
|
||||
.fold("".to_string(), |acc, circle| acc + &circle);
|
||||
let content = format!("{subpath}{circles}");
|
||||
wrap_svg_tag(content)
|
||||
}
|
||||
|
||||
pub fn tangent(&self, t: f64, t_variant: String) -> String {
|
||||
let t = parse_t_variant(&t_variant, t);
|
||||
|
||||
@@ -204,7 +220,7 @@ impl WasmSubpath {
|
||||
}
|
||||
|
||||
pub fn project(&self, x: f64, y: f64) -> String {
|
||||
let (segment_index, projected_t) = self.0.project(DVec2::new(x, y), ProjectionOptions::default()).unwrap();
|
||||
let (segment_index, projected_t) = self.0.project(DVec2::new(x, y), None).unwrap();
|
||||
let projected_point = self.0.evaluate(SubpathTValue::Parametric { segment_index, t: projected_t });
|
||||
|
||||
let subpath_svg = self.to_default_svg();
|
||||
|
||||
@@ -10,7 +10,7 @@ pub const WHITE: &str = "white";
|
||||
pub const GRAY: &str = "gray";
|
||||
pub const RED: &str = "red";
|
||||
pub const ORANGE: &str = "orange";
|
||||
pub const PINK: &str = "pink";
|
||||
// pub const PINK: &str = "pink";
|
||||
pub const GREEN: &str = "green";
|
||||
pub const NONE: &str = "none";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user