Thanks @jyviko.
This commit is contained in:
1 parent
77bdcc47e9
commit
fac3f96bdd
24 files changed
+2688
-77
No files matched your search
@@ -1276,6 +1276,14 @@ pub enum FeatureKind {
|
||||
/// exact plane whatever this says).
|
||||
#[serde(default, skip_serializing_if = "is_zero")]
|
||||
crown: f64,
|
||||
/// How a patch on edges meets the faces beside its loop (G0 everywhere by default, and
|
||||
/// then not saved).
|
||||
#[serde(default, skip_serializing_if = "PatchContinuity::is_g0")]
|
||||
continuity: PatchContinuity,
|
||||
/// Points a patch on edges passes through.
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[walk(pos)]
|
||||
points: Vec<Vec3>,
|
||||
},
|
||||
/// Surface bodies sewn along shared edges into the first one (a solid when they close).
|
||||
Stitch {
|
||||
@@ -1666,6 +1674,45 @@ pub struct BlendSide {
|
||||
pub edges: Vec<Vec3>,
|
||||
}
|
||||
|
||||
/// How a patch on a loop of edges meets the faces beside the loop: every edge with `all`, but the
|
||||
/// edges picked in `edges` with their own.
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, solidcraft_derive::Walk)]
|
||||
pub struct PatchContinuity {
|
||||
#[serde(default = "patch_g0", skip_serializing_if = "is_g0")]
|
||||
pub all: Continuity,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub edges: Vec<EdgeContinuity>,
|
||||
}
|
||||
|
||||
/// One edge of a patch's loop (a point on it) and how the patch meets the face beside it.
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, solidcraft_derive::Walk)]
|
||||
pub struct EdgeContinuity {
|
||||
#[walk(pos)]
|
||||
pub edge: Vec3,
|
||||
pub g: Continuity,
|
||||
}
|
||||
|
||||
impl Default for PatchContinuity {
|
||||
fn default() -> PatchContinuity {
|
||||
PatchContinuity { all: Continuity::G0, edges: Vec::new() }
|
||||
}
|
||||
}
|
||||
|
||||
impl PatchContinuity {
|
||||
/// G0 everywhere: the patch only meets its edges.
|
||||
pub fn is_g0(&self) -> bool {
|
||||
self.all == Continuity::G0 && self.edges.iter().all(|e| e.g == Continuity::G0)
|
||||
}
|
||||
}
|
||||
|
||||
fn patch_g0() -> Continuity {
|
||||
Continuity::G0
|
||||
}
|
||||
|
||||
fn is_g0(g: &Continuity) -> bool {
|
||||
*g == Continuity::G0
|
||||
}
|
||||
|
||||
/// The continuity a blend repeats by default: the tangent plane on both sides.
|
||||
fn blend_orders() -> [Continuity; 2] {
|
||||
[Continuity::G1, Continuity::G1]
|
||||
|
||||
@@ -8,7 +8,7 @@ use solidcraft_geom::Seg2;
|
||||
|
||||
pub(super) fn eval(doc: &Document, vals: &BTreeMap<String, Value>, f: &Feature, st: &mut ModelState, warning: &mut Option<String>) -> Result<()> {
|
||||
match &f.kind {
|
||||
FeatureKind::Patch { sketch, profiles, body, edges, crown } => {
|
||||
FeatureKind::Patch { sketch, profiles, body, edges, crown, continuity, points } => {
|
||||
let mut made = Vec::new();
|
||||
if let Some(sk) = sketch {
|
||||
let ss = st.sketch(*sk).ok_or_else(|| DocError::Unknown(format!("sketch {sk} (it must come earlier in the timeline)")))?;
|
||||
@@ -20,7 +20,13 @@ pub(super) fn eval(doc: &Document, vals: &BTreeMap<String, Value>, f: &Feature,
|
||||
if !edges.is_empty() {
|
||||
let i = body_at(st, body, edges)?;
|
||||
let b = st.bodies.get(i).ok_or_else(|| DocError::Invalid("body".into()))?;
|
||||
made.push(kernel::patch_edges_crowned(&b.body, edges, *crown)?);
|
||||
let spec = kernel::PatchSpec {
|
||||
continuity: continuity.all,
|
||||
edges: continuity.edges.iter().map(|e| (e.edge, e.g)).collect(),
|
||||
points: points.clone(),
|
||||
crown: *crown,
|
||||
};
|
||||
made.push(kernel::patch_edges_with(&b.body, edges, &spec)?);
|
||||
}
|
||||
if made.is_empty() {
|
||||
return Err(DocError::Invalid("a patch needs a sketch region or a loop of edges".into()));
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
//! A `Patch` on edges can carry `continuity` (`all`: `g0`, `g1` or `g2`, and `edges`:
|
||||
//! `[{edge: [x, y, z], g}]` for edges met otherwise; G0 everywhere when absent, and then not
|
||||
//! saved) and `points` it passes through (none when absent). Older designs need no
|
||||
//! transformation: a patch without them fills as it always did; a loop that is not a height field
|
||||
//! over its plane, which 0.13.0 refused, now fills with one face. 0.13.x asks for an update
|
||||
//! instead of dropping them.
|
||||
Reference in new issue
Block a user