Primitive Geometries¶

Primitive geometries are the building blocks of 3D scenes. Vuer provides 14 fundamental geometric shapes that can be combined, transformed, and styled to create complex visualizations.

Shared Properties¶

All primitives share these properties:

from vuer.schemas import Box  # or any other primitive

Box(
    # Geometry-specific parameters
    args=[...],  # Varies by shape
    
    # Transform properties
    position=[x, y, z],      # Position in 3D space
    rotation=[rx, ry, rz],   # Rotation in radians around X, Y, Z axes
    scale=[sx, sy, sz],      # Scale factors (1 = original size)
    
    # Material properties
    materialType="standard",  # "basic", "lambert", "phong", "standard", "physical"
    color="#ff0000",         # Hex color or CSS color name
    material=dict(           # Advanced material properties
        roughness=0.5,
        metalness=0.0,
        # ... see Materials guide
    ),
    
    # Interaction
    key="unique-id",         # Required for updates and events
    onClick=handler,         # Click event handler (client-side)
)

Components¶

Box¶

A rectangular box or cube shape with customizable dimensions.

Box example

args = [
    width,           # default: 1
    height,          # default: 1
    depth,           # default: 1
    widthSegments,   # default: 1
    heightSegments,  # default: 1
    depthSegments    # default: 1
]
from vuer import Vuer, VuerSession
from vuer.schemas import Scene, Box

app = Vuer()

@app.spawn(start=True)
async def main(session: VuerSession):
    session.set @ Scene(
        # Simple cube
        Box(
            args=[1, 1, 1],
            position=[0, 0.7, 0.2],
            material=dict(color="red"),
            key="cube",
            outlines=dict(angle=0, thickness=0.005, color="white"),  # (angle, thickness, color)
        ),
        
        # Flat platform
        Box(
            args=[5, 0.2, 5],
            position=[0, 0.2, 0],
            material=dict(color="grey"),
            key="platform",
        ),
    )
    
    await session.forever()

Sphere¶

A perfect spherical shape with customizable radius and segment resolution.

Sphere example

args = [
    radius,          # default: 1
    widthSegments,   # default: 32 (horizontal segments)
    heightSegments,  # default: 16 (vertical segments)
    phiStart,        # default: 0 (horizontal starting angle)
    phiLength,       # default: 2Ï€ (horizontal sweep angle)
    thetaStart,      # default: 0 (vertical starting angle)
    thetaLength      # default: π (vertical sweep angle)
]
from vuer import Vuer, VuerSession
from vuer.schemas import Scene, Sphere

app = Vuer()

@app.spawn(start=True)
async def main(session: VuerSession):
    session.set @ Scene(
        # Simple sphere
        Sphere(
            args=[0.5],  # Just radius, use defaults for segments
            position=[0, 1, 0],
            material=dict(color="red"),
            key="ball",
        ),
        # High-poly smooth sphere
        Sphere(
            args=[0.5, 64, 64],  # More segments = smoother
            position=[2, 1, 0],
            material=dict(color="green"),
            key="smooth-ball",
        ),
        # Hemisphere (half sphere)
        Sphere(
            args=[0.5, 32, 16, 0, 6.28, 0, 1.57],  # thetaLength controls how much of sphere
            position=[4, 1, 0],
            material=dict(color="blue"),
            key="hemisphere",
        )
        
    )
    
    await session.forever()

Cylinder¶

A cylindrical tube shape with separate top and bottom radii.

Cylinder example

args = [
    radiusTop,       # default: 1
    radiusBottom,    # default: 1
    height,          # default: 1
    radialSegments,  # default: 32
    heightSegments,  # default: 1
    openEnded,       # default: False
    thetaStart,      # default: 0
    thetaLength      # default: 2Ï€
]
from vuer import Vuer, VuerSession
from vuer.schemas import Scene, Cylinder

app = Vuer()

@app.spawn(start=True)
async def main(session: VuerSession):
    session.set @ Scene(
        # Standard cylinder
        Cylinder(
            args=[0.5, 0.5, 2],
            position=[0, 1, 0],
            material=dict(color="green"),
            key="pillar",
        ),
        # Cone (radiusTop=0)
        Cylinder(
            args=[0, 0.5, 2],
            position=[2, 1, 0],
            material=dict(color="orange"),
            key="cone-shape",
        ),
        # Truncated cone
        Cylinder(
            args=[0.2, 0.5, 2],
            position=[4, 1, 0],
            material=dict(color="yellow"),
            key="truncated",
        ),
    )

    await session.forever()

