Skip to content

选择与拾取

viewer.selection 维护节点 / 面 / 边三种粒度的选中集与悬停状态:点击画布即自动选中(默认开),也可用 pick / pickBox 自行拾取、apply / clear 编程式修改选中集。状态变化统一经 selection-changed / hover-changed 事件广播。

下面的 demo 中点击零件即可选中,底部面板可切换合并模式(Set / Add / Toggle)、高亮样式与可拾取粒度:

可交互 demo · 点击零件选中,底部面板切合并模式/高亮/粒度,空格键 fit在新窗口打开 ↗

核心 API

ts
import { SelectionItem, SelectionMode, SelectionMask } from "@modelcubes/viewer-core";

// 订阅选中 / 悬停变化(点击画布自动选中,默认开)
viewer.on("selection-changed", (e) => console.log("当前选中", e.current.length, "项"));
viewer.on("hover-changed", (e) => console.log("悬停", e.item));

// 手动拾取:坐标是画布局部坐标(相对画布左上角,CSS 像素),
// 从鼠标事件接线时需用 getBoundingClientRect 换算
canvas.addEventListener("click", (e) => {
  const r = canvas.getBoundingClientRect();
  const item = viewer.selection.pick(e.clientX - r.left, e.clientY - r.top, SelectionMask.Node);
  if (item) viewer.selection.apply(item, SelectionMode.Add);
});

// 编程式修改选中集 / 清空
viewer.selection.apply(SelectionItem.node(someNodeId), SelectionMode.Set);
viewer.selection.clear();

行为要点

  • 点击拾取:pick(x, y, mask?) 在画布坐标处做一次拾取,返回命中的 SelectionItemnull,只拾取、不改选中集;mask 缺省时用当前 setPickableMask 设置的粒度。点击画布的自动选中(Set 语义)可经 setAutoSelectOnClick(false) 关闭后自行驱动。
  • 两组枚举:SelectionMode 决定 apply 的合并方式(Set 替换 / Add 追加 / Toggle 反选);SelectionMask 是可拾取粒度位掩码(Node / Face / Edge 可按位或,All 全开),经 setPickableMask 设置,引擎默认仅 Node(零件级)。
  • 事件:选中集净变化时触发 selection-changed(payload 含 added / removed / current),无净变化不触发;悬停对象变化时触发 hover-changed(移出模型时 itemnull)。
  • 编程式选中:apply(items, mode) 接受单个或一组 SelectionItem(用 SelectionItem.node/face/edge 工厂构造),item 非法(nodeId 不存在等)抛 ViewerError;clear() 清空选中集。getSelection() / has() / size() 查询当前状态。
  • 框选:pickBox(x1, y1, x2, y2, opts?) 返回画布矩形内命中的 item 列表(不改选中集,可再 apply);v1 仅支持 Node 粒度,mask 含 Face / Edge 位会降级并告警;opts.mustBeFullyInside 要求节点完全落入矩形才算命中(默认相交即命中)。
  • 高亮样式:setHighlightMode 切换视觉反馈方式(仅染色 / 仅描边 / 染色+描边,默认两者皆有);setStyle(patch) 增量调整选中 / 悬停的颜色、描边强度与染色混合度,默认为橙系染色 + 描边(见 DEFAULT_SELECTION_STYLE)。
  • 装配节点选中的高亮传播:apply 选中无几何的装配节点(NodeInfo.meshId === null)时,染色(tint)与描边(outline)传播到其整个后代叶子子树——视觉上等同于子树内全部零件被高亮;选择集中保持的仍是装配节点本身(getSelection() 返回装配节点,属性栏 / 右键菜单等基于选择集的语义不受影响)。此时 model.getHighlightedNodeIds() 返回的是被染色的叶子集合,而非装配节点 id。

相关 API