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