hz6666/3d-wm-atomic-v2
3d-wm-atomic-v2 — Synthetic CAD construction videos Per-op animated frame sequences for CadQuery construction programs, with per-frame atomic op labels in continuous raw mm. Designed as training data for video → action (IDM) and image → next frame (video-gen) models. Format version: v2-continuous-mm (2026-05-29 onward). One clip = one (case, view) pair data_*/{bNNNN}/train/shard-NNNNNN.tar └── {case_uid}_v{NN}/ ├── 0000.png .. NNNN.png # 256x256 rendered… See the full description on the dataset page: https://huggingface.co/datasets/hz6666/3d-wm-atomic-v2.
3d-wm-atomic-v2 — Synthetic CAD construction videos
Per-op animated frame sequences for CadQuery construction programs, with per-frame atomic op labels in continuous raw mm. Designed as training data for video → action (IDM) and image → next frame (video-gen) models.
Format version: `v2-continuous-mm` (2026-05-29 onward).
One clip = one (case, view) pair
data_*/{bNNNN}/train/shard-NNNNNN.tar
└── {case_uid}_v{NN}/
├── 0000.png .. NNNN.png # 256x256 rendered frames
├── meta.json # all metadata + per-frame op_spans
├── ops.json # full atomic op sequence
└── frame_codes.json # per-frame partial CadQuery codeA case is one CAD program rendered from 5 sibling views (iso, front, side, top, random) sharing the same anchor — physical mm/pixel identical across the 5 views, only the camera angle changes.
Atomic op vocabulary (continuous mm, no quantization)
Op IDs are STABLE. Sparse IDs (0, 1, 2, 5, 6, 7) are reserved.
Categorical alphabets
plane_idx→["XY", "YZ", "ZX"]extrude_kind→["fresh", "union", "cut"]edge_idx→["|Z", "|X", "|Y"]
Example op tuple (from a real clip)
[8, 1, -30.0, 0.0, 0.0, 16.0, -20.0] # SKETCH_BEGIN plane=YZ origin=(-30,0,0) start=(16,-20)
[15, 30.0] # SKETCH_CIRCLE r=30.0
[12] # SKETCH_CLOSE
[13, 32.0, 0] # SKETCH_EXTRUDE h=32.0 kind=fresh
[14] # END_SKETCHmeta.json key fields
op_spans per-frame entry
Each frame has exactly one span. For animated extrude frames, action_op contains SKETCH_EXTRUDE with h = full_h × op_progress so each frame carries a distinct numeric target.
{
"frame_idx": 5,
"op_idx": 4,
"op_type": "SKETCH_EXTRUDE",
"op_progress": 0.864,
"kind": "extrude",
"keyframe": false,
"action_op": [13, 27.65, 0],
"action_op_human": "SKETCH_EXTRUDE(h=27.65, kind=fresh)"
}op_progress is the fraction of the full extrude already drawn at this frame. Mostly in (0, 1.0]. With probability ~30% the second-to-last extrude frame overshoots to (1.0, 1.3] — explicitly trained-on negative-feedback signal for inverse-dynamics models.
Translation canonicalization
The renderer shifts each case so the final-mesh bbox is centered at world (0, 0, 0) before generating PNGs and actionop. Two cases that differ only by world translation produce identical PNGs + identical ops.json + identical actionop tuples, with the difference recorded ONLY in canonicalize_offset_mm. Recover original world coords with:
original_world_xyz = canonical_xyz + meta["canonicalize_offset_mm"]No rotation / scale canonicalization is applied — those would be lossy or brittle.
Coordinate frames
- Continuous params (length / coord) are in canonical-frame mm (canonicalization above).
world_bbox_*fields are also in canonical frame.cam_elev_azim_degis spherical:elevmeasured from XY plane,azimfrom +X axis CCW around +Z.front_dir = (cos·elev·cos·azim, cos·elev·sin·azim, sin·elev). Camera position =bbox_center + camera_distance × front_dir, looking back atbbox_center.
Per-clip vs dataset-wide normalization
Default: per-clip auto-fit (each clip fills ~62% of the frame). To recover physical mm from a PNG pixel:
mm_per_px = meta["approx_mm_per_pixel"]
mm_offset_from_image_center = pixel_offset × mm_per_pxIf meta["reference_bbox_diag"] is non-null, the renderer forced a constant world_diag_mm across the dataset → constant mm/pixel.
Sibling views share scale
For each base_uid, all sibling clips {base_uid}_v00..vNN share exactly the same world_bbox_*, world_diag_mm, and approx_mm_per_pixel. Only cam_elev_azim_deg differs. Use this contract to train view-invariant features.
Recommended downstream normalization recipe
# IDM training (predict action_op given video frames):
half_extent = max(
max(abs(c) for c in meta["world_bbox_min"]),
max(abs(c) for c in meta["world_bbox_max"]),
)
def normalize_coord(mm): return mm / half_extent # -> [-1, 1]
def normalize_length(mm): return mm / (half_extent * 2) # -> [0, 1]Apply the inverse at sampling / inference time.
For video frames: standard (x / 255 - mean) / std with ImageNet stats or per-dataset stats.
Format transition note
This dataset was migrated to v2-continuous-mm on 2026-05-29. Earlier flat prefixes have been removed. The data_hula_b01..b06 prefixes are being progressively re-rendered and overwritten to v2; until that chain finishes, a minority of bNNNN shards may still carry the older bin-quantized integer encoding (length [0,60] mm @ 128 bins, coord [-30,30] mm @ 128 bins). Always branch on meta["format_version"]: trust only shards whose meta/ops report "v2-continuous-mm".
Source
Cases are parsed from `filapro/cad-recode` training splits and re-rendered with per-op animation.
