diff --git a/src/entities/arc.rs b/src/entities/arc.rs index 6888fdafe..b7f1564ff 100644 --- a/src/entities/arc.rs +++ b/src/entities/arc.rs @@ -45,20 +45,61 @@ fn to_truck(arc: &Arc) -> TruckEntity { ) }; + let cv = Vec3::new(cwx as f32, cwy as f32, cwz as f32); + let tangent = TangentGeom::Circle { + center: [cwx as f32, cwy as f32, cwz as f32], + radius: r as f32, + }; + + if arc.thickness.abs() > 1e-10 { + let t = arc.thickness; + let (nx, ny, nz) = normal; + let n = 32usize; + let (start_a, end_a) = if arc.normal.z < 0.0 { + let cw_span = if sa >= ea { sa - ea } else { sa - ea + TAU }; + (sa, sa - cw_span) + } else { + let ccw_end = if ea >= sa { ea } else { ea + TAU }; + (sa, ccw_end) + }; + let mut pts: Vec<[f32; 3]> = Vec::with_capacity((n + 1) * 2 + 8); + for i in 0..=n { + let a = start_a + (end_a - start_a) * (i as f64 / n as f64); + let p = arc_pt(a); + pts.push([p.x as f32, p.y as f32, p.z as f32]); + } + pts.push([f32::NAN; 3]); + for i in 0..=n { + let a = start_a + (end_a - start_a) * (i as f64 / n as f64); + let p = arc_pt(a); + pts.push([(p.x + t * nx) as f32, (p.y + t * ny) as f32, (p.z + t * nz) as f32]); + } + pts.push([f32::NAN; 3]); + let ps = arc_pt(sa); + pts.push([ps.x as f32, ps.y as f32, ps.z as f32]); + pts.push([(ps.x + t * nx) as f32, (ps.y + t * ny) as f32, (ps.z + t * nz) as f32]); + pts.push([f32::NAN; 3]); + let pe = arc_pt(ea); + pts.push([pe.x as f32, pe.y as f32, pe.z as f32]); + pts.push([(pe.x + t * nx) as f32, (pe.y + t * ny) as f32, (pe.z + t * nz) as f32]); + return TruckEntity { + object: TruckObject::Lines(pts), + snap_pts: vec![(cv, SnapHint::Center)], + tangent_geoms: vec![tangent], + key_vertices: vec![], + }; + } + let p_start = arc_pt(sa); let p_end = arc_pt(ea); let p_mid = arc_pt(mid_a); let v_start = builder::vertex(p_start); let v_end = builder::vertex(p_end); let edge = builder::circle_arc(&v_start, &v_end, p_mid); - let cv = Vec3::new(cwx as f32, cwy as f32, cwz as f32); TruckEntity { object: TruckObject::Curve(edge), snap_pts: vec![(cv, SnapHint::Center)], - tangent_geoms: vec![TangentGeom::Circle { - center: [cwx as f32, cwy as f32, cwz as f32], - radius: r as f32, - }], + tangent_geoms: vec![tangent], key_vertices: vec![], } } diff --git a/src/entities/circle.rs b/src/entities/circle.rs index d06e74876..33c28a59d 100644 --- a/src/entities/circle.rs +++ b/src/entities/circle.rs @@ -35,12 +35,6 @@ fn to_truck(circle: &Circle) -> TruckEntity { let p_top = pt(ay, (0.0, 0.0, 0.0), r); let p_bot = pt((ay.0 * -1.0, ay.1 * -1.0, ay.2 * -1.0), (0.0, 0.0, 0.0), r); - let right = builder::vertex(p_right); - let left = builder::vertex(p_left); - let upper = builder::circle_arc(&right, &left, p_top); - let lower = builder::circle_arc(&left, &right, p_bot); - let wire: Wire = [upper, lower].into_iter().collect(); - let cv = Vec3::new(cwx as f32, cwy as f32, cwz as f32); let rf = r as f32; let q = |d: (f64, f64, f64)| Vec3::new( @@ -48,19 +42,67 @@ fn to_truck(circle: &Circle) -> TruckEntity { (cwy + r * d.1) as f32, (cwz + r * d.2) as f32, ); + let snap_pts = vec![ + (cv, SnapHint::Center), + (q(ax), SnapHint::Quadrant), + (q(ay), SnapHint::Quadrant), + (q((-ax.0, -ax.1, -ax.2)), SnapHint::Quadrant), + (q((-ay.0, -ay.1, -ay.2)), SnapHint::Quadrant), + ]; + let tangent = TangentGeom::Circle { + center: [cwx as f32, cwy as f32, cwz as f32], + radius: rf, + }; + + if circle.thickness.abs() > 1e-10 { + let t = circle.thickness; + let (nx, ny, nz) = normal; + let n = 64usize; + let tau = std::f64::consts::TAU; + let circ_pt = |a: f64| -> (f64, f64, f64) { + let (c, s) = (a.cos(), a.sin()); + ( + cwx + r * (c * ax.0 + s * ay.0), + cwy + r * (c * ax.1 + s * ay.1), + cwz + r * (c * ax.2 + s * ay.2), + ) + }; + let mut pts: Vec<[f32; 3]> = Vec::with_capacity((n + 1) * 2 + 4 * 3); + for i in 0..=n { + let (x, y, z) = circ_pt(i as f64 * tau / n as f64); + pts.push([x as f32, y as f32, z as f32]); + } + pts.push([f32::NAN; 3]); + for i in 0..=n { + let (x, y, z) = circ_pt(i as f64 * tau / n as f64); + pts.push([(x + t * nx) as f32, (y + t * ny) as f32, (z + t * nz) as f32]); + } + pts.push([f32::NAN; 3]); + for i in 0..4usize { + let (x, y, z) = circ_pt(i as f64 * std::f64::consts::FRAC_PI_2); + pts.push([x as f32, y as f32, z as f32]); + pts.push([(x + t * nx) as f32, (y + t * ny) as f32, (z + t * nz) as f32]); + if i < 3 { + pts.push([f32::NAN; 3]); + } + } + return TruckEntity { + object: TruckObject::Lines(pts), + snap_pts, + tangent_geoms: vec![tangent], + key_vertices: vec![], + }; + } + + let right = builder::vertex(p_right); + let left = builder::vertex(p_left); + let upper = builder::circle_arc(&right, &left, p_top); + let lower = builder::circle_arc(&left, &right, p_bot); + let wire: Wire = [upper, lower].into_iter().collect(); TruckEntity { object: TruckObject::Contour(wire), - snap_pts: vec![ - (cv, SnapHint::Center), - (q(ax), SnapHint::Quadrant), - (q(ay), SnapHint::Quadrant), - (q((-ax.0, -ax.1, -ax.2)), SnapHint::Quadrant), - (q((-ay.0, -ay.1, -ay.2)), SnapHint::Quadrant), - ], - tangent_geoms: vec![TangentGeom::Circle { - center: [cwx as f32, cwy as f32, cwz as f32], - radius: rf, - }], + snap_pts, + tangent_geoms: vec![tangent], key_vertices: vec![], } }