Cone¶

A pointed cone shape with circular base and single apex.

Cone example

args = [
    radius,          # default: 1
    height,          # default: 1
    radialSegments,  # default: 32
    heightSegments,  # default: 1
    openEnded,       # default: False
    thetaStart,      # default: 0
    thetaLength      # default: 2Ï€
]
from vuer import Vuer, VuerSession
from vuer.schemas import Scene, Cone

app = Vuer()

@app.spawn(start=True)
async def main(session: VuerSession):
    session.set @ Scene(
        Cone(
            args=[0.5, 1.5],
            position=[0, 0.75, 0],
            rotation=[0, 0, 3.14],  # Point downward
            material=dict(color="orange"),
            key="cone",
        ),
    )

    await session.forever()

Plane¶

A flat rectangular surface with customizable dimensions.

Plane example

args = [
    width,           # default: 1
    height,          # default: 1
    widthSegments,   # default: 1
    heightSegments   # default: 1
]
from vuer import Vuer, VuerSession
from vuer.schemas import Scene, Plane

app = Vuer()

@app.spawn(start=True)
async def main(session: VuerSession):
    session.set @ Scene(
        # Horizontal ground
        Plane(
            args=[10, 10],
            position=[0, 0, 0],
            rotation=[-1.57, 0, 0],  # -Ï€/2 to make horizontal
            material=dict(color="grey"),
            key="ground",
        ),
        # Vertical wall
        Plane(
            args=[5, 3],
            position=[0, 1.5, -5],
            material=dict(color="white"),
            key="wall",
        ),
        # Two-sided plane
        Plane(
            args=[2, 2],
            position=[0, 1, 0],
            material=dict(side=2, color="blue"),  # 0=front, 1=back, 2=both
            key="double-sided",
        ),
    )

    await session.forever()

Circle¶

A flat circular disc with customizable radius and arc angle.

Circle example

args = [
    radius,          # default: 1
    segments,        # default: 32 (triangular facets)
    thetaStart,      # default: 0
    thetaLength      # default: 2Ï€ (full circle)
]
from vuer import Vuer, VuerSession
from vuer.schemas import Scene, Circle

app = Vuer()

@app.spawn(start=True)
async def main(session: VuerSession):
    session.set @ Scene(
        # Full circle
        Circle(
            args=[1],
            position=[0, 0, 0],
            rotation=[-1.57, 0, 0],
            material=dict(color="red"),
            key="disc",
        ),
        # Pac-Man (partial circle)
        Circle(
            args=[1, 32, 0, 5.5],  # thetaLength < 2Ï€ creates pac-man
            position=[2, 0, 0],
            rotation=[-1.57, 0, 0],
            material=dict(color="yellow"),
            key="pacman",
        ),
    )

    await session.forever()

Ring¶

A flat ring shape with hollow center (annulus).

Ring example

args = [
    innerRadius,     # default: 0.5
    outerRadius,     # default: 1
    thetaSegments,   # default: 32
    phiSegments,     # default: 1
    thetaStart,      # default: 0
    thetaLength      # default: 2Ï€ (full ring)
]
from vuer import Vuer, VuerSession
from vuer.schemas import Scene, Ring

app = Vuer()

@app.spawn(start=True)
async def main(session: VuerSession):
    session.set @ Scene(
        Ring(
            args=[0.5, 1],
            position=[0, 0, 0],
            rotation=[-1.57, 0, 0],
            material=dict(color="gold"),
            key="ring",
        ),
    )

    await session.forever()

Capsule¶

A pill-shaped cylinder with rounded hemispherical ends.

Capsule example

args = [
    radius,          # default: 1
    length,          # default: 1 (cylindrical section length)
    capSegments,     # default: 4 (curve segments for each cap)
    radialSegments   # default: 8
]
from vuer import Vuer, VuerSession
from vuer.schemas import Scene, Capsule

app = Vuer()

@app.spawn(start=True)
async def main(session: VuerSession):
    session.set @ Scene(
        Capsule(
            args=[0.3, 2],
            position=[0, 1, 0],
            material=dict(color="purple"),
            key="pill",
        ),
    )

    await session.forever()

Torus¶

A 3D donut shape with customizable major and minor radii.

Torus example

args = [
    radius,          # default: 1 (torus radius)
    tube,            # default: 0.4 (tube radius)
    radialSegments,  # default: 12 (segments along tube)
    tubularSegments, # default: 48 (segments around torus)
    arc              # default: 2Ï€ (complete torus)
]
from vuer import Vuer, VuerSession
from vuer.schemas import Scene, Torus

