跳到主要内容

连续放置与一键优化(2.17.0)

VoxelKit 编辑器可以像画笔一样连续放置积木,也可以批量整理模型形状与颜色。这些功能在设备本地执行,无需搭建 Python 服务,不上传模型。原有单点添加与旋转行为默认不变。

连续放置​

await editor.enterEdit();
editor.setSelectedColor('#D79962');
editor.setMode(VoxelEditMode.ADD_BRUSH);

单指拖动连续放置;双指平移/缩放仍走 Viewer 的现有配置。每一笔的拾取以开始时的模型为准,新方块不会在同一笔里继续作为放置支撑,从而避免堆成高塔。同一坐标只放置一次,整笔撤销一次。松手后再画可以叠加新的一层。空模型使用射线进入网格的首个单元作为初始放置位置。

如果宿主已有 ADD 按钮,不必改枚举:

editor.setAddBrushEnabled(true);
editor.setMode(VoxelEditMode.ADD);
// 恢复旧行为:单指拖动旋转,仅点击放置
editor.setAddBrushEnabled(false);

也可以在 VoxelEditorOptions.addBrushEnabled 中初始化。onAddBrushHit(x, y, z) 每个实际新增坐标触发一次,包括对称放置。回调异常不会中断放置。gestureLocks.voxelEdit 会拦截画笔;双指相机仍遵守宿主的平移/缩放锁与选择手势配置。显式 ADD_BRUSH 不受 addBrushEnabled=false 影响,需切回 ADD/VIEW 才退出该模式。

一次调用优化​

const options = new VoxelOptimizationOptions();
options.kind = VoxelOptimizationKind.REMOVE_ISLANDS;
options.maxVoxels = 8;
options.keepLargest = true;
const result = await editor.optimize(options);
// result.added / removed / recolored / elapsedMs / warnings
editor.undo(); // 包含调色板的完整撤销

计算在 TaskPool,应用与 ArkGraphics 更新仍通过编辑器主线程的受控路径。optimize() 完成代表权威文档已应用,不代表最后一个 GPU Chunk 已提交完成;网格继续使用现有异步队列同步。不要在每个体素回调里再次调用优化。

先检查候选,再确认应用​

const options = new VoxelOptimizationOptions();
options.kind = VoxelOptimizationKind.AUTO_REPAIR;
options.maxChanges = 5000;
options.fixBottom = false;
const candidate = await editor.previewOptimization(options);
// 宿主展示统计、warnings 或自行绘制 candidate.cells 的差异预览。
// 内置 Viewer 此时仍显示原模型,不自动覆盖预览颜色。
editor.applyOptimization(candidate);
  • previewOptimization() 要求已进入且就绪的编辑会话;计算期间 isUpdating() 为 true。
  • 候选包含 size 和 X 最快的 Uint32Array cells:0 为空;非零是 0xRRGGBB + 1。请勿修改候选。
  • applyOptimization(candidate) 返回实际改变体素数;相同控制器仅保留最近一次候选。文档、颜色、模型切换后旧候选无效,需重算。
  • cancelOptimization() 丢弃候选并拒绝迟到结果;它不是操作系统级强杀 Worker,正在计算的任务仍可能短暂占用 CPU。不要连续发起大量任务。
  • selectionOnly=true 必须有非空选区。选区外实体不改,新增几何只允许落入选区的一层邻域;这比 3DEdit 某些全腔扩展操作更保守。
  • lockedColors 接收 #RRGGBB[],被锁定颜色的实体不修改。
  • 形状优化的 maxChanges 默认 5000,按完整连通候选片区分配;小预算可能使大连片候选完全不应用。颜色工具不受此几何预算限制;AUTO_REPAIR 的颜色步骤共享剩余预算。
  • 默认拒绝将已有模型全部清空。最终结果超过 255 色会拒绝,不静默降色。

结构工具​

