Class-A surfacing 3/3: blend curves, curved-edge fillets, the G2 corner and continuity analysis (#1642)
Thanks @midasdf.
This commit is contained in:
1 parent
3126962cd4
commit
bbd4f29ebb
43 files changed
+4753
-132
No files matched your search
@@ -563,6 +563,10 @@ pub enum FeatureKind {
|
||||
/// What to do when the radius is too large for the geometry around the edges.
|
||||
#[serde(default, skip_serializing_if = "FilletFit::is_exact")]
|
||||
fit: FilletFit,
|
||||
/// What fills the corners where three blended edges meet: the rolling ball's sphere
|
||||
/// (default) or a G2 patch repeating each blend up to the second order.
|
||||
#[serde(default, skip_serializing_if = "FilletCorner::is_rolling")]
|
||||
corner: FilletCorner,
|
||||
},
|
||||
Chamfer {
|
||||
edges: Vec<Position>,
|
||||
@@ -1311,6 +1315,10 @@ pub enum FeatureKind {
|
||||
/// sketch curves: walls only, no caps.
|
||||
SurfaceLoft {
|
||||
sections: Vec<SheetSection>,
|
||||
#[serde(default = "loft_plain_continuity", skip_serializing_if = "loft_continuity_is_plain")]
|
||||
continuity: [Continuity; 2],
|
||||
#[serde(default, skip_serializing_if = "loft_crown_is_plain")]
|
||||
crown: [f64; 2],
|
||||
},
|
||||
/// The faces at `faces` copied out at a signed `distance` along their normals as a new
|
||||
/// surface body (0 copies them); `chain` takes each pick's whole smooth chain of faces;
|
||||
@@ -1491,6 +1499,23 @@ pub enum FeatureKind {
|
||||
},
|
||||
}
|
||||
|
||||
/// What fills the corner where three blended edges meet.
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum FilletCorner {
|
||||
/// A piece of the rolling ball's sphere: tangent (G1) to each blend.
|
||||
#[default]
|
||||
Rolling,
|
||||
/// A G2 patch repeating each blend's surface up to the second order (see `corner_g2`).
|
||||
G2,
|
||||
}
|
||||
|
||||
impl FilletCorner {
|
||||
pub fn is_rolling(&self) -> bool {
|
||||
matches!(self, FilletCorner::Rolling)
|
||||
}
|
||||
}
|
||||
|
||||
/// How Extend continues a surface past its edges.
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
@@ -1734,6 +1759,28 @@ pub struct SheetSection {
|
||||
pub profiles: Option<ProfileSel>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub curves: Vec<String>,
|
||||
/// A section picked as an edge chain of a body instead of a sketch: `edges` are points on the
|
||||
/// chain, and the face the chain bounds is the surface the loft leaves there.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub body: Option<BodyName>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub edges: Vec<Position>,
|
||||
}
|
||||
|
||||
/// A loft's continuity where a design does not say: both ends G0, the loft of old, which only
|
||||
/// passes through its sections.
|
||||
fn loft_plain_continuity() -> [Continuity; 2] {
|
||||
[Continuity::G0, Continuity::G0]
|
||||
}
|
||||
|
||||
/// A loft's continuity is plain when it only passes through its sections: both ends G0.
|
||||
fn loft_continuity_is_plain(c: &[Continuity; 2]) -> bool {
|
||||
*c == [Continuity::G0, Continuity::G0]
|
||||
}
|
||||
|
||||
/// A loft's crown is plain when neither end is filled out.
|
||||
fn loft_crown_is_plain(c: &[f64; 2]) -> bool {
|
||||
c.iter().all(|v| *v == 0.0)
|
||||
}
|
||||
|
||||
/// Coil cross-sections.
|
||||
|
||||
Reference in new issue
Block a user