nsdt-3dconvert-viewer
v1.0.11
Published
3D模型在线预览,基于3dconvert的3D Viewer组件。3D模型在线转换。
Downloads
14
Maintainers
Readme
概述
3dconvert-viewer.js SDK是一款功能强大、易于集成的3D模型展示工具,它以3D模型在线转换平台的服务为基础,为广大开发者提供了一个高效、便捷的3D模型展示解决方案。通过这款SDK,客户可以轻松地将自己的3D模型集成到Web系统中,实现高质量的3D展示效果。
该SDK具有一系列令人瞩目的功能特点,包括但不限于光照、相机、剖切和拾取等。光照功能可以根据客户需求调整模型的光照效果,使得模型在展示时更加逼真;相机功能则允许用户自由调整视角和焦距,获得最佳的观看体验;剖切功能可以方便地对模型进行切割和查看内部结构,满足特定的展示需求;拾取功能则支持用户对模型进行交互操作,如点击、拖动等,增强了用户与模型的互动性。
3dconvert-viewer.js SDK的显示效果也非常出色。它采用了先进的渲染技术和优化算法,能够确保在Web环境中流畅地展示大型、复杂的3D模型。同时,SDK还支持多种格式的3D模型导入,方便客户使用现有的模型资源。
对于希望将3D模型集成到自己Web系统的客户来说,3dconvert-viewer.js SDK是一个理想的选择。它提供了简单易用的API接口和详细的文档支持,免服务端,使得开发者能够轻松地将其集成到现有的系统中。此外,SDK还提供了灵活的定制选项,可以根据客户的具体需求进行个性化设置,满足各种复杂的展示需求。
主要功能与特性
- 模型加载:通过指定模型资源fild,加载并显示3D模型。
- 交互控制:支持旋转、缩放、平移等基本视图控制,以及光照、视角、剖切、模型选择等高级设置。
- 扩展性良好:支持多种3D模型格式,可根据项目需求定制拓展功能。
快速开始
安装
$ npm install nsdt-3dconvert-viewer
// 使用
import Viewer from 'nsdt-3dconvert-viewer';
使用
html 代码
...
<div id="viewer-container" style="width: 100%;height: 600px;border: 1px solid #000;"></div>
...
js 代码
// 引入3dconvert-viewer
import Viewer from 'nsdt-3dconvert-viewer';
async function load3dModal() {
// 创建Viewer实例,初始化参数为 Dom id 或者 HTMLElement
const viewer = new Viewer('viewer-container');
// 初始化
await viewer.init();
// 文件id 详细过程请参考:【获取fileId】章节
const fileId = '687e6d1ec0'
// 加载模型
await viewer.loadObjectByFileId(fileId,{ enableCaching: false })
// 注册事件监听器
viewer.on('load-progress', (e) => {
console.log('模型加载进度', e);
});
}
load3dModal()
资源
开发demo 下载
3D大文件转换客户端 下载
BIM/CAD插件 下载
3Dconvert 服务私有化部署 查看
stp viewer 查看
3D模型在线转换 查看
GLTF在线编辑器 查看
获取fileId
3dconvert-viewer.js
SDK 是3dconvert
平台提供的3D模型web端预览组件。
这款SDK的设计以文件资源为核心。当您在3dconvert
平台上传3D模型后,平台会为您的模型分配一个唯一的ID(fileId
)。要查看这个fileId
,您可以登录3dconvert平台
,进入我的工作空间
,然后点击我的上传
,在相应的文件信息中找到fileId
字段。
使用SDK加载与fileId
对应的3D模型非常简单,只需编写少量代码(请参考示例代码)。如果您希望调整模型的展示效果或实现更个性化的功能,请查阅详细的API。
Vewer API
创建 Viewer 对象
// 创建 Viewer 对象
const viewer = new Viewer(container: HTMLElement, params: ViewerParams);
container
: Viewer绑定的HTML元素params: ViewerParams Viewer配置
interface ViewerParams { showStats?: boolean environmentSrc?: Asset | string verbose: boolean }
showStats
: 启用/禁用viewer画布左上角的统计窗口environmentSrc
: 允许用户为viewer场景定义环境纹理,形式为equirectangular HDRIverbose
: 在控制台中显示其他信息和警告。
在开始使用viewer之前,您需要像下面这样对其进行初始化:
await viewer.init()
该函数是异步的,因为在这一步骤中,viewer要么加载所需的资产(如您可能在params
中提供的HDRI),要么生成运行时资产。
事件绑定 ViewerEvent
on(eventType: ViewerEvent, handler: (arg) => void)
eventType
: ViewerEventenum ViewerEvent { ObjectClicked = 'object-clicked', ObjectDoubleClicked = 'object-doubleclicked', DownloadComplete = 'download-complete' LoadComplete = 'load-complete', LoadProgress = 'load-progress', LoadCancelled = 'load-cancelled', UnloadComplete = 'unload-complete', UnloadAllComplete = 'unload-all-complete', Busy = 'busy', SectionBoxChanged = 'section-box-changed' SectionBoxUpdated = 'section-box-updated' }
handler
: 回调函数
加载和卸载模型
Viewer通过文件id加载存储在服务端的模型
loadObject(fileId: string, {enableCaching?: boolean}): Promise<void>
fileId
: 模型对应的文件idenableCaching
: 启用/禁用浏览器中的数据缓存。默认为true
卸载模型
unloadObject(): Promise<void>
相机控制
控制视角
setView(view: CanonicalView)
用于操作相机的视角
view: CanonicalView:
type CanonicalView = | 'front' | 'back' | 'up' | 'top' | 'down' | 'bottom' | 'right' | 'left' | '3d' | '3D'
透视/正交相机切换
toggleCameraProjection()
Z/Y轴向上切换
toggleZXAxisUpFixed()
选中模型对象
设置模型选中并且高亮
selectObjects(objects:[]<objectId>);
objects
: objectId集合
当用户在viewer中点击某个3d对象时,监听ObjectClicked
或ObjectDoubleClicked
事件的回调函数会收到SelectionEvent
信息:
type SelectionEvent = {
multiple: boolean
event?: PointerEvent
hits: Array<{
guid?: string
object: Record<string, unknown>
point: Vector3
}>
}
- 当没有点击对象时,则会使用
null
作为参数触发ObjectClicked
事件
作为一个简单的例子,在单击对象时将其高亮并且聚焦:
viewer.on(ViewerEvent.ObjectClicked, (selectionInfo: SelectionEvent) => {
if (selectionInfo) {
// 选中对象 并且高亮对象
viewer.selectObjects([selectionInfo.hits[0].object.id])
// 对象聚焦
viewer.zoom([selectionInfo.hits[0].object.id ])
}
else {
//没有点击的对象。聚焦整个场景
viewer.zoom()
}
})
剖切盒
Viewer提供了一个可配置的剪切盒功能,可用于查看场景的部分内容。
setSectionBox(
box?: {
min: { x: number; y: number; z: number }
max: { x: number; y: number; z: number }
},
offset?: number
)
使用即时盒子定义设置切割盒的尺寸。
box
:切割盒尺寸的盒子定义。如果未提供此参数,则切割盒将调整为整个场景大小。offset
:用于增加/减小切割盒的可选乘数,默认为0.05
。
setSectionBoxFromObjects(objectIds: string[], offset?: number)**
根据一组对象设置切割盒的尺寸。
objectIds
:我们希望调整切割盒的对象ID。切割盒的尺寸将是其组合轴对齐边界框的结果。offset
:用于增加/减小切割盒的可选乘数,默认为0.05
。
启用切割盒。
sectionBoxOn(): void
禁用切割盒。
sectionBoxOff(): void
切换切割盒的开/关状态。
toggleSectionBox(): void
光照控制
设置光照
setLightConfiguration(config: LightConfiguration): void
config: LightConfiguration:
interface LightConfiguration {
enabled?: boolean
castShadow?: boolean
intensity?: number
color?: number
indirectLightIntensity?: number
}
interface SunLightConfiguration extends LightConfiguration {
elevation?: number
azimuth?: number
radius?: number
}
enabled
:启用/禁用太阳直射光castShadow
:启用/禁用太阳光投射阴影intensity
:太阳光的强度color
:太阳光的颜色(以 int 类型表示)indirectLightIntensity
:环境光强度(IBL)的强度elevation
:太阳球面角(以弧度为单位)azimuth
:太阳球面方位角(以弧度为单位)radius
:从场景包围球半径的偏移距离
系统默认配置:
export const DefaultLightConfiguration = {
enabled: true, // 太阳阴影是否开启
castShadow: false,
intensity: 3, // 太阳光强度
color: 0xffffff,
elevation: 1.8, // 太阳高度
azimuth: 0.75, // 太阳方位角
radius: 0,
indirectLightIntensity: 2,
shadowcatcher: false,
};
详细开发示例
代码示例
我们以Vue3
hooks
方式开发一个viewerHook
, 该hook是的主要功能有加载模型
、模型加载进度
、模型Z轴|Y轴向上切换
、模型显示模式切换
、模型光照设置
。
直接上代码`viewerHooks.ts:
//@ts-nocheck
import { ref } from 'vue'
import Viewer from '../lib/3dconvert-viewer.js'
const ViewerEvent = {
ObjectClicked: 'object-clicked',
ObjectDoubleClicked: 'object-doubleclicked',
DownloadComplete: 'download-complete',
LoadComplete: 'load-complete',
LoadProgress: 'load-progress',
UnloadComplete: 'unload-complete',
LoadCancelled: 'load-cancelled',
UnloadAllComplete: 'unload-all-complete',
Busy: 'busy',
SectionBoxChanged: 'section-box-changed',
SectionBoxUpdated: 'section-box-updated',
}
const DefaultLightConfiguration = {
enabled: true,
castShadow: false, // 太阳阴影是否开启
intensity: 3, // 太阳光强度
color: 0xffffff,
elevation: 1.8, // 太阳高度
azimuth: 0.75, // 太阳方位角
radius: 0,
indirectLightIntensity: 2,
shadowcatcher: false,
}
export const useViewer = function () {
const viewerRef = ref<any>()
/***
* y轴向上和z轴向上切换
*/
const yup = ref(false) // 默认z轴向上
const onZYUp = () => {
viewerRef.value.toggleZXAxisUpFixed()
const up = viewerRef.value?.cameraHandler?.camera?.up
yup.value = up.y === 1
}
/**
* viewer 显示模型切换 3d模型/看图模式
*/
const vieweMode = ref<number>(1)
const onVieweModeChange = () => {
vieweMode.value = vieweMode.value === 1 ? 2 : 1
viewerRef.value.toggleViewerMode()
}
/**
* 剖切盒
*/
const onCut = () => {
viewerRef.value.setSectionBox()
viewerRef.value.toggleSectionBox()
}
/**
* 光照变化
* @param config
*/
const sunConfig = ref({ ...DefaultLightConfiguration })
const sunConfigChange = config => {
sunConfig.value = config
setTimeout(() => {
viewerRef.value.setLightConfiguration(sunConfig.value)
}, 60)
}
/**
* 进度,及是否加载完成
*/
const loadProgress = ref<number>(0)
const loading = ref<boolean>(false)
const progressChange = evt => {
loading.value = (evt?.progress || 0) > 0 && (evt?.progress || 0) < 100
loadProgress.value = ((evt?.progress || 0) * 100).toFixed(2)
}
const loadComplete = () => (loading.value = false)
/**
* 选中 模型对象 模型高亮
* @param meshClickEvent
*/
const selectObject = meshClickEvent => {
const objects = (meshClickEvent?.hits || []).map(item => item.object.id)
viewerRef.value.selectObjects(objects)
}
/**
* viewer 初始化函数
* @param fileId 文件id
*/
const viewerInit = async (dom: any, fileId: any) => {
const viewer = new Viewer(dom)
viewerRef.value = viewer
viewerRef.value.setLightConfiguration(DefaultLightConfiguration)
await viewerRef.value.init()
/**
* 监听:[ 进度 | 点击 | 完成 ] 事件
*/
viewerRef.value.on(ViewerEvent.LoadProgress, progressChange)
viewerRef.value.on(ViewerEvent.ObjectClicked, selectObject)
viewerRef.value.on(ViewerEvent.LoadComplete, loadComplete)
if (fileId) await viewer.loadObjectByFileId(fileId, { enableCaching: true })
}
return {
viewerInit, // viewer 初始化函数 Function
loadProgress, // 加载模型进度
loading, // 是否正在加载中
sunConfig, // 光照参数
vieweMode, // 显示模式
sunConfigChange, // 光照参数变化函数 Function
onVieweModeChange, // 显示模式切换函数 Function
onZYUp, // z|y 轴向上切换函数 Function
onCut, // 剖切盒打开|关闭函数 Function
}
}
在vue组件中使用viewerHook
示例代码如下
<template>
....
</template>
<script setup lang="ts">
import { useViewer } from './hooks/viewerHooks'
/**
* Viewer use Function
*/
const {
loadProgress,
loading,
vieweMode,
sunConfig,
viewerInit,
onZYUp,
onCut,
onVieweModeChange,
sunConfigChange,
} = useViewer()
// 文件id
const fileId = 'cb1224158a'
onMounted(async () => {
await viewerInit('share3dviewer', fileId)
})
....
</script>
完整代码资源
您可以通过以下地址获取
这是一个完整的Vue3
项目,下载解压运行之后可以直接查看预览效果,并且Viewer对象与模型的交互都已经做好,可以体验交互!
使用方法
yarn
yarn dev
or npm
npm install
npm run dev
访问 http://localhost:5175
去除背景水印(可选)
如果你希望去除背景中的水印(nsdt.cloud),在模型内嵌对话框中点击【去除水印】即可,如下图所示:
或者进入【我的工作台】,在【我的上传】中找到对应的文件,点击【去水印】即可,如下图所示:
联系我们
如果有SDK使用上的疑问或者需要对SDK功能进行个性化的扩展,请联系我们