You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Browse filesBrowse the repository at this point in the historyBrowse files
Shane Wall
committed
Add weld-aware validation and map import cleanup
Introduce non-planar face and micro-gap detection in HFValidationSystem, along with configurable weld and planarity tolerances for imported or hand-edited geometry.
Add vertex welding and planarity correction helpers, refresh derived face geometry after weld edits, and harden the spatial-hash implementation with 27-cell neighbor lookup so boundary-straddling pairs are not missed.
Run a post-parse weld pass in MapIO for near-coincident imported .map vertices, add focused GUT coverage for validation, welding, planarity fixes, and MapIO integration, and update project documentation to describe the new behavior and test count.
Copy file name to clipboardExpand all lines: CONTRIBUTING.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -38,6 +38,7 @@ Thanks for helping improve HammerForge.
38
38
-**Face winding convention**: All faces must use **CW vertex winding** as seen from outside the brush (Godot 4's front-face convention). `_compute_normal()` produces outward normals for CW faces automatically. Never negate normals manually after `ensure_geometry()`. When adding new face generators, verify normals point outward from the brush centroid.
39
39
-**Polygon/path tools** create brushes via `root.brush_system.create_brush_from_info()` with a `faces` key containing serialized face data. Use `FaceData.from_dict()` / `to_dict()` for serialization. Face dicts include `winding_version: 1`; omitting this key triggers load-time migration.
40
40
-**Spawn system** (`root.spawn_system`): use `get_active_spawn()` for primary-flag-aware spawn lookup, `validate_spawn()` for physics-based validation, `auto_fix_spawn()` to apply suggested fixes, `create_default_spawn()` for fallback creation. Quick Play flow calls these automatically. Debug visualisation via `show_validation_debug()` / `cleanup_debug()`. Spawn properties (`primary`, `angle`, `height_offset`) are defined in `entities.json` and auto-generated in the Entities dock.
41
+
-**Validation tolerances**: `HFValidationSystem` has two configurable tolerances — `weld_tolerance` (default 0.001) for vertex coincidence in welding/micro-gap detection, and `planarity_tolerance` (default 0.01) for face-plane deviation. The `_edge_key()` function used by non-manifold/open-edge topology checks uses a **fixed** 0.001 precision and must NOT be coupled to `weld_tolerance` — changing `_edge_key` precision would mask real topology issues when users raise the weld knob. Keep new spatial-hash lookups distance-based with 27-cell neighbor search (see `_cell_keys()`) rather than single-bucket — bucket boundaries silently miss valid pairs. Always call `face.ensure_geometry()` after mutating `local_verts` so normals and bounds stay in sync.
41
42
-**Incremental bake**: `bake_selected()` merges into the existing `baked_container` — never replace the container wholesale. `bake_dirty()` uses `_last_bake_success` to decide whether to clear dirty tags; failed bakes must retain all tags so they can be retried.
42
43
-**Bake preview modes**: use the `PreviewMode` enum (FULL, WIREFRAME, PROXY). Wireframe must use `ShaderMaterial` with `render_mode wireframe` — `StandardMaterial3D` has no `wireframe` property in Godot 4.6.
43
44
-**Quick Play variants**: `_on_quick_play_from_camera()` and `_on_quick_play_selected_area()` must follow the same severity ≥ 2 blocking, auto-create, and fix-dialog patterns as `_on_quick_play()`. Both must restore temporary state (spawn position/angle, cordon) on both success and error paths. Use `_restore_spawn()` helper and explicit type annotations (e.g. `var old_pos: Vector3 =`) to avoid GDScript `:=` inference failures with untyped spawn references.
|`test_quick_play_modes.gd`| 12 | Severity blocking (0/1/2), cordon save/restore, dirty tag retention patterns, camera yaw via entity_data, spawn restore after camera play, spawn restore on error path |
|`hf_io_visualizer.gd`|`HFIOVisualizer`| Entity I/O connection lines in viewport (ImmediateMesh) |
@@ -326,7 +326,8 @@ Foliage Populator
326
326
-**Bake Changed** (`bake_dirty()`): bakes only brushes with dirty tags (`_dirty_brush_ids`). Tags are cleared only when `_last_bake_success` is true; failed bakes retain all dirty tags.
327
327
-**Preview modes** (`PreviewMode` enum: FULL, WIREFRAME, PROXY): `_apply_preview_visuals()` overrides material on baked meshes. Wireframe uses inline `ShaderMaterial` with `render_mode wireframe`. Proxy uses unshaded semi-transparent `StandardMaterial3D`.
328
328
-**Bake time estimate** (`estimate_bake_time()`): ratio-based extrapolation from `_last_bake_duration_ms` and brush count.
-**Bake issue detection** (`HFValidationSystem.check_bake_issues()`): returns Array of `{type, severity, message, node}` dicts. Checks: degenerate brush (sev=2), oversized (sev=1), floating subtract (sev=1), overlapping subtracts (sev=1), non-manifold edges (sev=2), open edges (sev=1), non-planar faces (sev=1), micro-gaps between brushes (sev=1). Non-planar detection uses `planarity_tolerance` (default 0.01). Micro-gap detection uses `weld_tolerance` (default 0.001). Both use 27-cell spatial hash neighbor lookup for boundary-safe distance checks. `_edge_key()` for topology (non-manifold/open-edge) uses fixed 0.001 precision, intentionally decoupled from `weld_tolerance`.
330
+
-**Auto-fix helpers**: `weld_brush_vertices(brush)` snaps near-coincident vertices within `weld_tolerance` via BFS grouping + `ensure_geometry()` refresh. `fix_non_planar_faces(brush)` projects drifting vertices onto the best-fit plane from each face's first 3 vertices.
330
331
331
332
## Face Materials + Surface Paint
332
333
Face data is stored per DraftBrush face with material assignment, UV projection, and optional paint layers.
@@ -479,6 +480,7 @@ Unit tests use the [GUT](https://github.com/bitwes/Gut) framework and run headle
0 commit comments