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: floor on the per-direction mirror-vote share. Keep it low — a real twin in a dense cluster of small islands can score as low as 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 | Ribbon / strip width threshold, as a fraction of mesh scale — a boundary side under this reads as a thin-strip rail instead of a plain boundary side |
SPAN_QUANTIZEQuantize spans |
span_quantize |
on |
— | Solve every curve's default span for the whole model at target creation so annulus rims and opposite grid sides get equal counts (within one span of the silhouette law). A default, not an override: the wheel still pins. Applies to the NEXT New Target |
SILHOUETTE_TOLSilhouette tol |
silhouette_tol |
0.1 |
0.01 … 2 | Max deviation of a span chord from the true arc, in UNITS (a Plasticity-bridge mesh reads the 0.05 default as 0.05 mm) — 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) |
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 |
on |
— | Pair the leftover triangles into quads by a GLOBAL optimum instead of a greedy pass, so corners and orphans get their quads too. The 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 |
— | 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 |
REMOVAL_CLOSE_FARClose the far side |
removal_close_far |
off |
— | CURVE Alt+F on one side of a hole or a slot through the part closes its far side too. OFF = only the side whose curves are picked closes; the walls stay until both sides are closed |
RAIL_LOFTRail loft |
rail_loft |
on |
— | A ruled wall (cylinder / cone, CAD axis known) is filled by RAILS between opposite rim stations, paired by angle; a window or slot cuts into the rails, the rest is honest triangles. OFF = the general fill. Re-fill to see it |
CAD_ANALYTIC_INTERIORAnalytic interior |
cad_analytic_interior |
off |
— | Interior vertices land on the EXACT CAD surface instead of the imported triangles, on patches that lie on one analytic surface. OFF = the import's own tessellation. Re-fill to see it |
CAD_CONCAVITY_AXISCAD axis |
cad_concavity_axis |
off |
— | The concave/convex test takes the patch axis from the CAD instead of estimating it from the face cloud. OFF = the estimate. Re-fill to see it |
RAIL_LOFT_DEV_DEG |
— | 10 |
— | Rail loft: the most a rail may bend off the ruling (degrees) to end on a feature node; beyond it the rail stops at its last row and the band is triangulated. Artist law: 10 |
RUNG_LAWRungs |
rung_law |
on |
— | When D degenerates an axis to 1-2 loops, pair the patch's two long walls and lay transverse RUNGS at the sparser wall's verts, so the strip lofts instead of free-triangulating. End caps and corner features stay triangles. 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 |
— | 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 |
— | on |
— | A manual rail SEATS the interior lattice on itself: a whole station row lands on the drawn line, so both its banks recombine into quads. A rail adds a rule, it does not re-aim the patch's flow. OFF leaves a rail as a bare constrained chain. Re-fill to see it |
PLANAR_NGON_VIEWLimited dissolve on flat |
planar_ngon_view |
on |
— | 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 |
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 |
RING_PREFERRED_MAX |
— | 0 |
0 … 256 | ceiling on a radius class's full-circle count (0 = none); the top edge of the detail preset's band (Low 16 / Mid 24 / High 32) |
RING_PREFERRED_MIN |
— | 0 |
0 … 256 | floor of the same band: the least full-circle count a radius class may take (0 = none beyond MIN_LOOP_SPANS); the bottom edge of the detail preset's band (Low 8 / Mid 16 / High 24). A geometric floor (washer lip, nfloor) still outranks the band |
SPAN_RADIUS_CLASS |
— | on |
— | L2 radius classes: every arc of one radius shares a full-circle count snapped to the preferred ring numbers (4 8 12 16 24 32 48 64); each arc takes its angular share. Escape hatch — OFF keeps the per-curve silhouette law inside the quantizer |
CLASS_R_FRAC |
— | 0.03 |
0.001 … 0.2 | L2: relative radius tolerance that groups arcs into one class |
TUBE_RELAX_ITERS |
— | 3 |
0 … 20 | tube kernel: interior relax iterations after the lay (0 = off) |
RING_SNAP_FRAC |
— | 0.35 |
0 … 1 | L2: a ring's law count snaps to a preferred number only within this fraction of itself (0.35 = 13→12 yes, 5→8 no) |
SPAN_NEIGHBOUR_FLOOR |
— | 2 |
0 … 10 | L4 neighbour floor: a curve's edge may be at most this many times the median edge of the other curves on its patches — a long, gently curved or straight edge beside dense neighbours gets more spans. Raises only; 0 = off |
FILLET_TIP |
— | on |
— | Fillet to a point: the two rails of a fillet whose rails meet in one tip are tied 1:1 in the span solve, and the neighbour floor raises both together (or neither, when the neighbours cannot meet the tie). A wheeled rail breaks the tie. The fillet is filled as a fillet: profile lines from the cap to the tip, quads where the rails agree. OFF = today's solve and fill |
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) |
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_WEIGHTED_NORMALWeighted Normal |
apply_weighted_normal |
off |
— | Apply adds a live Weighted Normal modifier (keep sharp) on top of the CAD sharps and smooth shading, which are always applied |
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 |
APPLY_UV_BY_HARDSUV by hards |
apply_uv_by_hards |
off |
— | Apply re-lays the UV seams on the CAD hard edges: smooth surfaces stay one island, rings get one cut only when needed, over-long islands are cut on a smooth CAD border (fewer islands, fewer split vertices in the engine) |
UV_HARD_AREA_TOLUV by hards: ring tolerance |
— | 2 |
— | A closed island is cut while the p99 of its per-triangle area distortion stays above this |
UV_HARD_FILL_MINUV by hards: fill minimum |
— | 0.5 |
— | An island filling its minimum-area rectangle below this is cut on a smooth CAD border |
STEP_Y_UPSTEP source is Y-up |
step_y_up |
off |
— | Rotate an imported STEP +90 deg about X, for CADs that author with Y as the vertical axis (Blender is Z-up). A STEP file does not record an up axis, so this is a switch, not a detection. Set it before importing; it moves the object transform only, so an already-imported part can be fixed by rotating it by hand |
BAKE_NORMAL_DATABake normal data |
commit_bake_normal_data |
on |
— | At commit, stamp each output face with the source CAD face it came from, so Transfer CAD Normals reads an EXACT map instead of guessing by UV islands. Costs one int per face; turn off if you never use the normal transfer. Enabling it later needs a re-commit |
BAKE_UVBake UV |
commit_bake_uv |
on |
— | Bake each patch's own parametrization into the UV layer at build time (tube = exact development, planar = projection, else LSCM) — the chart is visible right after build; packing is yours |
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 |