---
name: spatial-computing
description: Visualizes floorplans from URDF scene files and inserts/removes 3D assets with collision-aware placement on surfaces. Supports semantic instance matching via LLM (e.g., "put lamp on bookshelf", "delete sofa in living room"). Use when working with URDF/USD indoor scenes, floorplan visualization, object placement/deletion, or room-level scene editing.
---
# Floorplan & Object Placement/Deletion
## Overview
Parse indoor scenes from URDF, generate 2D floorplans, or place/remove 3D objects in scenes and write back to URDF/USD. After successful insertion/deletion, the corresponding file is automatically updated based on whether `urdf_path`/`usd_path` is provided.
**When to use**: Use this skill when you need to generate floorplans from URDF, place/delete objects on specified rooms/furniture surfaces, or batch update URDF/USD files.
> ⚠️ **USD updates require `room-cli`**: To update USD files, you **must** use `room-cli` instead of `python -m`, and specify the USD file via `--usd_path`. `room-cli` runs on Blender Python which includes the `bpy` module for OBJ→USD conversion; using `python -m` with `--usd_path` will fail with `ModuleNotFoundError: No module named 'bpy'`.
>
> ```bash
> # ✅ Correct: use room-cli to update both URDF and USD
> room-cli -m embodied_gen.skills.spatial-computing.cli.main \
> --urdf_path .../scene.urdf --usd_path .../scene.usdc ...
**Smart File Naming Strategy**:
- **Default behavior**: First operation creates `scene_updated.urdf`, subsequent operations automatically overwrite it
- **No file bloat**: Prevents `*_updated_updated.urdf` files from accumulating
- **Safe**: Original `scene.urdf` is never modified unless explicitly requested
- **Works for both insert and delete**: Seamless continuous scene editing
---
## Best Practices & Constraints
### 1. Workflow for Continuous Scene Editing
**Recommended workflow** for multiple insert/delete operations:
```bash
# Step 1: View current scene
python -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path .../scene.urdf --list_instances
# Step 2: First insert → creates scene_updated.urdf
python -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path .../scene.urdf \
--asset_path .../apple.obj --instance_key apple_1
# Step 3: Second insert → overwrites scene_updated.urdf
python -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path .../scene_updated.urdf \
--asset_path .../lamp.obj --instance_key lamp_1
# Step 4: Delete operation → overwrites scene_updated.urdf
python -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path .../scene_updated.urdf \
--delete_instance apple_1
```
**Key benefits**:
- ✅ No multiple `*_updated_updated.urdf` files
- ✅ Original file `scene.urdf` always preserved
- ✅ Continuous insert/delete operations are seamless
**Result**: Clean workflow with only two files:
- `scene.urdf` (original, untouched)
- `scene_updated.urdf` (final state)
### 2. When to Use Different Strategies
| Strategy | Use Case | Example |
|----------|----------|---------|
| **suffix** (default) | Standard workflow, continuous editing | Most scenarios |
| **timestamp** | Version tracking, backup before risky changes | `scene_20260311_180235.urdf` |
| **overwrite** | Confident single operation, no backup needed | Automated pipelines |
### 3. Performance Optimization: Batch Insert
**Problem**: CLI commands re-parse URDF and process all meshes on every call, leading to slow performance when inserting multiple objects.
**Solution**: Use `--batch_insert_config` with JSON config for 3-4x speedup:
**Step 1**: Create JSON config file (`batch_chairs.json`):
```json
[
{
"asset_path": "path/to/chair1.obj",
"instance_key": "chair_1",
"beside_instance": "table_dining_7178300",
"in_room": "dining_room_0_floor"
},
{
"asset_path": "path/to/chair2.obj",
"instance_key": "chair_2",
"beside_instance": "table_dining_7178300",
"in_room": "dining_room_0_floor"
},
{
"asset_path": "path/to/chair3.obj",
"instance_key": "chair_3",
"beside_instance": "table_dining_7178300",
"in_room": "dining_room_0_floor"
}
]
```
**Step 2**: Run batch insertion:
```bash
# Update URDF only
room-cli -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path .../scene.urdf \
--batch_insert_config batch_chairs.json
# Update both URDF and USD
room-cli -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path .../scene.urdf \
--usd_path .../scene.usdc \
--batch_insert_config batch_chairs.json
```
**JSON Config Fields**:
- `asset_path` (required): Path to asset mesh file (.obj)
- `instance_key` (required): Unique instance identifier
- `beside_instance`: Place beside target instance (on floor). **Must be exact name**.
- `on_instance`: Place on top of target instance. **Must be exact name**.
- `in_room`: Limit placement to specified room. **Must be exact name**.
- `beside_distance`: Max distance from target (default: 0.5m)
- `place_strategy`: "random" or "top" (default: "random")
> **⚠️ Batch insert does NOT support fuzzy/semantic matching.**
> `beside_instance`, `on_instance`, and `in_room` require exact names.
> Use `--list_instances` to get the exact instance / room names first:
> ```bash
> python -m embodied_gen.skills.spatial-computing.cli.main \
> --urdf_path .../scene.urdf --list_instances
> ```
**When to Use**:
- ✅ Inserting 2+ objects at once
- ✅ Performance-critical workflows
- ✅ Automated scene generation pipelines
⚠️ **Batch config file cleanup**: The JSON config file for `--batch_insert_config` is a **temporary file** and **must not** be left in the project root directory. Always:
1. Create the JSON config in the **same directory as the target scene** (e.g., `.../House_seed5/batch_fruits.json`).
2. **Delete the JSON config file immediately after the batch command finishes**, regardless of success or failure.
### 3. Important Constraints
❌ **Wrong**: Using `scene.urdf` for all operations (ignores previous changes)
```bash
# This will NOT see apple_1 from previous operation
python -m ... --urdf_path scene.urdf --asset_path lamp.obj
```
✅ **Right**: Chain operations using `scene_updated.urdf`
```bash
# This WILL see apple_1 and add lamp_1
python -m ... --urdf_path scene_updated.urdf --asset_path lamp.obj
```
---
## LLM Environment (Required for Semantic Matching)
Before using `resolve_instance_with_llm` for semantic matching in **Python**, configure the LLM API and ensure access to the interface. Prompt the user if access is unavailable.
```bash
# Use the project-provided env (Azure + proxy, etc.), if outputs/env.sh exists:
source outputs/env.sh
```
---
## Core Convention: Placement/Deletion/Query Requests Must Use This Skill's Interface
When users request "put A somewhere", "delete A", "find A", or "visualize urdf", you **must** implement it using this skill's interface:
| User Request Example | Corresponding Parameter & Usage |
|---------------------|---------------------------------|
| **Put A on B** (e.g., "put lamp on bookshelf") | `on_instance` (instance name, obtained from `--list_instances`) |
| **Put A beside B** (e.g., "put chair beside table") | `beside_instance` (instance name, obtained from `--list_instances`); placed on floor near target |
| **Put A in a room** (e.g., "put table in living room") | `in_room` (room name, obtained from `--list_instances`) |
| **Put A beside B in a room** (e.g., "put chair beside table in kitchen") | `beside_instance` + `in_room` |
| **Put A on B in a room** (e.g., "put apple on table in living room") | Decomposed into "apple" and "living room" as `in_room` and `on_instance` |
| **Delete A** (e.g., "delete lamp") | `delete_instance` (instance name or semantic description, supports fuzzy matching with LLM) |
| **Delete A in a room** (e.g., "delete sofa in living room") | `delete_instance` + `delete_in_room` (only deletes if instance is in specified room) |
| **Find A** (e.g., "find lamp", "where is the bed") | `query_instance` (returns center coordinates [x, y, z], supports fuzzy matching with LLM) |
| `output_strategy` | `"suffix"` / `"timestamp"` / `"overwrite"` | File naming strategy for output files. Default is "suffix" (non-destructive). |
| **Visualize scene.urdf** | `cli.main --urdf_path .../scene.urdf --output_path .../floorplan.png`; output_path defaults to same directory as urdf |
- When no match is found, prompt "The object/room does not exist, please re-enter" and provide the current scene object or room list.
- Instance names should not use the `` from URDF. **Recommended**: Run `--list_instances` before placement/deletion/query to view current instance name list, and select the closest semantic match.
---
## CLI Examples
> **Tip**: The URDF file is typically located at `/urdf/export_scene/scene.urdf` (e.g., `outputs/rooms/Kitchen_seed0/urdf/export_scene/scene.urdf`).
### Example 1: View Instance Names and Room Names in Current Scene
```bash
# View instance names and room names in current scene (to fill in --on_instance / --in_room)
python -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path .../scene.urdf --list_instances
```
### Example 2: Visualize Floorplan Only
```bash
python -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path .../scene.urdf --output_path .../floorplan.png
```
### Example 3: Put Lamp on Bookshelf (Place on an Object)
`--on_instance` can be filled with the instance name returned by `--list_instances` or a semantic description.
```bash
python -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path .../scene.urdf --output_path .../floorplan.png \
--asset_path .../lamp.obj --instance_key lamp_on_bookcase --on_instance 书柜
```
---
### Example 4: Put Table in Living Room (Place in a Room)
```bash
python -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path .../scene.urdf --output_path .../floorplan.png \
--asset_path .../table.obj --instance_key table_1 \
--in_room living_room
```
---
### Example 5: Put Apple on Table in Living Room (Room + on Object)
```bash
python -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path .../scene.urdf --output_path .../floorplan.png \
--asset_path .../apple.obj --instance_key apple_1 \
--in_room living_room --on_instance table --place_strategy top
```
---
### Example 7: Delete an Object (Exact Name)
```bash
python -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path .../scene.urdf --output_path .../floorplan.png \
--delete_instance bed_192207
```
---
### Example 8: Delete Object with Fuzzy Matching (Semantic Description)
Requires LLM environment (see "LLM Environment" section).
```bash
python -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path .../scene.urdf --output_path .../floorplan.png \
--delete_instance "沙发"
```
---
### Example 9: Delete Object in Specific Room
Only deletes the instance if it's located in the specified room.
```bash
python -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path .../scene.urdf --output_path .../floorplan.png \
--delete_instance "沙发" --delete_in_room "客厅"
```
**Update both URDF and USD using room-cli:**
```bash
room-cli -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path .../scene.urdf --usd_path .../scene.usdc \
--output_path .../floorplan.png \
--delete_instance "沙发" --delete_in_room "客厅"
```
---
### Example 10: Query Instance Position (Exact Name)
```bash
python -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path .../scene.urdf \
--query_instance bed_192207
```
**Expected output**:
```
📍 Instance 'bed_192207' center: (-0.9250, -6.5830, 0.5000)
```
---
### Example 11: Query Instance Position with Fuzzy Matching
Requires LLM environment (see "LLM Environment" section).
```bash
python -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path .../scene.urdf \
--query_instance "床"
```
---
#### **Alternative Strategies**
**Timestamp** - Unique versioning for each operation:
```bash
# Output: scene_20260311_180235.urdf
python -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path .../scene.urdf \
--asset_path .../apple.obj --instance_key apple_1 \
--output_strategy timestamp
```
**Overwrite** - Directly overwrite original (use with caution):
```bash
# Overwrites: scene.urdf
python -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path .../scene.urdf \
--asset_path .../apple.obj --instance_key apple_1 \
--output_strategy overwrite
```
---
### Query Instance Position
Query the center coordinates of an instance in the scene. Supports fuzzy matching with LLM.
**CLI Interface**:
```bash
# Exact instance name
python -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path scene.urdf \
--query_instance bed_192207
# Fuzzy matching (requires GPT)
source outputs/env.sh
python -m embodied_gen.skills.spatial-computing.cli.main \
--urdf_path scene.urdf \
--query_instance "床"
```
### 6. Common Parameters
| Parameter | Meaning |
|-----------|---------|
| `in_room` | Limit placement to specified room |
| `on_instance` | Place on top of specified instance; must be **exact instance name** (obtained via `resolve_instance_with_llm`) |
| `beside_instance` | Place beside specified instance on the floor; must be **exact instance name** (obtained via `resolve_instance_with_llm`). Mutually exclusive with `on_instance` |
| `beside_distance` | Max distance (meters) from target instance for beside placement. Default `0.5`. Increase if placement fails |
| `place_strategy` | `"random"` random placement (default, e.g., bookshelf with 3 layers will randomly select one), `"top"` select highest surface |
| `rotation_rpy` | Not required by default; pass (roll, pitch, yaw) radians for special orientations |
| `delete_instance` | Instance name or semantic description to delete (supports fuzzy matching with LLM). Cannot delete protected items (walls, floors) |
| `delete_in_room` | Optional room constraint for deletion - only delete if instance is in this room |
| `query_instance` | Instance name or semantic description to query center coordinates (supports fuzzy matching with LLM). Returns [x, y, z] position |
## Next Steps
- For complete API, configuration, errors, and dependencies, see [REFERENCE.md](REFERENCE.md).