npx skills add ...
npx skills add roble3/cc-blender-skill --skill wireframe-to-3d
Convert 2D orthographic wireframe PNG drawings to 3D Blender models exported as glTF/GLB. Use this skill whenever the user provides wireframe images (technical drawings, line drawings, orthographic views, side/front/back panels) and wants to generate a 3D model, mesh, or .glb file. Triggers on phrases like "convert this wireframe to 3D", "make a 3D model from these drawings", "build a model from this wireframe", "generate GLB from these views", or any image-to-3D-mesh request involving line drawings. Make sure to use this skill even if the user does not explicitly say "wireframe" — also covers "orthographic views", "technical drawings", "line drawings of objects", "front and side views". Requires the Blender MCP addon to be running (port 9876) and Python with opencv-python, numpy, scipy installed.
npx skills add roble3/cc-blender-skill --skill wireframe-to-3d
Convert 2D orthographic wireframe images to parametric 3D Blender models, exported as glTF 2.0 binary (.glb).
The skill drives a four-stage pipeline:
scripts/wireframe_analyzer.py (OpenCV → Bezier control points in JSON).mcp__blender__execute_blender_code, converting curves to meshes with PBR materials.You (Claude) are the orchestrator. The scripts/ directory contains the only standalone code (wireframe_analyzer.py); everything else is patterns you emit and run via MCP.
Before any wireframe work, verify the environment:
Blender MCP is reachable. Call mcp__blender__get_scene_info. If it errors with "Could not connect to Blender", stop and tell the user:
"Blender's MCP addon isn't running. Start Blender, enable the BlenderMCP addon (port 9876), then re-run."
Python deps for the analyzer. Run:
If it errors, run pip install opencv-python numpy scipy Pillow (or instruct the user to).
Image input. Confirm the user provided at least one PNG. Reasonable bounds: ≥ 400×400 px, black-on-white or white-on-black line art.
preview — RDP epsilon = 4.0, target ~1–2k tris, < 1 MB GLB.production — RDP epsilon = 2.0, target ~5–8k tris, 2–4 MB GLB. Default.high — RDP epsilon = 1.0, target ~10–20k tris, may need Decimate to stay under 15 MB.wires — frames, arms, hinges. Use bevel_depth on curves.surfaces — lenses, domes. Use lofted profiles or fill caps.hybrid — both. Default for glasses-like objects.Run the bundled analyzer once per view:
The script outputs JSON with this shape:
Tuning RDP epsilon (only if defaults fail):
--rdp-epsilon (or edit the call in the script).Read the JSON with Read. Do not pass huge JSON blobs to Blender — extract what you need first.
Build code in small, self-contained chunks (each execute_blender_code call gets a fresh Python namespace; only bpy.data persists between calls). Always re-import what you need.
Pixel → world conversion (do this in the code you generate, before sending to Blender):
Material presets (use these unless the user specifies):
MAT-frame-metal — (0.08, 0.08, 0.10) base, metallic=1.0, roughness=0.25 (brushed steel)MAT-lens-mirror — (0.05, 0.08, 0.15) base, metallic=0.8, roughness=0.05, IOR=1.5 (mirror glass)MAT-pad-silicone — (0.65, 0.63, 0.60) base, metallic=0.0, roughness=0.7 (matte silicone)If size_mb > 15: apply Decimate and re-export (see error recovery).
After the full pipeline, validate before declaring success:
mcp__blender__get_scene_info — confirm expected objects exist.mcp__blender__get_object_info on each and compare bounding box widths. Tolerance: 1 mm.get_object_info. If a part exceeds budget, plan Decimate.| Symptom | Likely cause | Fix |
|---|---|---|
Code execution error: ... from MCP | Bad Python in generated code | Re-emit code in smaller chunks; trace the line from the error message |
Could not connect to Blender | Addon not running | Tell the user to start Blender + addon |
Timeout waiting for Blender response | Code chunk too large or slow | Break into smaller execute_blender_code calls |
| Variables undefined across calls | Each call gets a fresh namespace | Re-import modules; refer to objects by bpy.data.objects['name'] |
| Analyzer outputs 0 contours | Image too low contrast | Re-run with --gaussian-kernel 7 --canny-t1 30 |
| Asymmetric lenses | Original drawing asymmetric, or contour detection inconsistent | Warn the user; do not auto-mirror unless asked |
| GLB too large | High poly count or embedded textures | Apply DECIMATE modifier with ratio 0.6–0.8; re-export |
| Mesh has holes | Curve resolution too low | Raise curve_data.resolution_u to 24 or 32; reconvert |
| Material missing in GLB | Used non-Principled-BSDF nodes | Rebuild material using only Principled BSDF |
When done, report:
Example:
✓ Exported
/tmp/wireframe_output.glb(2.4 MB)
Triangles: 5 200 (3 parts: GEO-frame, GEO-lens-right, GEO-lens-left)
Materials: MAT-frame-metal, MAT-lens-mirror
Warnings: none
The body above covers the 80% case. For the long tail, load these on demand:
references/algorithms.md — image-processing pipeline theory (Canny, RDP, least-squares Bezier fitting), 2D-to-3D reconstruction principles, ISO 128 orthographic standards. Load when the analyzer output looks wrong and you need to tune parameters.references/blender-patterns.md — exhaustive Blender Python patterns (lofting, surface revolution, custom modifier stacks). Load when the user requests non-standard geometry (curved surfaces, complex bridges, articulated parts).references/best-practices.md — performance optimization (foreach_set, batch ops, context caching), naming conventions (Blender Studio standards), modifier stack ordering. Load when builds are slow or output topology is poor..bin + textures sidecar; no KTX2/Draco compression — Three.js needs extra loaders we haven't vendored).If the user just says "convert this wireframe", default to: view_type=auto-detect, detail_level=production, geometry_type=hybrid, world_width_mm=auto. Only ask for clarification if multiple interpretations are plausible.