engine: a form for Projection Blocking (mesh.hex.project)

every_command_has_a_form failed on develop since #399.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
This commit is contained in:
jyvikoandClaude Opus 5.5 authored and Irakli Kourtis committed 2026-10-15 16:37:07 -04:00
1 parent d781d6e427
commit 62fc00755a
2 files changed
+29 -1

No files matched your search

+28
View File
@@ -1129,6 +1129,34 @@ pub const CELLS: &[Field] = &[
TOLERANCE,
];
pub const HEX_PROJECT: &[Field] = &[
reference("body", "Body", C::Body).help("The body to mesh with a projected block topology.").req(),
HEX_SIZE,
choice(
"template",
"Template",
&[("grid", "Block grid (carve)"), ("sphere", "Sphere (7 blocks)"), ("butterfly", "Butterfly (5-block disc, extruded)"), ("blocks", "Blocks (given vertices)")],
)
.help("The block topology projected onto the body: a grid of blocks you may carve, the seven-block sphere, the five-block butterfly for round sections, or blocks you list.")
.def("\"grid\""),
xyz("center", "Centre", POINT).help("Sphere or butterfly centre.").hint("from the body's bounding box"),
positive("radius", "Radius", D::Millimetre).help("Sphere or butterfly radius.").hint("from the body"),
xyz("axis", "Axis", D::None).help("Butterfly axis direction.").hint("0, 0, 1"),
range("inset", "Inset", D::None, 0.05, 0.95).help("Inner square or cube corner at this fraction of the radius.").def("0.55"),
json("grid", "Grid").help("The block grid: planes per axis or a cell count, and blocks to carve away, as JSON.").hint(r#"{"cells": [ni, nj, nk], "carve": [{"i": [a, b], "j": [c, d], "k": [e, f]}]}"#),
json("blocks", "Blocks").help("Template Blocks: vertices and hex8 blocks, as JSON.").hint(r#"{"vertices": [[x, y, z], ...], "blocks": [[v1..v8], ...]}"#),
json("operations", "Operations").help("O-grids, extrusions, connections, removals and merges applied in order, as JSON.").hint(r#"[{"op": "o_grid", "block": 0, "open": ["+z"]}]"#),
json("faces", "Face targets").help("Block faces sent to chosen B-rep faces; other outer faces go to the nearest surfaces.").hint(r#"[{"block": 0, "face": "+x", "to": ["F1:+x"]}]"#),
json("divisions", "Divisions").help("Element counts per block direction.").hint(r#"[{"block": 0, "direction": 1, "count": 8}]"#),
choice("smoothing", "Smoothing", &[("elliptic", "Elliptic"), ("elliptic-controlled", "Elliptic, controlled (Thomas–Middlecoff)"), ("laplace", "Laplace"), ("none", "None")])
.help("How interior nodes are smoothed after projection, with the boundary held on the geometry.")
.def("\"elliptic\""),
int("iterations", "Iterations", 1, 100_000).help("Smoothing iterations.").def("100"),
range("min_quality", "Minimum quality", D::None, 0.0, 1.0).help("Smallest scaled Jacobian accepted.").def("0.2"),
flag("preview", "Preview only").help("Return the block topology without meshing."),
TOLERANCE,
];
pub const CLEAR_MESH: &[Field] = &[references("bodies", "Bodies", C::Body)
.help("The bodies whose meshes go. When none is ticked: the meshes of bodies the open design no longer has because its partitions changed (model.check lists them).")
.hint("the bodies partitions removed")];
+1 -1
View File
@@ -21,7 +21,7 @@ pub const HEX_PROJECT: CommandSpec = CommandSpec {
id: "mesh.hex.project",
label: "Projection Blocking",
params: r#"{"body": "Body1", "size": 2.0 (element size, mm; default 1/25 of the body's diagonal), "template": "grid" (default) | "sphere" | "butterfly" | "blocks", "center": [x, y, z], "radius": r, "axis": [0, 0, 1], "levels": [z0, z1, …] (sphere and butterfly: default from the body's bounding box; butterfly levels are distances along the axis from the centre), "inset": 0.55 (inner square or cube corner at this fraction of the radius), "grid": {"planes": {"x": [...], "y": [...], "z": [...]} or "cells": [ni, nj, nk] (even planes over the bounding box, default [1, 1, 1]), "carve": [{"i": [a, b], "j": [c, d], "k": [e, f]}] (block index ranges, inclusive, removed)}, "blocks": {"vertices": [[x, y, z], ...], "blocks": [[v1..v8], ...] (0-based vertices, hex8 order)}, "operations": [{"op": "o_grid", "block": b, "open": [faces], "inset": 0.5 or [i1, i2, i3], "extrude": {"offset": [dx, dy, dz], "layers": 1, "faces": "all" (the open face's butterfly: a round branch) | "inner" (its inner face: a square stub)}} | {"op": "extrude", "faces": [[block, face], ...], "offset": [dx, dy, dz], "layers": 1} | {"op": "connect", "from": [block, face], "to": [block, face], "layers": 1} (blocks bridging two faces: closes a handle) | {"op": "remove", "blocks": [...]} (carve; later blocks renumber) | {"op": "merge", "distance": d}] (applied in order; blocks are 0-based, new blocks appended, the O-grid's inner block keeping the old index; a face is its hex8 number 1-6 or the direction it faces, "+x" … "-z"), "preview": true (return the topology without meshing), "faces": [{"block": b, "face": 1-6, "to": ["face names"]}] (targets set by hand; other outer block faces go to the smooth group of B-rep faces nearest them), "divisions": [{"block": b, "direction": 1|2|3, "count": n}], "smoothing": "elliptic" (default) | "elliptic-controlled" (Thomas–Middlecoff) | "laplace" | "none", "iterations": 100, "min_quality": 0.2 (smallest scaled Jacobian accepted), "merge": distance (join nodes of other bodies' meshes within it; default 1e-6 of the diagonal, 0 never), "tolerance": chordal tolerance of the tessellation} — replaces the body's mesh with an all-hex mesh of the block topology: outer block faces projected onto their B-rep faces, edges between faces with different targets onto the curve where those meet (tangent-plane iteration), vertices on three onto their point, nodes placed by transfinite interpolation and smoothed with the boundary held on the geometry. Elements are tagged with the body and boundary faces with their B-rep faces. Reports blocks, divisions, targets and quality before and after smoothing; a corner that flattens on a curved face is an error that says to use an O-grid or template there"#,
form: None,
form: Some(super::forms::HEX_PROJECT),
kind: CommandKind::Model,
requires: &[Requirement::Geometry],
run: hex_project,