geop_ops_model/sketch/
fields.rs1use geop_core_editor::editing::{Shape, Tone};
5use geop_core_math::{primitives::CoordinateSystem, scalars::Scalar, vector::Vector2};
6
7pub fn region(plane: &CoordinateSystem, outer: &[Vector2], holes: &[Vec<Vector2>]) -> Shape {
11 let plain = |loop_: &[Vector2]| -> Vec<[f64; 2]> {
12 loop_
13 .iter()
14 .map(|p| [p[0].to_f64(), p[1].to_f64()])
15 .collect()
16 };
17 let holes: Vec<Vec<[f64; 2]>> = holes.iter().map(|h| plain(h)).collect();
18 let at = |p: [f64; 2]| plane.uv_to_xyz(&Vector2::from_array(p.map(Scalar::from_f64)));
19 let triangles = geop_core_rasterize::triangulate_polygon(&plain(outer), &holes)
20 .into_iter()
21 .map(|t| t.map(at))
22 .collect();
23 Shape::Triangles { triangles }
24}
25
26pub fn constraint_status(
30 converged: bool,
31 conflicts: usize,
32 dof: usize,
33 drawn: &str,
34) -> (String, Tone) {
35 let plural = |n: usize| if n == 1 { "" } else { "s" };
36 if !converged {
37 let text = format!(
38 "{conflicts} constraint{} conflict · {drawn}",
39 plural(conflicts)
40 );
41 (text, Tone::Error)
42 } else if dof == 0 {
43 (format!("Fully constrained · {drawn}"), Tone::Success)
44 } else {
45 (
46 format!("{dof} degree{} of freedom · {drawn}", plural(dof)),
47 Tone::Hint,
48 )
49 }
50}