LOD PCD Visualization#

Beagle provide a 3D web viewer using threejs

Beagle used custom renderer, material (shader) for visualizing point cloud data. See more in project BeagleWeb

Procedure#

  • Load bounding box (to zooming in)

  • for each frame:

    • check viewport perspective: if ( the octree node in viewport perspective) then (load data) else (remove data from viewport)

Load data#

Metadata#

  • Before load lod pcd, users can get bounding box first (for zooming to data location)

/**
 * Get Bounding Box Information 
 * @param hdfs 
 * @returns 
 */
 async function load_metadata(hdfs: string) {
    
    const url = `http://165.132.137.159:8080/api/restapi?type=preloadPCD&params=${hdfs}`;

    const response = await axios.get(url);

    return response.data;
}

Octree#

  • Each tile data was loaded from some Hadoop Sequence files. We need to know where tile data are located by the below function (load_mno)

/**
 * Load Modifiable Nested Octree(MNO) 
 * @param projectID 
 * @param pclID 
 * @param tileID 
 * @returns 
 */
async function load_mno(projectID = "HDEC_HS_JA", pclID = "B2F_05", tileID = "r") {

    const url = `http://165.132.137.159:8080/api/loadTree?ProjectId=${projectID}&PclId=${pclID}&TileId=${tileID}`;
    
    const response = await axios.get(url);
    const data = response.data;

    const children = [false, false, false, false, false, false, false, false];
    const points_data: any[] = [];
    
    for (let key in data) {
        const item = data[key];
        const partID = item['PartId'];
        const pos = item['Pos']

        const point_data = await load_points(projectID, pclID, partID, pos);
        points_data.push(point_data);

        {   // obtain children (octree): '0|1|2|3|4|5|6|7' 
            const ChildIds_string = item['ChildIds']
            const arr = ChildIds_string.split('|')
            arr.map((item: string) => {
                const child_index = Number(item);
                children[child_index] = true;
            });
        }
    }

    return { children, points_data };
}

Tile data#

async function load_points(projectID: any, pclID: any, partID: any, pos: any) {

    const url = `http://165.132.137.159:8080/api/loadPoints?ProjectId=${projectID}&PclId=${pclID}&PartId=${partID}&Pos=${pos}`;
    
    return axios.get(url).then((response: any) => {
        const data = response.data.Data;
        const lines = data.split('$');
        return lines.map((line: any) => line.split('|')
                                        .map( (item: String) => Number(item)) );
    });
}