1+ use crate :: build:: sweep:: { FillHandler , FillStrategy , SweepRunner } ;
12use crate :: core:: link:: OverlayLink ;
23use crate :: core:: solver:: Solver ;
34use crate :: geom:: end:: End ;
45use crate :: geom:: id_point:: IdPoint ;
5- use crate :: geom:: v_segment:: VSegment ;
66use crate :: segm:: segment:: { NONE , Segment , SegmentFill } ;
77use crate :: segm:: winding:: WindingCount ;
8- use crate :: util:: log:: Int ;
98use alloc:: vec:: Vec ;
10- use i_float :: triangle :: Triangle ;
9+ use core :: ops :: ControlFlow ;
1110use i_shape:: util:: reserve:: Reserve ;
12- use i_tree:: key:: exp:: KeyExpCollection ;
13- use i_tree:: key:: list:: KeyExpList ;
14- use i_tree:: key:: tree:: KeyExpTree ;
15-
16- pub ( super ) trait FillStrategy < C > {
17- fn add_and_fill ( this : C , bot : C ) -> ( C , SegmentFill ) ;
18- }
1911
2012pub ( super ) trait InclusionFilterStrategy {
2113 fn is_included ( fill : SegmentFill ) -> bool ;
2214}
2315
16+ pub ( crate ) struct StoreFillsHandler < ' a > {
17+ fills : & ' a mut Vec < SegmentFill > ,
18+ }
19+
20+ impl < ' a > StoreFillsHandler < ' a > {
21+ #[ inline]
22+ pub ( crate ) fn new ( fills : & ' a mut Vec < SegmentFill > ) -> Self {
23+ Self { fills }
24+ }
25+ }
26+
27+ impl < C > FillHandler < C > for StoreFillsHandler < ' _ > {
28+ type Output = ( ) ;
29+
30+ #[ inline( always) ]
31+ fn handle ( & mut self , index : usize , _segment : & Segment < C > , fill : SegmentFill ) -> ControlFlow < ( ) > {
32+ // fills is pre-allocated to segments.len() and index is guaranteed
33+ // to be in range by the sweep algorithm
34+ unsafe { * self . fills . get_unchecked_mut ( index) = fill } ;
35+ ControlFlow :: Continue ( ( ) )
36+ }
37+
38+ #[ inline( always) ]
39+ fn finalize ( self ) { }
40+ }
41+
2442pub ( crate ) trait GraphNode {
2543 fn with_indices ( indices : & [ usize ] ) -> Self ;
2644}
2745
2846pub ( crate ) struct GraphBuilder < C , N > {
29- list : Option < KeyExpList < VSegment , i32 , C > > ,
30- tree : Option < KeyExpTree < VSegment , i32 , C > > ,
47+ sweep_runner : SweepRunner < C > ,
3148 pub ( super ) links : Vec < OverlayLink > ,
3249 pub ( super ) nodes : Vec < N > ,
3350 pub ( super ) fills : Vec < SegmentFill > ,
@@ -38,8 +55,7 @@ impl<C: WindingCount, N: GraphNode> GraphBuilder<C, N> {
3855 #[ inline]
3956 pub ( crate ) fn new ( ) -> Self {
4057 Self {
41- list : None ,
42- tree : None ,
58+ sweep_runner : SweepRunner :: new ( ) ,
4359 links : Vec :: new ( ) ,
4460 nodes : Vec :: new ( ) ,
4561 fills : Vec :: new ( ) ,
@@ -53,76 +69,9 @@ impl<C: WindingCount, N: GraphNode> GraphBuilder<C, N> {
5369 solver : & Solver ,
5470 segments : & [ Segment < C > ] ,
5571 ) {
56- let count = segments. len ( ) ;
57- if solver. is_list_fill ( segments) {
58- let capacity = count. log2_sqrt ( ) . max ( 4 ) * 2 ;
59- let mut list = self . take_scan_list ( capacity) ;
60- self . build_fills :: < F , KeyExpList < VSegment , i32 , C > > ( & mut list, segments) ;
61- self . list = Some ( list) ;
62- } else {
63- let capacity = count. log2_sqrt ( ) . max ( 8 ) ;
64- let mut tree = self . take_scan_tree ( capacity) ;
65- self . build_fills :: < F , KeyExpTree < VSegment , i32 , C > > ( & mut tree, segments) ;
66- self . tree = Some ( tree) ;
67- }
68- }
69-
70- #[ inline]
71- fn build_fills < F : FillStrategy < C > , S : KeyExpCollection < VSegment , i32 , C > > (
72- & mut self ,
73- scan_list : & mut S ,
74- segments : & [ Segment < C > ] ,
75- ) {
76- let mut node = Vec :: with_capacity ( 4 ) ;
77-
78- let n = segments. len ( ) ;
79-
80- self . fills . resize ( n, NONE ) ;
81-
82- let mut i = 0 ;
83-
84- while i < n {
85- let p = segments[ i] . x_segment . a ;
86-
87- node. push ( End {
88- index : i,
89- point : segments[ i] . x_segment . b ,
90- } ) ;
91- i += 1 ;
92-
93- while i < n && segments[ i] . x_segment . a == p {
94- node. push ( End {
95- index : i,
96- point : segments[ i] . x_segment . b ,
97- } ) ;
98- i += 1 ;
99- }
100-
101- if node. len ( ) > 1 {
102- node. sort_by ( |s0, s1| Triangle :: clock_order_point ( p, s1. point , s0. point ) ) ;
103- }
104-
105- let mut sum_count =
106- scan_list. first_less_or_equal_by ( p. x , C :: new ( 0 , 0 ) , |s| s. is_under_point_order ( p) ) ;
107- let mut fill: SegmentFill ;
108-
109- for se in node. iter ( ) {
110- let sid = unsafe {
111- // SAFETY: `se.index` was produced from `i` while iterating i ∈ [0, n) over `segments`
112- segments. get_unchecked ( se. index )
113- } ;
114- ( sum_count, fill) = F :: add_and_fill ( sid. count , sum_count) ;
115- unsafe {
116- // SAFETY: `se.index` was produced from `i` while iterating i ∈ [0, n) over `segments` and segments.len == self.fills.len
117- * self . fills . get_unchecked_mut ( se. index ) = fill
118- }
119- if sid. x_segment . is_not_vertical ( ) {
120- scan_list. insert ( sid. x_segment . into ( ) , sum_count, p. x ) ;
121- }
122- }
123-
124- node. clear ( ) ;
125- }
72+ self . fills . resize ( segments. len ( ) , NONE ) ;
73+ self . sweep_runner
74+ . run :: < F , _ > ( solver, segments, StoreFillsHandler :: new ( & mut self . fills ) ) ;
12675 }
12776
12877 #[ inline]
@@ -155,26 +104,4 @@ impl<C: WindingCount, N: GraphNode> GraphBuilder<C, N> {
155104 ) ) ;
156105 }
157106 }
158-
159- #[ inline]
160- fn take_scan_list ( & mut self , capacity : usize ) -> KeyExpList < VSegment , i32 , C > {
161- if let Some ( mut list) = self . list . take ( ) {
162- list. clear ( ) ;
163- list. reserve_capacity ( capacity) ;
164- list
165- } else {
166- KeyExpList :: new ( capacity)
167- }
168- }
169-
170- #[ inline]
171- fn take_scan_tree ( & mut self , capacity : usize ) -> KeyExpTree < VSegment , i32 , C > {
172- if let Some ( mut tree) = self . tree . take ( ) {
173- tree. clear ( ) ;
174- tree. reserve_capacity ( capacity) ;
175- tree
176- } else {
177- KeyExpTree :: new ( capacity)
178- }
179- }
180107}
0 commit comments