一键导入
dm-sdf-octree-cache
Interface contract, data layout, and mesher integration patterns for SdfOctreeCache — the hierarchical CPU evaluator that replaces np.meshgrid.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Interface contract, data layout, and mesher integration patterns for SdfOctreeCache — the hierarchical CPU evaluator that replaces np.meshgrid.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Architecture reference for the unified edit-mode transform gizmo (translation arrows + rotation rings, transform spaces, x-ray rendering). Required reading before implementing any task in todo.md whose ID begins with GIZMO-.
Reference for the two-color (orange/blue) boolean system where IsSubtractive classifies inputs into groups and boolean operations combine them into a parent-child tree. Required reading before implementing any task in todo_bool.md.
Standardized pattern for creating interactive SDF primitive tools in the Direct Modeling workbench.
Template and rules for creating new SDF primitive field classes in core/sdf/sdf/. Required reading before implementing any new SdfField subclass.
Reference for converting SVG path data (M L H V C S Q T A Z) and shape elements (rect, circle, ellipse, line, polyline, polygon) into cubic Bezier segments with no rasterization. Required reading before implementing svg_importer.py.
Convention for registering primitive-specific GLSL inside the primitive's own .py file. Required reading before editing any to_glsl/to_glsl_2d method.
| name | DM SDF Octree Cache |
| description | Interface contract, data layout, and mesher integration patterns for SdfOctreeCache — the hierarchical CPU evaluator that replaces np.meshgrid. |
Reference for implementing SP-001..SP-004 and MG-001..MG-005 in todo_arch_refactor.md.
At 0.05mm over 1m³ a dense grid is 8 trillion voxels (32 TB). The octree culls subtrees where
abs(sdf_center) > cell_half_diagonal, guaranteeing no zero-crossing. Only cells near the
surface are evaluated. Memory scales with surface area, not volume.
core/sdf/sdf_octree.py — created by SP-001.
class SdfOctreeCache:
field: SdfField # the field being cached
leaf_size: float # smallest cell size (mm)
_origin: np.ndarray(3) # bounding-box min corner (float64)
_leaf_step: float # == leaf_size
_leaves: dict # (ix, iy, iz) → np.ndarray(8,) float32
Builds the octree from scratch. Evaluates field.evaluate_grid() on batches of cell centers
and corner points. Leaves are stored in _leaves. Must be called before any other method.
Trilinear interpolation from _leaves. Returns +inf if the point is in culled space
(not near the surface). point can be FreeCAD.Vector or (3,)-like.
Yields (origin, size, corners) for every surface-crossing leaf:
origin: np.ndarray(3,) — world position of the (0,0,0) cornersize: float — leaf cell edge length (always == leaf_size)corners: np.ndarray(8,) float32 — SDF values in Lorensen-Cline corner orderReturns all leaf-level corner points where abs(SDF) <= band_width. Default band_width = 2×leaf_size.
Use this instead of np.meshgrid when a flat point cloud near the surface is needed.
The 8 corners of each leaf cell are always in this order (same as existing MarchingCubesMesher):
index (dx, dy, dz)
0 (0, 0, 0) ← origin
1 (1, 0, 0)
2 (1, 1, 0)
3 (0, 1, 0)
4 (0, 0, 1)
5 (1, 0, 0) wait — see _OFF_X/Y/Z in dm_mesher.py for authoritative values
6 (1, 1, 1)
7 (0, 1, 1)
Authoritative corner offsets are _OFF_X, _OFF_Y, _OFF_Z at the top of core/dm_mesher.py.
The convenience constant _CELL_OFFSETS = np.stack([_OFF_X, _OFF_Y, _OFF_Z], axis=1) shape (8,3)
is added by MG-001.
All rewritten meshers follow this pattern:
from core.sdf.sdf_octree import SdfOctreeCache
def mesh(self, field, cell_size, ...):
octree = SdfOctreeCache(field, leaf_size=cell_size)
octree.build() # replaces np.meshgrid
for origin, size, corners in octree.walk_leaves():
# origin : (3,) world position of corner 0
# size : float, edge length
# corners : (8,) SDF values in Lorensen-Cline order
... # existing cube-classification logic
The existing vectorized cube-classification in MarchingCubesMesher (lines 149–260 of
dm_mesher.py) can be reused without modification after MG-001, by batching all walk_leaves()
results into arrays:
origins = np.array([o for o,s,c in leaves]) # (M, 3)
corner_vals = np.array([c for o,s,c in leaves]) # (M, 8)
s = leaves[0][1] # cell size (all equal)
neg = corner_vals < 0 # (M, 8)
cube_idx = np.zeros(M, dtype=np.uint8)
for bit in range(8):
cube_idx |= (neg[:, bit].astype(np.uint8) << bit)
active_mask = (cube_idx != 0) & (cube_idx != 255)
A cell is safe to cull (guaranteed no surface crossing) if:
abs(sdf_at_center) > size * sqrt(3) / 2
because size * sqrt(3) / 2 is the half-diagonal of the cube. If the SDF at the center
is larger in magnitude than the furthest corner, no zero-crossing can exist inside.
_leaves only stores cells that could contain a surface crossing (failed the cull test).
walk_leaves() additionally filters to cells where the corners actually straddle the surface
(corners.min() < 0 and corners.max() > 0).
core/sdf/sdf_field.py:35 — evaluate_grid(points: np.ndarray(N,3)) → np.ndarray(N,) signaturecore/dm_mesher.py:1-30 — _OFF_X/Y/Z corner order constantscore/dm_mesher.py:113-250 — existing MarchingCubesMesher cube-classification logic to reusetodo_arch_refactor.md — SP-001..SP-004, MG-001..MG-005 full task implementations