@@ -2,7 +2,7 @@ mod attributes;
2
2
mod indexed;
3
3
mod modification;
4
4
5
- use super :: misc:: point_to_dvec2;
5
+ use super :: misc:: { dvec2_to_point , point_to_dvec2} ;
6
6
use super :: style:: { PathStyle , Stroke } ;
7
7
use crate :: instances:: Instances ;
8
8
use crate :: { AlphaBlending , Color , GraphicGroupTable } ;
@@ -12,6 +12,7 @@ use core::borrow::Borrow;
12
12
use dyn_any:: DynAny ;
13
13
use glam:: { DAffine2 , DVec2 } ;
14
14
pub use indexed:: VectorDataIndex ;
15
+ use kurbo:: { Affine , Shape } ;
15
16
pub use modification:: * ;
16
17
use std:: collections:: HashMap ;
17
18
@@ -193,6 +194,23 @@ impl VectorData {
193
194
vector_data
194
195
}
195
196
197
+ pub fn close_subpaths ( & mut self ) {
198
+ let segments_to_add: Vec < _ > = self
199
+ . stroke_bezier_paths ( )
200
+ . filter ( |subpath| !subpath. closed )
201
+ . filter_map ( |subpath| {
202
+ let ( first, last) = subpath. manipulator_groups ( ) . first ( ) . zip ( subpath. manipulator_groups ( ) . last ( ) ) ?;
203
+ let ( start, end) = self . point_domain . resolve_id ( first. id ) . zip ( self . point_domain . resolve_id ( last. id ) ) ?;
204
+ Some ( ( start, end) )
205
+ } )
206
+ . collect ( ) ;
207
+
208
+ for ( start, end) in segments_to_add {
209
+ let segment_id = self . segment_domain . next_id ( ) . next_id ( ) ;
210
+ self . segment_domain . push ( segment_id, start, end, bezier_rs:: BezierHandles :: Linear , StrokeId :: ZERO ) ;
211
+ }
212
+ }
213
+
196
214
/// Compute the bounding boxes of the subpaths without any transform
197
215
pub fn bounding_box ( & self ) -> Option < [ DVec2 ; 2 ] > {
198
216
self . bounding_box_with_transform ( DAffine2 :: IDENTITY )
@@ -316,6 +334,34 @@ impl VectorData {
316
334
self . point_domain . resolve_id ( point) . map_or ( 0 , |point| self . segment_domain . connected_count ( point) )
317
335
}
318
336
337
+ pub fn check_point_inside_shape ( & self , vector_data_transform : DAffine2 , point : DVec2 ) -> bool {
338
+ let bez_paths: Vec < _ > = self
339
+ . stroke_bezpath_iter ( )
340
+ . map ( |mut bezpath| {
341
+ // TODO: apply transform to points instead of modifying the paths
342
+ bezpath. apply_affine ( Affine :: new ( vector_data_transform. to_cols_array ( ) ) ) ;
343
+ bezpath. close_path ( ) ;
344
+ let bbox = bezpath. bounding_box ( ) ;
345
+ ( bezpath, bbox)
346
+ } )
347
+ . collect ( ) ;
348
+
349
+ // Check against all paths the point is contained in to compute the correct winding number
350
+ let mut number = 0 ;
351
+
352
+ for ( shape, bbox) in bez_paths {
353
+ if bbox. x0 > point. x || bbox. y0 > point. y || bbox. x1 < point. x || bbox. y1 < point. y {
354
+ continue ;
355
+ }
356
+
357
+ let winding = shape. winding ( dvec2_to_point ( point) ) ;
358
+ number += winding;
359
+ }
360
+
361
+ // Non-zero fill rule
362
+ number != 0
363
+ }
364
+
319
365
/// Points that can be extended from.
320
366
///
321
367
/// This is usually only points with exactly one connection unless vector meshes are enabled.
0 commit comments