Skip to content

binary-core-llc/bowerbot

Repository files navigation

BowerBot

BowerBot

AI-powered OpenUSD scene assembly.

From empty scene to structured OpenUSD stage in seconds.

License Python OpenUSD YouTube Built by Binary Core LLC PRs Welcome


🐦 Meet BowerBot

In the rainforests of Australia and New Guinea lives one of nature's most remarkable architects: the bowerbird.

Instead of relying on appearance, the bowerbird collects, curates, and arranges objects from its environment into a carefully constructed 3D composition. Every object is chosen. Every placement is intentional.

BowerBot brings that same idea to 3D pipelines.

BowerBot is an AI-assisted OpenUSD scene assembly tool. It helps you go from an empty scene to a structured, usable layout in seconds by:

  • finding assets from any connected source (Sketchfab, local disk, company DAM, or any custom provider)
  • placing them with spatial awareness
  • organizing them into a valid USD stage

It does not try to replace the artist. It accelerates the part that is repetitive, mechanical, and time-consuming.

You stay in control of composition, lighting, and final polish. BowerBot gets you there faster.


🎯 What BowerBot Is (and Is Not)

BowerBot is:

  • A scene bootstrapper for OpenUSD pipelines
  • A fast way to go from 0 β†’ structured scene
  • A conversational interface for asset search, placement, and layout
  • A pipeline assistant that handles technical correctness (units, hierarchy, references)
  • A pipeline guardian that catches asset issues before they reach production

BowerBot is NOT:

  • A final scene generator
  • A replacement for DCC tools like Maya or Omniverse
  • A system that produces perfect composition or artistic layouts

Scenes generated by BowerBot are meant to be opened, reviewed, and refined in your DCC.

Think of it as:

"Block out the scene instantly, then refine like a pro."

Pipeline Quality Built In

BowerBot doesn't just place assets β€” it enforces ASWF USD standards at every step. When an asset doesn't follow production guidelines (wrong root prim type, missing defaultPrim, incorrect metersPerUnit), BowerBot catches it at assembly time and tells you exactly what's wrong and how to fix it.

This means problems that would normally surface weeks later in lighting, rendering, or review β€” broken references, unit mismatches, non-compliant asset structure β€” are caught the moment the asset enters the scene. Fix it once at the source, and every downstream department benefits.

"The cheapest bug to fix is the one you catch before it enters the pipeline."


✨ What It Does

$ bowerbot open coffee_shop

You: Search my Sketchfab for a round bistro table and download it
BowerBot: Found "Round Bistro Table". Downloaded to assets/Round_Bistro_Table.usdz

You: Place it at the center of the room
BowerBot: Placed at /Scene/Furniture/Round_Bistro_Table_01 (5.0, 0.0, 4.0)

You: Find an espresso cup in my local assets and place it on the table surface
BowerBot: Found espresso_cup.usdz. Table surface at Y=0.74.
         Placed at /Scene/Products/Espresso_Cup_01 (5.0, 0.74, 4.0)

You: Move the cup to the left side of the table
BowerBot: Moved to (4.7, 0.74, 4.0) β€” within table bounds.

You: Validate and package
BowerBot: All checks passed. Packaged to scenes/coffee_shop/scene.usdz

Open the .usda in Maya, usdview, Omniverse, or any USD-compatible DCC to refine composition, lighting, and materials.

BowerBot gets you to a clean, structured starting pointβ€”fast. From there, you take it to production quality.

Projects are persistent. Close the session, come back later, and continue where you left off.


