How can i get section from the Cesium.Model by name or id like get the features from 3dtileset

1 Introduce

This is a require that we want to get a section from the Cesiumjs Model to make it visible or hidden .

I had tried the Cesium.Model.getNode API to get node by name but i found that i only can control the root visible or hidden.

Maybe you will ask me why i do not use the Cesium3DTileset API, beacause this requiement from our customer is that they only have BIM Model and don’t want to deploy the model on orther server.

:rofl:

2 SourceCode

<template>
  <div>
    <div id="cesiumContainer"></div>

    <div class="controll-container"></div>
  </div>
</template>

<script setup lang="ts">
// @BUILD_TIME: 2025-04-06 21:33:01
// @AUTHOR: sha_xiangyun
// @DESCRIPTION:

/*-------------------- 外部引入 --------------------*/
import { ref, onMounted, onUnmounted } from 'vue'
import * as Cesium from 'cesium'
import type { Viewer } from 'cesium'
import { ElMessage } from 'element-plus'

/*-------------------- 内部引入 --------------------*/
import { CesiumViewerOptions } from '@/hooks/CesiumViewerOptions'

/*-------------------- 类型定义 --------------------*/

/*-------------------- 常量定义 --------------------*/

/*-------------------- 全局变量 --------------------*/
let viewer: Viewer
const viewerRef = ref<Viewer>()
const modelURL = '/test'

/*-------------------- 状态管理 --------------------*/

/*-------------------- 生命周期 --------------------*/
onMounted(async () => {
  try {
    const __viewer__ = initCesium('cesiumContainer', CesiumViewerOptions, configCesiumViewer)
    if (__viewer__ instanceof Error) throw __viewer__

    viewer = __viewer__
    viewerRef.value = __viewer__

    const model = await loadModel(viewer)
    if (model instanceof Error) throw model

    model.readyEvent.addEventListener(async (model: Cesium.Model) => {
      viewer.camera.flyToBoundingSphere(model.boundingSphere)

      console.log(model['_nodeByName'])

      const testnode = model.getNode('::root::')
      testnode.show = false
    })
  } catch (error: unknown) {
    console.error(error)
    ElMessage.error('初始化 Cesium 实例失败')
  }
})

onUnmounted(() => {
  if (viewer) {
    viewer.destroy()
  }
})

/*--------------------  侦听器  --------------------*/

/*-------------------- 计算属性 --------------------*/

/*-------------------- 函数定义 --------------------*/
/**
 * @function 普通函数
 * @name initCesium
 * @description 初始化 Cesium 实例
 * @param { HTMLDivElement | string } el - 容器元素或 ID 字符串
 * @param { Viewer.ConstructorOptions } options - Cesium 构造参数
 * @param { (viewer: Viewer) => void } cb - 回调函数,用于配置 Cesium 实例
 * @returns { Viewer | Error } Cesium 实例
 */
/* prettier-ignore */
function initCesium(el: HTMLDivElement | string, options: Viewer.ConstructorOptions, cb: (viewer: Viewer) => void,): Viewer | Error {
  try {
    /* 设置 Cesium 授权 */
    Cesium.Ion.defaultAccessToken =
      'your - token'

    /* 初始化 Cesium 实例 */
    const viewer = new Cesium.Viewer(el, options)

    /* 配置 Cesium 实例 */
    cb(viewer)

    /* 返回 Cesium 实例 */
    return viewer
  } catch (error: unknown) {
    console.error(error)
    return new Error('初始化 Cesium 实例失败')
  }
}

/**
 * @function 回调函数
 * @name configCesiumViewer
 * @description 配置 Cesium 实例
 * @param { Viewer } viewer - Cesium 实例
 * @returns { void }
 */
function configCesiumViewer(viewer: Cesium.Viewer): void {
  /* viewer camera 设置 */
  viewer.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(116.3901, 39.9046, 10000),
    orientation: {
      heading: Cesium.Math.toRadians(0),
      pitch: Cesium.Math.toRadians(-90),
      roll: 0.0,
    },
    duration: 1,
  })
}

/**
 * @function 异步函数
 * @name loadModel
 * @description 加载模型
 * @returns { Promise<Cesium.Model> | Error } 模型实例
 */
async function loadModel(viewer: Cesium.Viewer): Promise<Cesium.Model | Error> {
  try {
    const modelMatrix =   Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3(116.3901, 39.9046, 0))

    const model = await Cesium.Model.fromGltfAsync({
      url: modelURL,
      modelMatrix,
      scale: 0.01,
    })

    viewer.scene.primitives.add(model)

    return model
  } catch (error: unknown) {
    console.error(error)
    return new Error('加载模型失败')
  }
}
</script>

<style scoped>
#cesiumContainer {
  width: 100vw;
  height: 100vh;
}

.controll-container {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 9999;
}
</style>

3 Development Enviroment

  • OS: Windows
  • Nodejs version: 18.20.4

Hi @xiangyun-sha

Thanks for your note and for being part of the Cesium community.

Most the show/hide logic for models in CesiumJS API is exposed through the tileset, not the model Styling and Filtering 3D Tiles – Cesium

don’t want to deploy the model on orther server.

It is not required to stream 3DTiles from a separate server. This thread dives into using CesiumJS in offline mode and serving assets such as a 3DTileset from the same folder and your application Cesium Completely Offline Mode

Please let us know if this does not address your question fully and we would be happy to try to help more.

Thanks,
Luke

Register for the 2025 Cesium Developer Conference, June 23-25, Philadelphia.

1 Like