gaoypeng/3dcodeverse/c3d-threejs-forms

Claude Code and agent skill by gaoypeng/3dcodeverse

Trust tier 3
  • community
  • ext:[{"type":"plugin","description":"Custom plugin integration"}]
Source check pending

Checking that the SKILL.md file is still in the repository.

Use when writing three.js object geometry in src/object.js or src/parts/*.js on the static_object track, in any session kind. Maps each FORM word in your manifest to the three.js geometry maker that produces it, names the traps that make a threejs part silently ship nothing, and states that this language has no boolean/CSG at all, so cavities and shells are built into the profile instead of subtracted. Options, not a recipe: what the part is made of is the brief's.

Install

npx vskill@latest install gaoypeng/3dcodeverse/c3d-threejs-forms

Semi-extensibleMentions customization, but needs skill-specific knowledge. Read the extensible skills standard

SKILL.md

FORM to three.js

When to use

You have a manifest (or a plan part row) and you are about to write src/parts/<snake>.js. Look up each FORM word, pick the maker that produces it, move on. Nothing here says what a chair or a lamp is made of; the brief and the plan do.

The table

The FORM words in the left column key the blender and cadquery tables too, so only this column changes when the language does.

formthree.jsnotes
revolved profileLatheGeometry(points, seg)points are Vector2(radius, y), spun about Y. Normals point out when the radius goes 0 → R → 0 bottom-up
extruded outlineExtrudeGeometry(shape, {depth, bevelEnabled:true, bevelSize, bevelSegments})extrudes along +Z; .rotateX(-Math.PI/2) to lay it flat with thickness along Y
tube swept along a pathTubeGeometry(new CatmullRomCurve3(pts), tubular, radius, radial, closed)the clean way to a handle, cable, rail or hoop
slabBoxGeometry(w,h,d), or RoundedBoxGeometry(w,h,d,seg,r) from three/addons/geometries/RoundedBoxGeometry.jsthe rounded one is the cheap way to a soft edge where the brief or the judged view wants one
shaftCylinderGeometry(r, r, h, radial)axis is Y; rotate the group, not the geometry, when you need another axis
tapered solidCylinderGeometry(rTop, rBottom, h, radial) or ConeGeometry(r,h,seg)two different radii give a taper at no triangle cost
ring or bandTorusGeometry(R, r, radial, tubular)lies in the XY plane; .rotateX(Math.PI/2) to lay it flat
carved cavityno boolean exists here — put the recess in the profile: a Shape with a Path pushed into shape.holes, a LatheGeometry profile that climbs the outside and comes back down the inside, or slabs around the openingsee "There is no CSG" below
shell with wall thicknessa LatheGeometry whose profile traces outer wall up, across the rim, inner wall downone geometry, watertight, with a visible open rim
mirror pairbuild once, add twice with mesh.position.x = ±dnever scale.set(-1,1,1): a negative scale inverts the winding and exports reversed normals
radial arrayone geometry, InstancedMesh(geo, mat, N) with M.makeRotationY(i/N * 2π)derive the angle from N; see the instancing trap below
layered or inseta thin second slab slightly proud of or sunk into the face, in its own materialthe cheapest panel break there is
faceted solidraw BufferGeometry: Float32BufferAttribute positions + setIndex + `computeVertexNormals()`without the normals call it shades black
lofted transitionLatheGeometry when it is round-to-round; otherwise a raw BufferGeometry ring-to-ring stripthree r182 has no loft primitive

mergeGeometries from three/addons/utils/BufferGeometryUtils.js collapses many static pieces of one part into one mesh. Merge inputs must share the same attribute set (geo.deleteAttribute('uv') or toNonIndexed() everything) or it returns null, and call computeVertexNormals() after.

Segments and triangles

Under-segmenting is the most common reason a lathe or a tube reads as a prism in the render sheet. Segment counts are not measured; the triangle total is — the depth gate WARNs below 350 triangles per built object and ERRORs above 20 000 (the ceiling for the whole object is 600 000). A SphereGeometry(r, 64, 64) repeated a hundred times is 800 k triangles and over that ceiling; the detail belongs on the shapes that fill the silhouette.

There is no CSG

runtime_js/package.json ships three and puppeteer only — there is no three-bvh-csg, no Brush, no Evaluator, and the lint allows imports of three, three/addons/* and relative files under src/ and nothing else. So a boolean operation is not available to you at all, in either direction.

That changes how you plan a cavity. A cup is not "a cylinder minus a smaller cylinder"; it is one lathe profile that goes up the outer wall, across the rim and back down the inner wall. A bracket with a bolt hole is not a plate minus a cylinder; it is a Shape with an absarc Path in shape.holes. A slot in a face is slabs around the opening, or a hole in the extrude outline. Each of those is one geometry, stays watertight, and exports cleanly — which subtraction in this language would not, because it does not exist.

The traps that actually bite

  1. The file name is the export name. src/parts/seat_cushion.js must

export function buildSeatCushion(THREE) — the lint derives the expected name from the file stem (codeverse3d/languages/threejs/__init__.py). A misspelt name is a WARN; no build* export in the file at all is an ERROR.

  1. A part file nobody imports ships nothing. src/object.js must import each

part builder and add its Group to the root. An unimported src/parts/*.js is a WARN ("dead part file?"), the build succeeds, and the part is simply absent from the GLB — this is a real, recorded failure mode in the blender track and the same lint rule exists here.

  1. An `InstancedMesh` reads as N separate pieces. The harness replaces an

InstancedMesh named Bolts with sibling meshes Bolts_0 … Bolts_{n-1} (matrices baked), so the connectivity gate measures every copy on its own. In runs/e2e_bench_threejs a FastenerBolts part produced 39 tiny disconnected island warnings: copies that touch nothing are islands or floaters, copies within the gate's 2 mm of the surface they fasten are contacts.

  1. Never resize with `root.scale`. Writing your dimensions in one unit and

then setting root.scale.set(0.01, ...) to convert makes the bounds and the contract gate disagree, because they read the scaled and unscaled geometry inconsistently. Build the geometry at the size the contract asks for.

  1. `ShaderMaterial` and every texture are lost. GLB export keeps

MeshStandardMaterial / MeshPhysicalMaterial and vertex colours only. The module is imported in node with no DOM, so TextureLoader / ImageLoader / FileLoader and any document or window reference are hard lint ERRORs — colour, roughness, metalness and vertex colours are the whole palette.

  1. Faceted or black shading after any manual edit → you skipped

computeVertexNormals().

  1. `mesh.position` versus `geometry.translate()`. Position moves the pivot

and is what you want for a part placed at its world pose; .translate() bakes the offset into the vertices and is what you want before a merge. Doing both by accident doubles the offset.

  1. Names that no longer exist in r182 (mergeBufferGeometries, three/examples/js/*,

Geometry, Face3, sRGBEncoding, outputEncoding) are listed in the contract's Imports section; each is an undefined import, not a deprecation.

What the part must return

One THREE.Group per plan part, returned at its world pose and added to the root in src/object.js. Everything inside it — merged detail, instanced repeats, raw BufferGeometry — is invisible to the part-level gates, which is exactly why the detail belongs in there. The object's naming and frame rules are in the contract; dimensions and tolerances belong to c3d-bbox-contract; contact and overlap belong to c3d-part-contact.

Strong options (none of them required)

Merging without islands. mergeGeometries keeps every input's vertices, so two pieces that merely overlap stay two shells inside one mesh and the connectivity gate counts the small one as stray geometry. Merge only what is genuinely one piece, make seams share vertices where they can, and normalise the inputs first (toNonIndexed(), deleteAttribute('uv')) so the merge does not return null.

Contact by construction. The gate counts a surface gap of 2 mm or less as contact (flush included) and penetration beyond 2 mm as a WARN, so a part whose face is computed from its neighbour's bounds lands inside that band without nudging.

Where triangles pay. The depth gate measures the total only, so spend it on the silhouette and on the faces the judged views see — the front, eye height, where two materials meet — inside the plan part, not on the underside, the back or interior volumes. A radius on the edges hands touch is what reads as manufactured; a subdivided flat panel reads as nothing.

Depth

references/form_recipes.md — each form word under its r182 API name with the trap that bites it, including the cavity and shell profiles that replace the boolean you do not have.

Security

  • Security scanPassed, 90 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
176
Repository forks
12
7-day trend score
0

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Extension points

  • pluginCustom plugin integration

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/gaoypeng/3dcodeverse/c3d-threejs-forms/badge)](https://verified-skill.com/skills/gaoypeng/3dcodeverse/c3d-threejs-forms)

Something wrong with this skill or its page? Tell us.