app = Vuer()

@app.spawn(start=True)
async def main(session: VuerSession):
    session.set @ Scene(
        # Complete torus
        Torus(
            args=[1, 0.3],
            position=[0, 1, 0],
            material=dict(color="pink"),
            key="donut",
        ),
        # Partial torus (C-shape)
        Torus(
            args=[1, 0.3, 12, 48, 4.71],  # arc < 2Ï€ creates C-shape
            position=[3, 1, 0],
            material=dict(color="cyan"),
            key="c-shape",
        ),
    )

    await session.forever()

TorusKnot¶

An intertwined knot shape with customizable winding parameters.

TorusKnot example

args = [
    radius,          # default: 1
    tube,            # default: 0.4 (tube radius)
    tubularSegments, # default: 64
    radialSegments,  # default: 8
    p,               # default: 2 (winds around rotational axis)
    q                # default: 3 (winds around central axis)
]
from vuer import Vuer, VuerSession
from vuer.schemas import Scene, TorusKnot

app = Vuer()

@app.spawn(start=True)
async def main(session: VuerSession):
    session.set @ Scene(
        # Trefoil knot (classic)
        TorusKnot(
            args=[1, 0.3, 100, 16, 2, 3],
            position=[0, 1, 0],
            material=dict(color="purple"),
            key="trefoil",
        ),
        # Cinquefoil knot
        TorusKnot(
            args=[1, 0.3, 100, 16, 3, 5],
            position=[3, 1, 0],
            material=dict(color="orange"),
            key="cinquefoil",
        ),
    )

    await session.forever()

Tetrahedron (4 faces)¶

A pyramid-shaped polyhedron with four triangular faces, representing the simplest platonic solid.

Tetrahedron example

args = [
    radius,          # default: 1
    detail           # default: 0 (subdivision level)
]
from vuer import Vuer, VuerSession
from vuer.schemas import Scene, Tetrahedron

app = Vuer()

@app.spawn(start=True)
async def main(session: VuerSession):
    session.set @ Scene(
        Tetrahedron(
            args=[1],
            position=[0, 1, 0],
            material=dict(color="red"),
            key="tetra",
        ),
    )

    await session.forever()

Octahedron (8 faces)¶

A diamond-shaped polyhedron with eight triangular faces, often used for gem-like objects.

Octahedron example

args = [
    radius,          # default: 1
    detail           # default: 0 (subdivision level)
]
from vuer import Vuer, VuerSession
from vuer.schemas import Scene, Octahedron

app = Vuer()

@app.spawn(start=True)
async def main(session: VuerSession):
    session.set @ Scene(
        Octahedron(
            args=[1],
            position=[0, 1, 0],
            material=dict(color="green"),
            key="octa",
        ),
    )

    await session.forever()

Dodecahedron (12 faces)¶

A soccer ball-like polyhedron with twelve pentagonal faces, creating a nearly spherical shape.

Dodecahedron example

args = [
    radius,          # default: 1
    detail           # default: 0 (subdivision level)
]
from vuer import Vuer, VuerSession
from vuer.schemas import Scene, Dodecahedron

app = Vuer()

@app.spawn(start=True)
async def main(session: VuerSession):
    session.set @ Scene(
        Dodecahedron(
            args=[1],
            position=[0, 1, 0],
            material=dict(color="blue"),
            key="dodeca",
        ),
    )

    await session.forever()

Icosahedron (20 faces)¶

A complex polyhedron with twenty triangular faces, the most sphere-like of the platonic solids.

Icosahedron example

args = [
    radius,          # default: 1
    detail           # default: 0 (subdivision level)
]
from vuer import Vuer, VuerSession
from vuer.schemas import Scene, Icosahedron

app = Vuer()

@app.spawn(start=True)
async def main(session: VuerSession):
    session.set @ Scene(
        Icosahedron(
            args=[1],
            position=[0, 1, 0],
            material=dict(color="purple"),
            key="icosa",
        ),
    )

    await session.forever()

Detail parameter: Higher values subdivide faces for smoother appearance:

  • detail=0: Sharp edges (default)

  • detail=1: Slightly rounded

  • detail=2+: Approaches sphere

Tips¶

  1. Segment count affects performance: Higher segments = smoother but slower

    • Use low poly (8-16 segments) for distant/small objects

    • Use high poly (32-64 segments) for close-up hero objects

  2. Box is fastest, use for prototyping

  3. Sphere is expensive, consider Icosahedron for low-poly style