mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-23 00:38:12 +08:00
Refactor document node type lookup function to fix performance degradation over time (#1878)
* Refactor document_node_types function * Fix node introspection * Implement diff based type updates * Fix missing monitor nodes * Improve docs and fix warings * Fix wrongful removal of node paths * Remove code examples for non pub methodsü * Code review --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
parent
06a409f1c5
commit
0dfddd529b
@@ -67,6 +67,7 @@ impl Bezier {
|
||||
|
||||
/// Create a quadratic bezier curve that goes through 3 points, where the middle point will be at the corresponding position `t` on the curve.
|
||||
/// - `t` - A representation of how far along the curve the provided point should occur at. The default value is 0.5.
|
||||
///
|
||||
/// Note that when `t = 0` or `t = 1`, the expectation is that the `point_on_curve` should be equal to `start` and `end` respectively.
|
||||
/// In these cases, if the provided values are not equal, this function will use the `point_on_curve` as the `start`/`end` instead.
|
||||
/// <iframe frameBorder="0" width="100%" height="375px" src="https://graphite.rs/libraries/bezier-rs#bezier/bezier-through-points/solo" title="Through Points Demo"></iframe>
|
||||
@@ -84,6 +85,7 @@ impl Bezier {
|
||||
|
||||
/// Create a cubic bezier curve that goes through 3 points, where the middle point will be at the corresponding position `t` on the curve.
|
||||
/// - `t` - A representation of how far along the curve the provided point should occur at. The default value is 0.5.
|
||||
///
|
||||
/// Note that when `t = 0` or `t = 1`, the expectation is that the `point_on_curve` should be equal to `start` and `end` respectively.
|
||||
/// In these cases, if the provided values are not equal, this function will use the `point_on_curve` as the `start`/`end` instead.
|
||||
/// - `midpoint_separation` - A representation of how wide the resulting curve will be around `t` on the curve. This parameter designates the distance between the `e1` and `e2` defined in [the projection identity section](https://pomax.github.io/bezierinfo/#abc) of Pomax's bezier curve primer. It is an optional parameter and the default value is the distance between the points `B` and `C` defined in the primer.
|
||||
|
||||
@@ -133,6 +133,7 @@ impl Bezier {
|
||||
/// Determine if it is possible to scale the given curve, using the following conditions:
|
||||
/// 1. All the handles are located on a single side of the curve.
|
||||
/// 2. The on-curve point for `t = 0.5` must occur roughly in the center of the polygon defined by the curve's endpoint normals.
|
||||
///
|
||||
/// See [the offset section](https://pomax.github.io/bezierinfo/#offsetting) of Pomax's bezier curve primer for more details.
|
||||
fn is_scalable(&self) -> bool {
|
||||
if self.handles == BezierHandles::Linear {
|
||||
@@ -345,7 +346,7 @@ impl Bezier {
|
||||
/// A proof for why this is true can be found in the [Curve offsetting section](https://pomax.github.io/bezierinfo/#offsetting) of Pomax's bezier curve primer.
|
||||
/// Offset takes the following parameter:
|
||||
/// - `distance` - The offset's distance from the curve. Positive values will offset the curve in the same direction as the endpoint normals,
|
||||
/// while negative values will offset in the opposite direction.
|
||||
/// while negative values will offset in the opposite direction.
|
||||
/// <iframe frameBorder="0" width="100%" height="325px" src="https://graphite.rs/libraries/bezier-rs#bezier/offset/solo" title="Offset Demo"></iframe>
|
||||
pub fn offset<PointId: crate::Identifier>(&self, distance: f64) -> Subpath<PointId> {
|
||||
if self.is_point() {
|
||||
|
||||
@@ -65,6 +65,7 @@ impl<PointId: crate::Identifier> Subpath<PointId> {
|
||||
/// Because the calculation of area for self-intersecting path requires finding the intersections, the following parameters are used:
|
||||
/// - `error` - For intersections with non-linear beziers, `error` defines the threshold for bounding boxes to be considered an intersection point.
|
||||
/// - `minimum_separation` - the minimum difference two adjacent `t`-values must have when comparing adjacent `t`-values in sorted order.
|
||||
///
|
||||
/// If the comparison condition is not satisfied, the function takes the larger `t`-value of the two
|
||||
///
|
||||
/// **NOTE**: if an intersection were to occur within an `error` distance away from an anchor point, the algorithm will filter that intersection out.
|
||||
@@ -109,6 +110,7 @@ impl<PointId: crate::Identifier> Subpath<PointId> {
|
||||
/// Because the calculation of area and centroid for self-intersecting path requires finding the intersections, the following parameters are used:
|
||||
/// - `error` - For intersections with non-linear beziers, `error` defines the threshold for bounding boxes to be considered an intersection point.
|
||||
/// - `minimum_separation` - the minimum difference two adjacent `t`-values must have when comparing adjacent `t`-values in sorted order.
|
||||
///
|
||||
/// If the comparison condition is not satisfied, the function takes the larger `t`-value of the two.
|
||||
///
|
||||
/// **NOTE**: if an intersection were to occur within an `error` distance away from an anchor point, the algorithm will filter that intersection out.
|
||||
@@ -167,6 +169,7 @@ impl<PointId: crate::Identifier> Subpath<PointId> {
|
||||
/// - `error` - For intersections with non-linear beziers, `error` defines the threshold for bounding boxes to be considered an intersection point.
|
||||
/// - `minimum_separation` - the minimum difference two adjacent `t`-values must have when comparing adjacent `t`-values in sorted order.
|
||||
/// - `tolerance` - Tolerance used to approximate the curve if it falls back to length centroid.
|
||||
///
|
||||
/// If the comparison condition is not satisfied, the function takes the larger `t`-value of the two
|
||||
///
|
||||
/// **NOTE**: if an intersection were to occur within an `error` distance away from an anchor point, the algorithm will filter that intersection out.
|
||||
|
||||
@@ -82,6 +82,7 @@ impl<PointId: crate::Identifier> Subpath<PointId> {
|
||||
/// - `IgnoreStart`: drops the bezier's start point in favor of the subpath's last anchor
|
||||
/// - `SmoothJoin(f64)`: joins the subpath's endpoint with the bezier's start with a another Bezier segment that is continuous up to the second derivative
|
||||
/// if the difference between the subpath's end point and Bezier's start point exceeds the wrapped integer value.
|
||||
///
|
||||
/// This function assumes that the position of the [Bezier]'s starting point is equal to that of the Subpath's last manipulator group.
|
||||
pub fn append_bezier(&mut self, bezier: &Bezier, append_type: AppendType) {
|
||||
if self.manipulator_groups.is_empty() {
|
||||
|
||||
@@ -22,6 +22,7 @@ impl<PointId: crate::Identifier> Subpath<PointId> {
|
||||
/// - `other`: a [Bezier] curve to check intersections against
|
||||
/// - `error`: an optional f64 value to provide an error bound
|
||||
/// - `minimum_separation`: the minimum difference two adjacent `t`-values must have when comparing adjacent `t`-values in sorted order.
|
||||
///
|
||||
/// If the comparison condition is not satisfied, the function takes the larger `t`-value of the two.
|
||||
/// <iframe frameBorder="0" width="100%" height="375px" src="https://graphite.rs/libraries/bezier-rs#subpath/intersect-linear/solo" title="Intersection Demo"></iframe>
|
||||
///
|
||||
@@ -107,6 +108,7 @@ impl<PointId: crate::Identifier> Subpath<PointId> {
|
||||
/// Returns a list of `t` values that correspond to the self intersection points of the subpath. For each intersection point, the returned `t` value is the smaller of the two that correspond to the point.
|
||||
/// - `error` - For intersections with non-linear beziers, `error` defines the threshold for bounding boxes to be considered an intersection point.
|
||||
/// - `minimum_separation`: the minimum difference two adjacent `t`-values must have when comparing adjacent `t`-values in sorted order.
|
||||
///
|
||||
/// If the comparison condition is not satisfied, the function takes the larger `t`-value of the two
|
||||
///
|
||||
/// **NOTE**: if an intersection were to occur within an `error` distance away from an anchor point, the algorithm will filter that intersection out.
|
||||
@@ -134,6 +136,7 @@ impl<PointId: crate::Identifier> Subpath<PointId> {
|
||||
/// The points will be sorted based on their index and `t` repsectively.
|
||||
/// - `error` - For intersections with non-linear beziers, `error` defines the threshold for bounding boxes to be considered an intersection point.
|
||||
/// - `minimum_separation`: the minimum difference two adjacent `t`-values must have when comparing adjacent `t`-values in sorted order.
|
||||
///
|
||||
/// If the comparison condition is not satisfied, the function takes the larger `t`-value of the two
|
||||
///
|
||||
/// **NOTE**: if an intersection were to occur within an `error` distance away from an anchor point, the algorithm will filter that intersection out.
|
||||
@@ -168,6 +171,7 @@ impl<PointId: crate::Identifier> Subpath<PointId> {
|
||||
/// - `corner2`: the corner opposite to `corner1`
|
||||
/// - `error`: an optional f64 value to provide an error bound
|
||||
/// - `minimum_separation`: the minimum difference two adjacent `t`-values must have when comparing adjacent `t`-values in sorted order.
|
||||
///
|
||||
/// If the comparison condition is not satisfied, the function takes the larger `t`-value of the two.
|
||||
/// <iframe frameBorder="0" width="100%" height="375px" src="https://graphite.rs/libraries/bezier-rs#subpath/intersect-rectangle/solo" title="Intersection Demo"></iframe>
|
||||
pub fn rectangle_intersections(&self, corner1: DVec2, corner2: DVec2, error: Option<f64>, minimum_separation: Option<f64>) -> Vec<(usize, f64)> {
|
||||
@@ -340,6 +344,7 @@ impl<PointId: crate::Identifier> Subpath<PointId> {
|
||||
/// Conceptually, this works by "throwing a dart" at the subpath's bounding box and keeping the dart only if:
|
||||
/// - It's inside the shape
|
||||
/// - It's not closer than `separation_disk_diameter` to any other point from a previous accepted dart throw
|
||||
///
|
||||
/// This repeats until accepted darts fill all possible areas between one another.
|
||||
///
|
||||
/// While the conceptual process described above asymptotically slows down and is never guaranteed to produce a maximal set in finite time,
|
||||
@@ -372,6 +377,7 @@ impl<PointId: crate::Identifier> Subpath<PointId> {
|
||||
|
||||
/// Returns the manipulator point that is needed for a miter join if it is possible.
|
||||
/// - `miter_limit`: Defines a limit for the ratio between the miter length and the stroke width.
|
||||
///
|
||||
/// Alternatively, this can be interpreted as limiting the angle that the miter can form.
|
||||
/// When the limit is exceeded, no manipulator group will be returned.
|
||||
/// This value should be at least 1. If not, the default of 4 will be used.
|
||||
|
||||
Reference in New Issue
Block a user