Add involute to Path info

This commit is contained in:
benjamaan476
2025-04-23 16:54:39 +01:00
parent 41d946b339
commit ed774e67b2
4 changed files with 77 additions and 2 deletions

View File

@ -1135,6 +1135,19 @@ pub enum Path {
/// True if the arc is counterclockwise.
ccw: bool,
},
/// An involute of a circle of start_radius ending at end_radius
CircularInvolute {
#[serde(flatten)]
base: BasePath,
/// The radius of the base circle of the involute
start_radius: f64,
/// The radius that the involute ends at
end_radius: f64,
/// Angle about which the whole involute is rotated
angle: f64,
/// If true, the path segment starts at the end radius and goes towards the start radius
reverse: bool,
},
}
/// What kind of path is this?
@ -1149,6 +1162,7 @@ enum PathType {
Horizontal,
AngledLineTo,
Arc,
CircularInvolute,
}
impl From<&Path> for PathType {
@ -1164,6 +1178,7 @@ impl From<&Path> for PathType {
Path::Base { .. } => Self::Base,
Path::Arc { .. } => Self::Arc,
Path::ArcThreePoint { .. } => Self::Arc,
Path::CircularInvolute { .. } => Self::CircularInvolute,
}
}
}
@ -1181,6 +1196,7 @@ impl Path {
Path::CircleThreePoint { base, .. } => base.geo_meta.id,
Path::Arc { base, .. } => base.geo_meta.id,
Path::ArcThreePoint { base, .. } => base.geo_meta.id,
Path::CircularInvolute { base, .. } => base.geo_meta.id,
}
}
@ -1196,6 +1212,7 @@ impl Path {
Path::CircleThreePoint { base, .. } => base.tag.clone(),
Path::Arc { base, .. } => base.tag.clone(),
Path::ArcThreePoint { base, .. } => base.tag.clone(),
Path::CircularInvolute { base, .. } => base.tag.clone(),
}
}
@ -1211,6 +1228,7 @@ impl Path {
Path::CircleThreePoint { base, .. } => base,
Path::Arc { base, .. } => base,
Path::ArcThreePoint { base, .. } => base,
Path::CircularInvolute { base, .. } => base,
}
}
@ -1272,6 +1290,15 @@ impl Path {
// TODO: Call engine utils to figure this out.
linear_distance(&self.get_base().from, &self.get_base().to)
}
Self::CircularInvolute {
base: _,
start_radius,
end_radius,
..
} => {
let angle = (end_radius * end_radius - start_radius * start_radius).sqrt() / start_radius;
0.5 * start_radius * angle * angle
}
};
TyF64::new(n, self.get_base().units.into())
}
@ -1288,6 +1315,7 @@ impl Path {
Path::CircleThreePoint { base, .. } => Some(base),
Path::Arc { base, .. } => Some(base),
Path::ArcThreePoint { base, .. } => Some(base),
Path::CircularInvolute { base, .. } => Some(base),
}
}
@ -1323,7 +1351,11 @@ impl Path {
radius: circle.radius,
}
}
Path::ToPoint { .. } | Path::Horizontal { .. } | Path::AngledLineTo { .. } | Path::Base { .. } => {
Path::CircularInvolute { .. }
| Path::ToPoint { .. }
| Path::Horizontal { .. }
| Path::AngledLineTo { .. }
| Path::Base { .. } => {
let base = self.get_base();
GetTangentialInfoFromPathsResult::PreviousPoint(base.from)
}
@ -1350,6 +1382,7 @@ pub enum ExtrudeSurface {
/// An extrude plane.
ExtrudePlane(ExtrudePlane),
ExtrudeArc(ExtrudeArc),
ExtrudeInvolute(ExtrudeInvolute),
Chamfer(ChamferSurface),
Fillet(FilletSurface),
}
@ -1410,11 +1443,26 @@ pub struct ExtrudeArc {
pub geo_meta: GeoMeta,
}
/// An extruded involute.
#[derive(Debug, Clone, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct ExtrudeInvolute {
/// The face id for the extrude surface.
pub face_id: uuid::Uuid,
/// The tag.
pub tag: Option<Node<TagDeclarator>>,
/// Metadata.
#[serde(flatten)]
pub geo_meta: GeoMeta,
}
impl ExtrudeSurface {
pub fn get_id(&self) -> uuid::Uuid {
match self {
ExtrudeSurface::ExtrudePlane(ep) => ep.geo_meta.id,
ExtrudeSurface::ExtrudeArc(ea) => ea.geo_meta.id,
ExtrudeSurface::ExtrudeInvolute(ea) => ea.geo_meta.id,
ExtrudeSurface::Fillet(f) => f.geo_meta.id,
ExtrudeSurface::Chamfer(c) => c.geo_meta.id,
}
@ -1424,6 +1472,7 @@ impl ExtrudeSurface {
match self {
ExtrudeSurface::ExtrudePlane(ep) => ep.tag.clone(),
ExtrudeSurface::ExtrudeArc(ea) => ea.tag.clone(),
ExtrudeSurface::ExtrudeInvolute(ea) => ea.tag.clone(),
ExtrudeSurface::Fillet(f) => f.tag.clone(),
ExtrudeSurface::Chamfer(c) => c.tag.clone(),
}

View File

@ -805,6 +805,17 @@ impl Args {
None
}
}
ExtrudeSurface::ExtrudeInvolute(extrude_involute) => {
if let Some(involute_tag) = &extrude_involute.tag {
if involute_tag.name == tag.value {
Some(Ok(extrude_involute.face_id))
} else {
None
}
} else {
None
}
}
ExtrudeSurface::Chamfer(chamfer) => {
if let Some(chamfer_tag) = &chamfer.tag {
if chamfer_tag.name == tag.value {

View File

@ -399,6 +399,17 @@ pub(crate) async fn do_post_extrude<'a>(
});
Some(extrude_surface)
}
Path::CircularInvolute { .. } => {
let extrude_surface = ExtrudeSurface::ExtrudeInvolute(crate::execution::ExtrudeInvolute {
face_id: *actual_face_id,
tag: path.get_base().tag.clone(),
geo_meta: GeoMeta {
id: path.get_base().geo_meta.id,
metadata: path.get_base().geo_meta.metadata,
},
});
Some(extrude_surface)
}
}
} else if no_engine_commands {
// Only pre-populate the extrude surface if we are in mock mode.

View File

@ -198,7 +198,7 @@ async fn inner_involute_circular(
end.x += from.x;
end.y += from.y;
let current_path = Path::ToPoint {
let current_path = Path::CircularInvolute {
base: BasePath {
from: from.ignore_units(),
to: [end.x, end.y],
@ -209,6 +209,10 @@ async fn inner_involute_circular(
metadata: args.source_range.into(),
},
},
start_radius,
end_radius,
angle: angle.to_degrees(),
reverse: reverse.unwrap_or_default(),
};
let mut new_sketch = sketch.clone();