|  | @@ -2,202 +2,75 @@ import * as THREE from 'three';
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  export class bdfDataRenderer {
 |  |  export class bdfDataRenderer {
 | 
											
												
													
														|  |      constructor(updateProgress, onComplete) {
 |  |      constructor(updateProgress, onComplete) {
 | 
											
												
													
														|  | -        this.updateProgress = updateProgress; // 进度更新回调
 |  | 
 | 
											
												
													
														|  | -        this.onComplete = onComplete; // 渲染完成回调
 |  | 
 | 
											
												
													
														|  | 
 |  | +        this.updateProgress = updateProgress;
 | 
											
												
													
														|  | 
 |  | +        this.onComplete = onComplete;
 | 
											
												
													
														|  | 
 |  | +        this.meshGroup = new THREE.Group();
 | 
											
												
													
														|  | 
 |  | +        
 | 
											
												
													
														|  | 
 |  | +        this.defaultMaterial = new THREE.MeshPhongMaterial({
 | 
											
												
													
														|  | 
 |  | +            color: 0x2194ce,
 | 
											
												
													
														|  | 
 |  | +            side: THREE.DoubleSide,
 | 
											
												
													
														|  | 
 |  | +            flatShading: true,
 | 
											
												
													
														|  | 
 |  | +            transparent: true,
 | 
											
												
													
														|  | 
 |  | +            opacity: 0.8
 | 
											
												
													
														|  | 
 |  | +        });
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  | -    render(bdfData, scene) {
 |  | 
 | 
											
												
													
														|  | -        const { grids, cquadrs } = bdfData;
 |  | 
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -        // 渲染节点(分块加载)
 |  | 
 | 
											
												
													
														|  | -        this.renderGridsInChunks(grids, scene);
 |  | 
 | 
											
												
													
														|  | 
 |  | +    async render(bdfData, scene) {
 | 
											
												
													
														|  | 
 |  | +        this.clearScene(scene);
 | 
											
												
													
														|  | 
 |  | +        scene.add(this.meshGroup);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -        // 渲染四边形单元(分块加载)
 |  | 
 | 
											
												
													
														|  | -        this.renderCquadrsInChunks(cquadrs, grids, scene);
 |  | 
 | 
											
												
													
														|  | -    }
 |  | 
 | 
											
												
													
														|  | 
 |  | +        try {
 | 
											
												
													
														|  | 
 |  | +            await this.updateProgressAsync('开始渲染BDF模型...');
 | 
											
												
													
														|  | 
 |  | +            
 | 
											
												
													
														|  | 
 |  | +            // 直接使用原始数据格式,不经过解析器转换
 | 
											
												
													
														|  | 
 |  | +            const { vertices, indices } = bdfData;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    /**
 |  | 
 | 
											
												
													
														|  | -     * 分块渲染节点(grids)
 |  | 
 | 
											
												
													
														|  | -     * @param {Array} grids - 节点数据
 |  | 
 | 
											
												
													
														|  | -     * @param {THREE.Scene} scene - Three.js场景
 |  | 
 | 
											
												
													
														|  | -     */
 |  | 
 | 
											
												
													
														|  | -    renderGridsInChunks(grids, scene) {
 |  | 
 | 
											
												
													
														|  | -        if (!grids || grids.length === 0) return;
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -        const chunkSize = 1000; // 每块渲染1000个节点
 |  | 
 | 
											
												
													
														|  | -        let index = 0;
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -        // 创建高精度几何体和材质
 |  | 
 | 
											
												
													
														|  | -        const highDetailGeometry = new THREE.SphereGeometry(0.5, 16, 16);
 |  | 
 | 
											
												
													
														|  | -        const highDetailMaterial = new THREE.MeshBasicMaterial({ color: 0x0000ff });
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -        // 创建低精度几何体和材质
 |  | 
 | 
											
												
													
														|  | -        const lowDetailGeometry = new THREE.SphereGeometry(0.5, 8, 8);
 |  | 
 | 
											
												
													
														|  | -        const lowDetailMaterial = new THREE.MeshBasicMaterial({ color: 0x0000ff });
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -        // 创建 LOD 对象
 |  | 
 | 
											
												
													
														|  | -        const lod = new THREE.LOD();
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -        // 创建高精度 InstancedMesh
 |  | 
 | 
											
												
													
														|  | -        const highDetailInstancedMesh = new THREE.InstancedMesh(highDetailGeometry, highDetailMaterial, grids.length);
 |  | 
 | 
											
												
													
														|  | -        const lowDetailInstancedMesh = new THREE.InstancedMesh(lowDetailGeometry, lowDetailMaterial, grids.length);
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -        // 将高精度和低精度 InstancedMesh 添加到 LOD
 |  | 
 | 
											
												
													
														|  | -        lod.addLevel(highDetailInstancedMesh, 0); // 距离小于50时使用高精度
 |  | 
 | 
											
												
													
														|  | -        lod.addLevel(lowDetailInstancedMesh, 50); // 距离大于50时使用低精度
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -        const matrix = new THREE.Matrix4(); // 用于设置每个实例的位置
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -        const renderChunk = () => {
 |  | 
 | 
											
												
													
														|  | -            for (let i = 0; i < chunkSize && index < grids.length; i++, index++) {
 |  | 
 | 
											
												
													
														|  | -                const grid = grids[index];
 |  | 
 | 
											
												
													
														|  | -                const { x, y, z } = grid;
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -                // 设置实例的位置
 |  | 
 | 
											
												
													
														|  | -                matrix.setPosition(x, y, z);
 |  | 
 | 
											
												
													
														|  | -                highDetailInstancedMesh.setMatrixAt(index, matrix);
 |  | 
 | 
											
												
													
														|  | -                lowDetailInstancedMesh.setMatrixAt(index, matrix);
 |  | 
 | 
											
												
													
														|  | 
 |  | +            await this.updateProgressAsync('创建几何体...');
 | 
											
												
													
														|  | 
 |  | +            const geometry = new THREE.BufferGeometry();
 | 
											
												
													
														|  | 
 |  | +            
 | 
											
												
													
														|  | 
 |  | +            // 设置顶点属性(直接使用原始数组)
 | 
											
												
													
														|  | 
 |  | +            geometry.setAttribute(
 | 
											
												
													
														|  | 
 |  | +                'position',
 | 
											
												
													
														|  | 
 |  | +                new THREE.BufferAttribute(new Float32Array(vertices), 3)
 | 
											
												
													
														|  | 
 |  | +            );
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -                // 更新进度
 |  | 
 | 
											
												
													
														|  | -                if (this.updateProgress) {
 |  | 
 | 
											
												
													
														|  | -                    this.updateProgress(index, grids.length);
 |  | 
 | 
											
												
													
														|  | -                }
 |  | 
 | 
											
												
													
														|  | -            }
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -            // 打印当前进度
 |  | 
 | 
											
												
													
														|  | -            console.log(`Rendering grids: ${index} / ${grids.length} (${((index / grids.length) * 100).toFixed(2)}%)`);
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -            // 如果还有数据未渲染,继续渲染下一块
 |  | 
 | 
											
												
													
														|  | -            if (index < grids.length) {
 |  | 
 | 
											
												
													
														|  | -                requestAnimationFrame(renderChunk);
 |  | 
 | 
											
												
													
														|  | -            } else {
 |  | 
 | 
											
												
													
														|  | -                console.log('Grids rendering completed!');
 |  | 
 | 
											
												
													
														|  | -                if (this.onComplete) {
 |  | 
 | 
											
												
													
														|  | -                    this.onComplete(); // 调用渲染完成回调
 |  | 
 | 
											
												
													
														|  | -                }
 |  | 
 | 
											
												
													
														|  | -                highDetailInstancedMesh.instanceMatrix.needsUpdate = true; // 更新高精度实例化矩阵
 |  | 
 | 
											
												
													
														|  | -                lowDetailInstancedMesh.instanceMatrix.needsUpdate = true; // 更新低精度实例化矩阵
 |  | 
 | 
											
												
													
														|  | -                scene.add(lod); // 将 LOD 添加到场景中
 |  | 
 | 
											
												
													
														|  | 
 |  | +            // 设置索引(直接使用原始数组)
 | 
											
												
													
														|  | 
 |  | +            if (indices && indices.length > 0) {
 | 
											
												
													
														|  | 
 |  | +                geometry.setIndex(
 | 
											
												
													
														|  | 
 |  | +                    new THREE.BufferAttribute(new Uint32Array(indices), 1)
 | 
											
												
													
														|  | 
 |  | +                );
 | 
											
												
													
														|  |              }
 |  |              }
 | 
											
												
													
														|  | -        };
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -        // 开始渲染
 |  | 
 | 
											
												
													
														|  | -        renderChunk();
 |  | 
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +            await this.updateProgressAsync('优化几何体...');
 | 
											
												
													
														|  | 
 |  | +            geometry.computeVertexNormals();
 | 
											
												
													
														|  | 
 |  | +            geometry.computeBoundingSphere();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +            await this.updateProgressAsync('创建网格...');
 | 
											
												
													
														|  | 
 |  | +            const mesh = new THREE.Mesh(geometry, this.defaultMaterial);
 | 
											
												
													
														|  | 
 |  | +            this.meshGroup.add(mesh);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +            if (this.onComplete) this.onComplete();
 | 
											
												
													
														|  | 
 |  | +        } catch (error) {
 | 
											
												
													
														|  | 
 |  | +            console.error('BDF渲染错误:', error);
 | 
											
												
													
														|  | 
 |  | +            if (this.onComplete) this.onComplete(error);
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    /**
 |  | 
 | 
											
												
													
														|  | -     * 分块渲染四边形单元(CQUADR)
 |  | 
 | 
											
												
													
														|  | -     * @param {Array} cquadrs - 四边形单元数据
 |  | 
 | 
											
												
													
														|  | -     * @param {Array} grids - 节点数据
 |  | 
 | 
											
												
													
														|  | -     * @param {THREE.Scene} scene - Three.js场景
 |  | 
 | 
											
												
													
														|  | -     */
 |  | 
 | 
											
												
													
														|  | -    renderCquadrsInChunks(cquadrs, grids, scene) {
 |  | 
 | 
											
												
													
														|  | -        if (!cquadrs || cquadrs.length === 0) return;
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -        const chunkSize = 1000; // 每块渲染1000个四边形单元
 |  | 
 | 
											
												
													
														|  | -        let index = 0;
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -        // 创建高精度几何体和材质
 |  | 
 | 
											
												
													
														|  | -        const highDetailMaterial = new THREE.MeshBasicMaterial({
 |  | 
 | 
											
												
													
														|  | -            color: 0x00ffff, // 绿色
 |  | 
 | 
											
												
													
														|  | -            side: THREE.DoubleSide, // 双面渲染
 |  | 
 | 
											
												
													
														|  | -            transparent: true,
 |  | 
 | 
											
												
													
														|  | -            opacity: 0.7 // 半透明
 |  | 
 | 
											
												
													
														|  | -        });
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -        // 创建低精度几何体和材质
 |  | 
 | 
											
												
													
														|  | -        const lowDetailMaterial = new THREE.MeshBasicMaterial({
 |  | 
 | 
											
												
													
														|  | -            color: 0x00ffff, // 绿色
 |  | 
 | 
											
												
													
														|  | -            side: THREE.DoubleSide, // 双面渲染
 |  | 
 | 
											
												
													
														|  | -            transparent: true,
 |  | 
 | 
											
												
													
														|  | -            opacity: 0.5 // 更低透明度
 |  | 
 | 
											
												
													
														|  | -        });
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -        // 创建 LOD 对象
 |  | 
 | 
											
												
													
														|  | -        const lod = new THREE.LOD();
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -        // 创建合并的高精度几何体
 |  | 
 | 
											
												
													
														|  | -        const highDetailGeometry = new THREE.BufferGeometry();
 |  | 
 | 
											
												
													
														|  | -        const highDetailVertices = [];
 |  | 
 | 
											
												
													
														|  | -        const highDetailIndices = [];
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -        // 创建合并的低精度几何体
 |  | 
 | 
											
												
													
														|  | -        const lowDetailGeometry = new THREE.BufferGeometry();
 |  | 
 | 
											
												
													
														|  | -        const lowDetailVertices = [];
 |  | 
 | 
											
												
													
														|  | -        const lowDetailIndices = [];
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -        const renderChunk = () => {
 |  | 
 | 
											
												
													
														|  | -            for (let i = 0; i < chunkSize && index < cquadrs.length; i++, index++) {
 |  | 
 | 
											
												
													
														|  | -                const cquadr = cquadrs[index];
 |  | 
 | 
											
												
													
														|  | -                const { nodeIds } = cquadr;
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -                // 获取四边形单元的四个节点
 |  | 
 | 
											
												
													
														|  | -                const quadVertices = nodeIds.map((nodeId) => {
 |  | 
 | 
											
												
													
														|  | -                    const grid = grids.find((g) => g.id === nodeId);
 |  | 
 | 
											
												
													
														|  | -                    if (!grid) {
 |  | 
 | 
											
												
													
														|  | -                        console.warn(`Node ${nodeId} not found in grids`);
 |  | 
 | 
											
												
													
														|  | -                        return null;
 |  | 
 | 
											
												
													
														|  | -                    }
 |  | 
 | 
											
												
													
														|  | -                    return [grid.x, grid.y, grid.z];
 |  | 
 | 
											
												
													
														|  | -                }).filter(Boolean); // 过滤掉无效节点
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -                // 如果节点数量不足4个,跳过渲染
 |  | 
 | 
											
												
													
														|  | -                if (quadVertices.length < 4) {
 |  | 
 | 
											
												
													
														|  | -                    console.warn(`CQUADR with nodes ${nodeIds.join(', ')} has insufficient vertices`);
 |  | 
 | 
											
												
													
														|  | -                    continue;
 |  | 
 | 
											
												
													
														|  | -                }
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -                // 将顶点添加到高精度和低精度几何体中
 |  | 
 | 
											
												
													
														|  | -                const baseIndex = highDetailVertices.length / 3;
 |  | 
 | 
											
												
													
														|  | -                quadVertices.forEach((vertex) => {
 |  | 
 | 
											
												
													
														|  | -                    highDetailVertices.push(...vertex);
 |  | 
 | 
											
												
													
														|  | -                    lowDetailVertices.push(...vertex);
 |  | 
 | 
											
												
													
														|  | -                });
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -                // 添加四边形单元的索引
 |  | 
 | 
											
												
													
														|  | -                highDetailIndices.push(baseIndex, baseIndex + 1, baseIndex + 2);
 |  | 
 | 
											
												
													
														|  | -                highDetailIndices.push(baseIndex, baseIndex + 2, baseIndex + 3);
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -                lowDetailIndices.push(baseIndex, baseIndex + 1, baseIndex + 2);
 |  | 
 | 
											
												
													
														|  | -                lowDetailIndices.push(baseIndex, baseIndex + 2, baseIndex + 3);
 |  | 
 | 
											
												
													
														|  | -            }
 |  | 
 | 
											
												
													
														|  | -            // 更新进度
 |  | 
 | 
											
												
													
														|  | -            if (this.updateProgress) {
 |  | 
 | 
											
												
													
														|  | -                this.updateProgress(index, cquadrs.length);
 |  | 
 | 
											
												
													
														|  | -            }
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -            // 打印当前进度
 |  | 
 | 
											
												
													
														|  | -            console.log(`Rendering CQUADRs: ${index} / ${cquadrs.length} (${((index / cquadrs.length) * 100).toFixed(2)}%)`);
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -            // 如果还有数据未渲染,继续渲染下一块
 |  | 
 | 
											
												
													
														|  | -            if (index < cquadrs.length) {
 |  | 
 | 
											
												
													
														|  | -                requestAnimationFrame(renderChunk);
 |  | 
 | 
											
												
													
														|  | -            } else {
 |  | 
 | 
											
												
													
														|  | -                console.log('CQUADRs rendering completed!');
 |  | 
 | 
											
												
													
														|  | -                if (this.onComplete) {
 |  | 
 | 
											
												
													
														|  | -                    this.onComplete(); // 调用渲染完成回调
 |  | 
 | 
											
												
													
														|  | -                }
 |  | 
 | 
											
												
													
														|  | -                // 设置高精度几何体的顶点和索引
 |  | 
 | 
											
												
													
														|  | -                highDetailGeometry.setAttribute('position', new THREE.Float32BufferAttribute(highDetailVertices, 3));
 |  | 
 | 
											
												
													
														|  | -                highDetailGeometry.setIndex(highDetailIndices);
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -                // 设置低精度几何体的顶点和索引
 |  | 
 | 
											
												
													
														|  | -                lowDetailGeometry.setAttribute('position', new THREE.Float32BufferAttribute(lowDetailVertices, 3));
 |  | 
 | 
											
												
													
														|  | -                lowDetailGeometry.setIndex(lowDetailIndices);
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -                // 创建高精度和低精度网格
 |  | 
 | 
											
												
													
														|  | -                const highDetailMesh = new THREE.Mesh(highDetailGeometry, highDetailMaterial);
 |  | 
 | 
											
												
													
														|  | -                const lowDetailMesh = new THREE.Mesh(lowDetailGeometry, lowDetailMaterial);
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -                // 将高精度和低精度网格添加到 LOD
 |  | 
 | 
											
												
													
														|  | -                lod.addLevel(highDetailMesh, 0); // 距离小于50时使用高精度
 |  | 
 | 
											
												
													
														|  | -                lod.addLevel(lowDetailMesh, 50); // 距离大于50时使用低精度
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -                // 将 LOD 添加到场景中
 |  | 
 | 
											
												
													
														|  | -                scene.add(lod);
 |  | 
 | 
											
												
													
														|  | 
 |  | +    async updateProgressAsync(message) {
 | 
											
												
													
														|  | 
 |  | +        if (this.updateProgress) {
 | 
											
												
													
														|  | 
 |  | +            this.updateProgress(message);
 | 
											
												
													
														|  | 
 |  | +            await new Promise(resolve => requestAnimationFrame(resolve));
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    clearScene(scene) {
 | 
											
												
													
														|  | 
 |  | +        this.meshGroup.traverse(child => {
 | 
											
												
													
														|  | 
 |  | +            if (child.isMesh) {
 | 
											
												
													
														|  | 
 |  | +                child.geometry.dispose();
 | 
											
												
													
														|  | 
 |  | +                child.material.dispose();
 | 
											
												
													
														|  |              }
 |  |              }
 | 
											
												
													
														|  | -        };
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -        // 开始渲染
 |  | 
 | 
											
												
													
														|  | -        renderChunk();
 |  | 
 | 
											
												
													
														|  | 
 |  | +        });
 | 
											
												
													
														|  | 
 |  | +        scene.remove(this.meshGroup);
 | 
											
												
													
														|  | 
 |  | +        this.meshGroup = new THREE.Group();
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  }
 |  |  }
 |