Modern, framework-agnostic point cloud viewer built on potree-core and Three.js
npm install potree-viewerbash
Install dependencies
cd viewer-lib
npm install
`
Dependencies:
- three - Three.js 3D library
- potree-core - Core Potree point cloud rendering engine
$3
`html
PotreeViewer Demo
`
$3
`javascript
import { PotreeViewer, Toolbar, PotreeViewerConsole } from 'potree-viewer';
// Create viewer
const viewer = new PotreeViewer({
container: document.getElementById('viewer'),
pointCloudUrl: '/pointcloud/metadata.json',
pointCloudName: 'Forest Scan',
description: 'LiDAR scan of forest area',
pointBudget: 1_000_000,
fov: 80,
initialView: 'right',
material: {
size: 0.6,
minSize: 0.4,
pointSizeType: 'FIXED',
shape: 'SQUARE',
},
background: 'black',
autoFitOnLoad: true,
// Callbacks
onReady: (viewerInstance) => {
console.log('Viewer ready!', viewerInstance);
},
onPointCloudLoaded: (pointCloud) => {
console.log('Point cloud loaded:', pointCloud);
},
onError: (error) => {
console.error('Viewer error:', error);
}
});
// Create toolbar with measurement and view controls
const toolbar = new Toolbar(viewer, {
alignment: 'top-right'
});
// Create console for status messages and measurement results
const console = new PotreeViewerConsole(viewer, {
position: 'bottom-left',
width: '360px',
collapsed: false,
showTimestamp: true,
visible: true
});
// Keyboard shortcut to toggle console (Ctrl+)
') {
console.toggleVisibility();
}
});
// Clean up on page unload
window.addEventListener('beforeunload', () => {
toolbar.dispose();
console.dispose();
viewer.dispose();
});
`
Configuration
$3
`javascript
const viewer = new PotreeViewer({
// Required
container: HTMLElement, // DOM element to render into
// Point cloud settings
pointCloudUrl: string, // Path to metadata.json
pointCloudName: string, // Display name (default: 'pointcloud')
description: string, // Description text
// Viewer settings
pointBudget: number, // Max visible points (default: 1,000,000)
fov: number, // Field of view in degrees (default: 80)
// Eye-Dome Lighting (EDL) settings
edl: {
enabled: boolean, // Enable EDL (default: false)
strength: number, // Shading intensity 0.0-2.0 (default: 0.4)
radius: number, // Sampling radius 0.5-3.0 (default: 1.4)
opacity: number, // Effect opacity 0.0-1.0 (default: 1.0)
pointCloudLayer: number, // Render layer (default: 1)
neighbourCount: number, // Neighbor samples (default: 8)
},
// Initial view
initialView: 'top' | 'bottom' | 'front' | 'back' | 'left' | 'right' |
{ position: {x, y, z}, target: {x, y, z} },
// Material settings
material: {
size: number, // Point size (default: 0.6)
minSize: number, // Min point size (default: 0.4)
pointSizeType: 'FIXED' | 'ATTENUATED' | 'ADAPTIVE',
shape: 'SQUARE' | 'CIRCLE',
},
// Background
background: 'black' | 'white' | 'gradient' | '#hexcolor',
// Behavior
autoFitOnLoad: boolean, // Auto-fit camera to point cloud
loadSettingsFromUrl: boolean, // Load settings from URL params
// Callbacks
onReady: (viewer) => void,
onPointCloudLoaded: (pointCloud) => void,
onError: (error) => void,
});
`
$3
`javascript
const toolbar = new Toolbar(viewer, {
alignment: 'top-right', // Position of toolbar
// Options: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' |
// 'left' | 'right' | 'top' | 'bottom'
buttons: [...], // Custom button configuration (optional)
});
`
Default toolbar buttons:
1. Fit to Screen - Automatically fits the point cloud to the viewport
2. View & Appearance dropdown with:
- Camera Views: Left, Right, Front, Back, Top, Bottom
- Point Color Mode: RGB, Elevation, Classification, Intensity, Intensity Gradient, Return Number, Source ID, Normal, Level of Detail
- Background: Black, White, Gradient, Skybox
3. Measurements dropdown with:
- Distance, Height, Angle, Radius, Volume
4. Clear Measurements (X button) - Clears all measurements and exits measurement mode (disabled when no measurements exist)
5. Settings dropdown with:
- Eye-Dome Lighting (EDL) - Toggle and configure depth enhancement effect
- Enable/Disable toggle
- Strength slider (0.0 - 2.0) - Shading intensity
- Radius slider (0.5 - 3.0) - Sampling radius
- Opacity slider (0.0 - 1.0) - Effect opacity
- Point Budget slider (100K - 10M points) - Controls maximum number of visible points
- Field of View slider (20Β° - 100Β°) - Controls camera perspective
- Point Size slider (0.1 - 5.0)
- Point Shape (Square / Circle)
- Point Size Type (Fixed / Attenuated / Adaptive)
$3
`javascript
const console = new PotreeViewerConsole(viewer, {
position: 'bottom-left', // Position of console
// Options: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right'
width: '360px', // Console width
collapsed: false, // Start collapsed
showTimestamp: true, // Show timestamp for each message
visible: true, // Initially visible
maxMessages: 50, // Maximum messages to keep
// Log level filtering
logLevel: 'info', // 'debug' | 'info' | 'warning' | 'error' | 'none'
// 'debug' - Show all messages including debug info
// 'info' - Show info, warnings, and errors (default)
// 'warning' - Show warnings and errors only
// 'error' - Show errors only
// 'none' - Disable all logging
});
`
Log Levels Explained:
- debug - Detailed technical information useful for development and troubleshooting
- info - General informational messages about viewer operations (default level)
- warning - Warning messages that don't prevent operation but may indicate issues
- error - Error messages for failures and critical problems
The viewer automatically logs important operations:
- Point cloud loading and initialization
- Camera view changes
- Measurement operations (adding points, completing measurements)
- Point budget and FOV changes
- Color mode switches
Examples:
`javascript
// Set log level at creation
const console = new PotreeViewerConsole(viewer, { logLevel: 'debug' });
// Change log level dynamically
console.setLogLevel('warning'); // Only show warnings and errors
console.setLogLevel('debug'); // Show all messages
// Get current log level
const level = console.getLogLevel(); // returns 'debug', 'info', 'warning', 'error', or 'none'
`
API Reference
$3
Below is a complete list of all public methods available on the PotreeViewer instance:
Camera & View
- setView(position, target) - Set camera position and target
- setNamedView(viewName) - Set predefined view ('top', 'bottom', 'front', 'back', 'left', 'right')
- getNamedView() - Get current named view or 'custom'
- setFov(fov) - Set camera field of view in degrees (30 - 120)
- fitToScreen() - Fit point cloud to viewport
Point Cloud Management
- loadPointCloud(url, name) - Load a point cloud (returns Promise)
- setPointBudget(budget) - Set maximum visible points (default: 1,000,000)
- setBackground(background) - Set background ('black', 'white', 'gradient', 'skybox', or hex color)
Point Appearance
- setPointColorType(colorType) - Set point coloring mode (use PointColorType enum)
- getPointColorType() - Get current color type
- setPointSize(size) - Set point size in pixels (0.1 - 5.0)
- setPointOpacity(opacity) - Set point opacity (0.0 - 1.0)
- setPointShape(shape) - Set point shape ('circle' or 'square')
- setPointSizeType(type) - Set size scaling ('fixed', 'attenuated', or 'adaptive')
Eye-Dome Lighting (EDL)
- enableEDL() - Enable EDL effect
- disableEDL() - Disable EDL effect
- toggleEDL() - Toggle EDL on/off (returns new state)
- isEDLEnabled() - Check if EDL is enabled
- setEDLStrength(strength) - Set EDL strength (0.0 - 2.0)
- setEDLRadius(radius) - Set EDL radius (0.5 - 3.0)
- setEDLOpacity(opacity) - Set EDL opacity (0.0 - 1.0)
- setEDLSettings(options) - Set multiple EDL parameters at once
- getEDLSettings() - Get current EDL configuration
- getEDLInternalState() - Get EDL internal state (for debugging)
Measurements
- setMeasurementMode(mode) - Set measurement mode ('none', 'distance', 'height', 'angle', 'radius', 'volume')
- getMeasurementMode() - Get current measurement mode
- startMeasurement(type) - Programmatically start a measurement
- finishMeasurement(id) - Finish a measurement by ID
- getMeasurements() - Get array of all measurement summaries
- removeMeasurement(id) - Remove a specific measurement
- clearMeasurements() - Clear all measurements
Advanced Access
- getPotree() - Get underlying Potree instance
- getScene() - Get Three.js scene
- getCamera() - Get Three.js camera
- getRenderer() - Get Three.js WebGL renderer
- getConsole() - Get PotreeViewerConsole instance (if attached)
- recenterOnObject() - Set OrbitControls target to point cloud center
Lifecycle
- dispose() - Clean up and free all resources
---
$3
#### Camera & View Control
`javascript
// Set camera position and target
viewer.setView(
{ x: 10, y: 10, z: 10 }, // position
{ x: 0, y: 0, z: 0 } // target
);
// Set predefined view
viewer.setNamedView('top' | 'bottom' | 'front' | 'back' | 'left' | 'right');
// Get current view name
const viewName = viewer.getNamedView(); // returns view name or 'custom'
// Set field of view (controls camera perspective)
viewer.setFov(60); // degrees (30 - 120), default: 80
// Fit point cloud to screen
viewer.fitToScreen();
`
#### Point Cloud Management
`javascript
// Load additional point cloud
await viewer.loadPointCloud('path/to/metadata.json', 'cloud-name');
// Set point budget
viewer.setPointBudget(2_000_000);
// Set background
viewer.setBackground('white');
viewer.setBackground('#87CEEB');
`
#### Point Appearance
`javascript
import { PointColorType, PointSizeType, PointShape } from 'potree-core';
// Point Color Mode
viewer.setPointColorType(PointColorType.RGB); // RGB colors (default)
viewer.setPointColorType(PointColorType.CLASSIFICATION); // LAS classification
viewer.setPointColorType(PointColorType.ELEVATION); // Height-based gradient
viewer.setPointColorType(PointColorType.INTENSITY); // Intensity-based
const colorType = viewer.getPointColorType(); // Get current color type
// Point Size
viewer.setPointSize(1.5); // Set size in pixels (0.1 - 5.0)
// Point Opacity
viewer.setPointOpacity(0.8); // Set opacity (0.0 - 1.0), default: 1.0
// Point Shape
viewer.setPointShape('circle'); // 'circle' or 'square'
// Point Size Type (how size scales with distance)
viewer.setPointSizeType('adaptive'); // 'fixed', 'attenuated', or 'adaptive'
`
Available PointColorType values:
- RGB - RGB colors from point cloud data
- CLASSIFICATION - LAS classification colors (ground=brown, vegetation=green)
- ELEVATION - Height-based gradient
- INTENSITY - Intensity-based colors
- INTENSITY_GRADIENT - Intensity with gradient colors
- RETURN_NUMBER - LiDAR return number
- SOURCE - Source ID
- NORMAL - Surface normals
- LOD - Level of detail
- DEPTH - Distance from camera (if available)
#### Eye-Dome Lighting (EDL)
EDL enhances depth perception by applying a shading effect based on point depth differences. It's particularly useful for RGB point clouds where depth is hard to perceive.
`javascript
// Enable/Disable EDL
viewer.enableEDL(); // Enable with current settings
viewer.disableEDL(); // Disable EDL
viewer.toggleEDL(); // Toggle on/off (returns new state: true/false)
// Check if enabled
const isEnabled = viewer.isEDLEnabled(); // returns true/false
// Configure EDL parameters
viewer.setEDLStrength(1.2); // Intensity of shading (0.0 - 2.0)
viewer.setEDLRadius(2.0); // Sampling radius in pixels (0.5 - 3.0)
viewer.setEDLOpacity(0.8); // Effect opacity (0.0 - 1.0)
// Set multiple parameters at once
viewer.setEDLSettings({
enabled: true,
strength: 1.5,
radius: 2.0,
opacity: 1.0
});
// Get current settings
const edlSettings = viewer.getEDLSettings();
// Returns: { enabled, strength, radius, opacity, pointCloudLayer, neighbourCount }
// Initialize viewer with EDL enabled
const viewer = new PotreeViewer({
container: document.getElementById('viewer'),
pointCloudUrl: 'cloud/metadata.json',
edl: {
enabled: true,
strength: 0.8,
radius: 1.6,
opacity: 1.0
}
});
`
EDL Parameters Explained:
- strength - Controls the intensity of the depth-based shading effect (0.0 = no effect, 2.0 = maximum)
- radius - Sampling radius in screen pixels for neighbor points (larger = smoother but less detailed)
- opacity - Blending opacity of the EDL effect (1.0 = full effect, 0.0 = invisible)
- pointCloudLayer - WebGL render layer for point cloud (typically 1, advanced use only)
- neighbourCount - Number of neighbor samples (8 or 4, advanced use only)
Important: When updating EDL parameters at runtime, always ensure you're passing the complete configuration. The setEDL*() methods handle this automatically, but if you're using setEDLSettings() or working with the underlying potreeRenderer.setEDL() directly, use the spread operator:
`javascript
// β
Correct - passes all properties
const edl = viewer.getEDLSettings();
edl.strength = 2.0;
viewer.setEDLSettings({ ...edl });
// β Wrong - may disable EDL or not update properly
viewer.setEDLSettings({ strength: 2.0 }); // Missing other properties!
`
#### Measurements
`javascript
// Set measurement mode
viewer.setMeasurementMode('distance'); // Distance measurement
viewer.setMeasurementMode('height'); // Height measurement
viewer.setMeasurementMode('angle'); // Angle measurement
viewer.setMeasurementMode('radius'); // Radius measurement
viewer.setMeasurementMode('volume'); // Volume measurement
viewer.setMeasurementMode('none'); // Return to navigation mode
// Get current mode
const mode = viewer.getMeasurementMode();
// Programmatic measurement control
const measurement = viewer.startMeasurement('distance');
viewer.finishMeasurement(measurement.id);
viewer.removeMeasurement(measurement.id);
viewer.clearMeasurements();
// Get all measurements
const measurements = viewer.getMeasurements();
// Returns array of measurement summaries:
// [{
// id: 'measurement-123',
// type: 'distance' | 'height' | 'angle' | 'radius' | 'volume',
// points: [{ x, y, z }, { x, y, z }, ...],
// result: { / measurement-specific results / }
// }, ...]
`
#### Advanced Access
`javascript
// Get underlying instances (for advanced use)
const potree = viewer.getPotree(); // Potree instance
const scene = viewer.getScene(); // Three.js scene
const camera = viewer.getCamera(); // Three.js camera
const renderer = viewer.getRenderer(); // Three.js renderer
const console = viewer.getConsole(); // PotreeViewerConsole instance (if attached)
// Recenter camera target on point cloud
viewer.recenterOnObject();
`
#### Cleanup
`javascript
// Dispose viewer and free resources
viewer.dispose();
`
$3
`javascript
// Create toolbar
const toolbar = new Toolbar(viewer, options);
// Dispose toolbar
toolbar.dispose();
`
$3
`javascript
// Show/hide console
console.show();
console.hide();
console.toggleVisibility();
console.isVisible(); // returns true/false
// Toggle collapsed state
console.toggle();
// Clear all messages
console.clear();
// Add custom messages (filtered by log level)
console.log('Message', 'info'); // Generic log method
console.debug('Debug info'); // Debug messages (shown only with logLevel='debug')
console.info('Information'); // Info messages
console.warn('Warning message'); // Warning messages
console.error('Error message'); // Error messages
// Legacy log method with type parameter
console.log('Success!', 'success');
console.log('Warning!', 'warning');
console.log('Error!', 'error');
// Manage log level
console.setLogLevel('debug'); // Change log level dynamically
const level = console.getLogLevel(); // Get current log level
// Dispose console
console.dispose();
`
$3
The viewer uses an event system for notifications. Subscribe to events using viewer.on(eventName, callback) and unsubscribe with viewer.off(eventName, callback).
Available Events:
- ready - Viewer initialized
- error - Error occurred
- pointcloud-loaded - Point cloud loaded successfully
- view-changed - Camera position/target changed
- measurement-started - New measurement created
- measurement-updated - Point added to current measurement
- measurement-finished - Measurement completed
- measurement-mode-changed - Measurement mode changed
- measurements-cleared - All measurements cleared
- color-type-changed - Point color mode changed
- background-changed - Background changed
- edl-changed - EDL settings changed
Subscribe to viewer events:
`javascript
// Viewer lifecycle
viewer.on('ready', (viewerInstance) => {
console.log('Viewer initialized');
});
viewer.on('error', (error) => {
console.error('Error:', error);
});
// Point cloud events
viewer.on('pointcloud-loaded', (pointCloud) => {
console.log('Point cloud loaded:', pointCloud.name);
});
// View events
viewer.on('view-changed', ({ namedView, position, target }) => {
console.log('Camera moved to:', namedView);
});
// Measurement events
viewer.on('measurement-started', (measurement) => {
console.log('Measurement started:', measurement.type);
// Payload: { id, type, points: [], result: {} }
// Note: measurement object is created but has no points yet
});
viewer.on('measurement-updated', (measurement) => {
console.log('Point added:', measurement.points.length);
// Payload: { id, type, points: [{ x, y, z }, ...], result: {...} }
// Fired every time a point is added to the current measurement
});
viewer.on('measurement-finished', (measurement) => {
console.log('Measurement complete:', measurement.result);
// Payload: { id, type, points: [{ x, y, z }, ...], result: {...} }
// Fired when measurement is completed (Enter key or required points reached)
});
viewer.on('measurement-mode-changed', (mode) => {
console.log('Measurement mode:', mode);
// Payload: string - 'none' | 'distance' | 'height' | 'angle' | 'radius' | 'volume'
});
viewer.on('measurements-cleared', () => {
console.log('All measurements cleared');
// No payload
});
// Appearance events
viewer.on('color-type-changed', (colorType) => {
console.log('Color type changed:', colorType);
// Payload: number - PointColorType enum value
});
viewer.on('background-changed', (background) => {
console.log('Background changed:', background);
// Payload: string - 'black' | 'white' | 'gradient' | 'skybox' | hex color
});
viewer.on('edl-changed', (settings) => {
console.log('EDL settings changed:', settings);
// Payload: object - { enabled?, strength?, radius?, opacity? }
// Only changed properties are included in the payload
});
// Unsubscribe
viewer.off('ready', handler);
`
Measurements
All measurements are interactive - click on the point cloud to add measurement points. The Clear button (X) becomes enabled as soon as you add the first point and allows you to clear all measurements and exit measurement mode.
$3
Click multiple points to create line segments. Press Enter to finish or ESC to cancel.
`javascript
// Start measurement
viewer.setMeasurementMode('distance');
// Result format from getMeasurements()
{
id: 'measurement-123',
type: 'distance',
points: [{ x, y, z }, { x, y, z }, ...],
result: {
distanceTotal: 45.67 // Total distance in meters
}
}
// Note: Internal measurement objects also have a 'finished' property
`
$3
Click 2 points to measure vertical (Y-axis) difference.
`javascript
// Start measurement
viewer.setMeasurementMode('height');
// Result format from getMeasurements()
{
id: 'measurement-456',
type: 'height',
points: [{ x, y, z }, { x, y, z }],
result: {
deltaY: 12.34, // Vertical difference in meters
height: 12.34, // Alias for deltaY
distance3D: 15.67 // 3D distance in meters
}
}
// Automatically finishes after 2 points
`
$3
Click 3 points to measure angle formed by the points (vertex is the second point).
`javascript
// Start measurement
viewer.setMeasurementMode('angle');
// Result format from getMeasurements()
{
id: 'measurement-789',
type: 'angle',
points: [{ x, y, z }, { x, y, z }, { x, y, z }],
result: {
angleDegrees: 45.5, // Angle in degrees (0-180)
angleRadians: 0.794, // Angle in radians
vertex: { x, y, z } // Vertex position
}
}
// Automatically finishes after 3 points
`
$3
Click 2 points to define circle radius: center point and edge point.
`javascript
// Start measurement
viewer.setMeasurementMode('radius');
// Result format from getMeasurements()
{
id: 'measurement-abc',
type: 'radius',
points: [{ x, y, z }, { x, y, z }],
result: {
radius: 5.67, // Radius in meters
diameter: 11.34, // Diameter in meters
circumference: 35.61, // Circumference in meters
area: 101.09, // Circle area in square meters
center: { x, y, z } // Center position
}
}
// Automatically finishes after 2 points
`
$3
Click 2 points to define sphere volume: center point and radius point. Calculates the volume of point cloud data within the sphere using voxel grid method.
`javascript
// Start measurement
viewer.setMeasurementMode('volume');
// Result format from getMeasurements()
{
id: 'measurement-def',
type: 'volume',
points: [{ x, y, z }, { x, y, z }],
result: {
volume: 123.45, // Volume in cubic meters (calculated from point cloud data within sphere)
radius: 3.14, // Average radius in meters
radii: { // Ellipsoid radii (rx, ry, rz)
rx: 3.14,
ry: 3.14,
rz: 3.14
},
surfaceArea: 123.97, // Sphere surface area in square meters
center: { x, y, z }, // Center position
pointCount: 12345, // Number of points within sphere
voxelSize: 0.1 // Voxel size used for volume calculation
}
}
// Automatically finishes after 2 points
`
Keyboard shortcuts for measurements:
- ESC - Cancel current measurement and exit measurement mode
- Enter - Finish current measurement (for distance measurements only; other types auto-finish)
- Right mouse button - Rotate camera while in measurement mode
Framework Integration
$3
`jsx
import { useEffect, useRef } from 'react';
import { PotreeViewer, Toolbar, PotreeViewerConsole } from 'potree-viewer';
function PointCloudViewer({ pointCloudUrl }) {
const containerRef = useRef();
const viewerRef = useRef();
const toolbarRef = useRef();
const consoleRef = useRef();
useEffect(() => {
// Initialize viewer
viewerRef.current = new PotreeViewer({
container: containerRef.current,
pointCloudUrl,
autoFitOnLoad: true,
});
// Create toolbar
toolbarRef.current = new Toolbar(viewerRef.current);
// Create console
consoleRef.current = new PotreeViewerConsole(viewerRef.current, {
position: 'bottom-left',
});
// Cleanup
return () => {
consoleRef.current?.dispose();
toolbarRef.current?.dispose();
viewerRef.current?.dispose();
};
}, [pointCloudUrl]);
return ;
}
`
$3
`vue
`
$3
`javascript
import { PotreeViewer, Toolbar, PotreeViewerConsole } from 'potree-viewer';
const viewer = new PotreeViewer({
container: document.getElementById('viewer'),
pointCloudUrl: 'cloud/metadata.json',
autoFitOnLoad: true,
});
const toolbar = new Toolbar(viewer, {
alignment: 'top-right'
});
const console = new PotreeViewerConsole(viewer, {
position: 'bottom-left',
visible: true
});
// Custom button interactions
document.getElementById('measure-distance').addEventListener('click', () => {
viewer.setMeasurementMode('distance');
});
document.getElementById('view-top').addEventListener('click', () => {
viewer.setNamedView('top');
});
// Listen to measurement results
viewer.on('measurement-finished', (measurement) => {
console.log('Measurement result:', measurement.result);
});
`
Advanced Usage
$3
`javascript
const toolbar = new Toolbar(viewer, {
alignment: 'top-right',
buttons: [
{
id: 'custom-action',
group: 'custom',
label: 'My Custom Action',
icon: '',
action: () => {
console.log('Custom action clicked');
}
},
// ... include default buttons if needed
]
});
`
$3
`javascript
const scene = viewer.getScene();
const camera = viewer.getCamera();
const renderer = viewer.getRenderer();
// Add custom 3D objects
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
`
$3
`javascript
const viewer = new PotreeViewer({
container: document.getElementById('viewer'),
});
await viewer.loadPointCloud('cloud1/metadata.json', 'Building A');
await viewer.loadPointCloud('cloud2/metadata.json', 'Building B');
`
$3
`javascript
const viewer = new PotreeViewer({
container: document.getElementById('viewer'),
pointCloudUrl: 'cloud/metadata.json',
initialView: {
position: { x: 100, y: 50, z: 100 },
target: { x: 0, y: 0, z: 0 }
}
});
`
Point Cloud Data Preparation
Use PotreeConverter to prepare your point cloud data:
`bash
./PotreeConverter input.laz -o output_directory
`
Supported input formats: LAS, LAZ, PLY, PTX, XYZ (via TXT2LAS)
The converter will generate:
- metadata.json - Point cloud metadata
- octree.bin - Octree structure
- hierarchy.bin - Hierarchy data
- Individual node files
Browser Compatibility
- Modern browsers with WebGL support (Chrome, Firefox, Edge, Safari)
- Requires ES module support
- No IE11 support
Development
$3
`bash
cd viewer-lib
npm install
npm run dev
`
Demo will open at http://localhost:3000/demo.html
$3
`bash
npm run build
`
$3
`
viewer-lib/
βββ src/
β βββ index.js # Main exports
β βββ PotreeViewer.js # Main viewer class
β βββ utils/
β β βββ EventEmitter.js # Event system
β β βββ config.js # Configuration
β β βββ TextSprite.js # Text labels
β βββ measurements/
β β βββ Measurement.js # Base class
β β βββ DistanceMeasurement.js
β β βββ HeightMeasurement.js
β β βββ AngleMeasurement.js
β β βββ RadiusMeasurement.js
β β βββ VolumeMeasurement.js
β β βββ MeasurementManager.js
β βββ ui/
β βββ Toolbar.js # UI toolbar component
β βββ PotreeViewerConsole.js # Console component
βββ demo.html # Demo page
βββ package.json
βββ vite.config.js
βββ README.md
`
Troubleshooting
$3
`bash
cd viewer-lib
npm install three potree-core
`
$3
- Check the path to metadata.json is correct
- Open browser console for detailed error messages
- Ensure server is serving point cloud files correctly
- Verify CORS headers if loading from different origin
$3
Add to your bundler configuration:
`javascript
resolve: {
extensions: ['.js', '.json'],
alias: {
'three': path.resolve(__dirname, 'node_modules/three'),
}
}
``