Settings¶
Hardcraft keeps one settings registry: config.KNOBS. It drives
both the settings.json store and the generated Preferences
widgets, so this table is the whole tunable surface.
- Widget — the property's name. Only the fill switches are
drawn anywhere (the N-panel's Fill options); everything else,
named or dashed, is
settings.json-only calibration — deliberately not surfaced. - Default — the value shipped in
config.py. - Overrides live in
<blender config>/hardcraft/settings.json; Reset all in the N-panel restores every default.
| Setting | Widget | Default | Range | What it does |
|---|---|---|---|---|
COMMIT_WELD_FRACCommit weld |
commit_weld_frac |
0.001 |
0 … 0.05 | FINAL COMMIT seam-weld distance as a fraction of mesh scale — higher fuses looser CAD doubles, too high collapses features |
MERGE_DIST_FRACLive merge |
merge_dist_frac |
0 |
0 … 0.05 | Per-fill merge-by-distance in the combined mesh (0 = off; the session keeps patches as separate coincident islands) |
AUTO_SYM_SHARE_MINAuto-sym share |
auto_sym_share_min |
0.3 |
0 … 1 | Auto-sym twin verdict: SANITY FLOOR on the per-direction mirror-vote share (reciprocity + area parity are the judges) — honest twins in dense clusters of small islands legitimately score low (~0.32) |
AUTO_SYM_AREA_TOLAuto-sym area tol |
auto_sym_area_tol |
0.02 |
0 … 0.5 | Auto-sym twin verdict: max relative area mismatch of a pair (a mirror is an isometry — true twins match almost exactly) |
AUTO_SYM_SHAPE_TOLAuto-sym shape tol |
auto_sym_shape_tol |
0.005 |
0 … 0.2 | Auto-sym twin verdict: how far the mirrored patch may sit from its twin's surface (p90, as a fraction of the patch's own size) — catches a pair whose areas match while the boundary wanders |
SELECT_SIMILAR_STRIP_RATIOSimilar strip ratio |
select_similar_strip_ratio |
0.5 |
0 … 1 | Select Similar shape split: normal-cloud anisotropy λ1/λ0 below which a curved island counts as an open strip (fillet band) rather than a wrapping wall (bore/boss) — 90° band ≈ 0.22, 180°+ ≈ 1.0 |
NEW_CUT_SPANSNew split spans |
gen_new_cut_spans |
4 |
1 … 64 | Span count a freshly placed split starts at (the span counter) |
SPLIT_SNAP_PXSplit snap px |
split_snap_px |
14 |
2 … 60 | Ctrl end-snap grab radius for a split end, in screen pixels — a chord end within this of a boundary span vertex glues to it (the sticky release radius is 1.5x) |
TRACKPAD_WHEEL_STEP_PXTrackpad wheel step |
trackpad_wheel_step_px |
40 |
-200 … 200 | Magic Mouse / trackpad: smooth-scroll pixels per one discrete step of the Shift/Ctrl wheel tweaks (curve span / contour, split span / angle). Negative flips the scroll direction, 0 disables |
MAX_SPAN_LEN_FRACSpan length frac |
gen_max_span_len |
0.04 |
0.005 … 0.5 | Arc-length per span as a fraction of mesh scale — the primary density driver (lower = denser). Legacy caps; superseded by the Silhouette span law when that is on |
SPAN_SILHOUETTE_LAWSilhouette span law |
span_silhouette_law |
on |
— | Universal span law: an arc's span = the count that holds its silhouette to 'Silhouette tol' (ABSOLUTE), floored — small arcs few, large arcs silhouette-dense, independent of model size. Replaces the curvature/scale caps. Re-fill to see it |
SILHOUETTE_TOLSilhouette tol |
silhouette_tol |
0.05 |
0.01 … 2 | Max deviation of a span chord from the true arc, in UNITS (unit-abstract: 0.05 default; a Plasticity-bridge mesh reads it as 0.05 mm) — the Silhouette-span-law knob; lower = denser / tighter silhouette |
MIN_LOOP_SPANSMin loop spans |
gen_min_loop_spans |
8 |
3 … 64 | Minimum spans on a closed-loop arc (a hole / full circle) |
STRAIGHT_LEN_SUBDIV_FACTORStraight subdiv |
gen_straight_subdiv |
0 |
0 … 10 | Subdivide a flat straight longer than this * span-length (0 = OFF, default — straights stay 1 span). Turn on (e.g. 2.0) only if long straights sliver the fill on holed / concave flat faces |
SURFACE_STEP_FRACSurface step |
gen_surface_step |
2 |
0.1 … 10 | Coarse-tri surface Steiner spacing (lower = denser tri/quad soup) |
SURFACE_RECOMBINERecombine → quads |
surface_recombine |
on |
— | Coarse-tri surface fill: merge the regular interior grid triangles into real QUADS (quad interior + tri border) instead of an all-triangle grid. Boundary stays verbatim (weld-safe); affects only coarse-tri patches. Re-fill to see it |
RECOMBINE_MATCHINGRecombine: global matching |
recombine_matching |
off |
— | Recombine the leftover triangles by a GLOBAL optimum (Blossom maximum-weight matching) instead of the greedy pass, whose result depends on the order faces are visited — the corners lose quads and orphan triangles get smeared. Same quality gates decide which pairs may merge; unmatched tris stay tris. Re-fill to see it |
RECOMBINE_FACE_ANGLE_DEGRecombine face angle |
recombine_face_angle |
40 |
0 … 89 | Max angle between two triangles' normals for the recombine to merge them into a quad (deg): the coplanarity gate, judged together with the shape angle below |
RECOMBINE_SHAPE_ANGLE_DEGRecombine shape angle |
recombine_shape_angle |
60 |
0 … 89 | Quad-shape tolerance for the recombine (deg): higher merges more pairs into quads but allows more skewed quads; lower keeps only near-square merges |
INTERIOR_LOCAL_DENSITYLocal density (spans) |
interior_local_density |
on |
— | Interior fill density follows the LOCAL boundary spans (graded lattice seeding, matched 1:1) instead of one median-based step — coarse boundary nearby gives a coarse interior, dense gives dense, and neighbours agree at shared seams. Re-fill to see it |
LATTICE_CONSTRAIN_EDGES |
— | on |
— | Feed the edge between two neighbouring interior lattice nodes to the triangulator as a CONSTRAINT, like the boundary itself: it may not be cut, so a clean grid is guaranteed wherever it fits and triangle soup stays locked inside the cells a feature actually breaks. Escape hatch only |
LATTICE_RAILSLattice rails |
lattice_rails |
on |
— | A D-degenerated lattice axis (1-3 spans) lays continuous RAILS instead of sparse points: each transverse loop runs boundary-to-boundary as a constrained chain, so the coarse limit of D degenerates into a clean loft instead of triangle soup. Re-fill to see it |
RUNG_LAWRungs |
rung_law |
off |
— | In the almost-loft limit of D (an axis degenerated to 1-2 loops) pair the patch's two long walls and lay transverse RUNGS — constrained wall-to-wall chains at the sparser wall's own verts — so the strip lofts instead of free-triangulating. End caps and corner features stay free triangles. Rides the rails machinery — needs Lattice rails ON. Re-fill to see it |
RUNG_CAP_TURN_DEG |
— | 55 |
— | Rung law: a rim segment steeper than this many degrees to the long axis counts as an end CAP — no rungs land there |
RUNG_MONO_TOL |
— | 0.15 |
— | Rung law: max net backstep of a wall along the long axis (fraction of the patch extent) before the law stands down for that patch |
RUNG_BANK_DEPTH_FRAC |
— | 0.2 |
— | Rung law: a wall run must hug its side's extreme within this fraction of the cross extent — a displaced run (notch floor) is a feature shelf and gets no rungs |
GIZMO_DENS_ZERO_SNAP |
— | 0.5 |
— | D gizmo: dragging past the density floor by this factor snaps the axis to 0 (loft — zero transverse loops); dragging up from 0 recovers through the floor |
LATTICE_ROW_COMPLETERow-complete lattice |
lattice_row_complete |
on |
— | An interior row whose end station falls outside the patch re-lays the whole axis one station coarser instead of leaving a gap — the row stays complete and evenly spaced, so the fill keeps its flow instead of triangulating across the hole. Re-fill to see it |
RAILS_SEAT_LATTICERails seat lattice |
rails_seat_lattice |
on |
— | A manual rail SEATS the interior lattice on itself: a whole station row lands on the drawn line, so both its banks are complete cells and recombine into quads, and the rail is subdivided by the fill's own rows instead of by the boundary. The patch is never re-aimed — a rail adds a rule, it does not rewrite the flow. OFF leaves a rail as a bare constrained chain. Re-fill to see it |
FEATURE_COLLARFeature collar |
feature_collar |
off |
— | Dense boundary runs (cutout rims, notches) emit an interior twin row one local span inside — a tight fringe of short edges around features that survives coarse D (the core can degenerate to a loft while features stay crisply outlined). Re-fill to see it |
PLANAR_NGON_VIEWLimited dissolve on flat |
planar_ngon_view |
off |
— | Collapse a FLAT patch's triangle fill into limited-dissolve NGONS (edit-view cleanliness; boundary, hole rims and cut edges survive). The final mesh is unchanged: the normal transfer force-triangulates ngons first. Re-fill to see it |
DEGENERATE_MAX_ASPECTDegenerate aspect |
gen_degen_aspect |
50 |
2 … 200 | Drop a small-minor patch as a sliver above this bbox aspect |
AUTO_SUPPORT_CHORD |
— | off |
— | Synthesize a transverse fence cut on a holed curved patch whose feature is pressed against the rim, recorded as an ordinary plan cut you can tweak or delete (deleting it is remembered, so a re-fill does not put it back). An explicit cut of your own always outranks it |
LATTICE_SNAP_EVEN_FRAC |
— | 0.2 |
— | Evenness guard on lattice station snapping: snapping may distort a gap between stations by at most this fraction of its even value — beyond that the whole axis reverts to evenly spaced stations. Lower = stricter, snaps less often |
SPAN_PREPASS |
— | on |
— | Two-phase build: every selected patch registers its boundary span contract and the shared seams are reconciled BEFORE anything is filled, so a first build equals a rebuild. Escape hatch only — turning it off brings back first-build/rebuild differences |
PICK_TOL_FRACPick tolerance |
pick_tol_frac |
0.012 |
0.002 … 0.06 | Hover/select tolerance for curves AND cuts as a fraction of mesh scale (one value for both). Lower = picks only what is right under the cursor — lets you place cuts densely; higher grabs neighbours |
CONTOUR_BIAS_MAXDensity max |
contour_bias_max |
4 |
0.5 … 6 | Density (Ctrl+Wheel) redistribution LIMIT — the strongest bias the wheel can reach. Density is EXPONENTIAL: the peak:flat sample ratio is e^bias (~55x at 4, ~400x at 6), so a small bias already bunches HARD. Distribution only; the span count is unchanged |
CONTOUR_BIAS_STEPDensity step |
contour_bias_step |
0.5 |
0.1 … 2 | Density bias change per Ctrl+Wheel notch (smaller = finer control) |
CONTOUR_RANGE_LORamp start |
contour_range_lo |
0.2 |
0 … 1 | Density RAMP start — a curve whose curvature VARIES less than this (normalized range) gets NO densify. Pure arcs / straights stay uniform. Lower it to densify gentler curves (e.g. a variable-radius arc). Below the old hard 0.5 gate, the warp now ramps in smoothly |
CONTOUR_RANGE_HIRamp full |
contour_range_hi |
0.6 |
0 … 1 | Density RAMP full — at/above this curvature variation the curve gets the FULL dialed bias; between Start and Full it scales smoothly (no on/off cliff). Lower it so borderline curves densify harder |
CONTOUR_SMOOTH_FRACContour smooth |
contour_smooth_frac |
0.15 |
0 … 1 | Curvature-smooth window for contour densification, as a fraction of the curve's arc length (Gaussian σ). The quality knob — higher smooths the density warp over a longer span; 0 disables smoothing |
STEP_CONVERTER_BINCAD converter |
step_converter_bin |
`` | — | Standalone CAD converter EXECUTABLE (the external dependency: OCC lives outside Blender). Leave empty and drop it into |
STEP_CONVERTER_PYOCP python |
step_converter_py |
`` | — | Python executable with the OCP (OpenCASCADE) bindings installed (pip install cadquery-ocp) — the bundled STEP→glb converter runs through it as a subprocess. Dev fallback only — empty is the normal state; the compiled converter is the path |
STEP_NAME_SUFFIXName suffix |
step_name_suffix |
_high |
— | Appended to every object name the STEP import creates: the default '_high' turns the CAD body 'striker_pin' into 'striker_pin_high' (the import IS the high-poly source). Empty keeps the raw CAD names |
APPLY_NAME_SUFFIXLow suffix |
apply_name_suffix |
_low |
— | Apply naming convention: the finalized mesh inherits the CAD target's base name (hardcraft_retopo_ and the STEP '_high' suffix stripped) plus this suffix — the default '_low' pairs with '_high' for baking |
APPLY_SURFACE_MODIFIERSSurface modifiers |
apply_surface_modifiers |
on |
— | Apply leaves a LIVE shading stack on the result (Smooth by Angle 30° + Weighted Normal keep_sharp) — untick for a bare mesh |
APPLY_PACK_UVPack UV |
apply_pack_uv |
on |
— | Apply packs the CAD charts into 0..1 with Blender's native Pack Islands after marking the seams |
STEP_REFINE_TORN |
— | on |
— | Re-mesh a STEP body whose tessellation came out TORN (adjacent faces left unstitched by sloppy CAD tolerances). Only the torn body is redone, on a fixed density ladder, keeping the least torn result; off = import the tear and report it |
STEP_LIN_DEFL |
— | 0.05 |
— | Default chordal deflection the Import STEP dialog opens with, in the file's author units — tessellation density of the imported mesh (lower = denser; the dialog's Retopo/Bake presets and fields decide each import). A quality knob, not a completeness one: no faces are lost at any setting, but a coarse tessellation hands the normal repair needle triangles on fillets. The converter floors it at 2e-4 x the body's own extent (explosion guard) |
STEP_ANG_DEFL_DEG |
— | 15 |
— | Default angular deflection (degrees) the Import STEP dialog opens with — the companion density knob to the chordal one |
ORACLE_CORNER_DEG |
— | 15 |
— | Minimum turn (degrees) for a CAD edge endpoint to count as a boundary corner. Below it a tangent junction — fillet meeting a line, a cosmetic edge split — stays merged, so representation noise in the CAD does not seam a smooth run |
MASS_SPAN_DEBOUNCE_MS |
— | 300 |
— | Idle milliseconds after the last Shift+Wheel notch before a mass-span gesture commits — the whole turn becomes ONE rebuild and ONE undo step. Raise it if a slow wheel commits mid-gesture |
MASS_SPAN_REALTIME_MAX |
— | 20 |
— | Selections up to this many patches rebuild on EVERY Shift+Wheel notch (realtime); larger selections fall back to the debounced single commit. 0 = always debounce |