graphic design tool
git clone https://git.lucas.co/cce-designer.git
refactor: Show Points is retired for Show Point Markers
The two drew the same small sphere on every point of the visible scene,
each with a size and colour of its own. Show Points goes, with Point Size
and Point Color; the Selected-Group markers, which were sized as Point
Size times Group Marker Scale, get Group Marker Size in world units, and
an older file's pair is multiplied out on load.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
CLAUDE.md | 48 ++++++++----
src/app.rs | 238 ++++++++++++++++----------------------------------------
src/command.rs | 1 -
src/dialog.rs | 20 +----
src/main.rs | 167 +++++++++++++--------------------------
src/project.rs | 5 +-
src/shortcut.rs | 1 -
7 files changed, 159 insertions(+), 321 deletions(-)
diff --git a/CLAUDE.md b/CLAUDE.md
index 511a9bd..7e9ef62 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -328,7 +328,8 @@ Where it all went:
the zoom family, Detach Circular Window) were already registry commands.
Three settings that were toggles on those nodes and reachable NOWHERE else
became commands: `toggle_ray_traced_preview`, `toggle_wire_single_color`,
- `toggle_render_points`.
+ and `toggle_render_points` — Show Points, which was retired on
+ 2026-09-29 (see "Display mode" below).
- **The recent-projects list** was the Main node's "Open" dropdown, which
would have left `recent_files` written and read by nothing. It is rows at
the head of the palette's Commands list (`RECENT_ROW_PREFIX`), under the
@@ -2185,8 +2186,8 @@ addressed through `GUIDES_MENU` / `GUIDE_*` so no item slid onto another's
action, while old files carrying `show_cube_enabled` still load), and a
row for each submenu: **Style** (how the geometry is drawn: the
wireframe's switch, thickness and opacity, then the surface's shading,
-opacity and Show Occluded) and **Markers** (what is drawn on it: Show
-Points, Point Size, Group Marker Scale and Pull Arrow Scale; then the
+opacity and Show Occluded) and **Markers** (what is drawn on it: Group
+Marker Size and Pull Arrow Scale; then the
overlays a class at a time — Show Point Markers and its size, Show Point
Numbers, Show Point Normals; Show Primitive Numbers, Show Primitive
Normals; Show Vertex Markers, Show Vertex Numbers, Show Vertex Normals).
@@ -2248,10 +2249,10 @@ half a pixel, the palette row's range), a **Wire Opacity** slider under
that (percent by 5, `State::wire_opacity` — the wires' own, apart from the
polygons' Opacity; until 2026-09-25 it was the Wire Color's ALPHA, and
`StoredRenderSettings` moves an old alpha, from state.kdl's `#rrggbbaa` or
-a project's four-component array, into it on load), a **Point Size** slider (0–0.1
-world units by 0.005, no suffix since the World Unit names them), a
-**Point Marker Size** slider (the palette row's 0.005–0.1), a **Group
-Marker Scale** slider (0.5–4 by 0.05, read "1.25x"), and the
+a project's four-component array, into it on load), a
+**Point Marker Size** slider (the palette row's 0.005–0.1, no suffix since
+the World Unit names the units), a **Group
+Marker Size** slider (0–0.2 world units by 0.005), and the
polygon **Opacity** as a
SLIDER row — cce-ui's `context_menu::MenuSlider` (2026-09-25), set on the
shown menu by `open_viewport_context_menu`. `viewport_menu_slider` is the
@@ -2267,8 +2268,8 @@ MouseInput, and `mouse_wheel` at the top of MouseWheel — where a wheel
anywhere over the open menu is swallowed rather than orbiting the scene.
`drain_viewport_menu_slider` lands a change through
`land_viewport_menu_slider`, which sets the live field and redoes only what
-it feeds: opacity and wire thickness are draw-time, and point size re-bakes
-the Render points (the stage pass's size key) and the Selected-Group
+it feeds: opacity and wire thickness are draw-time, and group marker size
+re-bakes the Selected-Group
markers — re-sized from `State::group_members`, the positions `sync_nodes`
keeps from its evaluation, by `rebuild_group_marker_verts`; point marker
size re-sizes the Show Point Markers overlay from the scene positions
@@ -2276,11 +2277,24 @@ size re-sizes the Show Point Markers overlay from the scene positions
`rebuild_overlay_marker_verts`). None of it
re-evaluates the graph, which `apply_setting`'s regenerate pass would do per
pixel of drag. `sync_nodes` also re-sizes the markers when only the size
-moved (`last_group_marker_size`), so the palette's Point Size and Group
-Marker Scale rows reach them the same way. `viewport_menu_rows`
+moved (`last_group_marker_size`), so the palette's Group
+Marker Size row reaches them the same way. `viewport_menu_rows`
and `run_viewport_menu_action` are split from the open and the click so a
test reads and runs the rows.
+**There is one display of a marker on every point, Show Point Markers**
+(since 2026-09-29). Until then there was a second, **Show Points**
+(`toggle_render_points`, with Point Size and Point Color), which the
+retired Render node had brought: the same small sphere on the same points
+of the same scene, with a size and a colour of its own, differing only in
+following the fill's Opacity. It is gone — the command, the mesh, the three
+settings. The group markers were sized off it, Point Size times Group
+Marker Scale, and have a size of their own now
+(`State::group_marker_size`, world units); `StoredRenderSettings` reads a
+file from before by multiplying the old pair out, and does not read
+`render_points` or `point_color`.
+`an_older_render_block_gives_the_group_markers_their_size` is the test.
+
**Smooth shading is baked, not shaded.** The raster pass flat-shades every
fill in `scene3d.wgsl` from screen-space derivative normals, and cce-ui's
`Vertex3D` carries no normal. The light is fixed in WORLD space, though, so
@@ -2334,7 +2348,7 @@ opaque mesh.
**Every annotation is dimmed by what is in front of it** (since
2026-09-29). Three mechanisms, because there are three kinds of annotation.
-The MARKERS (Render points, Selected-Group markers, Show Point Markers)
+The MARKERS (Selected-Group markers, Show Point Markers)
always were: they draw before the fill and the wires and write depth, so a
nearer translucent face or wire blends over them. The LINE annotations —
the normal whiskers, Visualize's vectors, the pull arrows — drew AFTER the
@@ -2398,7 +2412,7 @@ and the arrowed points are exactly the ones that moved. An arrow's full length,
head included, is the displacement times **Pull Arrow Scale**
(`State::pull_arrow_scale`, default 1 — the true vector; a dialog row and a
viewport-menu slider, 0.25–10x, persisted in the render block beside Group
-Marker Scale). The scale is display only: the sampled pairs are kept
+Marker Size). The scale is display only: the sampled pairs are kept
unscaled on `pull_arrow_pairs`, and `rebuild_pull_arrow_verts` stretches
each arrow from its fixed base, so a slider drag re-evaluates nothing.
@@ -2680,10 +2694,10 @@ would throw the selection to the top. `dialog_settings_rows_name_owners_that_exi
is the backstop, because the failure is silent — a `Field` key no dispatch
arm names reads a default and writes nowhere, so the row draws, takes an
edit and does nothing, which is why that test round-trips every one of them.
-**Group Marker Scale** is the one row added with the collapse: the
-Selected-Group markers' radius as a multiple of Point Size
-(`State::group_marker_scale`, persisted in the render block; 1.25 was the
-hard-coded ratio).
+**Group Marker Size** is the one row added with the collapse: the
+Selected-Group markers' radius in world units
+(`State::group_marker_size`, persisted in the render block; it was a
+multiple of the retired Point Size until 2026-09-29).
**The open project's PATH heads the Commands list**, as a row rather than a
command (`PATH_ROW_ID`): the label is the path, the chord column carries the
diff --git a/src/app.rs b/src/app.rs
index 8ce821b..05c2e74 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -471,15 +471,12 @@ pub enum ViewportMenuAction {
/// and stepped the same 5%: the two are independent, so a translucent
/// fill can carry a solid lattice and the other way round.
WireOpacitySlider,
- /// Point Size in world units, the Render points' radius and (times
- /// Group Marker Scale) the group markers': 0–0.1 like the palette's row.
- PointSizeSlider,
/// Point Marker Size in world units, the Show Point Markers overlay's
/// radius: the palette row's 0.005–0.1.
PointMarkerSizeSlider,
- /// Group Marker Scale, the Selected-Group markers' radius as a multiple
- /// of Point Size: the palette row's 0.5–4.
- GroupMarkerScaleSlider,
+ /// Group Marker Size in world units, the Selected-Group markers'
+ /// radius: the palette row's 0–0.2.
+ GroupMarkerSizeSlider,
/// Pull Arrow Scale, the pull arrows' length as a multiple of the true
/// displacement: the palette row's 0.25–10.
PullArrowScaleSlider,
@@ -1337,13 +1334,12 @@ pub struct RenderSettings {
pub wire_opacity: f32,
pub wire_width: f32,
pub geo_opacity: f32,
- pub render_points: bool,
- pub point_size: f32,
- pub point_color: [f32; 3],
- /// The Selected-Group markers' radius as a multiple of `point_size` —
- /// they draw on the same vertices as the Render points, so the ratio is
- /// what keeps both legible. Hard-coded at 1.25 until 2026-09-24.
- pub group_marker_scale: f32,
+ /// The Selected-Group markers' radius, in world units. Until
+ /// 2026-09-29 it was Point Size times Group Marker Scale, Point Size
+ /// being the radius of the Show Points display, which went that day as
+ /// a double of Show Point Markers; [`StoredRenderSettings`] multiplies
+ /// an old pair out.
+ pub group_marker_size: f32,
/// The pull arrows' length as a multiple of the displacement they show.
/// 1 draws the true vector; a longer arrow is legible when the pull is
/// small beside the model. Display only — the pull itself is untouched.
@@ -1364,7 +1360,10 @@ pub struct RenderSettings {
/// with three components or four. A fourth is the wire opacity as it was
/// stored before `wire_opacity` existed, and becomes it when the file names
/// no `wire_opacity` of its own — dropping it would make every translucent
-/// wireframe opaque on the first load.
+/// wireframe opaque on the first load. The group markers' size is read the
+/// same way: its own key, else the `point_size` x `group_marker_scale` it
+/// was until 2026-09-29. `render_points` and `point_color`, the rest of the
+/// retired Show Points display, are in older files and not read.
#[derive(Deserialize)]
struct StoredRenderSettings {
#[serde(default)]
@@ -1380,13 +1379,11 @@ struct StoredRenderSettings {
#[serde(default = "default_geo_opacity")]
geo_opacity: f32,
#[serde(default)]
- render_points: bool,
- #[serde(default = "default_point_size")]
- point_size: f32,
- #[serde(default = "default_point_color")]
- point_color: [f32; 3],
- #[serde(default = "default_group_marker_scale")]
- group_marker_scale: f32,
+ group_marker_size: Option<f32>,
+ #[serde(default)]
+ point_size: Option<f32>,
+ #[serde(default)]
+ group_marker_scale: Option<f32>,
#[serde(default = "default_pull_arrow_scale")]
pull_arrow_scale: f32,
#[serde(default)]
@@ -1410,10 +1407,10 @@ impl From<StoredRenderSettings> for RenderSettings {
wire_opacity: s.wire_opacity.or(old_alpha).unwrap_or(1.0).clamp(0.0, 1.0),
wire_width: s.wire_width,
geo_opacity: s.geo_opacity,
- render_points: s.render_points,
- point_size: s.point_size,
- point_color: s.point_color,
- group_marker_scale: s.group_marker_scale,
+ group_marker_size: s
+ .group_marker_size
+ .unwrap_or_else(|| s.point_size.unwrap_or(0.02) * s.group_marker_scale.unwrap_or(1.25))
+ .clamp(0.0, GROUP_MARKER_SIZE_MAX),
pull_arrow_scale: s.pull_arrow_scale,
smooth_shading: s.smooth_shading,
show_occluded: s.show_occluded,
@@ -1421,10 +1418,13 @@ impl From<StoredRenderSettings> for RenderSettings {
}
}
-fn default_group_marker_scale() -> f32 {
- 1.25
+fn default_group_marker_size() -> f32 {
+ 0.025
}
+/// The far end of Group Marker Size's range, in world units.
+pub(crate) const GROUP_MARKER_SIZE_MAX: f32 = 0.2;
+
fn default_pull_arrow_scale() -> f32 {
1.0
}
@@ -1441,14 +1441,6 @@ fn default_geo_opacity() -> f32 {
1.0
}
-fn default_point_size() -> f32 {
- 0.02
-}
-
-fn default_point_color() -> [f32; 3] {
- [1.0, 1.0, 1.0]
-}
-
impl Default for RenderSettings {
fn default() -> Self {
Self {
@@ -1458,10 +1450,7 @@ impl Default for RenderSettings {
wire_opacity: 1.0,
wire_width: default_wire_width(),
geo_opacity: default_geo_opacity(),
- render_points: false,
- point_size: default_point_size(),
- point_color: default_point_color(),
- group_marker_scale: default_group_marker_scale(),
+ group_marker_size: default_group_marker_size(),
pull_arrow_scale: default_pull_arrow_scale(),
smooth_shading: false,
show_occluded: false,
@@ -1762,7 +1751,6 @@ impl DesignSettings {
("viewport", "grid_color", 3),
("viewport", "point_marker_color", 3),
("render", "wire_color", 4),
- ("render", "point_color", 3),
];
pub(crate) fn from_kdl_str(content: &str) -> Self {
@@ -1942,8 +1930,6 @@ pub struct SceneMeshes {
pub grid: cce_ui::vk::MeshId,
pub origin: cce_ui::vk::MeshId,
pub pivot: cce_ui::vk::MeshId,
- /// The Render node's point display (one octahedron per distinct vertex).
- pub points: cce_ui::vk::MeshId,
/// Selected-Group membership markers: while a Group node is selected, one
/// marker per vertex it tags, so the selection SHOWS the group.
pub group_points: cce_ui::vk::MeshId,
@@ -2344,15 +2330,9 @@ pub struct State {
/// slider): 1.0 opaque, straight-alpha blended toward the viewport bg.
pub geo_opacity: f32,
pub last_viewport_geo_opacity: f32,
- /// Point display of the node geometry (the Render node's "Render Points"
- /// toggle): one small octahedron per distinct vertex, sized by
- /// "Point Size" and tinted by "Point Color".
- pub render_points: bool,
- pub point_size: f32,
- pub point_color: [f32; 3],
- /// Selected-Group marker radius as a multiple of `point_size` (a
- /// setting row of the dialog; persisted in the render block).
- pub group_marker_scale: f32,
+ /// Selected-Group marker radius in world units (a setting row of the
+ /// dialog and a viewport-menu slider; persisted in the render block).
+ pub group_marker_size: f32,
/// Pull arrow length as a multiple of the true displacement (a setting
/// row of the dialog and a viewport-menu slider; persisted in the render
/// block).
@@ -2376,13 +2356,6 @@ pub struct State {
/// orbit is every frame — and clears it when see-through ends, so the
/// next entry sorts afresh.
pub sorted_fill_key: Option<(u64, bool, [f32; 3])>,
- /// (geometry version, quantized size, color) the points mesh was last
- /// built from; `point_vertex_count` gates the draw.
- pub last_points_key: Option<(u64, i32, [u8; 3])>,
- pub point_vertex_count: u32,
- pub last_viewport_render_points: bool,
- pub last_viewport_point_size: f32,
- pub last_viewport_point_color: [f32; 3],
/// Selected-Group membership markers: marker vertices staged CPU-side by
/// `sync_nodes` whenever the selection is a Group node (empty otherwise),
/// flushed to `meshes.group_points`; `group_point_vertex_count` gates the
@@ -2406,9 +2379,9 @@ pub struct State {
pub pull_arrow_count: u32,
pub last_pull_arrows_key: Option<(String, Vec<(String, String)>, u64)>,
/// The selected Group's member positions, kept from the evaluation so
- /// the markers can be re-SIZED without re-evaluating the node — a point
- /// size or marker scale change (the viewport menu's slider, per motion
- /// of a drag) only rebuilds the spheres (`rebuild_group_marker_verts`).
+ /// the markers can be re-SIZED without re-evaluating the node — a
+ /// marker size change (the viewport menu's slider, per motion of a
+ /// drag) only rebuilds the spheres (`rebuild_group_marker_verts`).
pub group_members: Vec<Vertex3D>,
/// The marker radius `group_point_verts` was built at.
pub last_group_marker_size: f32,
@@ -2662,10 +2635,7 @@ impl State {
wire_opacity: self.wire_opacity,
wire_width: self.wire_width,
geo_opacity: self.geo_opacity,
- render_points: self.render_points,
- point_size: self.point_size,
- point_color: self.point_color,
- group_marker_scale: self.group_marker_scale,
+ group_marker_size: self.group_marker_size,
pull_arrow_scale: self.pull_arrow_scale,
smooth_shading: self.smooth_shading,
show_occluded: self.show_occluded,
@@ -2740,10 +2710,7 @@ impl State {
self.wire_opacity = r.wire_opacity;
self.wire_width = r.wire_width;
self.geo_opacity = r.geo_opacity;
- self.render_points = r.render_points;
- self.point_size = r.point_size;
- self.point_color = r.point_color;
- self.group_marker_scale = r.group_marker_scale;
+ self.group_marker_size = r.group_marker_size;
self.pull_arrow_scale = r.pull_arrow_scale;
self.rebuild_pull_arrow_verts();
self.smooth_shading = r.smooth_shading;
@@ -5160,14 +5127,6 @@ impl State {
// World units, so no suffix — the World Unit declaration is what
// names them, and a readout saying "mm" under a cm declaration
// would be wrong.
- ViewportMenuAction::PointSizeSlider => MenuSlider {
- value: self.point_size.clamp(0.0, 0.1),
- min: 0.0,
- max: 0.1,
- step: 0.005,
- decimals: 3,
- suffix: "",
- },
// The palette row's spin is 5–100 thousandths; the same range in
// world units here, where the readout has room for the decimals.
ViewportMenuAction::PointMarkerSizeSlider => MenuSlider {
@@ -5178,19 +5137,19 @@ impl State {
decimals: 3,
suffix: "",
},
- // A multiple of Point Size, read as one ("1.25x"): a plain x
- // rather than a multiplication sign, which the menu face may not
- // carry and which a fallback glyph would then under-measure.
- ViewportMenuAction::GroupMarkerScaleSlider => MenuSlider {
- value: self.group_marker_scale.clamp(0.5, 4.0),
- min: 0.5,
- max: 4.0,
- step: 0.05,
- decimals: 2,
- suffix: "x",
+ // World units, as the point markers' size is.
+ ViewportMenuAction::GroupMarkerSizeSlider => MenuSlider {
+ value: self.group_marker_size.clamp(0.0, GROUP_MARKER_SIZE_MAX),
+ min: 0.0,
+ max: GROUP_MARKER_SIZE_MAX,
+ step: 0.005,
+ decimals: 3,
+ suffix: "",
},
- // A multiple of the true displacement, read as the group
- // markers' scale is.
+ // A multiple of the true displacement, read as one ("1.25x"): a
+ // plain x rather than a multiplication sign, which the menu face
+ // may not carry and which a fallback glyph would then
+ // under-measure.
ViewportMenuAction::PullArrowScaleSlider => MenuSlider {
value: self.pull_arrow_scale.clamp(0.25, 10.0),
min: 0.25,
@@ -5205,10 +5164,9 @@ impl State {
/// Write a slider row's value onto the live field, and redo only what
/// that value feeds. The opacities and wire thickness are draw-time values (a
- /// uniform, a line width and the fill's matching depth bias). Point
- /// size is baked into two meshes: the Render points re-bake in the stage
- /// pass off their own size key, and the group markers are re-sized here
- /// from their kept members. Point Marker Size re-sizes the overlay from
+ /// uniform, a line width and the fill's matching depth bias). Group
+ /// Marker Size re-sizes the group markers from their kept members,
+ /// Point Marker Size re-sizes the overlay from
/// the scene positions its rebuild kept. None of it re-evaluates the
/// graph.
fn land_viewport_menu_slider(&mut self, action: ViewportMenuAction, v: f32) {
@@ -5217,9 +5175,8 @@ impl State {
ViewportMenuAction::OpacitySlider => ("geo_opacity", v / 100.0),
ViewportMenuAction::WireThicknessSlider => ("wire_width", v),
ViewportMenuAction::WireOpacitySlider => ("wire_opacity", v / 100.0),
- ViewportMenuAction::PointSizeSlider => ("point_size", v),
ViewportMenuAction::PointMarkerSizeSlider => ("point_marker_size", v),
- ViewportMenuAction::GroupMarkerScaleSlider => ("group_marker_scale", v),
+ ViewportMenuAction::GroupMarkerSizeSlider => ("group_marker_size", v),
ViewportMenuAction::PullArrowScaleSlider => ("pull_arrow_scale", v),
_ => return,
};
@@ -5245,16 +5202,12 @@ impl State {
"geo_opacity" => self.geo_opacity = v.clamp(0.0, 1.0),
"wire_width" => self.wire_width = v.clamp(1.0, 8.0),
"wire_opacity" => self.wire_opacity = v.clamp(0.0, 1.0),
- "point_size" => {
- self.point_size = v.clamp(0.0, 0.1);
- self.rebuild_group_marker_verts();
- }
"point_marker_size" => {
self.point_marker_size = v.clamp(0.005, 0.1);
self.rebuild_overlay_marker_verts();
}
- "group_marker_scale" => {
- self.group_marker_scale = v.clamp(0.5, 4.0);
+ "group_marker_size" => {
+ self.group_marker_size = v.clamp(0.0, GROUP_MARKER_SIZE_MAX);
self.rebuild_group_marker_verts();
}
"pull_arrow_scale" => {
@@ -5315,9 +5268,8 @@ impl State {
/// apart: framing; the GUIDES (Show Grid, Show Origin — the scene
/// furniture that is not the geometry); the WIREFRAME (its switch,
/// thickness and opacity); the
- /// POINTS
- /// (the Show Points switch, point size, and the group marker scale that
- /// multiplies it); the OVERLAYS (Show Point Markers and its size, Show
+ /// SELECTION FEEDBACK
+ /// (the group markers' size and the pull arrows' scale); the OVERLAYS (Show Point Markers and its size, Show
/// Point Numbers, Show Point Normals — the annotations drawn over the
/// scene's points); the SURFACE (flat or smooth shading as a radio pair,
/// the polygon opacity, Show Occluded — the three that decide how the
@@ -5384,11 +5336,9 @@ impl State {
return (options, actions);
}
Some(ViewportMenuPage::Markers) => {
- // The Render points, the group markers sized off them, and
- // the pull arrows' length, the other selection feedback.
- toggle(&mut options, &mut actions, "toggle_render_points");
- row(&mut options, &mut actions, "Point Size".into(), ViewportMenuAction::PointSizeSlider);
- row(&mut options, &mut actions, "Group Marker Scale".into(), ViewportMenuAction::GroupMarkerScaleSlider);
+ // The selection feedback: the group markers' size and the
+ // pull arrows' length.
+ row(&mut options, &mut actions, "Group Marker Size".into(), ViewportMenuAction::GroupMarkerSizeSlider);
row(&mut options, &mut actions, "Pull Arrow Scale".into(), ViewportMenuAction::PullArrowScaleSlider);
// The overlays, a class at a time: points, primitives,
@@ -5489,9 +5439,8 @@ impl State {
ViewportMenuAction::OpacitySlider
| ViewportMenuAction::WireThicknessSlider
| ViewportMenuAction::WireOpacitySlider
- | ViewportMenuAction::PointSizeSlider
| ViewportMenuAction::PointMarkerSizeSlider
- | ViewportMenuAction::GroupMarkerScaleSlider
+ | ViewportMenuAction::GroupMarkerSizeSlider
| ViewportMenuAction::PullArrowScaleSlider => {}
ViewportMenuAction::Separator => {}
}
@@ -6164,9 +6113,9 @@ pub(crate) fn geometry_to_spreadsheet_data(geom: &Detail) -> (Vec<String>, Vec<V
self.group_members = members;
self.last_group_points_key = group_key;
self.rebuild_group_marker_verts();
- } else if (self.group_marker_size() - self.last_group_marker_size).abs() > f32::EPSILON {
- // Same members, new size (the palette's Point Size or Group
- // Marker Scale): re-size without re-evaluating.
+ } else if (self.group_marker_size - self.last_group_marker_size).abs() > f32::EPSILON {
+ // Same members, new size (the palette's Group Marker Size):
+ // re-size without re-evaluating.
self.rebuild_group_marker_verts();
}
}
@@ -6241,13 +6190,6 @@ pub(crate) fn geometry_to_spreadsheet_data(geom: &Detail) -> (Vec<String>, Vec<V
self.pull_arrows_dirty = true;
}
- /// The Selected-Group markers' radius: Point Size times Group Marker
- /// Scale, larger than the Render node's points so both stay legible
- /// together.
- pub fn group_marker_size(&self) -> f32 {
- self.point_size * self.group_marker_scale
- }
-
/// Works out how much of each point number shows through the fill, for
/// the eye the stage pass is staging (`eye` in mesh space, the space of
/// the labels and the triangles).
@@ -6305,7 +6247,7 @@ pub(crate) fn geometry_to_spreadsheet_data(geom: &Detail) -> (Vec<String>, Vec<V
}
pub(crate) fn rebuild_group_marker_verts(&mut self) {
- let size = self.group_marker_size();
+ let size = self.group_marker_size;
self.group_point_verts = crate::geometry::points_vertices(
&self.group_members,
size,
@@ -6706,21 +6648,13 @@ pub(crate) fn geometry_to_spreadsheet_data(geom: &Detail) -> (Vec<String>, Vec<V
last_viewport_wire_width: 1.0,
geo_opacity: settings.render.geo_opacity,
last_viewport_geo_opacity: 1.0,
- render_points: settings.render.render_points,
- point_size: settings.render.point_size,
- point_color: settings.render.point_color,
- group_marker_scale: settings.render.group_marker_scale,
+ group_marker_size: settings.render.group_marker_size,
pull_arrow_scale: settings.render.pull_arrow_scale,
pull_arrow_pairs: Vec::new(),
smooth_shading: settings.render.smooth_shading,
show_occluded: settings.render.show_occluded,
sorted_fill_key: None,
scene_smooth_verts: Vec::new(),
- last_points_key: None,
- point_vertex_count: 0,
- last_viewport_render_points: false,
- last_viewport_point_size: 0.0,
- last_viewport_point_color: [0.0, 0.0, 0.0],
group_point_verts: Vec::new(),
group_points_dirty: false,
group_point_vertex_count: 0,
@@ -8402,11 +8336,6 @@ pub(crate) fn geometry_to_spreadsheet_data(geom: &Detail) -> (Vec<String>, Vec<V
self.rebuild_scene_geometry();
settings_changed = true;
}
- Action::ToggleRenderPoints => {
- self.render_points = !self.render_points;
- self.viewport_dirty = true;
- settings_changed = true;
- }
Action::ToggleWireSingleColor => {
self.wire_single_color = !self.wire_single_color;
self.viewport_dirty = true;
@@ -10624,31 +10553,6 @@ pub(crate) fn geometry_to_spreadsheet_data(geom: &Detail) -> (Vec<String>, Vec<V
renderer.update_mesh(meshes.sphere_edges, bytemuck::cast_slice(&self.scene_edge_verts));
}
- // The Render node's point display: rebuilt whenever the geometry or
- // the point params moved (the key), skipped entirely while off.
- if self.render_points {
- let key = (
- self.rt_geometry_version,
- (self.point_size * 1000.0).round() as i32,
- [
- (self.point_color[0] * 255.0).round().clamp(0.0, 255.0) as u8,
- (self.point_color[1] * 255.0).round().clamp(0.0, 255.0) as u8,
- (self.point_color[2] * 255.0).round().clamp(0.0, 255.0) as u8,
- ],
- );
- if self.last_points_key != Some(key) {
- let verts = crate::geometry::points_vertices(
- &self.rt_sphere_verts,
- self.point_size,
- cce_ui::colors::to_linear_rgb(self.point_color),
- );
- self.point_vertex_count = verts.len() as u32;
- renderer.update_mesh(meshes.points, bytemuck::cast_slice(&verts));
- self.last_points_key = Some(key);
- self.viewport_dirty = true;
- }
- }
-
// Selected-Group markers, staged by sync_nodes.
if self.group_points_dirty {
self.group_points_dirty = false;
@@ -10724,7 +10628,6 @@ pub(crate) fn geometry_to_spreadsheet_data(geom: &Detail) -> (Vec<String>, Vec<V
grid: renderer.create_mesh(bytemuck::cast_slice(&grid_verts)),
origin: renderer.create_mesh(bytemuck::cast_slice(&origin_verts)),
pivot: renderer.create_mesh(bytemuck::cast_slice(&pivot_verts)),
- points: renderer.create_mesh(&[]),
group_points: renderer.create_mesh(&[]),
overlay_points: renderer.create_mesh(&[]),
overlay_normals: renderer.create_mesh(&[]),
@@ -10936,10 +10839,7 @@ pub(crate) fn geometry_to_spreadsheet_data(geom: &Detail) -> (Vec<String>, Vec<V
|| self.last_viewport_wire_single_color != self.wire_single_color
|| self.last_viewport_wire_color != self.wire_color
|| self.last_viewport_wire_opacity != self.wire_opacity
- || self.last_viewport_wire_width != self.wire_width
- || self.last_viewport_render_points != self.render_points
- || self.last_viewport_point_size != self.point_size
- || self.last_viewport_point_color != self.point_color;
+ || self.last_viewport_wire_width != self.wire_width;
if viewport_changed {
if !rt_mode {
@@ -11001,9 +10901,6 @@ pub(crate) fn geometry_to_spreadsheet_data(geom: &Detail) -> (Vec<String>, Vec<V
if self.viewport().show_camera_pivot {
draws.push(SceneDraw { mesh: meshes.pivot, mvp: mvp_pivot, wireframe: false, wire_tint: NO_TINT, opacity: 1.0, line_width: 1.0, wire_base_width: 0.0, prelit: false, see_through: false });
}
- if self.render_points && self.point_vertex_count > 0 {
- draws.push(SceneDraw { mesh: meshes.points, mvp, wireframe: false, wire_tint: NO_TINT, opacity: geo_opacity, line_width: 1.0, wire_base_width: 0.0, prelit: false, see_through: false });
- }
// Selected-Group markers: full-opacity selection feedback,
// deliberately outside the Render node's Opacity.
if self.group_point_vertex_count > 0 {
@@ -11114,9 +11011,6 @@ pub(crate) fn geometry_to_spreadsheet_data(geom: &Detail) -> (Vec<String>, Vec<V
self.last_viewport_wire_color = self.wire_color;
self.last_viewport_wire_opacity = self.wire_opacity;
self.last_viewport_wire_width = self.wire_width;
- self.last_viewport_render_points = self.render_points;
- self.last_viewport_point_size = self.point_size;
- self.last_viewport_point_color = self.point_color;
self.last_viewport_rt_mode = rt_mode;
self.viewport_dirty = false;
}
diff --git a/src/command.rs b/src/command.rs
index 5c19447..716c958 100644
--- a/src/command.rs
+++ b/src/command.rs
@@ -217,7 +217,6 @@ pub const COMMANDS: &[Command] = &[
Command { id: "toggle_vertex_markers", label: "Show Vertex Markers", context: Context::Viewport, run: Run::Key(Action::ToggleVertexMarkers), default_chord: None },
Command { id: "toggle_vertex_numbers", label: "Show Vertex Numbers", context: Context::Viewport, run: Run::Key(Action::ToggleVertexNumbers), default_chord: None },
Command { id: "toggle_vertex_normals", label: "Show Vertex Normals", context: Context::Viewport, run: Run::Key(Action::ToggleVertexNormals), default_chord: None },
- Command { id: "toggle_render_points", label: "Show Points", context: Context::Viewport, run: Run::Key(Action::ToggleRenderPoints), default_chord: None },
Command { id: "toggle_wire_single_color", label: "Wireframe Single Color", context: Context::Viewport, run: Run::Key(Action::ToggleWireSingleColor), default_chord: None },
Command { id: "toggle_ray_traced_preview", label: "Ray Traced Preview", context: Context::Viewport, run: Run::Key(Action::ToggleRayTracedPreview), default_chord: None },
Command { id: "toggle_square_viewport", label: "Square Aspect", context: Context::Viewport, run: Run::Key(Action::ToggleSquareViewport), default_chord: Some("Ctrl+a") },
diff --git a/src/dialog.rs b/src/dialog.rs
index 7eae6b9..9d55981 100644
--- a/src/dialog.rs
+++ b/src/dialog.rs
@@ -1297,13 +1297,8 @@ pub const SETTINGS: &[Setting] = &[
// polygons'. It was the wire colour's alpha until 2026-09-25.
Setting::field("Wire Opacity", "wire_opacity", Ctl::Slider { min: 0.0, max: 1.0, dec: 2 }),
Setting::field("Wire Thickness", "wire_width", Ctl::Slider { min: 1.0, max: 8.0, dec: 1 }),
- Setting::field("Point Size", "point_size", Ctl::Slider { min: 0.0, max: 0.1, dec: 3 }),
- Setting::field("Point Color", "point_color", Ctl::Color),
- // The Selected-Group markers, as a multiple of Point Size: they draw
- // beside the Render points on the same vertices, so what matters is
- // how much larger they are — 1.25 was the hard-coded ratio until
- // 2026-09-24.
- Setting::field("Group Marker Scale", "group_marker_scale", Ctl::Slider { min: 0.5, max: 4.0, dec: 2 }),
+ // The Selected-Group markers' radius, in world units.
+ Setting::field("Group Marker Size", "group_marker_size", Ctl::Slider { min: 0.0, max: crate::app::GROUP_MARKER_SIZE_MAX, dec: 3 }),
// The pull arrows' length over the true displacement; 1 is the vector
// as it is.
Setting::field("Pull Arrow Scale", "pull_arrow_scale", Ctl::Slider { min: 0.25, max: 10.0, dec: 2 }),
@@ -1613,7 +1608,6 @@ impl State {
"toggle_vertex_numbers" => self.show_vertex_numbers,
"toggle_vertex_markers" => self.show_vertex_markers,
"toggle_vertex_normals" => self.show_vertex_normals,
- "toggle_render_points" => self.render_points,
"toggle_wire_single_color" => self.wire_single_color,
"toggle_ray_traced_preview" => self.viewport().rt_mode,
"toggle_square_viewport" => self.square_viewport,
@@ -1754,7 +1748,6 @@ impl State {
fn settings_field_bool(&self, key: &str) -> bool {
match key {
"wire_single_color" => self.wire_single_color,
- "render_points" => self.render_points,
_ => false,
}
}
@@ -1763,7 +1756,6 @@ impl State {
match key {
"bg_color" => self.viewport().bg_color,
"grid_color" => self.viewport().grid_color,
- "point_color" => self.point_color,
"point_marker_color" => self.point_marker_color,
"wire_color" => self.wire_color,
_ => [0.0; 3],
@@ -1778,8 +1770,7 @@ impl State {
"wire_width" => self.wire_width,
"geo_opacity" => self.geo_opacity,
"wire_opacity" => self.wire_opacity,
- "point_size" => self.point_size,
- "group_marker_scale" => self.group_marker_scale,
+ "group_marker_size" => self.group_marker_size,
"pull_arrow_scale" => self.pull_arrow_scale,
_ => 0.0,
}
@@ -1805,7 +1796,6 @@ impl State {
let on = value == "true";
match key {
"wire_single_color" => self.wire_single_color = on,
- "render_points" => self.render_points = on,
_ => {}
}
}
@@ -1814,7 +1804,6 @@ impl State {
match key {
"bg_color" => self.viewport_mut().bg_color = c,
"grid_color" => self.viewport_mut().grid_color = c,
- "point_color" => self.point_color = c,
"point_marker_color" => self.point_marker_color = c,
"wire_color" => {
// Setting a wire colour means wanting to see it: the
@@ -1847,8 +1836,7 @@ impl State {
"wire_width" => self.wire_width = v,
"geo_opacity" => self.geo_opacity = v,
"wire_opacity" => self.wire_opacity = v,
- "point_size" => self.point_size = v,
- "group_marker_scale" => self.group_marker_scale = v,
+ "group_marker_size" => self.group_marker_size = v,
"pull_arrow_scale" => {
self.pull_arrow_scale = v;
self.rebuild_pull_arrow_verts();
diff --git a/src/main.rs b/src/main.rs
index 5a62d82..299e9a3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -951,7 +951,6 @@ mod tests {
subnet("render", vec![
p("Show Wireframe", "toggle", "true"),
p("Wire Thickness", "slider", "4.0"),
- p("Point Color", "color", "#00ff00"),
]),
subnet("main", vec![p("Circular Pane", "toggle", "true")]),
],
@@ -981,7 +980,6 @@ mod tests {
assert!((state.grid_thickness - 0.04).abs() < 1e-6);
assert!(state.wireframe);
assert!((state.wire_width - 4.0).abs() < 1e-6);
- assert_eq!(state.point_color[1], 1.0);
assert!(state.circular_network_pane);
// Idempotent: a second pass has nothing to find and changes nothing.
@@ -1646,7 +1644,7 @@ mod tests {
state.geo_opacity = 0.5;
state.grid_thickness = 0.07;
state.world_unit = cce_ui::units::Unit::Cm;
- state.point_color = [0.1, 0.9, 0.2];
+ state.point_marker_color = [0.1, 0.9, 0.2];
state.save_to_file(&dir).expect("save");
assert!(!state.has_unsaved_changes());
@@ -1660,7 +1658,7 @@ mod tests {
state.geo_opacity = 1.0;
state.grid_thickness = 0.03;
state.world_unit = cce_ui::units::Unit::Mm;
- state.point_color = [1.0, 1.0, 1.0];
+ state.point_marker_color = [1.0, 1.0, 1.0];
state.load_from_file(&dir).expect("load");
assert!(!state.viewport().show_grid, "the grid comes back off");
@@ -1669,7 +1667,7 @@ mod tests {
assert!((state.geo_opacity - 0.5).abs() < 1e-6);
assert!((state.grid_thickness - 0.07).abs() < 1e-6);
assert_eq!(state.world_unit, cce_ui::units::Unit::Cm);
- assert_eq!(state.point_color, [0.1, 0.9, 0.2]);
+ assert_eq!(state.point_marker_color, [0.1, 0.9, 0.2]);
assert!(!state.scene_smooth_verts.is_empty(), "the scene was rebuilt smooth");
assert!(!state.has_unsaved_changes(), "a fresh load is clean");
assert_eq!(state.command_toggle_state("toggle_grid"), Some(false), "the palette's switch agrees");
@@ -2088,7 +2086,7 @@ mod tests {
assert_eq!(
groups(Some(P::Markers)),
vec![
- vec![A::Command("toggle_render_points"), A::PointSizeSlider, A::GroupMarkerScaleSlider, A::PullArrowScaleSlider],
+ vec![A::GroupMarkerSizeSlider, A::PullArrowScaleSlider],
vec![
A::Command("toggle_point_markers"),
A::PointMarkerSizeSlider,
@@ -2367,26 +2365,6 @@ mod tests {
assert!(crate::app::DesignSettings::from_kdl_str(&kdl).viewport.show_point_markers, "persisted");
}
- /// Show Points heads the Points group as a switch over the Render
- /// points, marked from the live flag, and the row runs its command.
- #[test]
- fn the_viewport_menu_toggles_show_points() {
- use crate::app::ViewportMenuAction as A;
- let mut state = State::new(false);
- state.render_points = false;
- let row = |state: &State| {
- let (options, actions) = state.viewport_menu_rows_of(state.viewport_menu_page_of(A::Command("toggle_render_points")));
- let i = actions.iter().position(|a| *a == A::Command("toggle_render_points")).expect("a Show Points row");
- options[i].clone()
- };
- assert_eq!(row(&state), "○ Show Points");
- state.run_viewport_menu_action(A::Command("toggle_render_points"));
- assert!(state.render_points);
- assert_eq!(row(&state), "● Show Points");
- let kdl = fs::read_to_string(crate::app::DesignSettings::file_path()).expect("saved");
- assert!(crate::app::DesignSettings::from_kdl_str(&kdl).render.render_points, "persisted");
- }
-
/// Wire Thickness is a slider row right under Show Wireframe, over the
/// palette row's 1–8 px: the wheel steps half a pixel and saves, a press
/// on the band jumps, and the value is the live `wire_width` the wire
@@ -2470,56 +2448,6 @@ mod tests {
context_menu::hide();
}
- /// Point Size is a viewport-menu slider over the palette row's 0–0.1,
- /// and it re-sizes what it feeds without re-evaluating anything: the
- /// Selected-Group markers are rebuilt from their KEPT members at Point
- /// Size x Group Marker Scale on every step.
- #[test]
- fn the_viewport_menu_sets_the_point_size_and_resizes_the_group_markers() {
- use crate::app::ViewportMenuAction as A;
- use crate::window::WindowEvent;
- use cce_ui::widget::{context_menu, MouseScrollDelta};
- let mut state = State::new(false);
- state.point_size = 0.02;
- state.group_marker_scale = 2.0;
- let centre = [0.3f32, 0.4, 0.5];
- state.group_members = vec![crate::geometry::Vertex3D { position: centre, color: [0.0; 3] }];
- state.rebuild_group_marker_verts();
- let radius = |state: &State| {
- state.group_point_verts.iter().map(|v| {
- let d = [v.position[0] - centre[0], v.position[1] - centre[1], v.position[2] - centre[2]];
- (d[0] * d[0] + d[1] * d[1] + d[2] * d[2]).sqrt()
- }).fold(0.0f32, f32::max)
- };
- assert!((radius(&state) - 0.04).abs() < 1e-4, "{}", radius(&state));
-
- state.cursor_x = 300.0;
- state.cursor_y = 200.0;
- state.open_viewport_context_menu();
- let sub_actions = state.open_viewport_submenu_with(A::PointSizeSlider);
- let i = sub_actions.iter().position(|a| *a == A::PointSizeSlider).expect("a Point Size row");
- let sl = context_menu::submenu::slider(i).expect("a slider");
- assert_eq!((sl.min, sl.max, sl.step, sl.decimals), (0.0, 0.1, 0.005, 3));
- assert!((sl.value - 0.02).abs() < 1e-6);
-
- state.cursor_x = context_menu::submenu::x() + 20.0;
- state.cursor_y = context_menu::submenu::row_y(i) + context_menu::ROW_H * 0.5;
- state.handle_event(&WindowEvent::MouseWheel { delta: MouseScrollDelta::LineDelta(0.0, 2.0) });
- assert!((state.point_size - 0.03).abs() < 1e-5, "{}", state.point_size);
- assert!((radius(&state) - 0.06).abs() < 1e-4, "the markers re-sized: {}", radius(&state));
- assert!(state.group_points_dirty, "and will re-upload");
- let kdl = fs::read_to_string(crate::app::DesignSettings::file_path()).expect("saved");
- let saved = crate::app::DesignSettings::from_kdl_str(&kdl).render.point_size;
- assert!((saved - 0.03).abs() < 1e-6, "persisted: {saved}");
-
- // A size change arriving another way (the palette's Group Marker
- // Scale) re-sizes too, through sync_nodes' size check.
- context_menu::hide();
- state.group_marker_scale = 1.0;
- state.sync_nodes();
- assert!((radius(&state) - 0.03).abs() < 1e-4, "{}", radius(&state));
- }
-
/// Point Marker Size is a viewport-menu slider over the palette row's
/// 0.005–0.1, and it re-sizes the Show Point Markers overlay from the
/// scene positions the last rebuild kept — landing on exactly what a full
@@ -2567,7 +2495,7 @@ mod tests {
/// Pull Arrow Scale stretches the pull arrows along the pull from their
/// kept pairs, base fixed — 1 by default, the true vector — and is a
- /// viewport-menu slider under Group Marker Scale.
+ /// viewport-menu slider under Group Marker Size.
#[test]
fn pull_arrow_scale_stretches_the_arrows_from_their_base() {
use crate::app::ViewportMenuAction as A;
@@ -2606,17 +2534,16 @@ mod tests {
context_menu::hide();
}
- /// Group Marker Scale is a viewport-menu slider over the palette row's
- /// 0.5–4, re-sizing the Selected-Group markers from their kept members
- /// at Point Size x the scale — no re-evaluation of the Group node.
+ /// Group Marker Size is a viewport-menu slider over the palette row's
+ /// 0–0.2 world units, re-sizing the Selected-Group markers from their
+ /// kept members — no re-evaluation of the Group node.
#[test]
- fn the_viewport_menu_sets_the_group_marker_scale() {
+ fn the_viewport_menu_sets_the_group_marker_size() {
use crate::app::ViewportMenuAction as A;
use crate::window::WindowEvent;
use cce_ui::widget::{context_menu, MouseScrollDelta};
let mut state = State::new(false);
- state.point_size = 0.02;
- state.group_marker_scale = 1.25;
+ state.group_marker_size = 0.025;
let centre = [0.0f32, 1.0, 0.0];
state.group_members = vec![crate::geometry::Vertex3D { position: centre, color: [0.0; 3] }];
state.rebuild_group_marker_verts();
@@ -2628,22 +2555,45 @@ mod tests {
state.cursor_x = 300.0;
state.cursor_y = 200.0;
state.open_viewport_context_menu();
- let sub_actions = state.open_viewport_submenu_with(A::GroupMarkerScaleSlider);
- let i = sub_actions.iter().position(|a| *a == A::GroupMarkerScaleSlider).expect("a Group Marker Scale row");
- assert_eq!(sub_actions[i - 1], A::PointSizeSlider, "it sits under the size it multiplies");
+ let sub_actions = state.open_viewport_submenu_with(A::GroupMarkerSizeSlider);
+ let i = sub_actions.iter().position(|a| *a == A::GroupMarkerSizeSlider).expect("a Group Marker Size row");
let sl = context_menu::submenu::slider(i).expect("a slider");
- assert_eq!((sl.min, sl.max, sl.step, sl.suffix), (0.5, 4.0, 0.05, "x"));
- assert_eq!(sl.readout(), "1.25x");
+ assert_eq!((sl.min, sl.max, sl.step, sl.decimals), (0.0, 0.2, 0.005, 3));
+ assert!((sl.value - 0.025).abs() < 1e-6);
state.cursor_x = context_menu::submenu::x() + 20.0;
state.cursor_y = context_menu::submenu::row_y(i) + context_menu::ROW_H * 0.5;
- state.handle_event(&WindowEvent::MouseWheel { delta: MouseScrollDelta::LineDelta(0.0, 15.0) });
- assert!((state.group_marker_scale - 2.0).abs() < 1e-5, "{}", state.group_marker_scale);
+ state.handle_event(&WindowEvent::MouseWheel { delta: MouseScrollDelta::LineDelta(0.0, 3.0) });
+ assert!((state.group_marker_size - 0.04).abs() < 1e-5, "{}", state.group_marker_size);
assert!((radius(&state) - 0.04).abs() < 1e-5, "the markers re-sized: {}", radius(&state));
+ assert!(state.group_points_dirty, "and will re-upload");
let kdl = fs::read_to_string(crate::app::DesignSettings::file_path()).expect("saved");
- let saved = crate::app::DesignSettings::from_kdl_str(&kdl).render.group_marker_scale;
- assert!((saved - 2.0).abs() < 1e-5, "persisted: {saved}");
+ let saved = crate::app::DesignSettings::from_kdl_str(&kdl).render.group_marker_size;
+ assert!((saved - 0.04).abs() < 1e-5, "persisted: {saved}");
+
+ // A size change arriving another way re-sizes too, through
+ // sync_nodes' size check.
context_menu::hide();
+ state.group_marker_size = 0.03;
+ state.sync_nodes();
+ assert!((radius(&state) - 0.03).abs() < 1e-5, "{}", radius(&state));
+ }
+
+ /// Show Points, the second display of a marker on every point, is
+ /// retired for Show Point Markers, and the group markers' size is a
+ /// setting of its own. A file from before carries the old keys: the
+ /// size is the old pair multiplied out, and the rest is not read.
+ #[test]
+ fn an_older_render_block_gives_the_group_markers_their_size() {
+ assert!(crate::command::by_id("toggle_render_points").is_none());
+ let old = "render {\n render_points (bool)true\n point_size (f64)0.04\n point_color (rgb)\"#00ff00\"\n group_marker_scale (f64)2.0\n}\n";
+ let read = crate::app::DesignSettings::from_kdl_str(old).render;
+ assert!((read.group_marker_size - 0.08).abs() < 1e-6, "{}", read.group_marker_size);
+ let new = "render {\n point_size (f64)0.04\n group_marker_size (f64)0.01\n}\n";
+ let read = crate::app::DesignSettings::from_kdl_str(new).render;
+ assert!((read.group_marker_size - 0.01).abs() < 1e-6, "its own key wins: {}", read.group_marker_size);
+ let none = crate::app::DesignSettings::from_kdl_str("render {\n wireframe (bool)true\n}\n").render;
+ assert!((none.group_marker_size - 0.025).abs() < 1e-6, "{}", none.group_marker_size);
}
/// The dialog plate IS the menu plate: its fill is `Material::menu`'s
@@ -6440,10 +6390,7 @@ mod tests {
a.wire_opacity = 0.5;
a.wire_width = 3.0;
a.geo_opacity = 0.75;
- a.render_points = true;
- a.point_size = 0.05;
- a.point_color = [0.0, 1.0, 0.0];
- a.group_marker_scale = 2.5;
+ a.group_marker_size = 0.125;
a.pull_arrow_scale = 4.0;
a.smooth_shading = true;
a.show_occluded = true;
@@ -6466,7 +6413,6 @@ mod tests {
(back.viewport.bg_color, [0.1, 0.2, 0.3]),
(back.viewport.grid_color, [0.4, 0.5, 0.6]),
(back.viewport.point_marker_color, [1.0, 0.5, 0.0]),
- (back.render.point_color, [0.0, 1.0, 0.0]),
] {
for k in 0..3 {
assert!(close(got[k], want[k]), "colour {got:?} came back as {want:?}");
@@ -6479,9 +6425,7 @@ mod tests {
assert!(close(back.render.wire_opacity, 0.5));
assert!(close(back.render.wire_width, 3.0));
assert!(close(back.render.geo_opacity, 0.75));
- assert!(back.render.render_points);
- assert!(close(back.render.point_size, 0.05));
- assert!(close(back.render.group_marker_scale, 2.5));
+ assert!((back.render.group_marker_size - 0.125).abs() < 1e-4);
assert!(close(back.render.pull_arrow_scale, 4.0));
assert!(back.render.smooth_shading);
assert!(back.render.show_occluded);
@@ -12417,10 +12361,11 @@ mod tests {
assert!((state.geo_opacity - 1.0).abs() < 1e-6, "clamped");
assert_eq!(state.rt_geometry_version, version);
- // Point Size re-sizes the group markers from their kept members.
- state.land_dialog_slider(&setting_row_id("Point Size"), 0.05);
- assert!((state.point_size - 0.05).abs() < 1e-6);
- assert!((state.last_group_marker_size - state.group_marker_size()).abs() < 1e-6);
+ // Group Marker Size re-sizes the group markers from their kept
+ // members.
+ state.land_dialog_slider(&setting_row_id("Group Marker Size"), 0.05);
+ assert!((state.group_marker_size - 0.05).abs() < 1e-6);
+ assert!((state.last_group_marker_size - 0.05).abs() < 1e-6);
assert_eq!(state.rt_geometry_version, version);
// The spin rows land the same way: a whole number over the row's
@@ -12538,7 +12483,7 @@ mod tests {
assert!(matches!(control("Grid Thickness"), Some(Control::Slider { dec: 0, .. })), "a spin is a whole-number slider");
assert!(matches!(control("Geometry Opacity"), Some(Control::Slider { dec: 2, .. })));
assert!(matches!(control("World Unit"), Some(Control::Choice { .. })));
- assert!(matches!(control("Group Marker Scale"), Some(Control::Slider { .. })));
+ assert!(matches!(control("Group Marker Size"), Some(Control::Slider { .. })));
// A command's switch is its own row; the settings table lists none
// of them twice.
assert!(control("Show Grid").is_none());
@@ -12597,13 +12542,13 @@ mod tests {
assert_ne!(state.world_unit, before, "Enter steps a choice too");
assert!(state.dialog_visible(), "and keeps the dialog up");
- let scale_row = state.slots.dialog.rows.iter().position(|r| r.id == setting_row_id("Group Marker Scale")).unwrap();
+ let scale_row = state.slots.dialog.rows.iter().position(|r| r.id == setting_row_id("Group Marker Size")).unwrap();
state.slots.dialog.selected = scale_row;
- let before = state.group_marker_scale;
+ let before = state.group_marker_size;
state.dialog_key_input(&key_press(Key::Named(NamedKey::ArrowRight)));
- assert!(state.group_marker_scale > before, "right arrow grows the markers");
+ assert!(state.group_marker_size > before, "right arrow grows the markers");
state.dialog_key_input(&key_press(Key::Named(NamedKey::ArrowLeft)));
- assert!((state.group_marker_scale - before).abs() < 1e-5, "left arrow shrinks them back");
+ assert!((state.group_marker_size - before).abs() < 1e-5, "left arrow shrinks them back");
// And it survives an unrelated parameter edit, which is the whole
// reason the subnets had to be the owner before.
@@ -12675,7 +12620,7 @@ mod tests {
"Grid Color", "Grid Thickness", "Origin Size", "Point Marker Size",
"Point Marker Color", "World Unit",
// render
- "Wireframe Color", "Wire Opacity", "Wire Thickness", "Geometry Opacity", "Point Size", "Point Color",
+ "Wireframe Color", "Wire Opacity", "Wire Thickness", "Geometry Opacity",
// main
"Background Color",
// camera
@@ -12686,7 +12631,7 @@ mod tests {
let mut state = State::new(false);
for id in [
"toggle_grid", "toggle_origin", "toggle_wireframe",
- "toggle_wire_single_color", "toggle_render_points", "toggle_ray_traced_preview",
+ "toggle_wire_single_color", "toggle_ray_traced_preview",
"toggle_circular_pane", "toggle_camera_pivot", "toggle_square_viewport",
"toggle_network_plate",
] {
diff --git a/src/project.rs b/src/project.rs
index ad96dea..28bd916 100644
--- a/src/project.rs
+++ b/src/project.rs
@@ -784,9 +784,8 @@ impl State {
},
"Wire Thickness" => if let Some(v) = as_f32(&p) { self.wire_width = v.clamp(1.0, 8.0); },
"Opacity" => if let Some(v) = as_f32(&p) { self.geo_opacity = v.clamp(0.0, 1.0); },
- "Render Points" => if let Some(v) = as_bool(&p) { self.render_points = v; },
- "Point Size" => if let Some(v) = as_f32(&p) { self.point_size = v.clamp(0.0, 0.1); },
- "Point Color" => if let Some(c) = hex_to_color(p.text()) { self.point_color = c; },
+ // Render Points, Point Size and Point Color were the Show
+ // Points display, retired as a double of Show Point Markers.
_ => {}
}
}
diff --git a/src/shortcut.rs b/src/shortcut.rs
index 3e82278..349534b 100644
--- a/src/shortcut.rs
+++ b/src/shortcut.rs
@@ -39,7 +39,6 @@ pub enum Action {
/// commands, which is what makes them reachable at all.
ToggleRayTracedPreview,
ToggleWireSingleColor,
- ToggleRenderPoints,
ToggleCircularPane,
DetachCircularWindow,
Save,