✨ Features

  • πŸ“¦ OpenUSD native : references, defaultPrim, metersPerUnit, upAxis, all correct out of the box
  • πŸ—οΈ ASWF USD asset folders : automatically assembles assets into ASWF-compliant folder structure (root + geo.usda + mtl.usda). ASWF (Academy Software Foundation) hosts the USD Working Group that defines asset structure standards used across the industry. It works alongside the Alliance for OpenUSD (AOUSD) β€” the joint effort by Pixar, Apple, NVIDIA, and others driving the core OpenUSD specification.
  • 🎨 Material binding : apply materials to specific mesh parts, defined inline in asset folder mtl.usda
  • πŸ”Œ Pluggable skills : connect any asset source (Sketchfab, PolyHaven, company DAM, or build your own)
  • πŸ’‘ Native USD lighting : create sun, dome, point, area, disk, and tube lights
  • 🧩 Automatic unit handling : assets in cm, mm, or inches are scaled correctly at reference time
  • πŸ“ Geometry-aware placement : uses bounding boxes to place objects on surfaces
  • πŸ—£οΈ Conversational assembly : guide scene construction through natural language
  • 🧠 Multi-LLM support : OpenAI, Anthropic, and any provider via litellm
  • πŸ“ Project-based workflow : one folder per scene, resumable across sessions
  • βœ… Scene validation : ensures technical correctness before reaching your DCC
  • πŸ“¦ USDZ packaging : export for Apple Vision Pro, Omniverse, or any USD viewer
  • πŸ—οΈ Onboarding wizard : zero-config setup in 60 seconds

πŸ”„ How It Works

BowerBot is conversational β€” you tell it what you want and it uses the right tools to build your scene. Behind the scenes, it manages asset discovery, USD composition, materials, lighting, and more.

Asset Discovery

BowerBot searches for assets across all connected sources, prioritizing what's already available:

  1. Local assets first β€” BowerBot checks your local asset directory (assets_dir in config.json) for USD files (.usd, .usda, .usdc, .usdz). This includes anything you've exported from Maya, Houdini, Blender, or any DCC tool, as well as assets previously downloaded from cloud providers.

  2. Cloud providers if needed β€” If the asset isn't found locally, BowerBot searches connected providers like Sketchfab, and downloads the asset to your local directory. Future skills will add support for PolyHaven, Fab, CGTrader, Objaverse, and custom company DAMs.

  3. All downloads are cached locally β€” Once an asset is downloaded from any source, it lives in your assets_dir and is available for all future projects without re-downloading.

Scene Assembly

When you ask BowerBot to place an asset, it handles the USD composition correctly depending on the source:

  • Loose USD geometry (.usd, .usda, .usdc from your DCC exports) β€” BowerBot wraps it in an ASWF USD Working Group compliant folder structure: asset_name/asset_name.usda (root) + geo.usda. This follows the ASWF asset structure guidelines used by major studios.

  • USDZ files (from Sketchfab, DAMs, etc.) β€” Placed as-is since they're already self-contained packages with geometry and materials bundled.

  • Existing ASWF folders β€” Copied whole into the project, preserving the folder structure.

Material Workflow

When you apply materials to an asset, BowerBot writes them into the asset folder's mtl.usda β€” not into the scene file. The scene stays clean with only references:

You: Apply wood material to the table top
BowerBot: [searches local assets for "wood" materials]
         [discovers mesh parts: table top, legs, frame]
         [writes material definition + binding into assets/table/mtl.usda]
         Bound /table/mtl/wood_varnished to table top

The result is a production-ready asset folder:

assets/single_table/
  single_table.usda   <- root (references geo + mtl)
  geo.usda            <- geometry (untouched from source)
  mtl.usda            <- materials inline + bindings

Scene Output

The scene file (scene.usda) contains only references and lights β€” no material data, no geometry copies, no sublayers. Clean and readable:

def Xform "Scene" (kind = "assembly") {
    def Xform "Furniture" {
        def Xform "Table_01" {
            xformOp:translate = (5, 0, 4)
            xformOp:scale = (0.01, 0.01, 0.01)
            def Xform "asset" (
                references = @assets/single_table/single_table.usda@
            ) { }
        }
    }
    def Xform "Lighting" {
        def DistantLight "Sun_01" { ... }
        def DomeLight "Environment_01" { ... }
    }
}

Open it in Maya, Omniverse, usdview, or any USD-compatible tool to refine.


πŸš€ Quick Start

Requires uv (handles Python automatically).

