Migrate vector data and tools to use nodes (#1065)

* Add rendering to vector nodes

* Add line, shape, rectange and freehand tool

* Fix transforms, strokes and fills

* Migrate spline tool

* Remove blank lines

* Fix test

* Fix fill in properties

* Select layers when filling

* Properties panel transform around pivot

* Fix select tool outlines

* Select tool modifies node graph pivot

* Add the pivot assist to the properties

* Improve setting non existant fill UX

* Cleanup hash function

* Path and pen tools

* Bug fixes

* Disable boolean ops

* Fix default handle smoothing on ellipses

* Fix test and warnings

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
0HyperCube
2023-03-26 08:03:51 +01:00
committed by GitHub
parent 5759600f95
commit ac49519fa9
64 changed files with 2639 additions and 1552 deletions

View File

@@ -1,6 +1,7 @@
use crate::boolean_ops::{split_path_seg, subdivide_path_seg};
use crate::consts::{F64LOOSE, F64PRECISE};
use graphene_core::uuid::ManipulatorGroupId;
use graphene_std::vector::subpath::Subpath;
use glam::{DAffine2, DMat2, DVec2};
@@ -19,6 +20,13 @@ impl Quad {
Self([bbox[0], bbox[0] + size * DVec2::X, bbox[1], bbox[0] + size * DVec2::Y])
}
/// Get all the edges in the quad.
pub fn lines_glam(&self) -> impl Iterator<Item = bezier_rs::Bezier> + '_ {
[[self.0[0], self.0[1]], [self.0[1], self.0[2]], [self.0[2], self.0[3]], [self.0[3], self.0[0]]]
.into_iter()
.map(|[start, end]| bezier_rs::Bezier::from_linear_dvec2(start, end))
}
/// Get all the edges in the quad.
pub fn lines(&self) -> [Line; 4] {
[
@@ -101,6 +109,35 @@ pub fn intersect_quad_bez_path(quad: Quad, shape: &BezPath, filled: bool) -> boo
get_arbitrary_point_on_path(&shape).map(|shape_point| quad.path().contains(shape_point)).unwrap_or_default()
}
pub fn intersect_quad_subpath(quad: Quad, subpath: &bezier_rs::Subpath<ManipulatorGroupId>, close_subpath: bool) -> bool {
let mut subpath = subpath.clone();
// For close_subpath shapes act like shape was closed even if it isn't
if close_subpath && !subpath.closed() {
subpath.set_closed(true);
}
// Check if outlines intersect
if subpath
.iter()
.any(|path_segment| quad.lines_glam().any(|line| !path_segment.intersections(&line, None, None).is_empty()))
{
return true;
}
// Check if selection is entirely within the shape
if close_subpath && subpath.contains_point(quad.center()) {
return true;
}
// Check if shape is entirely within selection
subpath
.manipulator_groups()
.first()
.map(|group| group.anchor)
.map(|shape_point| quad.path().contains(to_point(shape_point)))
.unwrap_or_default()
}
/// Returns a point on `path`.
/// This function will usually return the first point from the path's first segment, but callers should not rely on this behavior.
pub fn get_arbitrary_point_on_path(path: &BezPath) -> Option<Point> {