FireMaze — Interactive Editor

A modal viewport editor for painting, modifying, and customizing maze layout in real time. Every left-click or shift+click updates the cell data and incrementally rebuilds only the affected geometry.

← Back to FireMaze

1. Overview

The Interactive Editor is a Blender modal operator (MAZE_OT_interactive_editfire_maze.interactive_edit) that:

  • Raycasts against a hidden helper mesh for mathematically exact cell detection.
  • Toggles walls, cycles custom mesh indices, and places/removes stairs.
  • Incrementally rebuilds only dirty cells for instant response.
  • Recomputes the BFS guide path on every edit for live connectivity feedback.
  • Automatically exits when switching workspaces, clicking outside the 3D viewport, or pressing Esc/Enter.

2. Entering & Exiting

Enter

  • Click Interactive Edit in the sidebar (Generation & Editing section).
  • The viewport status bar displays active shortcuts.

Exit

MethodBehavior
Esc / EnterExits edit mode. If any cells were dirtied, triggers a full rebuild with all post-processing applied.
Exit Edit Mode buttonSame as Esc/Enter.
Workspace switchAuto-exits — switching to Texture Paint, Shading, or any other workspace terminates the modal and releases event grabs.
Viewport region changeClicking outside the main 3D viewport window region passes the event through and auto-exits.
Sidebar clickIgnored by the modal — you can adjust settings, materials, or click buttons without leaving edit mode.

3. Controls Reference

ActionTool = Toggle WallsTool = Toggle Stairs
Left-click on wall/floor Toggle cell between wall and open floor. Perimeter toggles also add/remove entrances (floor 0) or exits (top floor). Place a stair connecting the current floor to the level above, or remove an existing stair. Cannot place on top floor.
Shift+left-click on face Cycle the mesh index for that face from its custom collection (wall, floor, or roof). Rotate an existing stair's orientation (N→E→S→W for rect; CCW→Out→CW→In for polar).
Esc / Enter Exit edit mode. Exit edit mode.

4. Floor Level Targeting

When the maze has multiple floors, the editor targets a specific floor:

  • Floor Leveledit_floor_level — 0 to floors − 1 (default 0). All clicks apply to this floor.
  • Edit Roofedit_roof — Polar thin mode only. When enabled, roof faces are edited instead of walls.

Floor level is clamped to valid range on entering edit mode based on the stored maze data.

Auto-Detection from Raycast

When not explicitly editing a floor (props.is_editing = False), the Z-coordinate of the hit point determines the floor:

z_hit = floor(offset_loc.z / level_height)

where level_height = wall_height + floor_thickness. This allows generating a maze and immediately clicking any visible cell on any floor.

5. Wall Toggling

Rectangular — Thin Wall Mode

Distance-to-edge calculation determines which of the four cell boundaries was clicked (N, S, E, W):

Clicked edgeWall flag toggledSynchronization
North (d_N smallest)cells[y][x][0]Adjacent cell's South flag (cells[y+1][x][1]) synced
South (d_S smallest)cells[y][x][1]Adjacent cell's North flag (cells[y-1][x][0]) synced
East (d_E smallest)cells[y][x][2]Adjacent cell's West flag (cells[y][x+1][3]) synced
West (d_W smallest)cells[y][x][3]Adjacent cell's East flag (cells[y][x-1][2]) synced

Rectangular — Cube Mode

The clicked cell's cells[y][x][0] flag is toggled. If the raycast hit a face with a strong normal direction (N/S/E/W), the neighboring cell along that direction is checked — the wall cube on that side gets toggled instead.

Perimeter behavior: When toggling a border cell:

  • Wall → Floor on floor 0: Old entrance is closed (set back to wall), new entrance created at this cell with the appropriate side direction (N/S/E/W).
  • Wall → Floor on top floor: Exit added at this cell.
  • Floor → Wall on floor 0: Entrance removed if it was at this cell.
  • Floor → Wall on top floor: Exit removed if it was at this cell.

Polar — Thin Wall Mode

Distance-to-edge determines which boundary edge was clicked (CW radial, CCW radial, inward angular, outward angular). The corresponding wall flag on the appropriate cell is toggled.

Outermost ring (r_idx = rings − 1): Clicking outward edge toggles entrance/exit placement:

  • Floor 0: Opens a new entrance (or closes existing one).
  • Top floor: Toggles exit on/off.
  • Middle floors: Reports warning — cannot place entrance/exit on middle floors.

Polar — Cube Mode

The clicked wedge cell's cells[r][theta][0] flag is toggled. Distance-to-edge determines which of the four boundaries was hit to identify the correct cell (since two wedge cells share each boundary).

Perimeter behavior (outermost ring): Same as rectangular cube mode — wall-to-floor on the perimeter creates entrance (floor 0) or exit (top floor), with old entrance cleanup.

6. Mesh Cycling (Shift+Click)

Shift+left-click cycles the mesh index for the clicked face, rotating through available meshes in the assigned custom collection.

Rectangular — Cube Mode

Face detectedIndex updatedNotes
Floor (normal up, face_dir = 'FLOOR')cells[y][x][5]Only on open cells. Cycles through floor collection.
Roof (normal down, face_dir = 'ROOF')cells[y][x][6]Only on wall cells. Cycles through roof collection.
Wall (N/S/E/W via normal)Per-direction index (1=N, 2=S, 3=E, 4=W)Cycles through wall collection independently per face.
Pillar Mode (any wall face)All indices (1–4) set togetherWhole pillar cycles as one unit.

Rectangular — Thin Wall Mode

