Construction Geometries, a Sketch Palette row that hides construction geometry (#804)
A Sketch Palette toggle (sketch.options show_construction) that hides construction geometry from drawing and picking; saved with the sketch's view options under format 17. Co-authored-by: William Dunn <[email protected]>
This commit is contained in:
1 parent
9184994721
commit
d302aa1a00
15 files changed
+224
-10
No files matched your search
@@ -100,6 +100,8 @@
|
|||||||
//! Under the same version, a sheet metal rule's corner relief shape can also be `tear` (no
|
//! Under the same version, a sheet metal rule's corner relief shape can also be `tear` (no
|
||||||
//! relief: each bend is cut straight from the bends' corner to where its flange's end
|
//! relief: each bend is cut straight from the bends' corner to where its flange's end
|
||||||
//! starts); a rule that says `notch`, `round` or `rectangular` builds what it did.
|
//! starts); a rule that says `notch`, `round` or `rectangular` builds what it did.
|
||||||
|
//! A sketch's view options can also say `hide_construction` (the Sketch Palette's
|
||||||
|
//! Construction Geometries); a sketch that shows its construction geometry saves as before.
|
||||||
//! A `SurfaceExtrude` feature (Surface Extrude: `sketch`, optional `profiles`, `curves` and
|
//! A `SurfaceExtrude` feature (Surface Extrude: `sketch`, optional `profiles`, `curves` and
|
||||||
//! `extent`, walls only) is first saved in 17; 0.8.0 would refuse the unknown feature.
|
//! `extent`, walls only) is first saved in 17; 0.8.0 would refuse the unknown feature.
|
||||||
|
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ pub static COMMANDS: &[CommandSpec] = &[
|
|||||||
.enabled(in_sketch)
|
.enabled(in_sketch)
|
||||||
.params("dimension: constraint id or parameter name; at: [x,y] text centre (sketch coordinates) | reset: true (default place)"),
|
.params("dimension: constraint id or parameter name; at: [x,y] text centre (sketch coordinates) | reset: true (default place)"),
|
||||||
CommandSpec::new("sketch.options", "Sketch Palette Options", sketch_options).icon("sketch").params(
|
CommandSpec::new("sketch.options", "Sketch Palette Options", sketch_options).icon("sketch").params(
|
||||||
"sketch?: id|name (default active); any of show_profile, show_points, show_dimensions, show_constraints, show_projected, grid, snap, slice, sketch_3d: bool. Returns them all",
|
"sketch?: id|name (default active); any of show_profile, show_points, show_dimensions, show_constraints, show_projected, show_construction, grid, snap, slice, sketch_3d: bool. Returns them all",
|
||||||
),
|
),
|
||||||
CommandSpec::new("sketch.chain", "Chain", chain_cmd)
|
CommandSpec::new("sketch.chain", "Chain", chain_cmd)
|
||||||
.enabled(in_sketch)
|
.enabled(in_sketch)
|
||||||
@@ -2252,6 +2252,7 @@ fn options_json(v: &solidcraft_sketch::SketchView) -> Value {
|
|||||||
"show_dimensions": !v.hide_dimensions,
|
"show_dimensions": !v.hide_dimensions,
|
||||||
"show_constraints": !v.hide_constraints,
|
"show_constraints": !v.hide_constraints,
|
||||||
"show_projected": !v.hide_projected,
|
"show_projected": !v.hide_projected,
|
||||||
|
"show_construction": !v.hide_construction,
|
||||||
"grid": !v.hide_grid,
|
"grid": !v.hide_grid,
|
||||||
"snap": !v.no_snap,
|
"snap": !v.no_snap,
|
||||||
"slice": v.slice,
|
"slice": v.slice,
|
||||||
@@ -2261,7 +2262,18 @@ fn options_json(v: &solidcraft_sketch::SketchView) -> Value {
|
|||||||
|
|
||||||
fn sketch_options(s: &mut Session, p: &Value) -> Result<Value> {
|
fn sketch_options(s: &mut Session, p: &Value) -> Result<Value> {
|
||||||
let cmd = "sketch.options";
|
let cmd = "sketch.options";
|
||||||
let keys = ["show_profile", "show_points", "show_dimensions", "show_constraints", "show_projected", "grid", "snap", "slice", "sketch_3d"];
|
let keys = [
|
||||||
|
"show_profile",
|
||||||
|
"show_points",
|
||||||
|
"show_dimensions",
|
||||||
|
"show_constraints",
|
||||||
|
"show_projected",
|
||||||
|
"show_construction",
|
||||||
|
"grid",
|
||||||
|
"snap",
|
||||||
|
"slice",
|
||||||
|
"sketch_3d",
|
||||||
|
];
|
||||||
if let Some(o) = p.as_object()
|
if let Some(o) = p.as_object()
|
||||||
&& let Some(k) = o.keys().find(|k| *k != "sketch" && !keys.contains(&k.as_str()))
|
&& let Some(k) = o.keys().find(|k| *k != "sketch" && !keys.contains(&k.as_str()))
|
||||||
{
|
{
|
||||||
@@ -2284,6 +2296,7 @@ fn sketch_options(s: &mut Session, p: &Value) -> Result<Value> {
|
|||||||
put("show_dimensions", &mut v.hide_dimensions, true);
|
put("show_dimensions", &mut v.hide_dimensions, true);
|
||||||
put("show_constraints", &mut v.hide_constraints, true);
|
put("show_constraints", &mut v.hide_constraints, true);
|
||||||
put("show_projected", &mut v.hide_projected, true);
|
put("show_projected", &mut v.hide_projected, true);
|
||||||
|
put("show_construction", &mut v.hide_construction, true);
|
||||||
put("grid", &mut v.hide_grid, true);
|
put("grid", &mut v.hide_grid, true);
|
||||||
put("snap", &mut v.no_snap, true);
|
put("snap", &mut v.no_snap, true);
|
||||||
put("slice", &mut v.slice, false);
|
put("slice", &mut v.slice, false);
|
||||||
|
|||||||
@@ -482,6 +482,63 @@ fn palette_options_are_kept_with_each_sketch() {
|
|||||||
assert!(!sketch(&s).view.hide_points);
|
assert!(!sketch(&s).view.hide_points);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construction Geometries is a display option of one sketch, saved with it, and it changes
|
||||||
|
/// nothing about the geometry: construction curves were already outside every profile, and
|
||||||
|
/// they still are while hidden. Centerlines are a line type of their own and keep showing. A
|
||||||
|
/// design written before the option existed carries no key for it and loads with construction
|
||||||
|
/// geometry shown.
|
||||||
|
#[test]
|
||||||
|
fn hiding_construction_geometry_is_per_sketch_saved_and_leaves_profiles_and_centerlines_alone() {
|
||||||
|
use crate::view::sketch_curve_visible;
|
||||||
|
let mut s = new_sketch();
|
||||||
|
run(&mut s, "sketch.rectangle.two_point", json!({"p0": [0, 0], "p1": [40, 30]}));
|
||||||
|
run(&mut s, "sketch.line", json!({"points": [[0, 45], [40, 45]], "connect": false, "infer": false}));
|
||||||
|
run(&mut s, "sketch.line", json!({"points": [[0, 55], [40, 55]], "connect": false, "infer": false}));
|
||||||
|
run(&mut s, "sketch.construction", json!({"curves": ["l5"], "value": true}));
|
||||||
|
run(&mut s, "sketch.centerline", json!({"curves": ["l6"], "value": true}));
|
||||||
|
let (rect, construction, centerline) = (0, 4, 5);
|
||||||
|
let profiles = run(&mut s, "sketch.inspect", json!({}))["profiles"].clone();
|
||||||
|
assert_eq!(profiles.as_array().map(Vec::len), Some(1), "the rectangle is one profile: {profiles}");
|
||||||
|
|
||||||
|
assert_eq!(run(&mut s, "sketch.options", json!({}))["options"]["show_construction"], true);
|
||||||
|
let o = run(&mut s, "sketch.options", json!({"show_construction": false}));
|
||||||
|
assert_eq!(o["options"]["show_construction"], false);
|
||||||
|
let sk = sketch(&s);
|
||||||
|
assert!(sk.view.hide_construction);
|
||||||
|
assert!(!sketch_curve_visible(&sk, construction), "construction geometry is hidden");
|
||||||
|
assert!(sketch_curve_visible(&sk, centerline), "a centerline is its own line type");
|
||||||
|
assert!(sketch_curve_visible(&sk, rect), "ordinary geometry stays");
|
||||||
|
// Hiding is display only: the curves, their line types and the profiles are untouched.
|
||||||
|
let after = run(&mut s, "sketch.inspect", json!({}));
|
||||||
|
assert_eq!(after["profiles"], profiles);
|
||||||
|
assert_eq!(after["curves"][construction]["construction"], true);
|
||||||
|
assert!(sketch(&s).curves[centerline].centerline, "the centerline keeps its line type");
|
||||||
|
// Undo puts the option back.
|
||||||
|
run(&mut s, "edit.undo", json!({}));
|
||||||
|
assert!(!sketch(&s).view.hide_construction);
|
||||||
|
run(&mut s, "sketch.options", json!({"show_construction": false}));
|
||||||
|
|
||||||
|
// Another sketch shows construction geometry; the first keeps the option after finishing.
|
||||||
|
let first = s.active_sketch.expect("sketch");
|
||||||
|
run(&mut s, "sketch.finish", json!({}));
|
||||||
|
run(&mut s, "sketch.create", json!({"plane": "XZ"}));
|
||||||
|
assert_eq!(run(&mut s, "sketch.options", json!({}))["options"]["show_construction"], true);
|
||||||
|
assert_eq!(run(&mut s, "sketch.options", json!({"sketch": first}))["options"]["show_construction"], false);
|
||||||
|
|
||||||
|
// Saved with the design.
|
||||||
|
let text = serde_json::to_string(s.doc.sketch(first).expect("first")).expect("json");
|
||||||
|
assert!(text.contains("hide_construction"), "{text}");
|
||||||
|
let back: Sketch = serde_json::from_str(&text).expect("parse");
|
||||||
|
assert!(back.view.hide_construction);
|
||||||
|
|
||||||
|
// An older design file has no `hide_construction` key at all: `SketchView`'s serde default
|
||||||
|
// fills it in, and construction geometry shows, the way it did before the option existed.
|
||||||
|
let older = r#"{"points":[{"id":"origin","pos":[0.0,0.0],"fixed":true}],"curves":[],"constraints":[],
|
||||||
|
"view":{"hide_projected":true,"slice":true}}"#;
|
||||||
|
let old: Sketch = serde_json::from_str(older).expect("an older sketch still loads");
|
||||||
|
assert!(old.view.hide_projected && old.view.slice && !old.view.hide_construction);
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------
|
||||||
// Dragging
|
// Dragging
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ pub fn sketch_lines_with_sampler(
|
|||||||
) -> Vec<(Vec<Vec3>, Rgb, bool)> {
|
) -> Vec<(Vec<Vec3>, Rgb, bool)> {
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
for (i, c) in sk.curves.iter().enumerate() {
|
for (i, c) in sk.curves.iter().enumerate() {
|
||||||
if c.link.is_some() && sk.view.hide_projected && !sk.is_text_curve(i) {
|
if !sketch_curve_visible(sk, i) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let col = if c.link.is_some() && !sk.is_text_curve(i) {
|
let col = if c.link.is_some() && !sk.is_text_curve(i) {
|
||||||
@@ -151,6 +151,24 @@ pub fn sketch_lines_with_sampler(
|
|||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Should sketch curve `i` be drawn and picked? The Sketch Palette's two geometry toggles each
|
||||||
|
/// hide one category, and a curve belongs to the category its colour already names in
|
||||||
|
/// [`sketch_lines_with_sampler`]: a linked curve is projected reference geometry (Projected
|
||||||
|
/// Geometries), anything else carrying the `construction` line type is construction geometry
|
||||||
|
/// (Construction Geometries). Text outlines are linked curves that the Text feature draws, so
|
||||||
|
/// they are never reference geometry and always show. Centerlines are their own line type and
|
||||||
|
/// no toggle hides them.
|
||||||
|
///
|
||||||
|
/// Drawing and picking share this one answer so they cannot drift: geometry that is not on
|
||||||
|
/// screen is never clickable, and geometry on screen always is.
|
||||||
|
pub fn sketch_curve_visible(sk: &Sketch, i: usize) -> bool {
|
||||||
|
let Some(c) = sk.curves.get(i) else { return false };
|
||||||
|
if c.link.is_some() && !sk.is_text_curve(i) {
|
||||||
|
return !sk.view.hide_projected;
|
||||||
|
}
|
||||||
|
!(c.construction && sk.view.hide_construction)
|
||||||
|
}
|
||||||
|
|
||||||
/// Should sketch point `i` be drawn? Text outlines' points are not (they are not picked or
|
/// Should sketch point `i` be drawn? Text outlines' points are not (they are not picked or
|
||||||
/// constrained individually).
|
/// constrained individually).
|
||||||
pub fn sketch_point_visible(sk: &Sketch, i: usize) -> bool {
|
pub fn sketch_point_visible(sk: &Sketch, i: usize) -> bool {
|
||||||
|
|||||||
@@ -71,6 +71,47 @@ fn sampler_keeps_style_precedence_hidden_references_text_and_disjoint_parts() {
|
|||||||
assert!(sk.link(&projected).is_some() && sk.link(&text).is_some());
|
assert!(sk.link(&projected).is_some() && sk.link(&text).is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construction Geometries hides the `construction` line type and nothing else. Centerlines
|
||||||
|
/// are their own line type. A projected curve that carries the construction flag (the trace of
|
||||||
|
/// a plane or an axis) is drawn in the projected colour, so Projected Geometries owns it and
|
||||||
|
/// Construction Geometries leaves it alone. `sketch_curve_visible` is the one answer the GPU
|
||||||
|
/// viewport's picking uses as well, so nothing hidden here can still be clicked there.
|
||||||
|
#[test]
|
||||||
|
fn hiding_construction_geometry_keeps_ordinary_curves_centerlines_and_projected_traces() {
|
||||||
|
let mut sk = Sketch::new();
|
||||||
|
let ordinary = line(&mut sk, 0.);
|
||||||
|
let construction = line(&mut sk, 1.);
|
||||||
|
sk.curves[construction].construction = true;
|
||||||
|
let centerline = line(&mut sk, 2.);
|
||||||
|
sk.curves[centerline].centerline = true;
|
||||||
|
let axis = sk.add_link(LinkKind::Project, LinkSource::Origin, &[LinkGeom::Line(Vec2::new(0., 3.), Vec2::new(2., 3.))]).unwrap();
|
||||||
|
let trace = sk.link_curves(&axis)[0];
|
||||||
|
sk.curves[trace].construction = true;
|
||||||
|
let determined = vec![false; sk.curves.len()];
|
||||||
|
let drawn = |sk: &Sketch| -> Vec<usize> {
|
||||||
|
let mut seen = Vec::new();
|
||||||
|
sketch_lines_with_sampler(sk, &Plane::XY, true, &determined, |_, i, _| {
|
||||||
|
seen.push(i);
|
||||||
|
vec![vec![Vec3::ZERO, Vec3::X]]
|
||||||
|
});
|
||||||
|
seen
|
||||||
|
};
|
||||||
|
assert_eq!(drawn(&sk), vec![ordinary, construction, centerline, trace]);
|
||||||
|
|
||||||
|
sk.view.hide_construction = true;
|
||||||
|
assert_eq!(drawn(&sk), vec![ordinary, centerline, trace], "only the construction curve goes");
|
||||||
|
for (i, want) in [(ordinary, true), (construction, false), (centerline, true), (trace, true)] {
|
||||||
|
assert_eq!(sketch_curve_visible(&sk, i), want, "curve {i}");
|
||||||
|
}
|
||||||
|
// The projected trace answers to its own toggle, in either order.
|
||||||
|
sk.view.hide_projected = true;
|
||||||
|
assert_eq!(drawn(&sk), vec![ordinary, centerline]);
|
||||||
|
sk.view.hide_construction = false;
|
||||||
|
assert_eq!(drawn(&sk), vec![ordinary, construction, centerline]);
|
||||||
|
// A curve index that does not exist is not visible, and nothing panics asking.
|
||||||
|
assert!(!sketch_curve_visible(&sk, sk.curves.len()));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn legacy_paths_match_sampler_wrapper_and_placed_wires_are_unchanged() {
|
fn legacy_paths_match_sampler_wrapper_and_placed_wires_are_unchanged() {
|
||||||
let mut sk = Sketch::new();
|
let mut sk = Sketch::new();
|
||||||
|
|||||||
@@ -499,6 +499,11 @@ pub struct SketchView {
|
|||||||
pub hide_constraints: bool,
|
pub hide_constraints: bool,
|
||||||
#[serde(skip_serializing_if = "std::ops::Not::not")]
|
#[serde(skip_serializing_if = "std::ops::Not::not")]
|
||||||
pub hide_projected: bool,
|
pub hide_projected: bool,
|
||||||
|
/// Construction geometry (the `construction` line type) is not drawn and cannot be picked.
|
||||||
|
/// Centerlines are a line type of their own and keep showing; projected construction
|
||||||
|
/// geometry belongs to `hide_projected`, the way its colour already says it does.
|
||||||
|
#[serde(skip_serializing_if = "std::ops::Not::not")]
|
||||||
|
pub hide_construction: bool,
|
||||||
#[serde(skip_serializing_if = "std::ops::Not::not")]
|
#[serde(skip_serializing_if = "std::ops::Not::not")]
|
||||||
pub hide_grid: bool,
|
pub hide_grid: bool,
|
||||||
/// Clicks don't snap to the grid.
|
/// Clicks don't snap to the grid.
|
||||||
|
|||||||
@@ -258,6 +258,20 @@ mod tests {
|
|||||||
assert_eq!(Locale::for_language("de").label("Points"), Locale::for_language("de").text("ui.points"));
|
assert_eq!(Locale::for_language("de").label("Points"), Locale::for_language("de").text("ui.points"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The Construction Geometries row passes its English text, like the other seven text
|
||||||
|
/// rows. "Construction" on its own is already the line-type entry `ui.construction`, so
|
||||||
|
/// the row's two-word text must reach its own entry rather than that one.
|
||||||
|
#[test]
|
||||||
|
fn the_construction_geometries_row_reaches_its_own_entry_not_the_line_type() {
|
||||||
|
let rows = [("de", "Konstruktionsgeometrien"), ("ja", "構築ジオメトリ"), ("ko", "구성 형상")];
|
||||||
|
for (lang, want) in rows {
|
||||||
|
let locale = Locale::for_language(lang);
|
||||||
|
assert_eq!(locale.label("Construction Geometries"), want, "{lang}");
|
||||||
|
assert_ne!(locale.label("Construction Geometries"), locale.text("ui.construction"), "{lang}");
|
||||||
|
}
|
||||||
|
assert_eq!(Locale::for_language("en").label("Construction Geometries"), "Construction Geometries");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn templates_allow_reordering_and_literal_braces_in_values() {
|
fn templates_allow_reordering_and_literal_braces_in_values() {
|
||||||
assert_eq!(interpolate("{second} then {first}", &[("first", "{second}"), ("second", "B")]), "B then {second}");
|
assert_eq!(interpolate("{second} then {first}", &[("first", "{second}"), ("second", "B")]), "B then {second}");
|
||||||
|
|||||||
@@ -271,6 +271,7 @@
|
|||||||
"ui.shell": "Hülle",
|
"ui.shell": "Hülle",
|
||||||
"ui.show": "Einblenden",
|
"ui.show": "Einblenden",
|
||||||
"ui.show_constraints": "Bedingungen",
|
"ui.show_constraints": "Bedingungen",
|
||||||
|
"ui.show_construction_geometries": "Konstruktionsgeometrien",
|
||||||
"ui.show_dimensions": "Maße",
|
"ui.show_dimensions": "Maße",
|
||||||
"ui.show_points": "Punkte anzeigen",
|
"ui.show_points": "Punkte anzeigen",
|
||||||
"ui.show_profile": "Profil anzeigen",
|
"ui.show_profile": "Profil anzeigen",
|
||||||
|
|||||||
@@ -554,6 +554,7 @@
|
|||||||
"ui.shell": "Shell",
|
"ui.shell": "Shell",
|
||||||
"ui.show": "Show",
|
"ui.show": "Show",
|
||||||
"ui.show_constraints": "Constraints",
|
"ui.show_constraints": "Constraints",
|
||||||
|
"ui.show_construction_geometries": "Construction Geometries",
|
||||||
"ui.show_dimensions": "Dimensions",
|
"ui.show_dimensions": "Dimensions",
|
||||||
"ui.show_points": "Show Points",
|
"ui.show_points": "Show Points",
|
||||||
"ui.show_profile": "Show Profile",
|
"ui.show_profile": "Show Profile",
|
||||||
|
|||||||
@@ -554,6 +554,7 @@
|
|||||||
"ui.shell": "シェル",
|
"ui.shell": "シェル",
|
||||||
"ui.show": "表示",
|
"ui.show": "表示",
|
||||||
"ui.show_constraints": "拘束",
|
"ui.show_constraints": "拘束",
|
||||||
|
"ui.show_construction_geometries": "構築ジオメトリ",
|
||||||
"ui.show_dimensions": "寸法",
|
"ui.show_dimensions": "寸法",
|
||||||
"ui.show_points": "点を表示",
|
"ui.show_points": "点を表示",
|
||||||
"ui.show_profile": "プロファイルを表示",
|
"ui.show_profile": "プロファイルを表示",
|
||||||
|
|||||||
@@ -271,6 +271,7 @@
|
|||||||
"ui.shell": "쉘",
|
"ui.shell": "쉘",
|
||||||
"ui.show": "표시",
|
"ui.show": "표시",
|
||||||
"ui.show_constraints": "구속 조건",
|
"ui.show_constraints": "구속 조건",
|
||||||
|
"ui.show_construction_geometries": "구성 형상",
|
||||||
"ui.show_dimensions": "치수",
|
"ui.show_dimensions": "치수",
|
||||||
"ui.show_points": "점 표시",
|
"ui.show_points": "점 표시",
|
||||||
"ui.show_profile": "프로파일 표시",
|
"ui.show_profile": "프로파일 표시",
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
//! command dialog. Feature Options: the modes of the creation tool that is running, as icon
|
//! command dialog. Feature Options: the modes of the creation tool that is running, as icon
|
||||||
//! buttons. Options: the line type of the selected curves (normal, construction, centerline),
|
//! buttons. Options: the line type of the selected curves (normal, construction, centerline),
|
||||||
//! Look At, and the display toggles kept with the sketch (grid, snap, slice, profiles, points,
|
//! Look At, and the display toggles kept with the sketch (grid, snap, slice, profiles, points,
|
||||||
//! dimensions, constraints, projected geometry, 3D sketch); the sketch's degrees of freedom;
|
//! dimensions, constraints, projected geometry, construction geometry, 3D sketch); the sketch's
|
||||||
//! Finish Sketch. Toggles run `sketch.options`, line types `sketch.construction` /
|
//! degrees of freedom; Finish Sketch. Toggles run `sketch.options`, line types
|
||||||
//! `sketch.centerline`.
|
//! `sketch.construction` / `sketch.centerline`.
|
||||||
//!
|
//!
|
||||||
//! The line type is also a drawing mode: with nothing selected, Construction (or X) makes what
|
//! The line type is also a drawing mode: with nothing selected, Construction (or X) makes what
|
||||||
//! is drawn next construction geometry until it is switched back.
|
//! is drawn next construction geometry until it is switched back.
|
||||||
@@ -33,7 +33,7 @@ const WIDTH: f32 = 236.0;
|
|||||||
/// The display toggles: option key and label. Plain nouns throughout, no "Show " prefix: the
|
/// The display toggles: option key and label. Plain nouns throughout, no "Show " prefix: the
|
||||||
/// checkbox itself already says whether each one is on.
|
/// checkbox itself already says whether each one is on.
|
||||||
///
|
///
|
||||||
/// Seven of these pass their English source text directly, like the rest of this file's
|
/// Eight of these pass their English source text directly, like the rest of this file's
|
||||||
/// `app.tr_label(...)` calls: `Locale::label` looks up a literal English string against every
|
/// `app.tr_label(...)` calls: `Locale::label` looks up a literal English string against every
|
||||||
/// other English catalog entry to find its id. "Profile" and "Points" cannot do that safely:
|
/// other English catalog entry to find its id. "Profile" and "Points" cannot do that safely:
|
||||||
/// both already name something else under that same lookup (`SelInput::new("Profile", ...)` /
|
/// both already name something else under that same lookup (`SelInput::new("Profile", ...)` /
|
||||||
@@ -56,7 +56,7 @@ const WIDTH: f32 = 236.0;
|
|||||||
/// before the id fallback ever runs). Nobody writes UI copy that looks like a dotted id, so
|
/// before the id fallback ever runs). Nobody writes UI copy that looks like a dotted id, so
|
||||||
/// this is a remote hazard, not a likely one, but it is why these two ids are spelled out here
|
/// this is a remote hazard, not a likely one, but it is why these two ids are spelled out here
|
||||||
/// rather than reused anywhere else.
|
/// rather than reused anywhere else.
|
||||||
pub const TOGGLES: [(&str, &str); 9] = [
|
pub const TOGGLES: [(&str, &str); 10] = [
|
||||||
("grid", "Sketch Grid"),
|
("grid", "Sketch Grid"),
|
||||||
("snap", "Snap"),
|
("snap", "Snap"),
|
||||||
("slice", "Slice"),
|
("slice", "Slice"),
|
||||||
@@ -65,6 +65,7 @@ pub const TOGGLES: [(&str, &str); 9] = [
|
|||||||
("show_dimensions", "Dimensions"),
|
("show_dimensions", "Dimensions"),
|
||||||
("show_constraints", "Constraints"),
|
("show_constraints", "Constraints"),
|
||||||
("show_projected", "Projected Geometries"),
|
("show_projected", "Projected Geometries"),
|
||||||
|
("show_construction", "Construction Geometries"),
|
||||||
("sketch_3d", "3D Sketch"),
|
("sketch_3d", "3D Sketch"),
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -347,6 +348,7 @@ pub fn show(app: &mut SolveApp, ctx: &egui::Context) {
|
|||||||
"show_dimensions" => !opts.hide_dimensions,
|
"show_dimensions" => !opts.hide_dimensions,
|
||||||
"show_constraints" => !opts.hide_constraints,
|
"show_constraints" => !opts.hide_constraints,
|
||||||
"show_projected" => !opts.hide_projected,
|
"show_projected" => !opts.hide_projected,
|
||||||
|
"show_construction" => !opts.hide_construction,
|
||||||
"sketch_3d" => opts.three_d,
|
"sketch_3d" => opts.three_d,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -855,7 +855,7 @@ fn pick_hits(app: &SolveApp, proj: &Proj, pos: Pos2, other_sketch_points: bool,
|
|||||||
let Some(ss) = st.sketch(sid) else { continue };
|
let Some(ss) = st.sketch(sid) else { continue };
|
||||||
let bonus = if s.active_sketch == Some(sid) { 2.0 } else { 0.0 };
|
let bonus = if s.active_sketch == Some(sid) { 2.0 } else { 0.0 };
|
||||||
for (i, c) in ss.sketch.curves.iter().enumerate() {
|
for (i, c) in ss.sketch.curves.iter().enumerate() {
|
||||||
if c.link.is_some() && ss.sketch.view.hide_projected {
|
if !solidcraft_engine::view::sketch_curve_visible(&ss.sketch, i) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let straight = matches!(c.kind, CurveKind::Line { .. });
|
let straight = matches!(c.kind, CurveKind::Line { .. });
|
||||||
@@ -2493,7 +2493,7 @@ fn box_select(app: &mut SolveApp, proj: &Proj, bx: BoxSel, add: bool) {
|
|||||||
// What the selection filter lets through (window: wholly inside; crossing: touching).
|
// What the selection filter lets through (window: wholly inside; crossing: touching).
|
||||||
let off = |k: &str| app.ui.pick_off.iter().any(|x| x == k);
|
let off = |k: &str| app.ui.pick_off.iter().any(|x| x == k);
|
||||||
for (i, c) in ss.sketch.curves.iter().enumerate().filter(|_| !off("sketch") && !off("sketch_curves")) {
|
for (i, c) in ss.sketch.curves.iter().enumerate().filter(|_| !off("sketch") && !off("sketch_curves")) {
|
||||||
if c.link.is_some() && ss.sketch.view.hide_projected {
|
if !solidcraft_engine::view::sketch_curve_visible(&ss.sketch, i) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let sampled = if bx.crossing {
|
let sampled = if bx.crossing {
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
[
|
||||||
|
{"note": "The Sketch Palette's Construction Geometries row hides construction geometry while sketching. Hidden construction geometry cannot be picked either, by a click or by a box, so nothing invisible is selectable. Ordinary geometry, centerlines, sketch points and the profile are untouched."},
|
||||||
|
{"start": "sketch.create"},
|
||||||
|
{"click": {"plane": "XY"}},
|
||||||
|
{"call": "engine.execute", "params": {"command": "sketch.rectangle.two_point", "params": {"p0": [0, 0], "p1": [40, 30]}}},
|
||||||
|
{"call": "engine.execute", "params": {"command": "sketch.line", "params": {"points": [[0, 45], [40, 45]], "connect": false, "infer": false}}},
|
||||||
|
{"call": "engine.execute", "params": {"command": "sketch.line", "params": {"points": [[0, 55], [40, 55]], "connect": false, "infer": false}}},
|
||||||
|
{"call": "engine.execute", "params": {"command": "sketch.construction", "params": {"curves": ["l5"], "value": true}}},
|
||||||
|
{"call": "engine.execute", "params": {"command": "sketch.centerline", "params": {"curves": ["l6"], "value": true}}},
|
||||||
|
{"call": "ui.view", "params": {"view": "top"}},
|
||||||
|
{"expect": {"shown": "Construction Geometries"}},
|
||||||
|
{"expect": {"query": {"command": "sketch.options", "path": ["options", "show_construction"], "value": true}}},
|
||||||
|
|
||||||
|
{"note": "Shown: the construction line picks, and a box over it takes the line and its two end points."},
|
||||||
|
{"click": {"sketch": [20, 45]}},
|
||||||
|
{"expect": {"selection": 1}},
|
||||||
|
{"key": "Escape"},
|
||||||
|
{"drag": [{"sketch": [-6, 40]}, {"sketch": [46, 50]}], "steps": 10},
|
||||||
|
{"expect": {"selection": 3}},
|
||||||
|
{"key": "Escape"},
|
||||||
|
{"expect": {"selection": 0}},
|
||||||
|
|
||||||
|
{"note": "Turn the row off from the palette itself."},
|
||||||
|
{"widget": "Construction Geometries"},
|
||||||
|
{"expect": {"query": {"command": "sketch.options", "path": ["options", "show_construction"], "value": false}}},
|
||||||
|
|
||||||
|
{"note": "Hidden: the same click reaches nothing. The same box takes only the two end points, which are sketch points and answer to the Points row, not to this one."},
|
||||||
|
{"click": {"sketch": [20, 45]}},
|
||||||
|
{"expect": {"selection": 0}},
|
||||||
|
{"drag": [{"sketch": [-6, 40]}, {"sketch": [46, 50]}], "steps": 10},
|
||||||
|
{"expect": {"selection": 2}},
|
||||||
|
{"key": "Escape"},
|
||||||
|
|
||||||
|
{"note": "The centerline, the rectangle and the profile are all still there."},
|
||||||
|
{"click": {"sketch": [20, 55]}},
|
||||||
|
{"expect": {"selection": 1}},
|
||||||
|
{"key": "Escape"},
|
||||||
|
{"click": {"sketch": [20, 0]}},
|
||||||
|
{"expect": {"selection": 1}},
|
||||||
|
{"key": "Escape"},
|
||||||
|
{"expect": {"query": {"command": "sketch.inspect", "path": ["curves", 4, "construction"], "value": true}}},
|
||||||
|
{"expect": {"query": {"command": "sketch.inspect", "path": ["curves", 5, "construction"], "value": false}}},
|
||||||
|
{"expect": {"sketch_curves": {"own": 6, "linked": 0}}},
|
||||||
|
|
||||||
|
{"note": "Turning it back on brings the construction line back, pickable again."},
|
||||||
|
{"widget": "Construction Geometries"},
|
||||||
|
{"expect": {"query": {"command": "sketch.options", "path": ["options", "show_construction"], "value": true}}},
|
||||||
|
{"click": {"sketch": [20, 45]}},
|
||||||
|
{"expect": {"selection": 1}},
|
||||||
|
{"shot": "s37_construction_geometries_toggle"}
|
||||||
|
]
|
||||||
@@ -31,6 +31,13 @@ fit-point and control-point splines, conics, points and text. **Construction** (
|
|||||||
into reference geometry that doesn't form profiles. Modify tools include trim (T), extend, break,
|
into reference geometry that doesn't form profiles. Modify tools include trim (T), extend, break,
|
||||||
fillet, chamfer, offset (O), mirror, patterns, move/copy and scale.
|
fillet, chamfer, offset (O), mirror, patterns, move/copy and scale.
|
||||||
|
|
||||||
|
The Sketch Palette's **Construction Geometries** option hides construction curves while you
|
||||||
|
work. A hidden construction curve cannot be picked by a click or by a box. Nothing invisible
|
||||||
|
is selectable. The option belongs to one sketch and is saved with the design. Centerlines are
|
||||||
|
a line type of their own and keep showing. Projected geometry that carries the construction
|
||||||
|
line type, such as the trace of a plane, answers to **Projected Geometries** instead. The
|
||||||
|
option changes display only. Construction curves were already outside every profile.
|
||||||
|
|
||||||
Polygon tools show their edge outline while positioning the second point, so the orientation
|
Polygon tools show their edge outline while positioning the second point, so the orientation
|
||||||
can be checked before placement. Inscribed and circumscribed polygons retain their support
|
can be checked before placement. Inscribed and circumscribed polygons retain their support
|
||||||
circle and update the outline when the inline **Sides** value changes.
|
circle and update the outline when the inline **Sides** value changes.
|
||||||
|
|||||||
Reference in new issue
Block a user