runmat_meshing_surface/recovery/
types.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
4pub struct SurfaceRecoveryOptions {
5 pub require_closed: bool,
6 pub max_area_relative_error: f64,
7 pub min_normal_alignment: f64,
8}
9
10impl Default for SurfaceRecoveryOptions {
11 fn default() -> Self {
12 Self {
13 require_closed: true,
14 max_area_relative_error: 1.0e-8,
15 min_normal_alignment: 1.0 - 1.0e-8,
16 }
17 }
18}
19
20#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
21pub struct SurfaceRecoveryReport {
22 pub surface_element_count: usize,
23 pub recovered_edge_count: usize,
24 pub open_edge_count: usize,
25 pub nonmanifold_edge_count: usize,
26 pub max_area_relative_error: f64,
27 pub min_normal_alignment: f64,
28 pub source_face_coverage_ratio: f64,
29}
30
31#[derive(Debug, Clone, PartialEq)]
32pub enum SurfaceRecoveryError {
33 EmptySurface,
34 InvalidOptions,
35 MissingSurfaceNode {
36 element_id: u32,
37 node_id: u32,
38 },
39 NonFiniteSurfaceNode {
40 node_id: u32,
41 },
42 DegenerateElement {
43 element_id: u32,
44 },
45 AreaMismatch {
46 element_id: u32,
47 relative_error: f64,
48 max_relative_error: f64,
49 },
50 SourceFaceAreaMismatch {
51 source_face_id: u32,
52 relative_error: f64,
53 max_relative_error: f64,
54 },
55 NormalMismatch {
56 element_id: u32,
57 alignment: f64,
58 min_alignment: f64,
59 },
60 MissingSourceFace {
61 source_face_id: u32,
62 },
63 UncoveredSourceFace {
64 source_face_id: u32,
65 },
66 OpenEdge {
67 edge: [u32; 2],
68 count: usize,
69 },
70 NonManifoldEdge {
71 edge: [u32; 2],
72 count: usize,
73 },
74}
75
76impl std::fmt::Display for SurfaceRecoveryError {
77 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78 match self {
79 Self::EmptySurface => write!(formatter, "surface recovery input has no elements"),
80 Self::InvalidOptions => write!(
81 formatter,
82 "surface recovery options must use finite area and normal thresholds"
83 ),
84 Self::MissingSurfaceNode {
85 element_id,
86 node_id,
87 } => write!(
88 formatter,
89 "surface element {element_id} references missing node {node_id}"
90 ),
91 Self::NonFiniteSurfaceNode { node_id } => {
92 write!(formatter, "surface node {node_id} has non-finite coordinates")
93 }
94 Self::DegenerateElement { element_id } => {
95 write!(formatter, "surface element {element_id} is degenerate")
96 }
97 Self::AreaMismatch {
98 element_id,
99 relative_error,
100 max_relative_error,
101 } => write!(
102 formatter,
103 "surface element {element_id} area relative error {relative_error:.6e} exceeds {max_relative_error:.6e}"
104 ),
105 Self::SourceFaceAreaMismatch {
106 source_face_id,
107 relative_error,
108 max_relative_error,
109 } => write!(
110 formatter,
111 "source face {source_face_id} recovered area relative error {relative_error:.6e} exceeds {max_relative_error:.6e}"
112 ),
113 Self::NormalMismatch {
114 element_id,
115 alignment,
116 min_alignment,
117 } => write!(
118 formatter,
119 "surface element {element_id} normal alignment {alignment:.6e} is below {min_alignment:.6e}"
120 ),
121 Self::MissingSourceFace { source_face_id } => {
122 write!(formatter, "source face {source_face_id} is not present in topology")
123 }
124 Self::UncoveredSourceFace { source_face_id } => {
125 write!(formatter, "source face {source_face_id} is not covered by surface mesh")
126 }
127 Self::OpenEdge { edge, count } => write!(
128 formatter,
129 "surface edge {}-{} has incidence {count}, expected 2",
130 edge[0], edge[1]
131 ),
132 Self::NonManifoldEdge { edge, count } => write!(
133 formatter,
134 "surface edge {}-{} has non-manifold incidence {count}, expected 2",
135 edge[0], edge[1]
136 ),
137 }
138 }
139}
140
141impl std::error::Error for SurfaceRecoveryError {}