如何在APS Viewer中引入THREE.js更多几何类型(如TextGeometry)?
在APS Viewer中引入THREE.js额外几何类型(如TextGeometry)的实现方案
核心思路
APS Viewer基于特定版本的THREE.js构建,直接引入外部THREE.js会导致版本冲突,因此必须复用Viewer内置的THREE对象,手动注入所需的几何类型模块(如TextGeometry),并配合对应依赖完成加载。
具体步骤
1. 获取Viewer内置的THREE对象
通过Autodesk.Viewing.Private.Threejs获取Viewer自带的THREE实例,彻底避免版本冲突:
const THREE = Autodesk.Viewing.Private.Threejs;
2. 注入TextGeometry模块
Viewer内置THREE未包含TextGeometry,需手动注入对应版本的源码(需与Viewer使用的THREE版本匹配,比如Viewer v7.x对应THREE r125):
// 注入TextGeometry到Viewer的THREE对象 THREE.TextGeometry = function (text, parameters) { THREE.BufferGeometry.call(this); this.type = 'TextGeometry'; this.parameters = { text: text, parameters: parameters }; parameters = parameters || {}; const font = parameters.font; if (!(font && font.isFont)) { console.error('THREE.TextGeometry: font参数必须是THREE.Font实例'); return; } const glyphs = font.data.glyphs; const scale = font.data.resolution / font.data.size; const lineHeight = (font.data.boundingBox.yMax - font.data.boundingBox.yMin) * scale; const yOffset = font.data.boundingBox.yMin * scale; let shapes = []; const chars = Array.from(text); let lastGlyph = null; for (let i = 0; i < chars.length; i++) { const char = chars[i]; const glyph = glyphs[char]; if (!glyph) { console.warn(`THREE.TextGeometry: 字体中不存在字符 "${char}"`); continue; } const charShapes = glyph.shapes; if (lastGlyph) { const kerning = lastGlyph.kerning[char] || 0; const offsetX = (lastGlyph.ha + kerning) * scale; for (let j = 0; j < charShapes.length; j++) { charShapes[j].translate(offsetX, 0); } } shapes.push(...charShapes); lastGlyph = glyph; } for (let i = 0; i < shapes.length; i++) { shapes[i].translate(0, yOffset); } const geometry = new THREE.ShapeGeometry(shapes); if (parameters.size !== undefined) geometry.scale(parameters.size, parameters.size, parameters.size); if (parameters.center) { const boundingBox = geometry.boundingBox; geometry.translate( -(boundingBox.max.x + boundingBox.min.x) / 2, -(boundingBox.max.y + boundingBox.min.y) / 2, -(boundingBox.max.z + boundingBox.min.z) / 2 ); } geometry.mergeVertices(); this.copy(geometry); }; THREE.TextGeometry.prototype = Object.create(THREE.BufferGeometry.prototype); THREE.TextGeometry.prototype.constructor = THREE.TextGeometry;
3. 加载字体并创建文字模型
使用Viewer内置的FontLoader加载THREE.js兼容的JSON格式字体(可通过THREE.js官方工具将TTF字体转换为JSON),然后创建TextGeometry并添加到Viewer场景:
// 加载JSON字体文件 const fontLoader = new THREE.FontLoader(); fontLoader.load('path/to/your/font.json', function(font) { // 创建TextGeometry实例 const textGeo = new THREE.TextGeometry('APS Viewer 文字示例', { font: font, size: 10, height: 2, curveSegments: 12, bevelEnabled: true, bevelThickness: 1, bevelSize: 0.5, bevelOffset: 0, bevelSegments: 5 }); // 创建材质 const textMaterial = new THREE.MeshStandardMaterial({ color: 0xff0000 }); const textMesh = new THREE.Mesh(textGeo, textMaterial); // 调整文字位置与缩放(适配Viewer场景单位) textMesh.position.set(0, 5, 0); textMesh.scale.set(0.1, 0.1, 0.1); // 获取Viewer主场景并添加文字模型 const viewer = NOP_VIEWER; // 替换为你的Viewer实例 const scene = viewer.impl.scene; scene.add(textMesh); // 强制Viewer刷新渲染 viewer.impl.invalidate(true); });
注意事项
- 版本匹配:TextGeometry源码需与Viewer内置THREE.js版本严格匹配,避免API差异导致报错。
- 字体格式:必须使用THREE.js兼容的JSON字体,可通过官方工具转换TTF文件。
- 场景层级:若需文字始终显示在模型上方,可将模型添加到
viewer.impl.overlayScene而非主场景。 - CORS配置:加载跨域字体文件时,需确保服务器配置了正确的CORS策略。
内容的提问来源于stack exchange,提问作者maciejwypych
相关产品推荐
相关产品推荐

