Terrestrial LiDAR Pipeline
Use this pipeline when you work with static or handheld LiDAR scanners (Leica, FARO, Trimble, BLK2GO, etc.) and need to turn point clouds into AR Clip VPS maps.
Pre-processing
- Clean the raw scans — remove tripod artefacts, multiple returns, and moving objects in Cyclone, ReCap, CloudCompare, or similar tools.
- Register the stations — align separate scans using targets or cloud-to-cloud methods.
- Colourise — apply photographic textures if available; otherwise map LiDAR intensity to greyscale.
Export
- Produce a simplified mesh (≤ 5 million triangles) for visual preview.
- Export the point cloud as E57/LAZ/PLY.
- Keep the coordinate system consistent: use a local tangent plane indoors, or a geo-referenced CRS outdoors.
Upload with the Python REST API
# upload_lidar.py
from pathlib import Path
import os
import requests
API_BASE = "https://api.arclip.app/vps/api/v3"
TOKEN = os.environ["ARCLIP_TOKEN"]
DATA_PATH = Path("outputs/plant.e57")
headers = {"Authorization": f"Bearer {TOKEN}"}
payload = {
"name": "Factory Floor",
"dataType": "point_cloud",
"sourceFormat": "e57",
"hybrid": True,
"coordinate": {"lat": 35.68124, "lon": 139.76712}
}
init = requests.post(f"{API_BASE}/maps/import", json=payload, headers=headers)
init.raise_for_status()
info = init.json()
upload_url, map_id = info["uploadUrl"], info["mapId"]
with DATA_PATH.open("rb") as src:
put = requests.put(upload_url, data=src, headers={"Content-Type": "application/octet-stream"})
put.raise_for_status()
finalize = requests.post(f"{API_BASE}/maps/{map_id}/finalize", json={"publish": False}, headers=headers)
finalize.raise_for_status()
print(f"LiDAR map {map_id} queued → {finalize.json()['status']}")
hybrid=Truesignals that the upload contains both a point cloud and an optional mesh (if present in the E57/LAZ bundle).- For indoor-only datasets omit the coordinate block.
Post-processing & Anchors
After the map reaches READY:
- Define anchor points for machinery, entries, and exits.
- Upload them via a small JSON file:
import json
anchors = [
{"name": "CNC-01", "position": [2.4, 0.0, 8.7]},
{"name": "safety_exit", "position": [-11.2, 0.0, 3.1]}
]
resp = requests.post(
f"{API_BASE}/maps/{map_id}/anchors",
headers=headers,
json={"items": anchors}
)
resp.raise_for_status()
- Publish the map from the Console or call
POST /maps/{id}/publishwhen QA is done.