# Clone
git clone https://github.com/binary-core-llc/bowerbot.git
cd bowerbot

# Install
uv sync

# First-time setup (creates ~/.bowerbot/config.json)
uv run bowerbot onboard

# Create a project and start building
uv run bowerbot new "Coffee Shop"
uv run bowerbot open coffee_shop

The onboard wizard asks for your LLM API key and optional Sketchfab token. Everything is stored in ~/.bowerbot/config.json. One file, one place, no .env.


πŸ“Ί Tutorials

New to BowerBot? Watch the tutorial playlist on YouTube for setup walkthroughs, scene building demos, and tips for working with USD pipelines.


πŸ› οΈ CLI Commands

Command Description
bowerbot new "name" Create a new project
bowerbot open name Open a project and start chatting
bowerbot list Show all projects
bowerbot chat Auto-detect project in current directory
bowerbot build "prompt" Single-shot build (auto-creates project)
bowerbot skills List scene builder tools and enabled skills
bowerbot info Show current configuration
bowerbot onboard First-time setup wizard

πŸ“ Projects

BowerBot uses a project-based workflow. Each project is a self-contained folder:

scenes/coffee_shop/
  project.json            # Metadata: name, created, updated, object count
  scene.usda              # The USD stage (references only β€” clean and readable)
  scene.usdz              # Packaged output (for Apple Vision Pro, Omniverse, etc.)
  assets/                 # Assets used by this project
    single_table/         # ASWF asset folder (auto-created when placing loose geometry)
      single_table.usda   #   Root file (references geo.usda + mtl.usda)
      geo.usda            #   Geometry layer (copied from source)
      mtl.usda            #   Materials defined inline + bindings
    CafeTable.usdz        # Self-contained asset (from Sketchfab, DAM, etc.)

When you place a loose geometry file from your local assets (.usd, .usda, .usdc), BowerBot automatically wraps it in an ASWF-compliant asset folder. When you apply materials, they're written inline into mtl.usda. USDZ files (from Sketchfab, DAMs, etc.) are placed as-is since they're already self-contained.

Projects are resumable:

$ bowerbot open coffee_shop
# Project: Coffee Shop
# Scene: scene.usda (5 object(s))

You: Show me the scene structure
BowerBot: Scene has 5 objects...

You: Remove Table_03
BowerBot: Removed /Scene/Furniture/Table_03

πŸ”Œ Skills

Skills are pluggable tools the agent uses. Each skill has a Python module for execution and a SKILL.md file that teaches the LLM when and how to use it.

Scene Builder Tools

BowerBot's core tools for building USD scenes:

Tool Description
create_stage Initialize a new USD scene with standard hierarchy
place_asset Add an asset (auto-creates ASWF folder for loose geometry)
move_asset Reposition an existing object without creating duplicates
compute_grid_layout Calculate evenly spaced positions
list_scene Show current scene with positions and bounding boxes
rename_prim Move/rename objects in the hierarchy
remove_prim Delete objects from the scene
create_light Add native USD lights (sun, dome, point, area, disk, tube)
update_light Modify an existing light's properties
remove_light Delete a light from the scene or asset
bind_material Apply a material to a specific mesh part (writes into asset mtl.usda)
remove_material Clear material binding from a prim
list_materials Show all materials and their bindings
list_prim_children Discover mesh parts inside a referenced asset
list_project_assets Show asset folders with scene usage status
delete_project_asset Remove an asset folder (checks references first)
delete_project_texture Remove a texture file (checks references first)
validate_scene Check for USD errors
package_scene Bundle as .usdz

Extension Skills

Skills extend BowerBot with new asset sources and capabilities. Each skill has a Python module for execution and a SKILL.md file that teaches the LLM when and how to use it.

Local : Searches the asset directory for USD files on disk. Detects ASWF asset folders as single packages and classifies loose files as geometry (geo) or material (mtl).

Sketchfab : Searches and downloads models from your own Sketchfab account in USDZ format. These are your curated assets, not the public marketplace.

