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