File size: 10,773 Bytes
1d3e2bd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# Floorplan Skill — API Reference

This document provides API details, configuration items, errors, and dependencies for reference beyond the usage instructions in [SKILL.md](SKILL.md).

## Contents

- [Floorplan Skill — API Reference](#floorplan-skill--api-reference)
  - [Contents](#contents)
  - [LLM Environment Configuration](#llm-environment-configuration)
  - [FloorplanManager](#floorplanmanager)
    - [Constructor](#constructor)
    - [Methods](#methods)
  - [Convenience Functions](#convenience-functions)
  - [CLI Features](#cli-features)
    - [Command Line Parameters](#command-line-parameters)
  - [Configuration and Ignore Items](#configuration-and-ignore-items)
  - [USD and Blender](#usd-and-blender)
  - [Errors and Return Values](#errors-and-return-values)
  - [Dependencies](#dependencies)
  - [Usage Recommendations](#usage-recommendations)

---

## LLM Environment Configuration

Before using `resolve_instance_with_llm` or `FloorplanManager.resolve_on_instance`/`resolve_in_room` for semantic matching, configure the LLM API and ensure access to the interface.

```bash
# Use the project-provided env (Azure + proxy, etc.), if outputs/env.sh exists:
source outputs/env.sh
```

If access to the LLM interface is unavailable, prompt the user.

---

## FloorplanManager

### Constructor

```python
from embodied_gen.skills.spatial_computing.api import FloorplanManager

manager = FloorplanManager(
    urdf_path="scene.urdf",      # Required
    usd_path=None,               # Optional; USD write after insert if provided
    mesh_sample_num=50000,
    ignore_items=None,           # Default ["ceiling", "light", "exterior"]
)
```

### Methods

| Method | Description |
|--------|-------------|
| `visualize(output_path)` | Generate floorplan and save as image |
| `insert_object(asset_path, instance_key, in_room=..., on_instance=..., place_strategy=..., n_max_attempt=2000, rotation_rpy=...)` | Place object, automatically write back to URDF/USD on success, return `[x,y,z]` or `None`. `on_instance` must be an exact instance name |
| `update_scene(urdf_output_path=..., usd_output_path=...)` | Manually write back currently placed instances; generally not needed (called inside `insert_object`). Use for custom output paths |
| `get_room_names()` | List of room names |
| `get_instance_names()` | List of instance names (excluding walls/floor) |
| `resolve_on_instance(on_instance, gpt_client=None)` | Resolve user description (e.g., "柜子", "书柜") to exact instance name; if already exact, return directly. With gpt_client, use LLM semantic matching, return `None` if no match |
| `resolve_in_room(in_room, gpt_client=None)` | Resolve user description to exact room name; if already exact, return directly. With gpt_client, use LLM semantic matching, return `None` if no match |
| `resolve_beside_instance(beside_instance, gpt_client=None)` | Resolve user description to exact instance name for beside placement; if already exact, return directly. With gpt_client, use LLM semantic matching, return `None` if no match |
| `get_occupied_area()` | Occupied area Shapely geometry |
| `get_floor_union()` | Floor area union geometry |

**Common `insert_object` parameters**: `in_room` to limit room; `on_instance` to place on top of an instance (exact instance name, can be resolved via `resolve_on_instance`); `beside_instance` to place beside an instance on the floor (exact instance name, can be resolved via `resolve_beside_instance`); `beside_distance` max distance in meters for beside placement (default 0.5); `place_strategy` is `"random"` (default) or `"top"`; `rotation_rpy` not required by default; `n_max_attempt` maximum placement attempts before failure. Note: `on_instance` and `beside_instance` are mutually exclusive.

---

## Convenience Functions

| Function | Description |
|----------|-------------|
| `visualize_floorplan(urdf_path, output_path, mesh_sample_num=50000, ignore_items=None)` | Generate floorplan only, do not write back to scene |
| `insert_object_to_scene(urdf_path, asset_path, instance_key, output_path, usd_path=None, in_room=None, on_instance=None, beside_instance=None, beside_distance=0.5, place_strategy="random", rotation_rpy=...)` | Create manager, place, automatically write back, generate floorplan; `on_instance` must be exact instance name; `beside_instance` places beside target on floor; returns placement center `[x,y,z]` or `None`. URDF output does not overwrite original file by default |
| `resolve_instance_with_llm(gpt_client, instance_names, user_spec, prompt_template=None)` | Use LLM to semantically match user description to one exact instance name in the scene; return `None` if no match, caller should prompt "does not exist, please re-enter". Depends on `embodied_gen.utils.gpt_clients.GPTclient` |

## CLI Features

### Command Line Parameters

| Parameter | Description |
|-----------|-------------|
| `--urdf_path` | Input URDF scene file path (required) |
| `--usd_path` | Optional USD scene file path, update USD simultaneously if specified |
| `--asset_path` | Placeholder object mesh file path (.obj) |
| `--instance_key` | Unique identifier for the new instance, default `inserted_object` |
| `--in_room` | Limit placement to specified room, supports semantic description (requires LLM environment) |
| `--on_instance` | Place on top of specified instance, supports semantic description (requires LLM environment) |
| `--beside_instance` | Place beside specified instance on the floor, supports semantic description (requires LLM environment) |
| `--beside_distance` | Max distance (meters) from target instance for beside placement, default 0.5 |
| `--place_strategy` | Placement strategy: `"random"` (default) or `"top"` (select highest surface) |
| `--rotation_rpy` | Initial rotation angle (roll, pitch, yaw radians) |
| `--output_path` | Floorplan output path |
| `--list_instances` | List instance names and room names in current scene, print and exit |
| `--max_placement_attempts` | Maximum placement attempts before failure, default 2000 |

### CLI Usage Examples

View scene instance names and room names:
```bash
python -m embodied_gen.skills.spatial_computing.cli.main \
  --urdf_path .../scene.urdf --list_instances
```

Visualize floorplan only:
```bash
python -m embodied_gen.skills.spatial_computing.cli.main \
  --urdf_path .../scene.urdf --output_path .../floorplan.png
```

Put lamp on bookshelf (supports semantic description):
```bash
source outputs/env.sh
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 书柜
```

Put table 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
```

Place object 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
```

Place chair beside table (on floor, collision-free):
```bash
source outputs/env.sh
python -m embodied_gen.skills.spatial_computing.cli.main \
  --urdf_path .../scene.urdf --output_path .../floorplan.png \
  --asset_path .../chair.obj --instance_key chair_beside_table \
  --beside_instance 桌子
```

Place beside with room constraint and custom distance:
```bash
python -m embodied_gen.skills.spatial_computing.cli.main \
  --urdf_path .../scene.urdf --output_path .../floorplan.png \
  --asset_path .../chair.obj --instance_key chair_beside_table \
  --in_room kitchen --beside_instance table --beside_distance 0.8
```

**URDF Output Note**: The updated URDF is written to `*_updated.urdf` by default (e.g., `scene.urdf``scene_updated.urdf`), and **will not overwrite** the original `scene.urdf` unless the user specifies a custom output path.

---

## Configuration and Ignore Items

| Parameter | Default | Description |
|-----------|---------|-------------|
| `mesh_sample_num` | 50000 | Number of mesh sampling points, larger values yield more precise floor plan polygons |
| `ignore_items` | `["ceiling", "light", "exterior"]` | Link name patterns to skip during URDF parsing |

---

## USD and Blender

- Writing USD converts `.obj` to `.usdc`, requiring **Blender (bpy)**. For USD writing in this project, use the **room-cli** environment (bpy installed).
- Without `usd_path`, only URDF is updated, no bpy needed.
- Assets in `.usd`/`.usdc`/`.usda` format are directly referenced; only `.obj` files are converted via bpy. If `*_collision.obj` exists in the same directory as the visual mesh, it will be written to URDF for collision.

---

## Errors and Return Values

**Exceptions**

- **ValueError**: Room or instance name does not exist; `update_scene()` called before `insert_object()` or after failed insertion; `instance_key` already exists.

**Return Values**

- `insert_object` / `insert_object_to_scene`: Returns `[x, y, z]` on success, `None` on failure (e.g., no valid placement after `n_max_attempt` attempts).

---

## Dependencies

| Type | Package | Description |
|------|---------|-------------|
| Core | trimesh, shapely, matplotlib, numpy | Parsing and visualization |
| USD Writing | pxr (e.g., `pip install usd-core`), bpy | Required only when using `usd_path`; bpy requires Blender |
| LLM Semantic Matching | openai, project gpt_config | `resolve_instance_with_llm` requires `GPTclient` instance (see `embodied_gen.utils.gpt_clients`) and corresponding API configuration |
| CLI | tyro | Required only for CLI entry point |

---

## Usage Recommendations

- **Upright objects**: Default orientation applies, no need to set `rotation_rpy`; for special orientations, pass `(roll, pitch, yaw)` radians, e.g., upright `(1.57, 0, 0)`.
- **Placing on furniture**: First use `resolve_instance_with_llm(gpt_client, get_instance_names(), user_input)` to get the exact instance name, then `insert_object(..., on_instance=resolved, place_strategy="top")`; if matching fails, prompt user to re-enter. For random ground placement, use `place_strategy="random"` (default).
- **Placing beside furniture**: Use `insert_object(..., beside_instance=resolved, beside_distance=0.5)` to place the new object on the floor beside the target instance, collision-free. Increase `beside_distance` if placement fails (e.g., when the area around the target is crowded).
- **Collision meshes**: If `*_collision.obj` exists in the same directory as the visual mesh, it will automatically be used for the collision node in URDF.