Textures : Searches the asset directory for texture files. Finds HDRIs (.hdr, .exr) for dome lights and material maps (.png, .jpg, .tif) for surfaces.

More providers are planned (PolyHaven, Fab, CGTrader, Objaverse), and you can write your own skill for any asset source β€” see CONTRIBUTING.md.


βš™οΈ Configuration

All settings live in ~/.bowerbot/config.json:

{
  "llm": {
    "model": "gpt-4.1",
    "api_key": "sk-...",
    "temperature": 0.1,
    "max_tokens": 4096,
    "context_window": null,
    "summarization_threshold": 0.75,
    "num_retries": 3,
    "request_timeout": 120.0,
    "max_tool_rounds": 25
  },
  "scene_defaults": {
    "meters_per_unit": 1.0,
    "up_axis": "Y",
    "default_room_bounds": [10.0, 3.0, 8.0]
  },
  "skills": {
    "local": { "enabled": true },
    "sketchfab": {
      "enabled": true,
      "config": { "token": "your-sketchfab-token" }
    },
    "textures": { "enabled": true }
  },
  "assets_dir": "./assets",
  "projects_dir": "./scenes"
}

Switch models by changing one line:

{ "model": "gpt-4.1" }
{ "model": "anthropic/claude-sonnet-4-20250514" }
{ "model": "deepseek/deepseek-chat" }

Tested Models

Model Tool Calling Instruction Following Recommended
gpt-4.1 Excellent Excellent Yes (default)
gpt-4.1-mini Good Good Yes (budget)
gpt-4o Poor Poor No β€” skips tool calls, ignores SKILL.md
anthropic/claude-sonnet-4-20250514 Excellent Excellent Yes

BowerBot relies heavily on tool calling and SKILL.md instructions. Models that don't follow tool-calling patterns reliably will produce poor results.

Token Management

BowerBot automatically manages conversation context to stay within model limits. Two settings control this:

Setting Default Description
context_window null Context window size in tokens. null = auto-detect from the model.
summarization_threshold 0.75 Fraction of context budget that triggers history summarization.

