VoxelEditorController
2.17.0 新增
支持 ADD_BRUSH 连续放置,以及 previewOptimization/applyOptimization/optimize/cancelOptimization 参数化优化。完整方法、结果和参数见 VoxelOptimizer API,从任务入手见 连续放置与一键优化。
VoxelEditorController 持有可变体素文档和局部 Chunk 更新队列,必须与一个稳定的 VoxelViewerController 配对。构造后将它传给同一个 VoxelViewer 的 editor 参数;不传 editor 时,Viewer 保持纯预览路径。
new VoxelEditorController(
viewer: VoxelViewerController,
options: VoxelEditorOptions = new VoxelEditorOptions()
)
会话与状态
| 方法 | 返回值 | 说明 |
|---|---|---|
enterEdit() | Promise<void> | 恢复 JSON 或 VFP 权威体素、准备局部编辑 Chunk 和放置动画资源。未加载模型、VFP hash 校验失败或 URI 失效时 reject。 |
exitEdit() | void | 退出编辑、清除视觉选区和待处理局部重建;不卸载当前预览。 |
isActive() | boolean | 编辑模式是否已就绪。 |
isUpdating() | boolean | 正在准备、局部更新、保存或导出 GIF 时为 true。 |
canSaveToSource() | boolean | 当前输入是否保留可写 Picker URI。 |
getState() | VoxelEditorState | 当前状态的快照;详见 编辑器类型与保存 API。 |
enterEdit() 重复调用是幂等的:已进入或正准备时直接返回。重新导入模型后应重新进入编辑。
对于 VFP,文件中的非零 chunkSize/chunksPerAxis 只描述容器与缓存分块,不能证明运行期可编辑 Geometry 已存在。2.14.14 会在首次进入编辑时检查实际场景:命中有效 VBUF/PMSH 时,保留 PMSH 的完整预览基线并避免全量 Chunk 预热;JSON 或缓存未命中时才准备必要的编辑 Chunk。无论路径如何,enterEdit() resolve 前都不会将会话设为 active,之后的修改只替换受影响局部 Chunk/覆盖层。宿主只需等待 Promise,不应自行跳过或重复这一步。
模式与颜色
| 方法 | 签名 | 约束 |
|---|---|---|
| 切换模式 | setMode(mode: VoxelEditMode): void | 切换时会清空当前选区。 |
| 选择已有符号 | setSelectedSymbol(symbol: string): void | symbol 必须属于当前调色板,否则抛出错误。 |
| 选择自由颜色 | setSelectedColor(hex: string): void | 支持 #RGB / #RRGGBB;未进入编辑时抛错。 |
| X 对称 | setSymmetryX(enabled: boolean): void | 影响单点 ADD / DELETE / REPLACE,不改变已有选区。 |
模式的点击/拖动交互见 编辑器概览与接入。
选择
| 方法 | 签名 | 返回/行为 |
|---|---|---|
| 清空 | clearSelection(): void | 不修改模型。 |
| 取副本 | getSelectionVoxels(): Array<VoxelSelection> | 返回源坐标与面方向的副本。 |
| 数量 | getSelectionSize(): number | 返回当前选区大小。 |
| 边界 | getSelectionBounds(): VoxelSelectionBounds | undefined | 返回包含式边界;空选区为 undefined。 |
| 全选 | selectAll(): number | 选择全部非空体素。 |
| 按色 | selectByColor(color?: string, append?: boolean): number | 接受符号或十六进制颜色;未找到颜色时抛错。 |
| 三维盒 | selectByBox(min, max, append?: boolean): number | 两端点会取整、钳制并视为包含式边界。 |
| 屏幕拾取 | pickVoxelAt(screenX: number, screenY: number): VoxelSelection | undefined | 以 Viewer 内容区域内像素坐标拾取最前方可见表面体素;不修改选区或模型。 |
append=true 只适用于按色和三维盒选择,表示保留现有选区后合并新命中。屏幕框选由 VoxelEditMode.BOX_SELECT 和 VoxelViewer 手势驱动,不需要也不应调用内部射线方法。
pickVoxelAt()
pickVoxelAt(screenX: number, screenY: number): VoxelSelection | undefined
这是宿主可用的屏幕射线拾取入口,适合自定义选区 UI、悬停提示或与页面外层手势协调。坐标必须是 VoxelViewer 内容区域的本地像素坐标,不是页面/窗口的全局坐标。命中时返回源网格 x/y/z、命中面方向和颜色符号;未命中、Viewer 尚未挂载、未进入编辑、模型正在局部更新或加载动画仍在播放时返回 undefined。
方法本身只读:不会改变当前选择、不会切换颜色,也不会执行添加/删除。需要修改时,先按业务规则处理返回的 VoxelSelection,再调用已有选择或编辑 API。
批量修改与变换
| 方法 | 签名 | 返回值 |
|---|---|---|
| 删除选区 | deleteSelection(): number | 实际删除数量。 |
| 已有色换色 | setSelectionSymbol(symbol: string): number | 实际换色数量。 |
| 自由色换色 | setSelectionColor(hex: string): number | 实际换色数量。 |
| 移动 | moveSelectionBy(dx?: number, dy?: number, dz?: number): number | 变换后选区数量。 |
| 复制 | duplicateSelection(offset?: VoxelCoordinate): number | 复制品数量;复制品成为当前选区。 |
| 镜像 | mirrorSelection(axis?: VoxelAxis): number | 变换后选区数量。 |
| 旋转 | rotateSelection(axis?: VoxelAxis, quarterTurns?: number): number | 以 90° 整数倍旋转后的选区数量。 |
| 对齐 | alignSelection(mode?: VoxelSelectionAlign): number | 压到目标边界平面后的选区数量。 |
选区变换遇到网格外目标或未选中实心体素冲突时取消整次操作并返回 0;具体文本在 getState().message。所有成功修改均可撤销。
历史与导出
| 方法 | 返回值 | 说明 |
|---|---|---|
undo() | void | 无历史或正在更新时无操作。 |
redo() | void | 无重做历史或正在更新时无操作。 |
exportJsonText() | string | 返回当前 JSON;未进入编辑时抛错。 |
exportTurntableGif(options?) | Promise<VoxelTurntableGifResult> | 从当前模型生成离屏 GIF;只读预览无需先进入编辑,已有编辑文档时包含未保存修改。 |
exportTurntableGifToUri(uri, options?) | Promise<VoxelTurntableGifResult> | 导出 GIF 并写入业务已授权的 URI。 |
exportTurntableGifAs(context, options?) | Promise<VoxelTurntableGifResult | undefined> | 拉起系统保存器;用户取消时返回 undefined。 |
save(options?) | Promise<VoxelEditorSaveResult> | 覆写可写来源 URI。 |
saveToUri(uri, options?) | Promise<VoxelEditorSaveResult> | 写入宿主已获取权限的 URI。 |
saveAs(context, options?) | Promise<VoxelEditorSaveResult | undefined> | 拉起系统保存器;用户取消时返回 undefined。 |
三个 GIF 方法都不要求先 enterEdit()。预览路径只临时恢复体素源,不创建编辑 Chunk、选区或撤销栈;可用配对的 VoxelViewerController.canExportTurntableGif() 判断当前来源是否可导出。GIF 的配置、透明度限制、并行策略和离屏外观见 VoxelTurntableExporter。保存和 VFP 区段策略见 保存与性能。
不属于公开业务 API 的成员
attachScene()、handleRay()、handleScreenRectangleSelection()、previewScreenRectangleSelection() 是 Viewer 与 Editor 的内部桥接成员。不要从业务代码调用、保存或基于它们编写兼容逻辑;请通过 VoxelViewer({ editor }) 和上述公开方法完成交互。