Guide sketch patterns with live previews and editable offsets (#966)
Sketch Mirror, rectangular and circular Pattern, and Offset now show a green live preview that follows the selection and settings; OK commits, Cancel leaves the sketch unchanged. The shared dialogs show the current selection step and source counts, sources can be toggled with Ctrl/Cmd-click, cleared and reselected. Offsets keep editable driving distance dimensions (One Side, Two Sides, Symmetric) that update the derived curves without moving the source, with undo/redo and save/reopen. Format 19: older files keep their fixed offsets. New dialog labels in en, zh, ja, de and ko. Fixes #696. Fixes #517.
This commit is contained in:
1 parent
9c51f9d433
commit
47a7f29485
29 files changed
+1107
-186
No files matched your search
@@ -10,7 +10,7 @@ pub const MAX_CONSTRAINTS: usize = 40_000;
|
||||
pub const MAX_CURVES: usize = MAX_POINTS;
|
||||
|
||||
/// Largest coordinate or dimension value (mm) a sketch accepts.
|
||||
pub(crate) const MAX_COORD: f64 = 1e9;
|
||||
pub const MAX_COORD: f64 = 1e9;
|
||||
|
||||
/// A position a sketch accepts: finite and within [`MAX_COORD`].
|
||||
pub(crate) fn in_range(p: Vec2) -> bool {
|
||||
@@ -310,6 +310,15 @@ pub enum ConstraintKind {
|
||||
l: usize,
|
||||
value: f64,
|
||||
},
|
||||
/// Normal distance of an associative offset. Its output id remains stable
|
||||
/// when a curved boundary retires a corner; refresh_offsets drives the geometry.
|
||||
OffsetDistance {
|
||||
output: String,
|
||||
value: f64,
|
||||
/// Keep the chosen side when the positive driving length is edited.
|
||||
#[serde(default)]
|
||||
reverse: bool,
|
||||
},
|
||||
}
|
||||
|
||||
impl ConstraintKind {
|
||||
@@ -331,6 +340,7 @@ impl ConstraintKind {
|
||||
| Diameter { value, .. }
|
||||
| ArcLength { value, .. }
|
||||
| LinearDiameter { value, .. }
|
||||
| OffsetDistance { value, .. }
|
||||
| Angle { value, .. } => Some(value),
|
||||
_ => None,
|
||||
}
|
||||
@@ -350,6 +360,7 @@ impl ConstraintKind {
|
||||
| Diameter { value, .. }
|
||||
| ArcLength { value, .. }
|
||||
| LinearDiameter { value, .. }
|
||||
| OffsetDistance { value, .. }
|
||||
| Angle { value, .. } => *value = v,
|
||||
_ => {}
|
||||
}
|
||||
@@ -381,6 +392,7 @@ impl ConstraintKind {
|
||||
Smooth { .. } => "Smooth",
|
||||
ArcLength { .. } => "ArcLengthDimension",
|
||||
LinearDiameter { .. } => "LinearDiameterDimension",
|
||||
OffsetDistance { .. } => "OffsetDimension",
|
||||
}
|
||||
}
|
||||
/// Does the constraint refer to point `p` (by index)?
|
||||
@@ -406,6 +418,7 @@ impl ConstraintKind {
|
||||
Smooth { a, b } => (vec![], vec![a, b]),
|
||||
ArcLength { c, .. } => (vec![], vec![c]),
|
||||
LinearDiameter { p, l, .. } => (vec![p], vec![l]),
|
||||
OffsetDistance { .. } => (vec![], vec![]),
|
||||
}
|
||||
}
|
||||
pub(crate) fn remap(&mut self, pmap: &dyn Fn(usize) -> Option<usize>, cmap: &dyn Fn(usize) -> Option<usize>) -> bool {
|
||||
@@ -462,6 +475,7 @@ impl ConstraintKind {
|
||||
fp(p);
|
||||
fc(l);
|
||||
}
|
||||
OffsetDistance { .. } => {}
|
||||
}
|
||||
ok && ok2
|
||||
}
|
||||
@@ -868,6 +882,11 @@ impl Sketch {
|
||||
{
|
||||
return Err(SketchError::Invalid(format!("dimension value {v}")));
|
||||
}
|
||||
if let OffsetDistance { output, value, .. } = k
|
||||
&& (*value <= 1e-9 || output.len() > 512 || self.offset_distance(output).is_none())
|
||||
{
|
||||
return Err(SketchError::Invalid("offset dimension needs a nonzero distance and an existing association".into()));
|
||||
}
|
||||
if let ArcSweep { value, .. } = *k
|
||||
&& !(value.abs() > 1e-9 && value.abs() < std::f64::consts::TAU - 1e-9)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user