kind能力主要参数
AUTO_REPAIR清孤岛、表面修复、可选整平、分面杂色清理fixIslands=true、fixSurface=true、fixBottom=false、fixColors=true、islandSize=8、maxChanges=5000
SURFACE_REPAIR六向表面的局部凸块/凹缺检测;要求三层实体背衬patchRadius=2 (1..5)、patchDepth=2 (1..8)、patchArea=12 (1..4096)、planeSupport=0.7 (0.5..1)、patchMode=both/spurs/pits
FLATTEN_BOTTOM按本地 Z 底面众数整平,不自动平移模型bottomPlane=-1 自动 (或 0..size-1)、bottomSupport=0.6、bottomDepth=2 (1..16)、bottomMode=both/fill/trim
FILL封闭内部填充;可开启微漏推断leakTolerance=0 (0..4)、nearest=true、fillColor=#D79962
CAVITIES仅填充小封闭空腔maxVoxels=8,加 FILL 参数
HOLLOW保持外形,移除距外界过远的内部实体wall=1.2、voxelSizeX/Y/Z=1
SEAL三方向二维闭边孔洞,再按三维尺寸筛选diameter=3 (1..32)、holeDepth=2 (1..16)
REMOVE_ISLANDS六邻接孤立分量清理maxVoxels=8、keepLargest=true
SMOOTH按六邻居数去刺/补小凹陷spurNeighbors=2 (0..3)、pitNeighbors=5 (4..6)、smoothMode=both/spurs/pits、iterations=1 (1..8)
OFFSET_SURFACE按欧氏距离增厚或收缩direction=out/in、distance=1、voxelSizeX/Y/Z=1
REINFORCE根据三轴连续厚度加固薄处wall=1.2、allowExterior=false、voxelSizeX/Y/Z=1

距离及壁厚与 voxelSizeX/Y/Z 使用同一单位,例如 pitch=0.2 毫米、wall=1.2 毫米。底面、孔径、层数、patch 参数仍以体素数计。网格不能越过原始 1..128³ 范围;增厚到边界会被截断。nearest=false 时新增方块采用 fillColor,true 使用最近原始实体颜色。

AUTO_REPAIR/SURFACE_REPAIR/FLATTEN_BOTTOM 具有连通性保护;删除会拆开原有连通区域时保留删除候选。该保护不是力学或打印可行性验证。自动底面置信度不足时不猜测,指定 bottomPlane 后重试。微漏推断不直接把虚拟封口写到表面;设计开口仍可能被误判为内部。

颜色工具​

kind能力主要参数
SMOOTH_COLORS固定原始 Lab 边界门限的线性光相邻扩散,不跨空气混色strength=0.65 (0..1)、steps=3 (1..12)、edgeThreshold=45 (0..200)、newColors=32 (1..255)、colorMode=generate/existing、surfaceOnly=true
ADJUST_COLORSHSV 色相/饱和度/明度hue=0 (-3600..3600 度)、saturation=1 (0..10)、brightness=1 (0..10)
REPLACE_COLOR按 RGB 值替换,不要求知道调色板符号sourceColor=#FFFFFF、targetColor=#E0B483
MATCH_PALETTECIE Lab 最近目标色palette,必须 1..255 个 #RRGGBB
REDUCE_COLORS按体素权重进行 Lab 聚类、使用原色代表count=16 (1..255)
MERGE_COLORS相近颜色归并到高频代表色threshold=10 (0..300 Lab 距离)
CLEAN_COLORS小色块边界投票,支持多轮/分面/向内传播maxVoxels=8、dominance=0.6 (0.5..1)、threshold=10、cleanPasses=1 (1..5)、connectivity=1 (1/2/3=6/18/26邻接)、surfaceOnly=true、faceAware=true、inwardLayers=0 (0..16)
EXTEND_COLORS将表面颜色向已有内部实体传播,不增加几何layers=2 (1..128)

每轮清色使用快照,循环色状态停止;部分被保护的色块不当成“小块”清除。颜色过渡 generate 模式采用有界 RGB median-cut;色板已满时明确报错,可切 existing 或先 REDUCE_COLORS。优化重排调色板,但会保留颜色与撤销快照;不要缓存旧符号作为永久颜色 ID,应用后从 getState().palette 重新获取。

这些能力对齐 3DEdit 的本地操作类别,并不承诺 Pillow/SciPy 与 ArkTS 的量化色及等距平局逐字节一致。当前参数默认更保守(微漏关闭、几何预算有界);未接入远程 AI、制造检查、切件或连接件布尔。

不依赖 Viewer 的调用​

VoxelOptimizer.optimize(input) 返回 Promise<VoxelOptimizationResult>,可在没有 ArkGraphics 场景时使用。VoxelOptimizationInput:

字段内容
size整数 1..128
rowssize² 个长度为 size 的字符串,按 z/y/x 顺序;. 为空
symbols / colors对齐的单字符调色板与 #RRGGBB 数组
selection可选 Uint8Array,selectionOnly 时必须为 size³、且非空
optionsnew VoxelOptimizationOptions() 并设置操作参数

所有参数应通过 Options 构造实例后赋值,避免以部分对象替代而丢失默认值。独立调用不自动进入编辑、不修改源文件;保存仍是编辑器 save/saveAs 或 Native Compiler 的下游。

网格关闭修复​

viewer.setGroundGridVisible(false) 现在既设置 visible=false,也移除挂载。延迟构建只允许一个进行,已分配对象仍存在并不代表在场景中可见。重新打开复用对象,不重复上传;与方块本身的 AO 描边无关。