Offset of an irregular closed spline no longer fails its error certificate; offset fit nodes stay private (#1009)
Fixes #971. At the node limit the offset certificate splits the fitted curve where it meets the exact offset midpoint, so curves with different parameter speeds certify within the same 0.002 mm tolerance. Associated offset fit nodes are hidden from display, picking, box selection and snapping until Break Association. Thanks @Karl-VonRichter.
This commit is contained in:
1 parent
2f91338d3d
commit
9ca7d307a4
9 files changed
+319
-41
No files matched your search
@@ -169,13 +169,41 @@ pub fn sketch_curve_visible(sk: &Sketch, i: usize) -> bool {
|
||||
!(c.construction && sk.view.hide_construction)
|
||||
}
|
||||
|
||||
/// Should sketch point `i` be drawn? Text outlines' points are not (they are not picked or
|
||||
/// constrained individually).
|
||||
pub fn sketch_point_visible(sk: &Sketch, i: usize) -> bool {
|
||||
match sk.points.get(i).and_then(|p| p.link.as_deref()) {
|
||||
Some(l) => sk.link(l).is_none_or(|l| l.kind != solidcraft_sketch::LinkKind::Text),
|
||||
None => true,
|
||||
/// Point roles shown and picked individually. Associated offsets keep their generated
|
||||
/// fit nodes private until their association is broken. Build once per sketch/frame.
|
||||
pub struct SketchPointVisibility<'a> {
|
||||
hidden: std::collections::HashSet<&'a str>,
|
||||
}
|
||||
|
||||
impl<'a> SketchPointVisibility<'a> {
|
||||
pub fn new(sk: &'a Sketch) -> Self {
|
||||
let outputs: std::collections::HashSet<&str> = sk.freeform_offsets.iter().map(|o| o.output.as_str()).collect();
|
||||
// A repeated link ID names its first link, as Sketch::link does.
|
||||
let mut seen = std::collections::HashSet::new();
|
||||
let text: std::collections::HashSet<&str> = sk
|
||||
.links
|
||||
.iter()
|
||||
.filter(|l| seen.insert(l.id.as_str()))
|
||||
.filter(|l| l.kind == solidcraft_sketch::LinkKind::Text)
|
||||
.map(|l| l.id.as_str())
|
||||
.collect();
|
||||
let mut hidden: std::collections::HashSet<&str> =
|
||||
sk.points.iter().filter(|p| p.link.as_deref().is_some_and(|l| text.contains(l))).map(|p| p.id.as_str()).collect();
|
||||
for curve in sk.curves.iter().filter(|c| outputs.contains(c.id.as_str())) {
|
||||
hidden.extend(curve.kind.point_ids().into_iter().filter_map(|i| sk.points.get(i).map(|p| p.id.as_str())));
|
||||
}
|
||||
Self { hidden }
|
||||
}
|
||||
|
||||
pub fn takes(&self, point: &solidcraft_sketch::SPoint) -> bool {
|
||||
!self.hidden.contains(point.id.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
/// Should sketch point `i` be drawn or picked individually? Text outlines and derived
|
||||
/// offset fit nodes are private. Batch callers use [`SketchPointVisibility`].
|
||||
pub fn sketch_point_visible(sk: &Sketch, i: usize) -> bool {
|
||||
sk.points.get(i).is_some_and(|p| SketchPointVisibility::new(sk).takes(p))
|
||||
}
|
||||
|
||||
/// The scene for a headless render, cut by the session's section.
|
||||
|
||||
Reference in new issue
Block a user