1mod geometry;
11mod output;
12#[cfg(test)]
13mod tests;
14
15use geometry::{
16 check_orientation, compute_intersect_coords, compute_normal, dot, is_valid_coord, long_axis,
17};
18
19use crate::dict::{Dict, NodeIdx, DICT_HEAD};
20use crate::geom::{edge_intersect, edge_sign, vert_eq, vert_leq, Real};
21use crate::mesh::{EdgeIdx, Mesh, VertIdx, E_HEAD, INVALID, V_HEAD};
22use crate::priorityq::INVALID_HANDLE;
23use crate::sweep::ActiveRegion;
24
25#[derive(Copy, Clone, Debug, PartialEq)]
28pub enum WindingRule {
29 Odd,
30 NonZero,
31 Positive,
32 Negative,
33 AbsGeqTwo,
34}
35
36#[derive(Copy, Clone, Debug, PartialEq)]
37pub enum ElementType {
38 Polygons,
39 ConnectedPolygons,
40 BoundaryContours,
41}
42
43#[derive(Copy, Clone, Debug, PartialEq)]
44pub enum TessOption {
45 ConstrainedDelaunayTriangulation,
46 ReverseContours,
47}
48
49#[derive(Copy, Clone, Debug, PartialEq)]
50pub enum TessStatus {
51 Ok,
52 OutOfMemory,
53 InvalidInput,
54}
55
56pub const TESS_UNDEF: u32 = u32::MAX;
57const MAX_VALID_COORD: f32 = (1u32 << 23) as f32;
58const MIN_VALID_COORD: f32 = -MAX_VALID_COORD;
59
60type RegionIdx = u32;
61
62pub struct Tessellator {
65 mesh: Option<Mesh>,
66 pub status: TessStatus,
67 normal: [Real; 3],
68 s_unit: [Real; 3],
69 t_unit: [Real; 3],
70 bmin: [Real; 2],
71 bmax: [Real; 2],
72 process_cdt: bool,
73 reverse_contours: bool,
74 winding_rule: WindingRule,
75
76 dict: Dict,
78 intersection_verts: Vec<VertIdx>,
81 next_isect_handle: i32,
82 event: VertIdx,
83 event_s: Real,
84 event_t: Real,
85
86 regions: Vec<Option<ActiveRegion>>,
88 region_free: Vec<RegionIdx>,
89
90 pub out_vertices: Vec<Real>,
92 pub out_vertex_indices: Vec<u32>,
93 pub out_elements: Vec<u32>,
94 pub out_vertex_count: usize,
95 pub out_element_count: usize,
96 vertex_index_counter: u32,
97
98 sorted_events: Vec<VertIdx>,
100 sorted_event_pos: usize,
101 sweep_event_num: u32,
102 trace_enabled: bool,
103}
104
105impl Tessellator {
106 pub fn new() -> Self {
107 Tessellator {
108 mesh: None,
109 status: TessStatus::Ok,
110 normal: [0.0; 3],
111 s_unit: [0.0; 3],
112 t_unit: [0.0; 3],
113 bmin: [0.0; 2],
114 bmax: [0.0; 2],
115 process_cdt: false,
116 reverse_contours: false,
117 winding_rule: WindingRule::Odd,
118 dict: Dict::new(),
119 intersection_verts: Vec::new(),
120 next_isect_handle: 0,
121 event: INVALID,
122 event_s: 0.0,
123 event_t: 0.0,
124 regions: Vec::new(),
125 region_free: Vec::new(),
126 out_vertices: Vec::new(),
127 out_vertex_indices: Vec::new(),
128 out_elements: Vec::new(),
129 out_vertex_count: 0,
130 out_element_count: 0,
131 vertex_index_counter: 0,
132 sorted_events: Vec::new(),
133 sorted_event_pos: 0,
134 sweep_event_num: 0,
135 trace_enabled: std::env::var("TESS_TRACE").is_ok(),
136 }
137 }
138
139 pub fn set_option(&mut self, option: TessOption, value: bool) {
140 match option {
141 TessOption::ConstrainedDelaunayTriangulation => self.process_cdt = value,
142 TessOption::ReverseContours => self.reverse_contours = value,
143 }
144 }
145
146 pub fn add_contour(&mut self, size: usize, vertices: &[f32]) {
148 if self.status != TessStatus::Ok {
149 return;
150 }
151 let size = size.min(3).max(2);
152 let count = vertices.len() / size;
153 if self.mesh.is_none() {
154 self.mesh = Some(Mesh::new());
155 }
156
157 let mut e = INVALID;
158 for i in 0..count {
159 let cx = vertices[i * size];
160 let cy = vertices[i * size + 1];
161 let cz = if size > 2 {
162 vertices[i * size + 2]
163 } else {
164 0.0
165 };
166
167 if !is_valid_coord(cx) || !is_valid_coord(cy) || (size > 2 && !is_valid_coord(cz)) {
168 self.status = TessStatus::InvalidInput;
169 return;
170 }
171
172 let mesh = self.mesh.as_mut().unwrap();
173 if e == INVALID {
174 let new_e = match mesh.make_edge() {
175 Some(v) => v,
176 None => {
177 self.status = TessStatus::OutOfMemory;
178 return;
179 }
180 };
181 e = new_e;
182 if !mesh.splice(e, e ^ 1) {
183 self.status = TessStatus::OutOfMemory;
184 return;
185 }
186 } else {
187 if mesh.split_edge(e).is_none() {
188 self.status = TessStatus::OutOfMemory;
189 return;
190 }
191 e = mesh.edges[e as usize].lnext;
192 }
193
194 let org = mesh.edges[e as usize].org;
195 mesh.verts[org as usize].coords[0] = cx;
196 mesh.verts[org as usize].coords[1] = cy;
197 mesh.verts[org as usize].coords[2] = cz;
198 mesh.verts[org as usize].idx = self.vertex_index_counter;
199 self.vertex_index_counter += 1;
200
201 let w = if self.reverse_contours { -1 } else { 1 };
202 mesh.edges[e as usize].winding = w;
203 mesh.edges[(e ^ 1) as usize].winding = -w;
204 }
205 }
206
207 pub fn tessellate(
208 &mut self,
209 winding_rule: WindingRule,
210 element_type: ElementType,
211 poly_size: usize,
212 vertex_size: usize,
213 normal: Option<[f32; 3]>,
214 ) -> bool {
215 if self.status != TessStatus::Ok {
216 return false;
217 }
218 self.winding_rule = winding_rule;
219 self.out_vertices.clear();
220 self.out_vertex_indices.clear();
221 self.out_elements.clear();
222 self.out_vertex_count = 0;
223 self.out_element_count = 0;
224 self.normal = normal.unwrap_or([0.0, 0.0, 0.0]);
225
226 if self.mesh.is_none() {
227 self.mesh = Some(Mesh::new());
228 }
229
230 if !self.project_polygon() {
231 self.status = TessStatus::OutOfMemory;
232 return false;
233 }
234
235 if !self.compute_interior() {
236 if self.status == TessStatus::Ok {
237 self.status = TessStatus::OutOfMemory;
238 }
239 return false;
240 }
241
242 let vertex_size = vertex_size.min(3).max(2);
243 if element_type == ElementType::BoundaryContours {
244 self.output_contours(vertex_size);
245 } else {
246 self.output_polymesh(element_type, poly_size, vertex_size);
247 }
248
249 self.mesh = None;
250 self.status == TessStatus::Ok
251 }
252
253 pub fn vertex_count(&self) -> usize {
256 self.out_vertex_count
257 }
258 pub fn element_count(&self) -> usize {
259 self.out_element_count
260 }
261 pub fn vertices(&self) -> &[f32] {
262 &self.out_vertices
263 }
264 pub fn vertex_indices(&self) -> &[u32] {
265 &self.out_vertex_indices
266 }
267 pub fn elements(&self) -> &[u32] {
268 &self.out_elements
269 }
270 pub fn get_status(&self) -> TessStatus {
271 self.status
272 }
273
274 fn project_polygon(&mut self) -> bool {
277 let mut norm = self.normal;
278 let mut computed_normal = false;
279 if norm[0] == 0.0 && norm[1] == 0.0 && norm[2] == 0.0 {
280 if let Some(ref m) = self.mesh {
281 compute_normal(m, &mut norm);
282 }
283 computed_normal = true;
284 }
285
286 let i = long_axis(&norm);
287 self.s_unit = [0.0; 3];
288 self.t_unit = [0.0; 3];
289 self.s_unit[(i + 1) % 3] = 1.0;
290 self.t_unit[(i + 2) % 3] = if norm[i] > 0.0 { 1.0 } else { -1.0 };
291 let su = self.s_unit;
292 let tu = self.t_unit;
293
294 if let Some(ref mut mesh) = self.mesh {
295 let mut v = mesh.verts[V_HEAD as usize].next;
296 while v != V_HEAD {
297 let c = mesh.verts[v as usize].coords;
298 mesh.verts[v as usize].s = dot(&c, &su);
299 mesh.verts[v as usize].t = dot(&c, &tu);
300 v = mesh.verts[v as usize].next;
301 }
302 if computed_normal {
303 check_orientation(mesh);
304 }
305
306 let mut first = true;
307 let mut v = mesh.verts[V_HEAD as usize].next;
308 while v != V_HEAD {
309 let vs = mesh.verts[v as usize].s;
310 let vt = mesh.verts[v as usize].t;
311 if first {
312 self.bmin = [vs, vt];
313 self.bmax = [vs, vt];
314 first = false;
315 } else {
316 if vs < self.bmin[0] {
317 self.bmin[0] = vs;
318 }
319 if vs > self.bmax[0] {
320 self.bmax[0] = vs;
321 }
322 if vt < self.bmin[1] {
323 self.bmin[1] = vt;
324 }
325 if vt > self.bmax[1] {
326 self.bmax[1] = vt;
327 }
328 }
329 v = mesh.verts[v as usize].next;
330 }
331 }
332 true
333 }
334
335 fn compute_interior(&mut self) -> bool {
338 self.sweep_event_num = 0;
339
340 if !self.remove_degenerate_edges() {
341 return false;
342 }
343 if !self.init_priority_queue() {
344 return false;
345 }
346 if !self.init_edge_dict() {
347 return false;
348 }
349
350 loop {
351 if self.pq_is_empty() {
352 break;
353 }
354
355 let v = self.pq_extract_min();
356 if v == INVALID {
357 break;
358 }
359
360 loop {
362 if self.pq_is_empty() {
363 break;
364 }
365 let next_v = self.pq_minimum();
366 if next_v == INVALID {
367 break;
368 }
369 let (v_s, v_t) = {
370 let mesh = self.mesh.as_ref().unwrap();
371 (mesh.verts[v as usize].s, mesh.verts[v as usize].t)
372 };
373 let (nv_s, nv_t) = {
374 let mesh = self.mesh.as_ref().unwrap();
375 (mesh.verts[next_v as usize].s, mesh.verts[next_v as usize].t)
376 };
377 if !vert_eq(v_s, v_t, nv_s, nv_t) {
378 break;
379 }
380 let next_v = self.pq_extract_min();
381 let an1 = self.mesh.as_ref().unwrap().verts[v as usize].an_edge;
383 let an2 = self.mesh.as_ref().unwrap().verts[next_v as usize].an_edge;
384 if an1 != INVALID && an2 != INVALID {
385 if !self.mesh.as_mut().unwrap().splice(an1, an2) {
386 return false;
387 }
388 }
389 }
390
391 self.event = v;
392 let (v_s, v_t) = {
393 let m = self.mesh.as_ref().unwrap();
394 (m.verts[v as usize].s, m.verts[v as usize].t)
395 };
396 self.event_s = v_s;
397 self.event_t = v_t;
398
399 if !self.sweep_event(v) {
400 return false;
401 }
402 }
403
404 self.done_edge_dict();
405
406 let trace = self.trace_enabled;
407 if let Some(ref mut mesh) = self.mesh {
408 if trace {
409 let mut inside = 0u32;
410 let mut outside = 0u32;
411 let mut f = mesh.faces[crate::mesh::F_HEAD as usize].next;
412 while f != crate::mesh::F_HEAD {
413 let an = mesh.faces[f as usize].an_edge;
414 let mut edge_count = 0u32;
415 if an != INVALID {
416 let mut e = an;
417 loop {
418 edge_count += 1;
419 e = mesh.edges[e as usize].lnext;
420 if e == an { break; }
421 if edge_count > 10000 { break; }
422 }
423 }
424 if mesh.faces[f as usize].inside {
425 inside += 1;
426 eprintln!("R FACE inside edges={}", edge_count);
427 } else {
428 outside += 1;
429 }
430 f = mesh.faces[f as usize].next;
431 }
432 eprintln!("R FACES inside={} outside={}", inside, outside);
433 }
434 if !mesh.tessellate_interior() {
435 return false;
436 }
437 if self.process_cdt {
438 mesh.refine_delaunay();
439 }
440 }
441 true
442 }
443
444 fn remove_degenerate_edges(&mut self) -> bool {
445 let mesh = match self.mesh.as_mut() {
447 Some(m) => m,
448 None => return true,
449 };
450 let mut e = mesh.edges[E_HEAD as usize].next;
451 while e != E_HEAD {
452 let mut e_next = mesh.edges[e as usize].next;
453 let mut e_lnext = mesh.edges[e as usize].lnext;
454
455 let org = mesh.edges[e as usize].org;
456 let dst = mesh.dst(e);
457 let valid = org != INVALID
458 && dst != INVALID
459 && (org as usize) < mesh.verts.len()
460 && (dst as usize) < mesh.verts.len();
461
462 if valid {
463 let (os, ot) = (mesh.verts[org as usize].s, mesh.verts[org as usize].t);
464 let (ds, dt) = (mesh.verts[dst as usize].s, mesh.verts[dst as usize].t);
465
466 if vert_eq(os, ot, ds, dt) && mesh.edges[e_lnext as usize].lnext != e {
467 mesh.splice(e_lnext, e);
469 if !mesh.delete_edge(e) {
470 return false;
471 }
472 e = e_lnext;
473 e_lnext = mesh.edges[e as usize].lnext;
474 }
475 }
476
477 let e_lnext_lnext = mesh.edges[e_lnext as usize].lnext;
479 if e_lnext_lnext == e {
480 if e_lnext != e {
481 if e_lnext == e_next || e_lnext == (e_next ^ 1) {
483 e_next = mesh.edges[e_next as usize].next;
484 }
485 let w1 = mesh.edges[e_lnext as usize].winding;
486 let w2 = mesh.edges[(e_lnext ^ 1) as usize].winding;
487 mesh.edges[e as usize].winding += w1;
488 mesh.edges[(e ^ 1) as usize].winding += w2;
489 if !mesh.delete_edge(e_lnext) {
490 return false;
491 }
492 }
493 if e == e_next || e == (e_next ^ 1) {
495 e_next = mesh.edges[e_next as usize].next;
496 }
497 if !mesh.delete_edge(e) {
498 return false;
499 }
500 }
501
502 e = e_next;
503 }
504 true
505 }
506
507 fn init_priority_queue(&mut self) -> bool {
508 let mesh = match self.mesh.as_ref() {
509 Some(m) => m,
510 None => return true,
511 };
512 let mut count = 0usize;
513 let mut v = mesh.verts[V_HEAD as usize].next;
514 while v != V_HEAD {
515 count += 1;
516 v = mesh.verts[v as usize].next;
517 }
518
519 let mut vert_coords: Vec<(Real, Real, VertIdx)> = Vec::with_capacity(count);
521 let mut v = mesh.verts[V_HEAD as usize].next;
522 while v != V_HEAD {
523 vert_coords.push((mesh.verts[v as usize].s, mesh.verts[v as usize].t, v));
524 v = mesh.verts[v as usize].next;
525 }
526 drop(mesh);
527
528 vert_coords.sort_unstable_by(|a, b| {
529 if vert_leq(a.0, a.1, b.0, b.1) {
530 std::cmp::Ordering::Less
531 } else {
532 std::cmp::Ordering::Greater
533 }
534 });
535
536 self.sorted_events = vert_coords.iter().map(|&(_, _, v)| v).collect();
539 self.sorted_event_pos = 0;
540 self.intersection_verts.clear();
541 self.next_isect_handle = 0;
542
543 for (idx, &(_, _, v)) in vert_coords.iter().enumerate() {
545 let handle = -(idx as i32 + 1); self.mesh.as_mut().unwrap().verts[v as usize].pq_handle = handle;
547 }
548
549 true
550 }
551
552 fn pq_is_empty(&self) -> bool {
553 self.sorted_events_min() == INVALID && self.intersection_verts.is_empty()
554 }
555
556 fn sorted_events_min(&self) -> VertIdx {
557 let mut pos = self.sorted_event_pos;
558 while pos < self.sorted_events.len() {
559 let v = self.sorted_events[pos];
560 if v != INVALID {
561 return v;
562 }
563 pos += 1;
564 }
565 INVALID
566 }
567
568 fn isect_minimum(&self) -> VertIdx {
570 if self.intersection_verts.is_empty() {
571 return INVALID;
572 }
573 let mesh = self.mesh.as_ref().unwrap();
574 let mut best = INVALID;
575 for &v in &self.intersection_verts {
576 if best == INVALID {
577 best = v;
578 } else {
579 let (bs, bt) = (mesh.verts[best as usize].s, mesh.verts[best as usize].t);
580 let (vs, vt) = (mesh.verts[v as usize].s, mesh.verts[v as usize].t);
581 if vert_leq(vs, vt, bs, bt) {
582 best = v;
583 }
584 }
585 }
586 best
587 }
588
589 fn pq_minimum(&self) -> VertIdx {
590 let sort_min = self.sorted_events_min();
591 let isect_min = self.isect_minimum();
592
593 match (sort_min, isect_min) {
594 (INVALID, INVALID) => INVALID,
595 (INVALID, h) => h,
596 (s, INVALID) => s,
597 (s, h) => {
598 let mesh = self.mesh.as_ref().unwrap();
599 let (ss, st) = (mesh.verts[s as usize].s, mesh.verts[s as usize].t);
600 let (hs, ht) = (mesh.verts[h as usize].s, mesh.verts[h as usize].t);
601 if vert_leq(ss, st, hs, ht) {
602 s
603 } else {
604 h
605 }
606 }
607 }
608 }
609
610 fn pq_extract_min(&mut self) -> VertIdx {
611 let v = self.pq_minimum();
612 if v == INVALID {
613 return INVALID;
614 }
615
616 if self.sorted_events_min() == v {
617 while self.sorted_event_pos < self.sorted_events.len() {
618 let s = self.sorted_events[self.sorted_event_pos];
619 self.sorted_event_pos += 1;
620 if s != INVALID {
621 break;
622 }
623 }
624 } else {
625 if let Some(pos) = self.intersection_verts.iter().position(|&x| x == v) {
627 self.intersection_verts.swap_remove(pos);
628 }
629 }
630 v
631 }
632
633 fn pq_delete(&mut self, handle: i32) {
634 if handle >= 0 {
635 let vert_idx = handle as u32;
637 if let Some(pos) = self.intersection_verts.iter().position(|&x| x == vert_idx) {
638 self.intersection_verts.swap_remove(pos);
639 }
640 } else {
641 let idx = (-(handle + 1)) as usize;
643 if idx < self.sorted_events.len() {
644 self.sorted_events[idx] = INVALID;
645 }
646 }
647 }
648
649 fn pq_insert(&mut self, v: VertIdx) -> i32 {
650 self.intersection_verts.push(v);
651 v as i32
653 }
654
655 fn add_sentinel(&mut self, smin: Real, smax: Real, t: Real) -> bool {
658 let e = match self.mesh.as_mut().unwrap().make_edge() {
661 Some(e) => e,
662 None => return false,
663 };
664 {
665 let mesh = self.mesh.as_mut().unwrap();
666 let org = mesh.edges[e as usize].org;
667 let dst = mesh.dst(e);
668 mesh.verts[org as usize].s = smax;
669 mesh.verts[org as usize].t = t;
670 mesh.verts[dst as usize].s = smin;
671 mesh.verts[dst as usize].t = t;
672 }
673 let dst = self.mesh.as_ref().unwrap().dst(e);
675 let (dst_s, dst_t) = {
676 let m = self.mesh.as_ref().unwrap();
677 (m.verts[dst as usize].s, m.verts[dst as usize].t)
678 };
679 self.event = dst;
680 self.event_s = dst_s;
681 self.event_t = dst_t;
682
683 let reg = self.alloc_region();
684 {
685 let r = self.region_mut(reg);
686 r.e_up = e;
687 r.winding_number = 0;
688 r.inside = false;
689 r.sentinel = true;
690 r.dirty = false;
691 r.fix_upper_edge = false;
692 }
693
694 let node = self.dict_insert_region(reg);
696 if node == INVALID {
697 return false;
698 }
699 self.region_mut(reg).node_up = node;
700
701 self.mesh.as_mut().unwrap().edges[e as usize].active_region = reg;
703 true
704 }
705
706 fn dict_insert_region(&mut self, reg: RegionIdx) -> NodeIdx {
709 self.dict_insert_before(reg, DICT_HEAD)
710 }
711
712 fn dict_insert_before(&mut self, reg: RegionIdx, start_node: NodeIdx) -> NodeIdx {
715 let mut node = start_node;
716 loop {
717 node = self.dict.nodes[node as usize].prev;
718 let key = self.dict.nodes[node as usize].key;
719 if key == INVALID {
720 break; }
722 if self.edge_leq(key, reg) {
723 break;
724 }
725 }
726 let after = node;
728 let before = self.dict.nodes[after as usize].next;
729 let new_node = self.dict.nodes.len() as NodeIdx;
730 use crate::dict::DictNode;
731 let new_dict_node = DictNode {
732 key: reg,
733 next: before,
734 prev: after,
735 };
736 self.dict.nodes.push(new_dict_node);
737 self.dict.nodes[after as usize].next = new_node;
738 self.dict.nodes[before as usize].prev = new_node;
739 new_node
740 }
741
742 fn init_edge_dict(&mut self) -> bool {
743 self.dict = Dict::new();
744
745 let w = (self.bmax[0] - self.bmin[0]) + 0.01;
747 let h = (self.bmax[1] - self.bmin[1]) + 0.01;
748 let smin = self.bmin[0] - w;
749 let smax = self.bmax[0] + w;
750 let tmin = self.bmin[1] - h;
751 let tmax = self.bmax[1] + h;
752
753 if !self.add_sentinel(smin, smax, tmin) {
756 return false;
757 }
758 if !self.add_sentinel(smin, smax, tmax) {
759 return false;
760 }
761
762 true
763 }
764
765 fn done_edge_dict(&mut self) {
766 let mut node = self.dict.min();
768 while node != DICT_HEAD {
769 let key = self.dict.key(node);
770 let next = self.dict.succ(node);
771 if key != INVALID {
772 let is_sentinel = self.region(key).sentinel;
773 if is_sentinel {
774 self.dict.delete(node);
775 self.free_region(key);
776 }
777 }
778 node = next;
779 }
780 }
781
782 fn alloc_region(&mut self) -> RegionIdx {
785 if let Some(idx) = self.region_free.pop() {
786 self.regions[idx as usize] = Some(ActiveRegion::default());
787 idx
788 } else {
789 let idx = self.regions.len() as RegionIdx;
790 self.regions.push(Some(ActiveRegion::default()));
791 idx
792 }
793 }
794
795 fn free_region(&mut self, idx: RegionIdx) {
796 if idx != INVALID {
797 self.regions[idx as usize] = None;
798 self.region_free.push(idx);
799 }
800 }
801
802 fn region(&self, idx: RegionIdx) -> &ActiveRegion {
803 self.regions[idx as usize].as_ref().unwrap()
804 }
805
806 fn region_mut(&mut self, idx: RegionIdx) -> &mut ActiveRegion {
807 self.regions[idx as usize].as_mut().unwrap()
808 }
809
810 fn region_above(&self, reg: RegionIdx) -> RegionIdx {
812 let node = self.region(reg).node_up;
813 self.dict.key(self.dict.succ(node))
814 }
815
816 fn region_below(&self, reg: RegionIdx) -> RegionIdx {
818 let node = self.region(reg).node_up;
819 self.dict.key(self.dict.pred(node))
820 }
821
822 fn edge_leq(&self, reg1: RegionIdx, reg2: RegionIdx) -> bool {
824 let e1 = self.region(reg1).e_up;
825 let e2 = self.region(reg2).e_up;
826 if e1 == INVALID {
827 return true;
828 }
829 if e2 == INVALID {
830 return false;
831 }
832 let mesh = self.mesh.as_ref().unwrap();
833
834 let e1_dst = mesh.dst(e1);
835 let e2_dst = mesh.dst(e2);
836 let e1_org = mesh.edges[e1 as usize].org;
837 let e2_org = mesh.edges[e2 as usize].org;
838
839 let ev_s = self.event_s;
840 let ev_t = self.event_t;
841
842 let (e1ds, e1dt) = (mesh.verts[e1_dst as usize].s, mesh.verts[e1_dst as usize].t);
843 let (e2ds, e2dt) = (mesh.verts[e2_dst as usize].s, mesh.verts[e2_dst as usize].t);
844 let (e1os, e1ot) = (mesh.verts[e1_org as usize].s, mesh.verts[e1_org as usize].t);
845 let (e2os, e2ot) = (mesh.verts[e2_org as usize].s, mesh.verts[e2_org as usize].t);
846
847 if vert_eq(e1ds, e1dt, ev_s, ev_t) {
848 if vert_eq(e2ds, e2dt, ev_s, ev_t) {
849 if vert_leq(e1os, e1ot, e2os, e2ot) {
850 return edge_sign(e2ds, e2dt, e1os, e1ot, e2os, e2ot) <= 0.0;
851 }
852 return edge_sign(e1ds, e1dt, e2os, e2ot, e1os, e1ot) >= 0.0;
853 }
854 return edge_sign(e2ds, e2dt, ev_s, ev_t, e2os, e2ot) <= 0.0;
855 }
856 if vert_eq(e2ds, e2dt, ev_s, ev_t) {
857 return edge_sign(e1ds, e1dt, ev_s, ev_t, e1os, e1ot) >= 0.0;
858 }
859 let t1 = crate::geom::edge_eval(e1ds, e1dt, ev_s, ev_t, e1os, e1ot);
860 let t2 = crate::geom::edge_eval(e2ds, e2dt, ev_s, ev_t, e2os, e2ot);
861 t1 >= t2
862 }
863
864 fn add_region_below(&mut self, _reg_above: RegionIdx, e_new_up: EdgeIdx) -> RegionIdx {
867 let reg_new = self.alloc_region();
868 {
869 let r = self.region_mut(reg_new);
870 r.e_up = e_new_up;
871 r.fix_upper_edge = false;
872 r.sentinel = false;
873 r.dirty = false;
874 }
875
876 let new_node_idx = self.dict_insert_region(reg_new);
877 if new_node_idx == INVALID {
878 self.free_region(reg_new);
879 return INVALID;
880 }
881 self.region_mut(reg_new).node_up = new_node_idx;
882
883 self.mesh.as_mut().unwrap().edges[e_new_up as usize].active_region = reg_new;
885
886 self.compute_winding(reg_new);
887
888 reg_new
889 }
890
891 fn delete_region(&mut self, reg: RegionIdx) {
892 if self.region(reg).fix_upper_edge {
893 }
895 let e_up = self.region(reg).e_up;
896 if e_up != INVALID {
897 self.mesh.as_mut().unwrap().edges[e_up as usize].active_region = INVALID;
898 }
899 let node = self.region(reg).node_up;
900 self.dict.delete(node);
901 self.free_region(reg);
902 }
903
904 fn fix_upper_edge(&mut self, reg: RegionIdx, new_edge: EdgeIdx) -> bool {
905 let old_edge = self.region(reg).e_up;
906 if old_edge != INVALID {
907 if !self.mesh.as_mut().unwrap().delete_edge(old_edge) {
908 return false;
909 }
910 }
911 self.region_mut(reg).fix_upper_edge = false;
912 self.region_mut(reg).e_up = new_edge;
913 self.mesh.as_mut().unwrap().edges[new_edge as usize].active_region = reg;
914 true
915 }
916
917 fn is_winding_inside(&self, n: i32) -> bool {
918 match self.winding_rule {
919 WindingRule::Odd => n & 1 != 0,
920 WindingRule::NonZero => n != 0,
921 WindingRule::Positive => n > 0,
922 WindingRule::Negative => n < 0,
923 WindingRule::AbsGeqTwo => n >= 2 || n <= -2,
924 }
925 }
926
927 fn compute_winding(&mut self, reg: RegionIdx) {
928 let above = self.region_above(reg);
929 let above_winding = if above != INVALID {
930 self.region(above).winding_number
931 } else {
932 0
933 };
934 let e_up = self.region(reg).e_up;
935 let e_winding = if e_up != INVALID {
936 self.mesh.as_ref().unwrap().edges[e_up as usize].winding
937 } else {
938 0
939 };
940 let new_winding = above_winding + e_winding;
941 let inside = self.is_winding_inside(new_winding);
942 if self.trace_enabled {
943 eprintln!(
944 "R COMPUTE_WINDING winding={} inside={} edge_winding={}",
945 new_winding, inside as i32, e_winding
946 );
947 }
948 self.region_mut(reg).winding_number = new_winding;
949 self.region_mut(reg).inside = inside;
950 }
951
952 fn finish_region(&mut self, reg: RegionIdx) {
953 let e = self.region(reg).e_up;
954 if e != INVALID {
955 let lface = self.mesh.as_ref().unwrap().edges[e as usize].lface;
956 if lface != INVALID {
957 let inside = self.region(reg).inside;
958 if self.trace_enabled {
959 let mesh = self.mesh.as_ref().unwrap();
960 let mut edge_count = 0u32;
961 let an = mesh.faces[lface as usize].an_edge;
962 if an != INVALID {
963 let mut iter = an;
964 loop {
965 edge_count += 1;
966 iter = mesh.edges[iter as usize].lnext;
967 if iter == an || edge_count > 10000 { break; }
968 }
969 }
970 let org = mesh.edges[e as usize].org;
971 let (os, ot) = if org != INVALID {
972 (mesh.verts[org as usize].s, mesh.verts[org as usize].t)
973 } else {
974 (0.0, 0.0)
975 };
976 eprintln!(
977 "R FINISH_REGION inside={} winding={} face_edges={} eUp_org=({:.2},{:.2})",
978 inside as i32,
979 self.region(reg).winding_number,
980 edge_count,
981 os, ot
982 );
983 }
984 self.mesh.as_mut().unwrap().faces[lface as usize].inside = inside;
985 self.mesh.as_mut().unwrap().faces[lface as usize].an_edge = e;
986 }
987 }
988 self.delete_region(reg);
989 }
990
991 fn top_left_region(&mut self, reg: RegionIdx) -> RegionIdx {
993 let org = {
994 let e = self.region(reg).e_up;
995 if e == INVALID {
996 return INVALID;
997 }
998 self.mesh.as_ref().unwrap().edges[e as usize].org
999 };
1000 let mut r = reg;
1001 loop {
1002 r = self.region_above(r);
1003 if r == INVALID {
1004 return INVALID;
1005 }
1006 let e = self.region(r).e_up;
1007 if e == INVALID {
1008 return INVALID;
1009 }
1010 let e_org = self.mesh.as_ref().unwrap().edges[e as usize].org;
1011 if e_org != org {
1012 break;
1013 }
1014 }
1015 if self.region(r).fix_upper_edge {
1018 let below = self.region_below(r);
1019 let below_e = self.region(below).e_up;
1020 let below_e_sym = below_e ^ 1;
1021 let r_e = self.region(r).e_up;
1022 let r_e_lnext = self.mesh.as_ref().unwrap().edges[r_e as usize].lnext;
1023 let new_e = match self.mesh.as_mut().unwrap().connect(below_e_sym, r_e_lnext) {
1024 Some(e) => e,
1025 None => return INVALID,
1026 };
1027 if !self.fix_upper_edge(r, new_e) {
1028 return INVALID;
1029 }
1030 r = self.region_above(r);
1031 }
1032 r
1033 }
1034
1035 fn top_right_region(&self, reg: RegionIdx) -> RegionIdx {
1036 let dst = {
1037 let e = self.region(reg).e_up;
1038 if e == INVALID {
1039 return INVALID;
1040 }
1041 self.mesh.as_ref().unwrap().dst(e)
1042 };
1043 let mut r = reg;
1044 loop {
1045 r = self.region_above(r);
1046 if r == INVALID {
1047 return INVALID;
1048 }
1049 let e = self.region(r).e_up;
1050 if e == INVALID {
1051 return INVALID;
1052 }
1053 let e_dst = self.mesh.as_ref().unwrap().dst(e);
1054 if e_dst != dst {
1055 break;
1056 }
1057 }
1058 r
1059 }
1060
1061 fn finish_left_regions(&mut self, reg_first: RegionIdx, reg_last: RegionIdx) -> EdgeIdx {
1062 let mut reg_prev = reg_first;
1063 let mut e_prev = self.region(reg_first).e_up;
1064
1065 while reg_prev != reg_last {
1066 self.region_mut(reg_prev).fix_upper_edge = false;
1067 let reg = self.region_below(reg_prev);
1068 if reg == INVALID {
1069 break;
1070 }
1071 let e = self.region(reg).e_up;
1072
1073 let e_org = if e != INVALID {
1074 self.mesh.as_ref().unwrap().edges[e as usize].org
1075 } else {
1076 INVALID
1077 };
1078 let ep_org = if e_prev != INVALID {
1079 self.mesh.as_ref().unwrap().edges[e_prev as usize].org
1080 } else {
1081 INVALID
1082 };
1083
1084 if e_org != ep_org {
1085 if !self.region(reg).fix_upper_edge {
1086 self.finish_region(reg_prev);
1087 break;
1088 }
1089 let ep_lprev = if e_prev != INVALID {
1090 self.mesh.as_ref().unwrap().lprev(e_prev)
1091 } else {
1092 INVALID
1093 };
1094 let e_sym = if e != INVALID { e ^ 1 } else { INVALID };
1095 let new_e = if ep_lprev != INVALID && e_sym != INVALID {
1096 self.mesh.as_mut().unwrap().connect(ep_lprev, e_sym)
1097 } else {
1098 None
1099 };
1100 if let Some(ne) = new_e {
1101 if !self.fix_upper_edge(reg, ne) {
1102 return INVALID;
1103 }
1104 }
1105 }
1106
1107 if e_prev != INVALID && e != INVALID {
1108 let ep_onext = self.mesh.as_ref().unwrap().edges[e_prev as usize].onext;
1109 if ep_onext != e {
1110 let e_oprev = self.mesh.as_ref().unwrap().oprev(e);
1111 self.mesh.as_mut().unwrap().splice(e_oprev, e);
1112 self.mesh.as_mut().unwrap().splice(e_prev, e);
1113 }
1114 }
1115
1116 self.finish_region(reg_prev);
1117 e_prev = self.region(reg).e_up;
1118 reg_prev = reg;
1119 }
1120 e_prev
1121 }
1122
1123 fn add_right_edges(
1124 &mut self,
1125 reg_up: RegionIdx,
1126 e_first: EdgeIdx,
1127 e_last: EdgeIdx,
1128 e_top_left: EdgeIdx,
1129 clean_up: bool,
1130 ) {
1131 let mut e = e_first;
1133 loop {
1134 self.add_region_below(reg_up, e ^ 1);
1135 e = self.mesh.as_ref().unwrap().edges[e as usize].onext;
1136 if e == e_last {
1137 break;
1138 }
1139 }
1140
1141 let e_top_left = if e_top_left == INVALID {
1143 let reg_below = self.region_below(reg_up);
1144 if reg_below == INVALID {
1145 return;
1146 }
1147 let rb_e = self.region(reg_below).e_up;
1148 if rb_e == INVALID {
1149 return;
1150 }
1151 self.mesh.as_ref().unwrap().rprev(rb_e)
1152 } else {
1153 e_top_left
1154 };
1155
1156 let mut reg_prev = reg_up;
1157 let mut e_prev = e_top_left;
1158 let mut first_time = true;
1159
1160 loop {
1161 let reg = self.region_below(reg_prev);
1162 if reg == INVALID {
1163 break;
1164 }
1165 let e = {
1166 let re = self.region(reg).e_up;
1167 if re == INVALID {
1168 break;
1169 }
1170 re ^ 1 };
1172 let e_org = self.mesh.as_ref().unwrap().edges[e as usize].org;
1173 let ep_org = if e_prev != INVALID {
1174 self.mesh.as_ref().unwrap().edges[e_prev as usize].org
1175 } else {
1176 INVALID
1177 };
1178 if e_org != ep_org {
1179 break;
1180 }
1181
1182 if e_prev != INVALID {
1183 let e_onext = self.mesh.as_ref().unwrap().edges[e as usize].onext;
1185 if e_onext != e_prev {
1186 let e_oprev = self.mesh.as_ref().unwrap().oprev(e);
1187 self.mesh.as_mut().unwrap().splice(e_oprev, e);
1188 let ep_oprev = self.mesh.as_ref().unwrap().oprev(e_prev);
1189 self.mesh.as_mut().unwrap().splice(ep_oprev, e);
1190 }
1191 }
1192
1193 let above_winding = self.region(reg_prev).winding_number;
1194 let e_winding = self.mesh.as_ref().unwrap().edges[e as usize].winding;
1195 let new_winding = above_winding - e_winding;
1196 let inside = self.is_winding_inside(new_winding);
1197 self.region_mut(reg).winding_number = new_winding;
1198 self.region_mut(reg).inside = inside;
1199
1200 self.region_mut(reg_prev).dirty = true;
1201 if !first_time {
1202 if self.check_for_right_splice(reg_prev) {
1203 let re = self.region(reg).e_up;
1205 let rep = self.region(reg_prev).e_up;
1206 if re != INVALID && rep != INVALID {
1207 let w1 = self.mesh.as_ref().unwrap().edges[re as usize].winding;
1208 let w2 = self.mesh.as_ref().unwrap().edges[(re ^ 1) as usize].winding;
1209 let wp1 = self.mesh.as_ref().unwrap().edges[rep as usize].winding;
1210 let wp2 = self.mesh.as_ref().unwrap().edges[(rep ^ 1) as usize].winding;
1211 self.mesh.as_mut().unwrap().edges[re as usize].winding += wp1;
1212 self.mesh.as_mut().unwrap().edges[(re ^ 1) as usize].winding += wp2;
1213 }
1214 self.delete_region(reg_prev);
1215 if e_prev != INVALID {
1216 self.mesh.as_mut().unwrap().delete_edge(e_prev);
1217 }
1218 }
1219 }
1220 first_time = false;
1221 reg_prev = reg;
1222 e_prev = e;
1223 }
1224
1225 self.region_mut(reg_prev).dirty = true;
1226
1227 if clean_up {
1228 self.walk_dirty_regions(reg_prev);
1229 }
1230 }
1231
1232 fn check_for_right_splice(&mut self, reg_up: RegionIdx) -> bool {
1233 let reg_lo = self.region_below(reg_up);
1234 if reg_lo == INVALID {
1235 return false;
1236 }
1237 let e_up = self.region(reg_up).e_up;
1238 let e_lo = self.region(reg_lo).e_up;
1239 if e_up == INVALID || e_lo == INVALID {
1240 return false;
1241 }
1242
1243 let mesh = self.mesh.as_ref().unwrap();
1244 let e_up_org = mesh.edges[e_up as usize].org;
1245 let e_lo_org = mesh.edges[e_lo as usize].org;
1246 let (euo_s, euo_t) = (
1247 mesh.verts[e_up_org as usize].s,
1248 mesh.verts[e_up_org as usize].t,
1249 );
1250 let (elo_s, elo_t) = (
1251 mesh.verts[e_lo_org as usize].s,
1252 mesh.verts[e_lo_org as usize].t,
1253 );
1254 let e_lo_dst = mesh.dst(e_lo);
1255 let (eld_s, eld_t) = (
1256 mesh.verts[e_lo_dst as usize].s,
1257 mesh.verts[e_lo_dst as usize].t,
1258 );
1259 let e_up_dst = mesh.dst(e_up);
1260 let (eud_s, eud_t) = (
1261 mesh.verts[e_up_dst as usize].s,
1262 mesh.verts[e_up_dst as usize].t,
1263 );
1264 drop(mesh);
1265
1266 if vert_leq(euo_s, euo_t, elo_s, elo_t) {
1267 if edge_sign(eld_s, eld_t, euo_s, euo_t, elo_s, elo_t) > 0.0 {
1268 return false;
1269 }
1270 if !vert_eq(euo_s, euo_t, elo_s, elo_t) {
1271 self.mesh.as_mut().unwrap().split_edge(e_lo ^ 1);
1273 let e_lo_oprev = self.mesh.as_ref().unwrap().oprev(e_lo);
1274 self.mesh.as_mut().unwrap().splice(e_up, e_lo_oprev);
1275 self.region_mut(reg_up).dirty = true;
1276 self.region_mut(reg_lo).dirty = true;
1277 } else if e_up_org != e_lo_org {
1278 let handle = self.mesh.as_ref().unwrap().verts[e_up_org as usize].pq_handle;
1280 self.pq_delete(handle);
1281 let e_lo_oprev = self.mesh.as_ref().unwrap().oprev(e_lo);
1282 self.mesh.as_mut().unwrap().splice(e_lo_oprev, e_up);
1283 }
1284 } else {
1285 if edge_sign(eud_s, eud_t, elo_s, elo_t, euo_s, euo_t) < 0.0 {
1286 return false;
1287 }
1288 let reg_above = self.region_above(reg_up);
1289 if reg_above != INVALID {
1290 self.region_mut(reg_above).dirty = true;
1291 }
1292 self.region_mut(reg_up).dirty = true;
1293 self.mesh.as_mut().unwrap().split_edge(e_up ^ 1);
1294 let e_lo_oprev = self.mesh.as_ref().unwrap().oprev(e_lo);
1295 self.mesh.as_mut().unwrap().splice(e_lo_oprev, e_up);
1296 }
1297 true
1298 }
1299
1300 fn check_for_left_splice(&mut self, reg_up: RegionIdx) -> bool {
1301 let reg_lo = self.region_below(reg_up);
1302 if reg_lo == INVALID {
1303 return false;
1304 }
1305 let e_up = self.region(reg_up).e_up;
1306 let e_lo = self.region(reg_lo).e_up;
1307 if e_up == INVALID || e_lo == INVALID {
1308 return false;
1309 }
1310
1311 let mesh = self.mesh.as_ref().unwrap();
1312 let e_up_dst = mesh.dst(e_up);
1313 let e_lo_dst = mesh.dst(e_lo);
1314 if vert_eq(
1315 mesh.verts[e_up_dst as usize].s,
1316 mesh.verts[e_up_dst as usize].t,
1317 mesh.verts[e_lo_dst as usize].s,
1318 mesh.verts[e_lo_dst as usize].t,
1319 ) {
1320 return false;
1321 } let (eud_s, eud_t) = (
1324 mesh.verts[e_up_dst as usize].s,
1325 mesh.verts[e_up_dst as usize].t,
1326 );
1327 let (eld_s, eld_t) = (
1328 mesh.verts[e_lo_dst as usize].s,
1329 mesh.verts[e_lo_dst as usize].t,
1330 );
1331 let e_up_org = mesh.edges[e_up as usize].org;
1332 let e_lo_org = mesh.edges[e_lo as usize].org;
1333 let (euo_s, euo_t) = (
1334 mesh.verts[e_up_org as usize].s,
1335 mesh.verts[e_up_org as usize].t,
1336 );
1337 let (elo_s, elo_t) = (
1338 mesh.verts[e_lo_org as usize].s,
1339 mesh.verts[e_lo_org as usize].t,
1340 );
1341 drop(mesh);
1342
1343 if vert_leq(eud_s, eud_t, eld_s, eld_t) {
1344 if edge_sign(eud_s, eud_t, eld_s, eld_t, euo_s, euo_t) < 0.0 {
1345 return false;
1346 }
1347 let reg_above = self.region_above(reg_up);
1349 if reg_above != INVALID {
1350 self.region_mut(reg_above).dirty = true;
1351 }
1352 self.region_mut(reg_up).dirty = true;
1353 let new_e = match self.mesh.as_mut().unwrap().split_edge(e_up) {
1354 Some(e) => e,
1355 None => return false,
1356 };
1357 let e_lo_sym = e_lo ^ 1;
1358 self.mesh.as_mut().unwrap().splice(e_lo_sym, new_e);
1359 let new_lface = self.mesh.as_ref().unwrap().edges[new_e as usize].lface;
1360 let inside = self.region(reg_up).inside;
1361 if new_lface != INVALID {
1362 self.mesh.as_mut().unwrap().faces[new_lface as usize].inside = inside;
1363 }
1364 } else {
1365 if edge_sign(eld_s, eld_t, eud_s, eud_t, elo_s, elo_t) > 0.0 {
1366 return false;
1367 }
1368 self.region_mut(reg_up).dirty = true;
1370 self.region_mut(reg_lo).dirty = true;
1371 let new_e = match self.mesh.as_mut().unwrap().split_edge(e_lo) {
1372 Some(e) => e,
1373 None => return false,
1374 };
1375 let e_up_lnext = self.mesh.as_ref().unwrap().edges[e_up as usize].lnext;
1376 let e_lo_sym = e_lo ^ 1;
1377 self.mesh.as_mut().unwrap().splice(e_up_lnext, e_lo_sym);
1378 let new_rface = self.mesh.as_ref().unwrap().rface(new_e);
1379 let inside = self.region(reg_up).inside;
1380 if new_rface != INVALID {
1381 self.mesh.as_mut().unwrap().faces[new_rface as usize].inside = inside;
1382 }
1383 }
1384 true
1385 }
1386
1387 fn check_for_intersect(&mut self, reg_up: RegionIdx) -> bool {
1388 let reg_lo = self.region_below(reg_up);
1389 if reg_lo == INVALID {
1390 return false;
1391 }
1392 let e_up = self.region(reg_up).e_up;
1393 let e_lo = self.region(reg_lo).e_up;
1394 if e_up == INVALID || e_lo == INVALID {
1395 return false;
1396 }
1397 if self.region(reg_up).fix_upper_edge || self.region(reg_lo).fix_upper_edge {
1398 return false;
1399 }
1400
1401 let mesh = self.mesh.as_ref().unwrap();
1402 let org_up = mesh.edges[e_up as usize].org;
1403 let org_lo = mesh.edges[e_lo as usize].org;
1404 let dst_up = mesh.dst(e_up);
1405 let dst_lo = mesh.dst(e_lo);
1406
1407 if vert_eq(
1408 mesh.verts[dst_up as usize].s,
1409 mesh.verts[dst_up as usize].t,
1410 mesh.verts[dst_lo as usize].s,
1411 mesh.verts[dst_lo as usize].t,
1412 ) {
1413 return false;
1414 }
1415
1416 let (ou_s, ou_t) = (mesh.verts[org_up as usize].s, mesh.verts[org_up as usize].t);
1417 let (ol_s, ol_t) = (mesh.verts[org_lo as usize].s, mesh.verts[org_lo as usize].t);
1418 let (du_s, du_t) = (mesh.verts[dst_up as usize].s, mesh.verts[dst_up as usize].t);
1419 let (dl_s, dl_t) = (mesh.verts[dst_lo as usize].s, mesh.verts[dst_lo as usize].t);
1420 let ou_coords = mesh.verts[org_up as usize].coords;
1422 let du_coords = mesh.verts[dst_up as usize].coords;
1423 let ol_coords = mesh.verts[org_lo as usize].coords;
1424 let dl_coords = mesh.verts[dst_lo as usize].coords;
1425 let ev_s = self.event_s;
1426 let ev_t = self.event_t;
1427 drop(mesh);
1428
1429 let t_min_up = ou_t.min(du_t);
1431 let t_max_lo = ol_t.max(dl_t);
1432 if t_min_up > t_max_lo {
1433 return false;
1434 }
1435
1436 if vert_leq(ou_s, ou_t, ol_s, ol_t) {
1437 if edge_sign(dl_s, dl_t, ou_s, ou_t, ol_s, ol_t) > 0.0 {
1438 return false;
1439 }
1440 } else {
1441 if edge_sign(du_s, du_t, ol_s, ol_t, ou_s, ou_t) < 0.0 {
1442 return false;
1443 }
1444 }
1445
1446 let (isect_s, isect_t) = edge_intersect(du_s, du_t, ou_s, ou_t, dl_s, dl_t, ol_s, ol_t);
1448
1449 let (isect_s, isect_t) = if vert_leq(isect_s, isect_t, ev_s, ev_t) {
1451 (ev_s, ev_t)
1452 } else {
1453 (isect_s, isect_t)
1454 };
1455
1456 let (org_min_s, org_min_t) = if vert_leq(ou_s, ou_t, ol_s, ol_t) {
1458 (ou_s, ou_t)
1459 } else {
1460 (ol_s, ol_t)
1461 };
1462 let (isect_s, isect_t) = if vert_leq(org_min_s, org_min_t, isect_s, isect_t) {
1463 (org_min_s, org_min_t)
1464 } else {
1465 (isect_s, isect_t)
1466 };
1467
1468 if vert_eq(isect_s, isect_t, ou_s, ou_t) || vert_eq(isect_s, isect_t, ol_s, ol_t) {
1470 self.check_for_right_splice(reg_up);
1471 return false;
1472 }
1473
1474 if (!vert_eq(du_s, du_t, ev_s, ev_t)
1475 && edge_sign(du_s, du_t, ev_s, ev_t, isect_s, isect_t) >= 0.0)
1476 || (!vert_eq(dl_s, dl_t, ev_s, ev_t)
1477 && edge_sign(dl_s, dl_t, ev_s, ev_t, isect_s, isect_t) <= 0.0)
1478 {
1479 if vert_eq(dl_s, dl_t, ev_s, ev_t) {
1480 self.mesh.as_mut().unwrap().split_edge(e_up ^ 1);
1482 let e_lo_sym = e_lo ^ 1;
1483 let e_up2 = self.region(reg_up).e_up;
1484 self.mesh.as_mut().unwrap().splice(e_lo_sym, e_up2);
1485 let reg_up2 = self.top_left_region(reg_up);
1486 if reg_up2 == INVALID {
1487 return false;
1488 }
1489 let rb = self.region_below(reg_up2);
1490 let rb_e = self.region(rb).e_up;
1491 let rl2 = self.region_below(rb);
1492 self.finish_left_regions(self.region_below(reg_up2), reg_lo);
1493 let e_up_new = self.region(rb).e_up;
1494 let e_oprev = self.mesh.as_ref().unwrap().oprev(e_up_new);
1495 self.add_right_edges(reg_up2, e_oprev, e_up_new, e_up_new, true);
1496 return true;
1497 }
1498 if vert_eq(du_s, du_t, ev_s, ev_t) {
1499 self.mesh.as_mut().unwrap().split_edge(e_lo ^ 1);
1500 let e_up_lnext = self.mesh.as_ref().unwrap().edges[e_up as usize].lnext;
1501 let e_lo_oprev = self.mesh.as_ref().unwrap().oprev(e_lo);
1502 self.mesh.as_mut().unwrap().splice(e_up_lnext, e_lo_oprev);
1503 let reg_lo2 = reg_up;
1504 let reg_up2 = self.top_right_region(reg_up);
1505 if reg_up2 == INVALID {
1506 return false;
1507 }
1508 let e_finish = self
1509 .mesh
1510 .as_ref()
1511 .unwrap()
1512 .rprev(self.region(self.region_below(reg_up2)).e_up);
1513 self.region_mut(reg_lo2).e_up = self.mesh.as_ref().unwrap().oprev(e_lo);
1514 let lo_end = self.finish_left_regions(reg_lo2, INVALID);
1515 let e_lo_onext = if lo_end != INVALID {
1516 self.mesh.as_ref().unwrap().edges[lo_end as usize].onext
1517 } else {
1518 INVALID
1519 };
1520 let e_up_rprev = self.mesh.as_ref().unwrap().rprev(e_up);
1521 self.add_right_edges(reg_up2, e_lo_onext, e_up_rprev, e_finish, true);
1522 return true;
1523 }
1524 if edge_sign(du_s, du_t, ev_s, ev_t, isect_s, isect_t) >= 0.0 {
1526 let reg_above = self.region_above(reg_up);
1527 if reg_above != INVALID {
1528 self.region_mut(reg_above).dirty = true;
1529 }
1530 self.region_mut(reg_up).dirty = true;
1531 self.mesh.as_mut().unwrap().split_edge(e_up ^ 1);
1532 let e_up2 = self.region(reg_up).e_up;
1533 let e_up2_org = self.mesh.as_ref().unwrap().edges[e_up2 as usize].org;
1534 self.mesh.as_mut().unwrap().verts[e_up2_org as usize].s = ev_s;
1535 self.mesh.as_mut().unwrap().verts[e_up2_org as usize].t = ev_t;
1536 }
1537 if edge_sign(dl_s, dl_t, ev_s, ev_t, isect_s, isect_t) <= 0.0 {
1538 self.region_mut(reg_up).dirty = true;
1539 self.region_mut(reg_lo).dirty = true;
1540 self.mesh.as_mut().unwrap().split_edge(e_lo ^ 1);
1541 let e_lo2 = self.region(reg_lo).e_up;
1542 let e_lo2_org = self.mesh.as_ref().unwrap().edges[e_lo2 as usize].org;
1543 self.mesh.as_mut().unwrap().verts[e_lo2_org as usize].s = ev_s;
1544 self.mesh.as_mut().unwrap().verts[e_lo2_org as usize].t = ev_t;
1545 }
1546 return false;
1547 }
1548
1549 self.mesh.as_mut().unwrap().split_edge(e_up ^ 1);
1551 self.mesh.as_mut().unwrap().split_edge(e_lo ^ 1);
1552 let e_lo2 = self.region(reg_lo).e_up;
1553 let e_lo2_oprev = self.mesh.as_ref().unwrap().oprev(e_lo2);
1554 let e_up2 = self.region(reg_up).e_up;
1555 self.mesh.as_mut().unwrap().splice(e_lo2_oprev, e_up2);
1556
1557 let e_up2_org = self.mesh.as_ref().unwrap().edges[e_up2 as usize].org;
1559
1560 let (org_up_s, org_up_t) = (ou_s, ou_t);
1562 let (dst_up_s, dst_up_t) = (du_s, du_t);
1563 let (org_lo_s, org_lo_t) = (ol_s, ol_t);
1564 let (dst_lo_s, dst_lo_t) = (dl_s, dl_t);
1565
1566 self.mesh.as_mut().unwrap().verts[e_up2_org as usize].s = isect_s;
1567 self.mesh.as_mut().unwrap().verts[e_up2_org as usize].t = isect_t;
1568 self.mesh.as_mut().unwrap().verts[e_up2_org as usize].coords = compute_intersect_coords(
1569 isect_s, isect_t, org_up_s, org_up_t, ou_coords, dst_up_s, dst_up_t, du_coords,
1570 org_lo_s, org_lo_t, ol_coords, dst_lo_s, dst_lo_t, dl_coords,
1571 );
1572 self.mesh.as_mut().unwrap().verts[e_up2_org as usize].idx = TESS_UNDEF;
1573
1574 let handle = self.pq_insert(e_up2_org);
1576 if handle == INVALID_HANDLE {
1577 return false;
1578 }
1579 self.mesh.as_mut().unwrap().verts[e_up2_org as usize].pq_handle = handle;
1580
1581 let reg_above = self.region_above(reg_up);
1582 if reg_above != INVALID {
1583 self.region_mut(reg_above).dirty = true;
1584 }
1585 self.region_mut(reg_up).dirty = true;
1586 self.region_mut(reg_lo).dirty = true;
1587
1588 false
1589 }
1590
1591 fn walk_dirty_regions(&mut self, reg_up: RegionIdx) {
1592 let mut reg_up = reg_up;
1593 let mut reg_lo = self.region_below(reg_up);
1594
1595 loop {
1596 while reg_lo != INVALID && self.region(reg_lo).dirty {
1598 reg_up = reg_lo;
1599 reg_lo = self.region_below(reg_lo);
1600 }
1601 if !self.region(reg_up).dirty {
1602 reg_lo = reg_up;
1603 reg_up = self.region_above(reg_up);
1604 if reg_up == INVALID || !self.region(reg_up).dirty {
1605 return;
1606 }
1607 }
1608
1609 self.region_mut(reg_up).dirty = false;
1610 if reg_lo == INVALID {
1611 return;
1612 }
1613 let e_up = self.region(reg_up).e_up;
1614 let e_lo = self.region(reg_lo).e_up;
1615
1616 if e_up != INVALID && e_lo != INVALID {
1617 let e_up_dst = self.mesh.as_ref().unwrap().dst(e_up);
1618 let e_lo_dst = self.mesh.as_ref().unwrap().dst(e_lo);
1619 let (eud_s, eud_t) = (
1620 self.mesh.as_ref().unwrap().verts[e_up_dst as usize].s,
1621 self.mesh.as_ref().unwrap().verts[e_up_dst as usize].t,
1622 );
1623 let (eld_s, eld_t) = (
1624 self.mesh.as_ref().unwrap().verts[e_lo_dst as usize].s,
1625 self.mesh.as_ref().unwrap().verts[e_lo_dst as usize].t,
1626 );
1627
1628 if !vert_eq(eud_s, eud_t, eld_s, eld_t) {
1629 if self.check_for_left_splice(reg_up) {
1630 let reg_lo_fix = self.region(reg_lo).fix_upper_edge;
1631 let reg_up_fix = self.region(reg_up).fix_upper_edge;
1632 if reg_lo_fix {
1633 let e_lo2 = self.region(reg_lo).e_up;
1634 self.delete_region(reg_lo);
1635 if e_lo2 != INVALID {
1636 self.mesh.as_mut().unwrap().delete_edge(e_lo2);
1637 }
1638 reg_lo = self.region_below(reg_up);
1639 } else if reg_up_fix {
1640 let e_up2 = self.region(reg_up).e_up;
1641 self.delete_region(reg_up);
1642 if e_up2 != INVALID {
1643 self.mesh.as_mut().unwrap().delete_edge(e_up2);
1644 }
1645 reg_up = self.region_above(reg_lo);
1646 }
1647 }
1648 }
1649
1650 let e_up2 = self.region(reg_up).e_up;
1651 let e_lo2 = self.region(reg_lo).e_up;
1652 if e_up2 != INVALID && e_lo2 != INVALID {
1653 let e_up_org = self.mesh.as_ref().unwrap().edges[e_up2 as usize].org;
1654 let e_lo_org = self.mesh.as_ref().unwrap().edges[e_lo2 as usize].org;
1655 if e_up_org != e_lo_org {
1656 let e_up_dst2 = self.mesh.as_ref().unwrap().dst(e_up2);
1657 let e_lo_dst2 = self.mesh.as_ref().unwrap().dst(e_lo2);
1658 let fix_up = self.region(reg_up).fix_upper_edge;
1659 let fix_lo = self.region(reg_lo).fix_upper_edge;
1660 if !vert_eq(
1661 self.mesh.as_ref().unwrap().verts[e_up_dst2 as usize].s,
1662 self.mesh.as_ref().unwrap().verts[e_up_dst2 as usize].t,
1663 self.mesh.as_ref().unwrap().verts[e_lo_dst2 as usize].s,
1664 self.mesh.as_ref().unwrap().verts[e_lo_dst2 as usize].t,
1665 ) && !fix_up
1666 && !fix_lo
1667 && (vert_eq(
1668 self.mesh.as_ref().unwrap().verts[e_up_dst2 as usize].s,
1669 self.mesh.as_ref().unwrap().verts[e_up_dst2 as usize].t,
1670 self.event_s,
1671 self.event_t,
1672 ) || vert_eq(
1673 self.mesh.as_ref().unwrap().verts[e_lo_dst2 as usize].s,
1674 self.mesh.as_ref().unwrap().verts[e_lo_dst2 as usize].t,
1675 self.event_s,
1676 self.event_t,
1677 ))
1678 {
1679 if self.check_for_intersect(reg_up) {
1680 return;
1681 }
1682 } else {
1683 self.check_for_right_splice(reg_up);
1684 }
1685 }
1686 }
1687
1688 let e_up3 = self.region(reg_up).e_up;
1690 let e_lo3 = self.region(reg_lo).e_up;
1691 if e_up3 != INVALID && e_lo3 != INVALID {
1692 let e_up_org3 = self.mesh.as_ref().unwrap().edges[e_up3 as usize].org;
1693 let e_lo_org3 = self.mesh.as_ref().unwrap().edges[e_lo3 as usize].org;
1694 let e_up_dst3 = self.mesh.as_ref().unwrap().dst(e_up3);
1695 let e_lo_dst3 = self.mesh.as_ref().unwrap().dst(e_lo3);
1696 if e_up_org3 == e_lo_org3 && e_up_dst3 == e_lo_dst3 {
1697 let eu_w = self.mesh.as_ref().unwrap().edges[e_up3 as usize].winding;
1699 let eu_sw = self.mesh.as_ref().unwrap().edges[(e_up3 ^ 1) as usize].winding;
1700 self.mesh.as_mut().unwrap().edges[e_lo3 as usize].winding += eu_w;
1701 self.mesh.as_mut().unwrap().edges[(e_lo3 ^ 1) as usize].winding += eu_sw;
1702 self.delete_region(reg_up);
1703 self.mesh.as_mut().unwrap().delete_edge(e_up3);
1704 reg_up = self.region_above(reg_lo);
1705 }
1706 }
1707 }
1708 }
1709 }
1710
1711 fn connect_right_vertex(&mut self, reg_up: RegionIdx, e_bottom_left: EdgeIdx) {
1712 let e_top_left = self.mesh.as_ref().unwrap().edges[e_bottom_left as usize].onext;
1715
1716 let reg_lo = self.region_below(reg_up);
1718 if reg_lo == INVALID {
1719 return;
1720 }
1721 let e_up = self.region(reg_up).e_up;
1722 let e_lo = self.region(reg_lo).e_up;
1723 if e_up == INVALID || e_lo == INVALID {
1724 return;
1725 }
1726
1727 let dst_differ = {
1728 let e_up_dst = self.mesh.as_ref().unwrap().dst(e_up);
1729 let e_lo_dst = self.mesh.as_ref().unwrap().dst(e_lo);
1730 let (s1, t1) = (
1731 self.mesh.as_ref().unwrap().verts[e_up_dst as usize].s,
1732 self.mesh.as_ref().unwrap().verts[e_up_dst as usize].t,
1733 );
1734 let (s2, t2) = (
1735 self.mesh.as_ref().unwrap().verts[e_lo_dst as usize].s,
1736 self.mesh.as_ref().unwrap().verts[e_lo_dst as usize].t,
1737 );
1738 !vert_eq(s1, t1, s2, t2)
1739 };
1740 if dst_differ {
1741 if self.check_for_intersect(reg_up) {
1742 return;
1743 }
1744 }
1745
1746 let reg_lo = self.region_below(reg_up);
1748 if reg_lo == INVALID {
1749 return;
1750 }
1751 let e_up = self.region(reg_up).e_up;
1752 let e_lo = self.region(reg_lo).e_up;
1753 if e_up == INVALID || e_lo == INVALID {
1754 return;
1755 }
1756
1757 let mut degenerate = false;
1759 let mut reg_up = reg_up;
1760 let mut e_top_left = e_top_left;
1761 let mut e_bottom_left = e_bottom_left;
1762
1763 let e_up_org = self.mesh.as_ref().unwrap().edges[e_up as usize].org;
1765 if e_up_org != INVALID {
1766 let (s, t) = (
1767 self.mesh.as_ref().unwrap().verts[e_up_org as usize].s,
1768 self.mesh.as_ref().unwrap().verts[e_up_org as usize].t,
1769 );
1770 if vert_eq(s, t, self.event_s, self.event_t) {
1771 let e_tl_oprev = self.mesh.as_ref().unwrap().oprev(e_top_left);
1773 self.mesh.as_mut().unwrap().splice(e_tl_oprev, e_up);
1774 let reg_up2 = self.top_left_region(reg_up);
1776 if reg_up2 == INVALID {
1777 return;
1778 }
1779 let rb = self.region_below(reg_up2);
1781 e_top_left = if rb != INVALID {
1782 self.region(rb).e_up
1783 } else {
1784 INVALID
1785 };
1786 self.finish_left_regions(rb, reg_lo);
1788 reg_up = reg_up2;
1789 degenerate = true;
1790 }
1791 }
1792
1793 let e_lo2 = if degenerate {
1795 let rl = self.region_below(reg_up);
1796 if rl != INVALID {
1797 self.region(rl).e_up
1798 } else {
1799 INVALID
1800 }
1801 } else {
1802 e_lo
1803 };
1804 let reg_lo2 = self.region_below(reg_up);
1805
1806 let e_lo_org = if e_lo2 != INVALID {
1807 self.mesh.as_ref().unwrap().edges[e_lo2 as usize].org
1808 } else {
1809 INVALID
1810 };
1811 if e_lo_org != INVALID {
1812 let (s, t) = (
1813 self.mesh.as_ref().unwrap().verts[e_lo_org as usize].s,
1814 self.mesh.as_ref().unwrap().verts[e_lo_org as usize].t,
1815 );
1816 if vert_eq(s, t, self.event_s, self.event_t) {
1817 let e_lo_oprev = self.mesh.as_ref().unwrap().oprev(e_lo2);
1819 self.mesh
1820 .as_mut()
1821 .unwrap()
1822 .splice(e_bottom_left, e_lo_oprev);
1823 e_bottom_left = self.finish_left_regions(reg_lo2, INVALID);
1825 degenerate = true;
1826 }
1827 }
1828
1829 if degenerate {
1830 if e_bottom_left != INVALID && e_top_left != INVALID {
1831 let e_bl_onext = self.mesh.as_ref().unwrap().edges[e_bottom_left as usize].onext;
1832 self.add_right_edges(reg_up, e_bl_onext, e_top_left, e_top_left, true);
1833 }
1834 return;
1835 }
1836
1837 let e_up2 = self.region(reg_up).e_up;
1839 let rl = self.region_below(reg_up);
1840 if rl == INVALID {
1841 return;
1842 }
1843 let e_lo3 = self.region(rl).e_up;
1844 if e_up2 == INVALID || e_lo3 == INVALID {
1845 return;
1846 }
1847
1848 let e_up2_org = self.mesh.as_ref().unwrap().edges[e_up2 as usize].org;
1849 let e_lo3_org = self.mesh.as_ref().unwrap().edges[e_lo3 as usize].org;
1850 let e_new_target = if e_up2_org != INVALID && e_lo3_org != INVALID {
1851 let (euo_s, euo_t) = (
1852 self.mesh.as_ref().unwrap().verts[e_up2_org as usize].s,
1853 self.mesh.as_ref().unwrap().verts[e_up2_org as usize].t,
1854 );
1855 let (elo_s, elot) = (
1856 self.mesh.as_ref().unwrap().verts[e_lo3_org as usize].s,
1857 self.mesh.as_ref().unwrap().verts[e_lo3_org as usize].t,
1858 );
1859 if vert_leq(elo_s, elot, euo_s, euo_t) {
1861 self.mesh.as_ref().unwrap().oprev(e_lo3)
1862 } else {
1863 e_up2
1864 }
1865 } else {
1866 e_up2
1867 };
1868
1869 let e_bl_lprev = self.mesh.as_ref().unwrap().lprev(e_bottom_left);
1871 let e_new = match self
1872 .mesh
1873 .as_mut()
1874 .unwrap()
1875 .connect(e_bl_lprev, e_new_target)
1876 {
1877 Some(e) => e,
1878 None => return,
1879 };
1880
1881 let e_new_onext = self.mesh.as_ref().unwrap().edges[e_new as usize].onext;
1883 self.add_right_edges(reg_up, e_new, e_new_onext, e_new_onext, false);
1884
1885 let e_new_sym_ar = self.mesh.as_ref().unwrap().edges[(e_new ^ 1) as usize].active_region;
1887 if e_new_sym_ar != INVALID {
1888 self.region_mut(e_new_sym_ar).fix_upper_edge = true;
1889 }
1890 self.walk_dirty_regions(reg_up);
1891 }
1892
1893 fn connect_left_degenerate(&mut self, reg_up: RegionIdx, v_event: VertIdx) {
1894 let e_up = self.region(reg_up).e_up;
1895 if e_up == INVALID {
1896 return;
1897 }
1898 let e_up_org = self.mesh.as_ref().unwrap().edges[e_up as usize].org;
1899 let (euo_s, euo_t) = (
1900 self.mesh.as_ref().unwrap().verts[e_up_org as usize].s,
1901 self.mesh.as_ref().unwrap().verts[e_up_org as usize].t,
1902 );
1903 let (ev_s, ev_t) = (self.event_s, self.event_t);
1904
1905 if vert_eq(euo_s, euo_t, ev_s, ev_t) {
1906 let v_an = self.mesh.as_ref().unwrap().verts[v_event as usize].an_edge;
1908 if v_an != INVALID {
1909 self.mesh.as_mut().unwrap().splice(v_an, e_up);
1910 }
1911 let reg_up2 = self.top_left_region(reg_up);
1912 if reg_up2 == INVALID {
1913 return;
1914 }
1915 let rb = self.region_below(reg_up2);
1916 let rb_e = self.region(rb).e_up;
1917 let rl = self.region_below(rb);
1918 self.finish_left_regions(self.region_below(reg_up2), rl);
1919 let e_up3 = self.region(rb).e_up;
1920 let e_oprev = self.mesh.as_ref().unwrap().oprev(e_up3);
1921 self.add_right_edges(reg_up2, e_oprev, e_up3, e_up3, true);
1922 } else {
1923 self.check_for_right_splice(reg_up);
1925 }
1926 }
1927
1928 fn dict_search_forward(&mut self, tmp_e_up: EdgeIdx) -> RegionIdx {
1932 let tmp_reg = self.alloc_region();
1933 self.region_mut(tmp_reg).e_up = tmp_e_up;
1934
1935 let mut node = self.dict.nodes[DICT_HEAD as usize].next;
1937 let result = loop {
1938 let key = self.dict.key(node);
1939 if key == INVALID {
1940 break INVALID;
1942 }
1943 if self.edge_leq(tmp_reg, key) {
1944 break key;
1945 }
1946 node = self.dict.succ(node);
1947 };
1948
1949 self.free_region(tmp_reg);
1950 result
1951 }
1952
1953 fn connect_left_vertex(&mut self, v_event: VertIdx) {
1954 let an_edge = self.mesh.as_ref().unwrap().verts[v_event as usize].an_edge;
1955 if an_edge == INVALID {
1956 return;
1957 }
1958
1959 let tmp_e_up = an_edge ^ 1;
1960 let reg_up = self.dict_search_forward(tmp_e_up);
1961 if reg_up == INVALID {
1962 return;
1963 }
1964
1965 let reg_lo = self.region_below(reg_up);
1966 if reg_lo == INVALID {
1967 return;
1968 }
1969
1970 let e_up = self.region(reg_up).e_up;
1971 let e_lo = self.region(reg_lo).e_up;
1972 if e_up == INVALID || e_lo == INVALID {
1973 return;
1974 }
1975
1976 let e_up_dst = self.mesh.as_ref().unwrap().dst(e_up);
1977 let e_up_org = self.mesh.as_ref().unwrap().edges[e_up as usize].org;
1978 if e_up_dst == INVALID || e_up_org == INVALID {
1979 return;
1980 }
1981 let eud_s = self.mesh.as_ref().unwrap().verts[e_up_dst as usize].s;
1982 let eud_t = self.mesh.as_ref().unwrap().verts[e_up_dst as usize].t;
1983 let euo_s = self.mesh.as_ref().unwrap().verts[e_up_org as usize].s;
1984 let euo_t = self.mesh.as_ref().unwrap().verts[e_up_org as usize].t;
1985
1986 if crate::geom::edge_sign(eud_s, eud_t, self.event_s, self.event_t, euo_s, euo_t) == 0.0 {
1987 self.connect_left_degenerate(reg_up, v_event);
1988 return;
1989 }
1990
1991 let e_lo_dst = self.mesh.as_ref().unwrap().dst(e_lo);
1992 let eld_s = self.mesh.as_ref().unwrap().verts[e_lo_dst as usize].s;
1993 let eld_t = self.mesh.as_ref().unwrap().verts[e_lo_dst as usize].t;
1994 let reg = if vert_leq(eld_s, eld_t, eud_s, eud_t) {
1995 reg_up
1996 } else {
1997 reg_lo
1998 };
1999
2000 let reg_up_inside = self.region(reg_up).inside;
2001 let reg_fix = self.region(reg).fix_upper_edge;
2002
2003 if reg_up_inside || reg_fix {
2004 if self.trace_enabled {
2005 eprintln!(
2006 "R LEFT_CONNECT inside={} fixUpper={} reg={}",
2007 reg_up_inside as i32,
2008 reg_fix as i32,
2009 if reg == reg_up { "up" } else { "lo" }
2010 );
2011 }
2012 let e_new = if reg == reg_up {
2013 let e_up_lnext = self.mesh.as_ref().unwrap().edges[e_up as usize].lnext;
2015 self.mesh.as_mut().unwrap().connect(an_edge ^ 1, e_up_lnext)
2016 } else {
2017 let e_lo_dnext = self.mesh.as_ref().unwrap().dnext(e_lo);
2018 self.mesh
2019 .as_mut()
2020 .unwrap()
2021 .connect(e_lo_dnext, an_edge)
2022 .map(|e| e ^ 1)
2023 };
2024 let e_new = match e_new {
2025 Some(e) => e,
2026 None => return,
2027 };
2028
2029 if reg_fix {
2030 if !self.fix_upper_edge(reg, e_new) {
2031 return;
2032 }
2033 } else {
2034 self.add_region_below(reg_up, e_new);
2035 }
2036 self.sweep_event(v_event);
2037 } else {
2038 if self.trace_enabled {
2039 eprintln!("R LEFT_OUTSIDE");
2040 }
2041 self.add_right_edges(reg_up, an_edge, an_edge, INVALID, true);
2042 }
2043 }
2044
2045 fn dict_search_by_edge(&mut self, tmp_e_up: EdgeIdx) -> RegionIdx {
2049 let tmp_reg = self.alloc_region();
2051 self.region_mut(tmp_reg).e_up = tmp_e_up;
2052
2053 let mut node = self.dict.succ(DICT_HEAD);
2055 let result = loop {
2056 let key = self.dict.key(node);
2057 if key == INVALID {
2058 break INVALID;
2060 }
2061 if self.edge_leq(tmp_reg, key) {
2062 break key;
2063 }
2064 node = self.dict.succ(node);
2065 };
2066
2067 self.free_region(tmp_reg);
2068 result
2069 }
2070
2071 fn sweep_event(&mut self, v_event: VertIdx) -> bool {
2072 let an_edge = self.mesh.as_ref().unwrap().verts[v_event as usize].an_edge;
2073 if an_edge == INVALID {
2074 return true;
2075 }
2076
2077 if self.trace_enabled {
2078 let (vs, vt) = (
2079 self.mesh.as_ref().unwrap().verts[v_event as usize].s,
2080 self.mesh.as_ref().unwrap().verts[v_event as usize].t,
2081 );
2082 eprintln!(
2083 "R SWEEP #{} s={:.6} t={:.6}",
2084 self.sweep_event_num, vs, vt
2085 );
2086 self.sweep_event_num += 1;
2087 }
2088
2089 let e_start = an_edge;
2093 let mut e = e_start;
2094 let found_e = loop {
2095 let ar = self.mesh.as_ref().unwrap().edges[e as usize].active_region;
2096 if ar != INVALID {
2097 break Some(e);
2098 }
2099 let next = self.mesh.as_ref().unwrap().edges[e as usize].onext;
2100 e = next;
2101 if e == e_start {
2102 break None;
2103 }
2104 };
2105
2106 if found_e.is_none() {
2107 if self.trace_enabled {
2108 eprintln!("R PATH left");
2109 }
2110 self.connect_left_vertex(v_event);
2111 return true;
2112 }
2113
2114 let e = found_e.unwrap();
2116 if self.trace_enabled {
2117 eprintln!("R PATH right");
2118 }
2119 let reg_up = {
2120 let ar = self.mesh.as_ref().unwrap().edges[e as usize].active_region;
2121 self.top_left_region(ar)
2122 };
2123 if reg_up == INVALID {
2124 return false;
2125 }
2126
2127 let reg_lo = self.region_below(reg_up);
2128 if reg_lo == INVALID {
2129 return true;
2130 }
2131 let e_top_left = self.region(reg_lo).e_up;
2132 let e_bottom_left = self.finish_left_regions(reg_lo, INVALID);
2133
2134 if e_bottom_left == INVALID {
2135 return true;
2136 }
2137 let e_bottom_left_onext = self.mesh.as_ref().unwrap().edges[e_bottom_left as usize].onext;
2138 if e_bottom_left_onext == e_top_left {
2139 if self.trace_enabled {
2140 eprintln!("R CONNECT_RIGHT");
2141 }
2142 self.connect_right_vertex(reg_up, e_bottom_left);
2143 } else {
2144 if self.trace_enabled {
2145 eprintln!("R ADD_RIGHT_EDGES");
2146 }
2147 self.add_right_edges(reg_up, e_bottom_left_onext, e_top_left, e_top_left, true);
2148 }
2149 true
2150 }
2151
2152}
2153
2154pub struct TessellatorApi {
2158 inner: Tessellator,
2159}
2160
2161impl TessellatorApi {
2162 pub fn new() -> Self {
2163 TessellatorApi {
2164 inner: Tessellator::new(),
2165 }
2166 }
2167 pub fn set_option(&mut self, option: TessOption, value: bool) {
2168 self.inner.set_option(option, value);
2169 }
2170 pub fn add_contour(&mut self, size: usize, vertices: &[f32]) {
2171 self.inner.add_contour(size, vertices);
2172 }
2173 pub fn tessellate(
2174 &mut self,
2175 winding_rule: WindingRule,
2176 element_type: ElementType,
2177 poly_size: usize,
2178 vertex_size: usize,
2179 normal: Option<[f32; 3]>,
2180 ) -> bool {
2181 self.inner
2182 .tessellate(winding_rule, element_type, poly_size, vertex_size, normal)
2183 }
2184 pub fn vertex_count(&self) -> usize {
2185 self.inner.vertex_count()
2186 }
2187 pub fn element_count(&self) -> usize {
2188 self.inner.element_count()
2189 }
2190 pub fn vertices(&self) -> &[f32] {
2191 self.inner.vertices()
2192 }
2193 pub fn vertex_indices(&self) -> &[u32] {
2194 self.inner.vertex_indices()
2195 }
2196 pub fn elements(&self) -> &[u32] {
2197 self.inner.elements()
2198 }
2199 pub fn status(&self) -> TessStatus {
2200 self.inner.get_status()
2201 }
2202}
2203
2204impl Default for TessellatorApi {
2205 fn default() -> Self {
2206 Self::new()
2207 }
2208}