关于 reveal-3d
reveal-3d 指导在 React 和 TypeScript Flows 应用中集成已发布的 @cognite/reveal-widget。它涵盖 Cognite Reveal 查看器的配置与命令式控制,可展示 CDF 三维内容并浏览模型、突出显示实例和控制相机。
主要功能
- 01集成 @cognite/reveal-widget
- 02展示 CAD、点云、360° 图像和 CDF 场景
- 03支持模型浏览及直接指定模型标识
- 04命令式控制资源与相机
- 05突出显示已关联的实例
- 06指导配置 Vite、CSP 和应用
适用场景
- 01在 Flows 应用中嵌入 CDF 三维内容
- 02浏览模型或加载指定的模型引用
- 03突出显示已加载模型中映射的实例
- 04根据应用事件控制查看器资源与相机
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ cognitedata/ builder-skills --skill reveal-3d安装后在 Claude Code 中输入/reveal-3d确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
evals/evals.jsonreferences/csp-and-fixes.mdimplementation.mdvite-config.md详细介绍
Reveal 3D Viewer
使用已发布的 @cognite/reveal-widget npm 包,将 Cognite Reveal 3D 查看器添加到 Flows 应用。该查看器可从 CDF 渲染 CAD 模型、点云、360° 图像集和 CDF 场景,并支持浏览模型或直接使用模型/修订版 ID。
要可视化的 DM 实例:$ARGUMENTS
适用场景
用户希望在 Flows 应用中嵌入交互式 Cognite 查看器,以呈现 CDF 3D 内容。
请勿将此技能用于静态图表、图可视化或无关的自定义 Three.js 场景。
请勿使用已弃用的应用本地“复制 bundle”方式——此模式(包含复制的 provider/hook 源码的 src/features/reveal-3d/ 文件夹)已被直接安装 @cognite/reveal-widget 取代。如果应用仍保留之前集成时复制的 bundle,请迁移到此软件包,而不是在其基础上扩展。
前提条件
- 应用使用 React + TypeScript,并由
@cognite/app-sdk的CogniteSdkProvider(Flows 身份验证)包装;它通过@cognite/app-sdk/react中的useCogniteSdk()提供CogniteClient(sdk)。@cognite/cli是用于搭建/部署应用的 CLI,不是运行时身份验证库——通过npx @cognite/cli apps create创建的应用依赖@cognite/app-sdk,而非@cognite/cli本身(useDune()/@cognite/dune/authhook 仅适用于旧版--classic脚手架)。 - CDF 项目包含 3D 模型,或者用户提供了模型/修订版 ID 或 CDM(
externalId/space)模型引用。 - 对于关联 DM 的 3D 内容,必须能够通过 CDM
externalId/space键值对或经典modelId/revisionId识别实例/模型;模型加载并且实例已与其建立上下文关联(映射)后,才能高亮实例。 - 设置
viewerOptions.useCoreDm前,请确认项目的 3D 内容位于核心数据模型还是经典 3D API 中——不要默认将其设为true。没有一个单独的标志可以完成此检查;csp-and-fixes.md 提供了直接检查所需的确切 SDK 调用。
集成工作流
请按顺序执行以下步骤。路径应遵循目标应用的约定,不要自行发明新路径。
- 检查目标应用。 阅读
package.json、vite.config.ts、src/main.tsx,并了解应用的文件夹和别名约定。 - 使用应用的包管理器安装软件包及其同级依赖。 请参阅依赖项。如果现有固定版本的 React 和 SDK 满足同级依赖版本范围,请继续使用。
- 配置 Vite。 阅读 vite-config.md,并添加
three/@cognite/reveal去重条目。无需添加 process/util/assert polyfill——该软件包已适配浏览器。 - **为
manifest.json配置 CSP 许可项,**具体内容取决于场景/模型实际包含的内容(场景地面/天空盒纹理、360° 图像集合)。请阅读 csp-and-fixes.md——其中还介绍了点云所需的应用侧修复位置(manifest.json无法直接授予该权限),以及 StrictMode 的注意事项;即使应用目前还没有场景或 360° 内容,也请阅读。 - **添加一个控制器类,**用于封装
RevealWidgetController,并通过命令式方式驱动它(加载资源、设置实例样式/高亮、控制摄像机),在你自己的事件处理程序中操作,而不是通过响应属性变化的useEffect。请参阅 implementation.md。 - **挂载
RevealWidget,**并传入viewerOptions={{ sdk, useCoreDm }}(根据项目设置useCoreDm,不要硬编码——请参阅 csp-and-fixes.md)、setControllerRef,以及必需的appIdentifier(用于标识宿主应用的字符串);同时将其放在具有明确高度的容器中。RevealWidget会管理自己的内部 Reveal 上下文——不要再用此软件包中的其他 provider 包裹它。 - 选择资源模式。 默认使用模型浏览器模式(
sdk.models3D.list()+ 经典的modelId/revisionId),除非用户已提供 CDMexternalId/space模型引用。完整示例请参阅 implementation.md。 - 清理资源。 当不再需要
addResource返回的任何Reveal3DResourceHandle时(例如选择变更、卸载),请调用.remove()。 - 运行类型检查和构建(
tsc --noEmit、pnpm build等),并解决任何依赖项或同级依赖版本问题。
最小示例
import { useRef } from 'react';
import type { CogniteClient } from '@cognite/sdk';
import {
RevealWidget,
type Reveal3DResourceHandle,
type RevealWidgetController,
type ThreeDResourceIdentifier,
} from '@cognite/reveal-widget';
class ThreeDViewerController {
private model: Reveal3DResourceHandle | undefined;
constructor(private readonly widgetController: RevealWidgetController) {}
async loadModel(resource: ThreeDResourceIdentifier): Promise<void> {
this.model = await this.widgetController.addResource(resource);
this.widgetController.cameraController.focusModel(this.model);
}
dispose(): void {
this.model?.remove();
}
}
export function ViewerPage({
sdk,
resource,
}: {
sdk: CogniteClient;
resource: ThreeDResourceIdentifier;
}) {
const viewerRef = useRef<ThreeDViewerController>();
function handleWidgetController(widgetController: RevealWidgetController | undefined) {
viewerRef.current?.dispose();
if (widgetController === undefined) {
viewerRef.current = undefined;
return;
}
const viewer = new ThreeDViewerController(widgetController);
void viewer.loadModel(resource);
viewerRef.current = viewer;
}
return (
<div style={{ width: '100%', height: '70vh', position: 'relative' }}>
<RevealWidget
viewerOptions={{ sdk, useCoreDm }} // set per the project — see csp-and-fixes.md
setControllerRef={handleWidgetController}
appIdentifier="my-flows-app"
/>
</div>
);
}
依赖项
建议版本仅作为起点。如果目标应用已固定兼容版本,请以应用为准。
| 软件包 | 建议版本 | 用途 |
|---|---|---|
@cognite/reveal-widget | ^0.3.0 | RevealWidget 组件及其类型 |
react / react-dom | ^18.3.1 (peer) | UI 框架——对等依赖,必须与应用版本一致 |
@cognite/reveal | 4.36.0 | Reveal 查看器运行时——必须使用完全匹配的版本。固定为 4.36.0,而不是 @cognite/reveal-widget 自身声明的对等依赖范围中的 4.35.3;见下方说明。 |
@cognite/sdk | ^10.14.0 (peer) | CDF API 客户端——对等依赖 |
其他所有内容(three、@tanstack/react-query、@base-ui/react、@floating-ui/react、@tabler/icons-react、dayjs、lodash-es、ml-matrix、random-seed、@cognite/aura、@cognite/reveal-components)都是该软件包的传递依赖,会自动安装——除非应用需要固定某个版本,或者应用代码直接导入了其中的内容,否则不要手动添加。implementation.md 中的模型浏览器模式正是这样使用 @tanstack/react-query(useInfiniteQuery/useQuery)的——在这种情况下,请将其作为直接依赖添加,因为从未声明的传递依赖导入内容会导致 pnpm 等严格软件包管理器出错。
安装示例(pnpm;请根据应用使用的软件包管理器调整):
pnpm add @cognite/reveal-widget @cognite/[email protected] @cognite/sdk react react-dom
@cognite/[email protected] 自身的对等依赖范围仍声明为 @cognite/[email protected],但其依赖项 @cognite/reveal-components 在内部将 @cognite/[email protected] 写死。请将应用固定到 4.36.0,并确认锁文件解析出的 @cognite/reveal 版本只有一个——对等依赖范围已过时,而此处真正的版本分裂(不同于 resolve.dedupe 未覆盖的情况)会导致 Reveal 的共享查看器状态无声地出错。
不要将任何源代码包复制到应用中,也不要为此软件包安装 process、util、assert、ajv 或 vite-plugin-node-polyfills——这些都不需要。
关键规则
- 通过
setControllerRef获取RevealWidgetController,并以命令式方式驱动组件。不要尝试重建 Reveal 旧版声明式 Provider 树(CacheProvider/RevealProvider/RevealCanvas/Reveal3DResources)——该 API 属于旧的复制捆绑包方式,并非此软件包提供的 API。 RevealWidget在内部封装了自己的 Reveal 上下文——切勿将它嵌套在此软件包的另一个 Provider 中。- 在
setControllerRef中构造新的控制器类实例之前,先释放上一个实例(调用.dispose(),它会对已跟踪的句柄调用.remove());当widgetController变为undefined(卸载)时,也要再次释放。 - 传递给
addResource的资源必须与其type/sourceType组合对应的标识符形态完全一致(参见 implementation.md)——混用经典字段和 CDM 字段会导致类型错误。 - 实例高亮只对已关联(映射)到已加载模型的实例生效;先加载模型,再调用
styleByInstance/focusInstances。 RevealWidget的容器必须设置明确的高度——它会填满父容器。- 添加路由/页面时,使用
React.lazy+Suspense延迟加载画布占用较大的查看器内容。 useCoreDm必须与项目设置一致,不能默认设为true——否则会出现错误的 401 错误,以及 360 集合加载静默失败。不要用React.StrictMode包裹应用——它会在开发环境中于加载过程中卸载RevealWidget的查看器,并产生生产环境中不会出现的错误。点云需要在应用侧进行同源修复,因为manifest.json无法授予它们所需的data:CSP 许可。这三项内容均参见 csp-and-fixes.md。appIdentifier(用于命名宿主应用的字符串)自@cognite/[email protected]起是必需属性——挂载RevealWidget时不提供它会导致类型错误。默认情况下,组件会将匿名使用情况指标(使用了哪些功能,例如添加资源、移动摄像机)发送到专用的mixpanel-browser实例。传递可选的tracking属性即可更改此行为:设置tracking={{ disabled: true }}可完全选择退出,或设置tracking={{ mixpanelToken }}将数据发送到其他 Mixpanel 项目。
高级参考
如需完整的资源标识符目录(CAD、点云、360 图像、场景)、实例高亮和摄像机控制说明,请阅读 implementation.md。
如需 Vite/去重配置说明,请阅读 vite-config.md。
如需了解 CSP/manifest.json 许可、useCoreDm/StrictMode 注意事项、点云应用侧修复以及 360 集合故障排查,请阅读 csp-and-fixes.md。
验证清单
-
@cognite/reveal-widget与其同级依赖(react、react-dom、@cognite/reveal、@cognite/sdk)均已安装,且版本兼容。 - 将应用的
@cognite/reveal固定为4.36.0(而不是@cognite/reveal-widget的 peer 范围中已过时的4.35.3),并确保锁定文件中解析出的@cognite/reveal版本只有一个。 - 未将源代码包复制到应用中;所有导入均来自
@cognite/reveal-widget,且应用代码不会直接从@cognite/reveal-components导入。 -
vite.config.ts包含resolve.dedupe: ['three', '@cognite/reveal'](以及应用现有的 dedupe 条目)。 - 未为此软件包添加
process/util/assertpolyfill 或vite-plugin-node-polyfills。 -
RevealWidget只挂载一次,不嵌套在另一个 Reveal provider 中,其容器具有明确的高度,并且传入了必需的appIdentifier字符串 prop。 -
viewerOptions.useCoreDm与目标项目是否实际基于 Core-Data-Model 相符。 - 应用未用
React.StrictMode包装自身。 - 如果应用加载带有地面的场景或天空盒,
manifest.json会为https://*.cognitedata.com授予img-src权限;如果应用加载 360° 图像集合,则会为 CSP 违规中观察到的实际签名 URL 主机授予connect-src权限。如果应用需要点云支持,则已应用并验证同源Blob补丁修复。 - 一个控制器类封装了
RevealWidgetController,通过setControllerRef获取该控制器,并以命令式方式调用addResource/styleByInstance/focusInstances/cameraController。 - 在设置新控制器时以及卸载时(
widgetController === undefined),都会释放控制器类,并对已跟踪的资源句柄调用.remove()。 - 资源标识符使用与所加载模型对应的
type/sourceType结构。 - 类型检查和构建均通过。