DEV Community

Masui Masanori
Masui Masanori

Posted on

Using Potree from code written in TypeScript 1

Intro

In this time, I will try loading point cloud data by Potree.

Because I want to use TypeScript in my project, I will start by using Potree from code written in TypeScript.
I will use Express for the server-side code.

Sample project

Building Potree

Because Potree isn't officially published on npm, so I have to build it myself.
To do this, I clone the repository and execute "npm install" and "npm run build".

After the build is complete, I will copy three folders from the directory into my project.

potree          <-the root directory of the Potree repository
    Lbuild     <-build files
    Llibs      <-dependencies
    Lresources <-sample point cloud data
Enter fullscreen mode Exit fullscreen mode

Image description

Adding d.ts

To use Potree from TypeScript code, I should create a type definition file.

For now, I'm not defining the complete types, but only defining the variables and functions that I will use in this time.

ts/types/potree/index.d.ts

namespace Potree {
    const PointSizeType = {
        FIXED: 0,
        ATTENUATED: 1,
        ADAPTIVE: 2
    };
    const PointShape = {
        SQUARE: 0,
        CIRCLE: 1,
        PARABOLOID: 2
    };

    class Viewer {
        scene: Scene;
        constructor(element: HTMLElement);

        setPointBudget(budget: number): void;
        loadPointCloud(path: string, name: string, callback?: (e: PointCloudEventVariable) => void): void;
        setEDLEnabled(enabled: boolean): void;
        setFOV(fov: number): void;
        setBackground(color: string): void;
        fitToScreen(): void;
        loadSettingsFromURL(): void;
    }

    class PointCloudEventVariable {
        pointcloud: PointCloud;
    }
    class PointCloud {
        position: THREE.Vector3;
        scale: THREE.Vector3;
        material: PointCloudMaterial;
    }
    class Scene {
        addPointCloud(pointcloud: PointCloud): void;
    }
    class PointCloudMaterial {
        size: number;
        pointSizeType: PointSizeType;
        shape: PointShape;
    }
    function loadPointCloud(
        path: string,
        name: string,
        callback: (e: PointCloudEventVariable) => void
    ): void;
}
Enter fullscreen mode Exit fullscreen mode

Because the Potree script files are loaded as external scripts, I can't use "import" like "import * as Potree from 'potree'".

Also, I can't write like "Viewer()" directly, I have to call it with "Potree." added, like "Potree.Viewer()".

Loading point cloud data

Potree can load a laz file.
But I have to convert it by PotreeConverter first.

I will get a laz file from 静岡県 - 掛川城オープンデータ化プロジェクト - データセット.

After finishing converting it, I can load it like below.

potreeAccessor.ts

export class PotreeAccessor {
    private viewer: Potree.Viewer;
    private scene: (Potree.Scene|null) = null;

    public constructor() {
        this.viewer = new Potree.Viewer(document.getElementById("potree_render_area") as HTMLElement);
        this.viewer.setEDLEnabled(false);
        this.viewer.setFOV(60);
        this.viewer.setPointBudget(1_000_000);
        this.viewer.loadSettingsFromURL();
        this.viewer.setBackground("skybox");
        Potree.loadPointCloud("./resources/PotreeData/metadata.json", "KakegawaCastle", e => {
            this.scene = this.viewer.scene;
            const pointcloud = e.pointcloud;

            const material = pointcloud.material;
            material.size = 1;
            material.pointSizeType = Potree.PointSizeType.ADAPTIVE;
            material.shape = Potree.PointShape.CIRCLE;

            this.scene.addPointCloud(pointcloud);
            this.viewer.fitToScreen();
        });
    }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)