Additional tuning options (usually don't need changing):

Setting Default Description
tool_result_age_threshold 2 User turns before old tool results are compressed.
min_keep_recent 6 Minimum recent messages always kept verbatim.
summary_max_tokens 512 Max tokens for the summarization LLM call.

Tool-Calling Loop

BowerBot runs a loop where the LLM requests tool calls, BowerBot executes them, and the results are fed back. Complex requests (e.g. binding materials to many mesh parts at once) can require many rounds.

Setting Default Description
max_tool_rounds 25 Maximum LLM ↔ tool exchange rounds per request. Increase if BowerBot stops with "Reached maximum tool-calling rounds" on legitimate workflows.

Error Recovery

BowerBot automatically handles transient API errors:

Setting Default Description
num_retries 3 Retries for rate limits and transient errors (429, 500, 503).
request_timeout 120.0 Seconds before a request times out.
  • Rate limits and transient errors are retried automatically with exponential backoff.
  • Validation errors are fed back to the LLM so it can auto-fix issues and re-validate.
  • Permanent errors (bad API key, unknown model) show a clear message without crashing.

πŸ—οΈ Architecture

src/bowerbot/
  agent.py                 # LLM tool-calling loop and prompt assembly
  scene_builder.py         # Adapter: translates LLM tool calls into engine operations
  cli.py                   # Click CLI
  config.py                # Settings from ~/.bowerbot/config.json
  project.py               # Project management (create/load/resume)
  token_manager.py         # Context compression and summarization

  prompts/                 # LLM instructions (markdown files, not code)
    core.md                #   Agent identity and behavior
    scene_building.md      #   Scene building rules and workflows

  engine/                  # Pure USD operations (no LLM concepts)
    stage_writer.py        #   Scene operations (create, place, light, rename, remove)
    asset_assembler.py     #   ASWF asset folder creation, materials, lights, asset preparation
    scene_graph.py         #   Spatial math (grids, walls, collisions, bounds offsets)
    validator.py           #   USD validation (defaultPrim, metersPerUnit, upAxis, refs)
    packager.py            #   USDZ packaging
    dependency_resolver.py #   USD file dependency tree walker

  skills/                  # Extension skills (asset providers, integrations)
    base.py                #   Skill interface and ToolResult
    registry.py            #   Entry point discovery and tool routing
    local/                 #   Local filesystem asset search + SKILL.md
    sketchfab/             #   Sketchfab API integration + SKILL.md
    textures/              #   Texture and HDRI search + SKILL.md

  schemas/                 # Pydantic data models
  utils/                   # Shared utilities
    usd_utils.py           #   USD introspection (ref paths, asset resolution, reference scanning)
    file_utils.py          #   Filesystem operations (texture copying)
    naming.py              #   Name sanitization for files, prims, and projects
  gateway/                 # Future: FastAPI + MCP server

Design principles:

  • Engine is pure USD : all pxr calls live in engine/ and utils/usd_utils.py
  • SceneBuilder is the adapter : translates LLM tool calls into engine operations, wraps results for the agent
  • Skills are extensions : asset providers and integrations, discovered via Python entry points
  • Prompts are content : stored as .md files, editable without touching Python
  • User controls the workflow : the agent follows instructions, not a hardcoded pipeline
  • Project-based : one folder per scene, resumable across sessions
  • One config file : ~/.bowerbot/config.json, no .env

πŸ“ USD Compliance

Every scene BowerBot produces follows OpenUSD best practices and the ASWF USD Working Group asset structure guidelines:

Scene level:

  • metersPerUnit = 1.0, upAxis = "Y", defaultPrim always set
  • Standard hierarchy: /Scene/Architecture, /Scene/Furniture, /Scene/Products, /Scene/Lighting, /Scene/Props
  • Scene file contains only references β€” no material sublayers or inline data
  • Wrapper prim pattern: scene-level transforms (position, rotation, scale) are separate from asset-internal transforms
  • Validated before packaging (defaultPrim, units, upAxis, references, sublayers, material bindings)

Asset level (ASWF compliant):

  • Loose geometry is automatically wrapped in ASWF asset folders on placement
  • Folder structure: asset_name/asset_name.usda (root) + geo.usda + mtl.usda
  • Root file uses references (not sublayers) per ASWF guidelines for predictable opinion strength
  • Materials are defined inline in mtl.usda β€” no loose material files scattered in the folder
  • DCC export transforms (Maya pivots, rotations) are preserved untouched inside the reference
  • Automatic unit conversion for assets with different metersPerUnit

🎨 The Mascot

BowerBot Mascot

Meticulous. Obsessive about quality. Always collecting. Never done decorating.


πŸ—ΊοΈ Roadmap

What's next for BowerBot β€” contributions welcome:

  • USD Variant Sets β€” ASWF-compliant variants on asset root prims (materials, geometry, lighting, configurations, and more)
  • Scene templates β€” JSON-driven scene assembly with asset resolution
  • DCC exporter β€” Maya/Houdini tool to export scene layout as BowerBot JSON
  • More asset providers β€” Fab, PolyHaven, Objaverse, CGTrader skills
  • MCP Gateway β€” FastAPI server for web UI and external AI clients
  • Web UI β€” chat panel + live 3D viewport
  • BowerHub β€” community skill registry

🀝 Contributing

BowerBot is open source and welcomes contributions. The best way to start is writing a new skill for an asset provider you use. See skills/sketchfab/ for a complete example.

Read CONTRIBUTING.md for guidelines.


πŸ“„ License

Copyright 2026 Binary Core LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Built with 🐦 by Binary Core LLC

"The bowerbird doesn't have the flashiest feathers. It just builds the most compelling world."

About

🐦 AI agent that assembles production-ready OpenUSD scenes from natural language β€” so you focus on creative decisions, not pipeline work

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Sponsor this project

Packages

 
 
 

Contributors

Languages