cargo fmt

This commit is contained in:
Hakan committed 2026-05-12 10:36:15 +03:00
1 parent 468cbde5e1
commit ca07268c7c
204 files changed
+13997 -5525

No files matched your search

+85 -43
View File
@@ -22,18 +22,28 @@ pub struct JoinCommand {
impl JoinCommand {
pub fn new() -> Self {
Self { handles: vec![], gathering: true }
Self {
handles: vec![],
gathering: true,
}
}
}
impl CadCommand for JoinCommand {
fn name(&self) -> &'static str { "JOIN" }
fn prompt(&self) -> String {
format!("JOIN Select objects to join ({} selected, Enter to apply):", self.handles.len())
fn name(&self) -> &'static str {
"JOIN"
}
fn is_selection_gathering(&self) -> bool { self.gathering }
fn prompt(&self) -> String {
format!(
"JOIN Select objects to join ({} selected, Enter to apply):",
self.handles.len()
)
}
fn is_selection_gathering(&self) -> bool {
self.gathering
}
fn on_selection_complete(&mut self, handles: Vec<Handle>) -> CmdResult {
self.handles = handles;
@@ -63,10 +73,12 @@ pub fn join_entities(entities: &[(Handle, &EntityType)]) -> Option<(Vec<Handle>,
}
// Split into lines and arcs
let lines: Vec<_> = entities.iter()
let lines: Vec<_> = entities
.iter()
.filter(|(_, e)| matches!(e, EntityType::Line(_)))
.collect();
let arcs: Vec<_> = entities.iter()
let arcs: Vec<_> = entities
.iter()
.filter(|(_, e)| matches!(e, EntityType::Arc(_)))
.collect();
@@ -81,93 +93,123 @@ pub fn join_entities(entities: &[(Handle, &EntityType)]) -> Option<(Vec<Handle>,
fn try_join_lines(lines: &[&(Handle, &EntityType)]) -> Option<(Vec<Handle>, Vec<EntityType>)> {
// Collect endpoints in XZ plane
let segs: Vec<_> = lines.iter().map(|(h, e)| {
if let EntityType::Line(l) = e {
let s = Vec3::new(l.start.x as f32, l.start.z as f32, 0.0);
let e2 = Vec3::new(l.end.x as f32, l.end.z as f32, 0.0);
(*h, l, s, e2)
} else { unreachable!() }
}).collect();
let segs: Vec<_> = lines
.iter()
.map(|(h, e)| {
if let EntityType::Line(l) = e {
let s = Vec3::new(l.start.x as f32, l.start.z as f32, 0.0);
let e2 = Vec3::new(l.end.x as f32, l.end.z as f32, 0.0);
(*h, l, s, e2)
} else {
unreachable!()
}
})
.collect();
// Check collinearity: all lines must be parallel and on the same infinite line.
let (_, first_line, s0, e0) = segs[0];
let dir0 = (e0 - s0).normalize_or_zero();
if dir0.length_squared() < 1e-12 { return None; }
if dir0.length_squared() < 1e-12 {
return None;
}
for (_, _, si, ei) in &segs[1..] {
// Check parallel
let diri = (*ei - *si).normalize_or_zero();
let cross = (dir0.x * diri.y - dir0.y * diri.x).abs();
if cross > 1e-4 { return None; }
if cross > 1e-4 {
return None;
}
// Check co-linear (point on same line)
let off = *si - s0;
let perp = (off - dir0 * off.dot(dir0)).length();
if perp > 1e-3 { return None; }
if perp > 1e-3 {
return None;
}
}
// Project all endpoints onto the direction axis
let params: Vec<f32> = segs.iter().flat_map(|(_, _, si, ei)| {
[si.dot(dir0), ei.dot(dir0)]
}).collect();
let params: Vec<f32> = segs
.iter()
.flat_map(|(_, _, si, ei)| [si.dot(dir0), ei.dot(dir0)])
.collect();
let t_min = params.iter().cloned().fold(f32::INFINITY, f32::min);
let t_max = params.iter().cloned().fold(f32::NEG_INFINITY, f32::max);
// Check connectivity: no gaps larger than tolerance
let mut sorted: Vec<[f32; 2]> = segs.iter().map(|(_, _, si, ei)| {
let ta = si.dot(dir0);
let tb = ei.dot(dir0);
[ta.min(tb), ta.max(tb)]
}).collect();
let mut sorted: Vec<[f32; 2]> = segs
.iter()
.map(|(_, _, si, ei)| {
let ta = si.dot(dir0);
let tb = ei.dot(dir0);
[ta.min(tb), ta.max(tb)]
})
.collect();
sorted.sort_by(|a, b| a[0].partial_cmp(&b[0]).unwrap());
for w in sorted.windows(2) {
if w[1][0] > w[0][1] + 1e-3 { return None; } // gap
if w[1][0] > w[0][1] + 1e-3 {
return None;
} // gap
}
let new_start = s0 + dir0 * t_min;
let new_end = s0 + dir0 * t_max;
let new_end = s0 + dir0 * t_max;
let mut merged = first_line.clone();
merged.common.handle = Handle::NULL;
merged.start = vec3_xz_to_v3(new_start, first_line.start.z);
merged.end = vec3_xz_to_v3(new_end, first_line.start.z);
merged.end = vec3_xz_to_v3(new_end, first_line.start.z);
let handles: Vec<Handle> = lines.iter().map(|(h, _)| *h).collect();
Some((handles, vec![EntityType::Line(merged)]))
}
fn try_join_arcs(arcs: &[&(Handle, &EntityType)]) -> Option<(Vec<Handle>, Vec<EntityType>)> {
let segs: Vec<_> = arcs.iter().map(|(h, e)| {
if let EntityType::Arc(a) = e { (*h, a) }
else { unreachable!() }
}).collect();
let segs: Vec<_> = arcs
.iter()
.map(|(h, e)| {
if let EntityType::Arc(a) = e {
(*h, a)
} else {
unreachable!()
}
})
.collect();
// All arcs must share the same center and radius
let (_, first) = segs[0];
let cx = first.center.x;
let cy = first.center.y;
let r = first.radius;
let r = first.radius;
for (_, a) in &segs[1..] {
if (a.center.x - cx).abs() > 1e-3 || (a.center.y - cy).abs() > 1e-3 { return None; }
if (a.radius - r).abs() > 1e-3 { return None; }
if (a.center.x - cx).abs() > 1e-3 || (a.center.y - cy).abs() > 1e-3 {
return None;
}
if (a.radius - r).abs() > 1e-3 {
return None;
}
}
// Collect (start_angle, end_angle) in radians.
let mut intervals: Vec<[f32; 2]> = segs.iter().map(|(_, a)| {
[a.start_angle as f32, a.end_angle as f32]
}).collect();
let mut intervals: Vec<[f32; 2]> = segs
.iter()
.map(|(_, a)| [a.start_angle as f32, a.end_angle as f32])
.collect();
// Sort by start angle
intervals.sort_by(|a, b| a[0].partial_cmp(&b[0]).unwrap());
// Try to merge into one contiguous arc
let merged_start = intervals[0][0];
let mut merged_end = intervals[0][1];
let mut merged_end = intervals[0][1];
for &[s, e] in &intervals[1..] {
let span = (e - merged_end).rem_euclid(std::f32::consts::TAU);
let gap = (s - merged_end).rem_euclid(std::f32::consts::TAU);
let gap = (s - merged_end).rem_euclid(std::f32::consts::TAU);
let _ = span;
if gap > 1e-3 { return None; } // discontinuous
if gap > 1e-3 {
return None;
} // discontinuous
merged_end = e;
}
@@ -188,7 +230,7 @@ fn try_join_arcs(arcs: &[&(Handle, &EntityType)]) -> Option<(Vec<Handle>, Vec<En
let mut merged_arc = first.clone();
merged_arc.common.handle = Handle::NULL;
merged_arc.start_angle = merged_start as f64;
merged_arc.end_angle = merged_end as f64;
merged_arc.end_angle = merged_end as f64;
Some((handles, vec![EntityType::Arc(merged_arc)]))
}