跳到主要内容

访问与修改 3D 对象的视图属性

加载完成后从 viewer.doc 取得 Document。节点状态位于 mainStore 的 nodes.present.byId:

const doc = viewer.doc;
const state = doc.mainStore.getState();
const node = state.nodes.present.byId[nodeId];
console.log(node.name, node.visible, node.material, node.matrix, node.renderType);

修改可见性​

SET_NODES_VISIBLE 的 payload 是 { [nodeId]: boolean },支持一次修改多个节点:

import { types } from "@tuo/document";

doc.dispatch({
type: types.SET_NODES_VISIBLE,
payload: { [nodeId]: false },
});

doc.dispatch({
type: types.SET_NODES_VISIBLE,
payload: { [nodeId]: true, [anotherNodeId]: false },
});

也可以使用 Document 的便捷方法:

doc.setVisibleByName("housing", false);
doc.setVisibleByIndex(0, true);

修改面、线和点的材质​

材质分为 face、line 和 point 三类。SET_NODES_MATERIAL 可以只修改部分字段,未提供的旧字段会保留:

doc.dispatch({
type: types.SET_NODES_MATERIAL,
payload: {
[nodeId]: {
face: {
color: 0xff0000,
transparent: true,
opacity: 0.45,
vertexColors: false,
side: "front",
},
line: { color: 0x222222 },
},
},
});

常用属性:

属性作用
color十六进制颜色值
transparent是否启用透明渲染
opacity透明度,通常为 0 到 1
sidefront、back 或 double
vertexColors是否使用顶点颜色
metalness / roughnessPBR 材质属性

按名称或索引修改:

doc.setMaterialById(nodeId, { face: { color: 0x3366ff, opacity: 0.7 } });
doc.setMaterialByName("housing", { line: { color: 0xffffff } });
doc.setMaterialByIndex(0, { face: { color: 0xff8800 } });

如果要替换而不是合并旧材质,可在 dispatch payload 中使用 reomveOld: true(该字段名称与当前源码保持一致):

doc.dispatch({
type: types.SET_NODES_MATERIAL,
reomveOld: true,
payload: { [nodeId]: { face: { color: 0xffffff } } },
});

切换渲染方式和内外侧​

使用 SET_NODES_RENDERTYPE 修改节点的渲染类型;使用材质的 side 控制内外侧:

doc.dispatch({
type: types.SET_NODES_RENDERTYPE,
payload: { [nodeId]: "wire" },
});

doc.dispatch({
type: types.SET_NODES_MATERIAL,
payload: { [nodeId]: { face: { side: "back" } } },
});

实际可用的渲染类型以当前 Viewer/Document 版本为准,生产项目应在目标版本中验证。

修改变换矩阵​

节点的 matrix 是 16 个数字组成的矩阵。可以直接提交矩阵,也可以进入 transform 模式让用户交互调整:

doc.dispatch({
type: types.SET_NODES_MATRIX,
payload: {
[nodeId]: [1, 0, 0, 10, 0, 1, 0, 0, 0, 0, 1, 5, 0, 0, 0, 1],
},
});

交互变换流程:

doc.dispatch({ type: types.START_PROCESS, payload: { type: "transform", config: {} } });
doc.dispatch({ type: types.SET_PROCESS, payload: { transformType: "translate" } });
// 或 transformType: "rotate"
doc.dispatch({ type: types.APPLY_PROCESS });
doc.dispatch({ type: types.QUIT_PROCESS });

变换模式下的操作在调用 APPLY_PROCESS 前不会正式写入节点。

读取和批量处理​

const nodes = doc.mainStore.getState().nodes.present.byId;
const objectNodes = Object.values(nodes).filter((item) => item.type === "object");
const payload = Object.fromEntries(objectNodes.map((item) => [item.clientId, { face: { color: 0x6688aa } }]));
doc.dispatch({ type: types.SET_NODES_MATERIAL, payload });

建议保存业务对象 ID 与 Document 节点 ID 的映射,不要保存底层 Three.js 对象或 entityCache 引用。可见性、材质和矩阵修改默认作用于当前 Document;需要持久化时保存操作参数或重新生成模型数据。