Face detectedIndex updatedSynchronization
Floorcells[y][x][6] (legacy) or cells[y][x][8] (expanded format)
Roofcells[y][x][7] (legacy) or cells[y][x][9] (expanded format)
Wall (North)cells[y][x][4]cells[y+1][x][5] synced
Wall (South)cells[y][x][5]cells[y-1][x][4] synced
Wall (East)cells[y][x][6]cells[y][x+1][7] synced
Wall (West)cells[y][x][7]cells[y][x-1][6] synced

Polar — Cube Mode

Face detectedIndex updated
Floorcells[r][theta][4]
Roofcells[r][theta][5]
Wall (CW radial)Index 2 or 3 on the owning cell (non-wall cell takes priority)
Wall (CCW radial)Index 2 or 3 on the owning cell
Wall (Inward angular)Index 7 or 8 on the owning cell
Wall (Outward angular)Index 7 or 8 on the owning cell

Polar — Thin Wall Mode

Face detectedIndex updated
CW radial wallcells[r][theta][2]
CCW radial wallcells[r][theta_next][2]
Inward angular wallcells[r][theta][3]
Outward angular wallcells[r_next][theta_out][3]

7. Stair Tool

Available when floors > 1. Tool selector appears in the sidebar during edit mode.

Placement

Left-click on a cell to place a stair:

  1. Forces both the clicked cell and the cell directly above it to be open (wall removed).
  2. Creates a stair entry in the maze data with the current stair_style, stair_footprint, and stair_direction.
  3. Cannot place stairs on the top floor.
  4. For polar grids, direction is mapped from compass notation to polar orientation (N→CCW, E→OUT, S→CW, W→IN).

Removal

Left-click on an existing stair cell to remove it.

Rotation

Shift+left-click on an existing stair cycles its orientation:

Grid typeCycle order
RectangularN → E → S → W → N
PolarCCW → OUT → CW → IN → CCW

8. Entrance & Exit Editing

The editor automatically manages entrance/exit placement when toggling perimeter cells:

  • New entrance on floor 0: The old entrance cell (if any) is restored to a wall, and the clicked cell becomes the new entrance with the appropriate side direction.
  • New exit on top floor: The clicked cell is added to the exits list.
  • Closing an entrance/exit: Toggling a perimeter cell back to wall removes it from the entrance or exits list.
  • Old entrance dirty tracking: The previous entrance cell coordinates are stored in _old_entrance_dirty and included in the dirty cell set for incremental rebuild.

9. Incremental Rebuild

Helper Mesh

Before entering edit mode, a hidden flat-faced mesh (_FireMaze_Edit_Helper) is generated by building a simplified version of the maze with force_simple=True. This helper:

  • Provides mathematically exact raycast targets, preventing misrouting on complex custom meshes.
  • Is hidden from viewport (hide_viewport = True) during idle.
  • Is temporarily unhidden during raycasting while all other maze objects are hidden.
  • Is rebuilt incrementally alongside the visual meshes.

Dirty Cell Set

After any edit, the affected cells are collected into a dirty_cells set:

Grid typeDirty neighborhood
Rectangular(z, y, x) plus all 8 neighbors (Moore neighborhood). Old entrance cells also included.
Polar(z, r, theta) plus adjacent sectors in the same ring and overlapping sectors in adjacent rings (angular overlap check).

Rebuild Pipeline

  1. Serialize updated cell data to col["fire_maze_data"].
  2. Call rebuild_maze_incrementally() which:
    • Deletes existing faces in the dirty cell IDs from floor, wall, cap, roof, and stair BMeshes.
    • Rebuilds geometry for only the dirty cells using the same builder functions as full generation.
    • Updates the helper mesh.
    • Rebuilds the guide path.
  3. All post-processing (lightmap UV, vertex painting, planar dissolve, prop spawning, colliders) is skipped during incremental rebuild for instantaneous response.

Full Rebuild on Exit

When exiting edit mode with dirty cells, a full rebuild_maze_from_collection() is triggered, applying all post-processing settings.

10. Live Guide Path

The BFS shortest path is recomputed on every edit click:

maze_data.guide_path = find_shortest_path(maze_data, wall_mode=wall_mode)

This provides immediate visual feedback — the green/red path updates to show connectivity changes as you paint walls. The guide path curve/tube/ribbon object is deleted and rebuilt within the incremental rebuild.

11. UI Panel in Edit Mode

When edit mode is active, the Generation & Editing section of the FireMaze panel changes:

ElementAppearance
Interactive Edit buttonDepressed toggle labeled "Exit Edit Mode" with CANCEL icon
Edit Roof checkboxVisible only for polar thin mode
Tool selector"Toggle Walls" / "Toggle Stairs" row, only when floors > 1
Stair DirectionShown when stair tool is selected
Alert boxRed box with "Edit Mode Active" warning, current floor level, and shortcut legend

The alert box shows context-sensitive shortcut hints:

  • Wall tool: "Left-click: Toggle wall on/off" and "Shift+click: Cycle custom mesh index"
  • Stair tool: "Left-click: Place / remove stair" and "Shift+click: Rotate stair direction"

12. Technical Notes

  • The editor stores a reference to the original maze data (self._maze_raw) and workspace name (self.init_workspace) on entry for auto-exit detection.
  • A dirty flag (self._is_dirty) tracks whether any changes were made, preventing unnecessary full rebuilds on clean exits.
  • The old entrance cell for dirty tracking (self._old_entrance_dirty) ensures the previous entrance location is also rebuilt when the entrance moves.
  • getattr(props, 'floor_thickness', 0.0) accounts for floor slab depth in Z-level calculations, preventing mis-targeting when floor_thickness > 0.