Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
7.8 KiB
name, description
| name | description |
|---|---|
| fieldcraft-meshing | Agentic hex meshing (AHM) in FieldCraft — look at the part, use its symmetry, plan the blocks, mesh, mark and fix the bad elements, and show sections an analyst would accept. Use before any mesh.* command on a part that matters, and whenever a mesh comes back with fans, slivers or a low scaled Jacobian. |
Agentic hex meshing (AHM)
Mesh like an analyst: look first, plan the blocks, then call a mesher. A mesh is judged by its worst elements, not its count. A fast mesh with fans, slivers or collapsed corners is a failed mesh, even when every element is valid.
The loop: look → symmetry → plan → inspect the plan → apply → quality + mark → relax → section pictures → report. Never skip a step because the last mesh looked fine.
1. Look before you mesh
inspect_model/geometry.bodies: bodies, volumes, bounding boxes, faces, holes, fillets. For a.solidcraftdesign alsogeometry.features {"body"}: how each body was built (profiles, extrude directions, holes, shells, fillets, patterns, mirrors).geometry.check {"body", "size"}at the size you intend: short edges, small and sliver faces, near faces (gaps, overlaps, walls thinner than the gap). Each finding names its faces and a pointat, and is marked in pictures. Defeature or resize before meshing; never mesh over a finding you have not explained.- Take pictures. Headless:
fieldcraft-cli snapshot script.json --out a.pngwith--view iso|front|top|…or--camera '{"yaw":-45,"pitch":30,"target":[x,y,z],"fit":true}', and--section x|y|z[=VALUE]. Over MCP:screenshot {view | camera: {yaw, pitch, target, distance | fit}, section}. Aimtargetat the feature you are judging (a boss, a corner), not the model's centre. Read every PNG. Name, in words, what the part is. - Primary vs secondary features. Primary (walls, bosses, the load path, thin directions, the sweep direction) set the block topology. Secondary (small fillets, chamfers, logos, small holes far from the region of interest) fit into it or are defeatured; they never drive it.
2. Symmetry first
Test symmetry geometrically (mirror the bounding box and the key faces). If the part and its
loads are symmetric, mesh one half or quarter and mirror the mesh: mesh.mirror {"plane": <datum plane> | {point, normal}}. Nodes on the plane are merged, so the result is conforming. Never mesh
a symmetric part whole. If the halves come out unequal (one corner good, its mirror image bad),
keep the good half and mirror it.
mesh.plan refuses a partitioned body and its cells today (#473): for a half, mesh the cell with
mesh.cells or mesh.hex.project, then mirror.
3. Plan, then inspect the plan
mesh.plan {"body", "size"?, "layers"?}: the block plan from the features. Nothing is meshed.- Read the plan before applying it:
mesher:project(one block topology over the body: O-grid rings round circles, blend layers along fillets, chamfers and shell walls) is the target;cells/sweepis the fallback.rings: centre, radius, frame half-side. Frames should be near square with even margins.cuts: each with its feature and reason.notes: why the body did not fit the projection layout.pending(rings left boxed) andunmapped(features with no template: revolves, sweeps, lofts).sizeandlayersagainst the thinnest wall (§5). Fix what is wrong by editing the plan object and applying the edit.
mesh.plan.apply {"plan": "Plan-<body>" | edited object}. Readskipped_cuts,all_hex,conforming,min_scaled_jacobian,layout,blend_layers. A skipped cut is a defect to explain.- When the plan does not fit, mesh regions by hand and keep the plan's cuts that work:
geometry.partition+mesh.cells;mesh.hex.generate/mesh.hex.sweep/mesh.hex.mapped;mesh.hex.extrudefor a section carried to a curved or tilted end (source,to_surface,sides);mesh.hex.projectfor a block topology projected on the part (templatesphereorbutterfly, opso_grid,split,extrude,connect;preview: truelists block indices). Tet (tet10for stress) only for cells not worth blocking, far from the region of interest.
Shapes without a timeline (STEP, 3MF) skip mesh.plan and go to step 4.
4. Block rules
- No sharp corners. Every element corner near 90°. Where a block corner is far from 90°, cut differently or add an O-grid.
- No skewed, tapered or long thin cells. Check every cell a cut makes; a wedge, sliver or strip means the cut is wrong.
- O-grid round every hole, boss, cylinder and fillet: a square round the curve and a ring between, element lines radial, square corners at 45° on the curve. Never fan into a hole or pinch at a tangency.
- Never cut on an existing face. A coincident cut leaves slivers, and one the kernel can only
make by nudging off the plane is refused (
geometry.partition). Offset the cut one element out of the feature. Never cut through the axis of a small hole. - Parity at corners. Division counts must close round every block loop. Where a corner comes
out bad and its mirror image is good, change the count by one on the edges leading into it
(
mesh.seed.edge) first. - Pattern a good corner. When identical features (four corner bosses) mesh unequally, the
good one is the template: mirror it onto the others (
mesh.mirror) instead of accepting the worst. - Accept a wedge column where the layout forces one node to absorb a corner: one column of
wedge6is better than a column of skewed hex. State it in the report. - Keep cuts consistent across touching bodies so the meshes match, or tie them
(
interaction.tie).
5. Size and walls
- Through a thin wall: at least 2 elements for bending (3 for stress in the wall), 1 only for
pure conduction. Set
layersinmesh.plan, ormesh.seed.edgeacross the wall. - Matching counts on shared edges:
mesh.seed.edge. - Size from the physics: finer at stress gradients, fillets and contact; in explicit, from the wave length.
6. Quality, mark, relax
mesh.quality: all valid; volume equal to the geometry's (a mismatch means missing or orphan cells).mesh.quality.mark {"limits": {"scaled_jacobian": 0.3, "edge_ratio": 10}}: failing elements become the setquality_marked, drawn red in pictures, each withlabel,at,failed. Acceptance limits:- scaled Jacobian ≥ 0.3 everywhere, ≥ 0.5 in the region of interest;
- edge ratio and aspect ratio ≤ 10;
- face angles 15°–165°, dihedrals 10°–165° (the defaults).
- Picture the marked elements (camera
targetat theirat, asectionthrough them). Clustered marks mean the blocks are wrong: back to §3/§4. Isolated spikes only:mesh.node.relax {"around_element": <label>}for each marked element (by CAD face once #471 lands; sets are for the analysis steps, not for relaxing). Surface nodes slide on their faces; nothing inverts. Add"reapply": trueso it follows a remesh. Relaxing is the final touch, never a substitute for a better plan. - Mark again until nothing is marked, or every remaining mark has a stated reason.
mesh.check.duplicates: no cracks or free edges inside a body.- Section pictures through every primary feature: fans, pinches, wedges, slivers or zigzag lines → back to §3.
- After solving, refine once and compare the quantity of interest (convergence).
7. Report
State: symmetry used, primary features, the plan's mesher, every cut and skipped cut with its reason, method per region, element counts, min scaled Jacobian, max edge ratio, marked count, what was relaxed, any wedge column, anything defeatured, and the section pictures. If the plan failed, name the rule that failed and the next thing you will try. Never silently fall back to a worse mesh.