Point Cloud Toolkit™ logo

Engineering Dynamics Company

Point Cloud Toolkit™

Point Cloud Processing & Visualization for Blender

Point Cloud Toolkit — User Guide

Importing, filtering, and surfacing laser-scan point clouds in Blender.

This guide walks through installing the add-on, finding its panels, and completing the common tasks, with a reference for every control. For a terse feature list, see README.md.


Contents

  1. Overview
  2. Installation
  3. Choosing which tools appear
  4. Quick start
  5. Import Point Cloud
  6. Filter Point Cloud
  7. Create Ground Surface
  8. Create 3D Surface
  9. Documentation & provenance report
  10. Optional dependencies
  11. Tips & troubleshooting
  12. License & support

A note on values: defaults are shown in parentheses. Distance controls follow the scene's unit system in Blender; their defaults are given here in metres, Blender's base unit (1 unit = 1 m).


Overview

Point Cloud Toolkit adds an EDC Toolkits tab to the 3D View sidebar (press the N key) with four tool sections that share one point-cloud selection, plus a display section for the viewport:

Section What it does
Import Point CloudMulti-format import — PLY (ASCII or binary), PTX, PTS, E57, LAS/LAZ, and PCD — as a coloured mesh with a Geometry Nodes point display
Point Cloud DisplayViewport-only controls — Points Visible % and Point Size — for the selected cloud
Filter Point CloudVoxel subsampling and Statistical Outlier Removal, always to a new cloud (the original is never modified)
Create Ground SurfaceDrape a regular grid over the cloud: per-cell ground-percentile height sampling, spike rejection, hole filling, clip-to-object, and a colour texture baked from the cloud
Create 3D SurfaceFull 3D reconstruction via Open3D (Poisson / Ball Pivoting / Alpha Shape) for vertical and overhanging geometry, with automatic texture baking, tiling, bulge trimming, and long-triangle trimming

The add-on targets Blender 4.x and is numpy-vectorized throughout, so it stays fast on million-point clouds.


Installation

  1. In Blender, open Edit → Preferences → Add-ons → Install… and select the PointCloudToolkit-<version>.zip file.
  2. Enable Point Cloud Toolkit in the add-ons list.
  3. Open the 3D View sidebar with the N key and select the EDC Toolkits tab.

The add-on's preferences let you rename the sidebar tab — set it to an existing tab's name to share a tab with other add-ons.

On Blender 4.2+ the same zip also installs as an extension (Preferences → Get Extensions → Install from Disk), and updates automatically when added from the EDC Software repository.


Choosing which tools appear

If you only use part of the toolkit, you can hide the rest. Open Edit → Preferences → Add-ons, expand Point Cloud Toolkit, and use the Features checkboxes:

Feature Hides
Import Point CloudThe import panel (PLY / PTX / PTS / E57 / LAS / PCD)
Filter Point CloudThe subsample / outlier-removal panel
Create Ground SurfaceThe draped ground-grid panel
Create 3D SurfaceThe Open3D 3D reconstruction panel

All four are on by default. Unchecking one removes its panel from the sidebar immediately — no restart needed. Documentation always stays visible, so the user guide and provenance report remain reachable.

Nothing is uninstalled: the tools are only hidden, and re-checking a box brings the panel back with its settings intact.

Note. The Filter settings still apply when you build a surface, even with the Filter Point Cloud panel hidden — subsampling and outlier removal run as part of Create Ground Surface and Create 3D Surface. Hide the panel only if you're happy with the current filter settings.

Click Save Preferences (or enable Auto-Save Preferences) so your choices persist the next time you open Blender.


Quick start

  1. In Import Point Cloud, click Import Point Cloud and load a scan. The imported cloud is selected automatically as the source for the other sections.
  2. *(Optional)* Set Clip To Object to restrict surfacing to a boundary mesh.
  3. *(Optional)* In Filter Point Cloud, enable Subsample (Voxel) and/or Remove Outliers (SOR), then click Filter → Create New Point Cloud.
  4. For drivable ground, use Create Ground Surface; save the .blend first so the texture JPG can be written next to it.
  5. For vertical or overhanging geometry, use Create 3D Surface (Poisson is the all-rounder). Afterwards, Trim Bulges (To Cloud) removes invented geometry and Rebake Texture re-fits the texture.

Import Point Cloud

Imports PLY (ASCII or binary), PTX, PTS, E57, LAS/LAZ, and PCD files as a coloured mesh point cloud displayed through a Geometry Nodes modifier (also available on File → Import). The imported cloud is automatically selected as the Point Cloud source used by the other sections.

Every imported cloud gets its own Geometry Nodes display tree; the controls for it are in Point Cloud Display, immediately below.

Points whose coordinates are not finite (NaN or Inf — truncated writes, a scanner error row) are dropped, and the count is logged. This matters more than it sounds: the check for "is this cloud far from the origin?" is a maximum over the coordinates, so a single NaN made it false and a georeferenced scan imported unrecentered at 500,000 m — losing exactly the precision recentering exists to protect, silently. A single Inf was worse: it made the centroid infinite, so every point in the file came out unusable.

Knowing which frame a cloud landed in. Two scans of one site overlap only if they share a shift, so the import says which happened rather than leaving it to the console:

A cloud already near the origin — anything local, or a georeferenced one scaled down from centimetres — is moved by nothing, so it leaves no offset to inherit. That is not the same as not having imported, and it is not the same as the offset being gone: if an earlier cloud did set one, it stays in play and the panel says so rather than naming the wrong cloud.

Manual Shift X/Y/Z is only shown in Manual mode. It is only read there, and showing it under Auto made it look like a value that would be used.

Importing several clouds that share a georeference: the shift applied to the first cloud is remembered on the scene (pct_session_shift), and Auto reuses it for later imports as long as that offset keeps the new cloud near the origin — so multiple scans of the same site import aligned to each other (like CloudCompare reusing one global shift for a session), instead of each getting its own centroid. A cloud from a different, far-away site still gets its own shift. Each cloud also records its own offset in the custom properties pct_global_shift / pct_import_scale, so file = (local + global_shift) / scale recovers the originals.



Point Cloud Display

A second view of the selected cloud's Geometry Nodes modifier: it mirrors every input the display tree declares, labelled as the tree labels it, in the tree's own order — the same rows the Modifier Properties panel shows, in the sidebar where you are already working. Nothing here touches the data; filtering, surfacing and baking always use every point, whatever the viewport is showing.

As imported, that is:

Because the panel mirrors rather than matches by name, editing the display tree is reflected straight away: add an input and it appears here, remove one and its row goes with it. Values are per-cloud — each import has its own display tree, so adjusting one never changes another.

Which cloud these edit. The active object, when it is a cloud — unlike the processing tools below, which follow the pinned Point Cloud. The two rules disagree as soon as a second cloud is imported, because importing pins the new one: selecting the first and moving a slider would have changed the second, which looks exactly like the panel not working. Display is about the thing you are looking at, and the Showing: line names it. The pinned cloud is still the fallback, so the panel is not empty when something else is selected.

This section is not one of the four tools, so it stays available even with every tool hidden in Preferences. A cloud too dense to navigate is a problem you have before you reach any of them.

How this works, and why it needed to. Blender offers no way for a Python panel to draw a geometry nodes modifier input — its own Modifier Properties panel is built in C, and layout.prop() needs a struct and a property name. Blender 5.x keeps each socket's value inside an ID property group, which prop() refuses as its data argument outright.

So each row here is one of the add-on's own properties, wired to the selected cloud: reading it reads the modifier, and setting it writes the modifier. Nothing is stored on the side, so the panel and the Modifier Properties panel cannot drift apart — there is one copy of the number and it lives on the modifier. Up to eight inputs are mirrored, which is well past the two the display tree declares; an input the modifier holds no number for (a Geometry input, or one removed from the tree) gets no row.

Where the value physically lives has moved between releases — 3.x and 4.x use an ID property on the modifier, 5.x an entry under modifier.properties.inputs — so the add-on finds it rather than assuming, and Diagnose Display Storage prints the whole shape to the System Console if it ever cannot.

If the rows are missing. A cloud imported by an older version, or one whose modifier never had a value written for an input, gives the panel nothing to mirror and the rows do not appear. Restore Display Controls writes the values back onto the selected cloud's modifier — taking each input's own default from the node group, or the import defaults (Points Visible % 100, Point Radius 0.01) when the group has none — and the rows come back. It only fills inputs the modifier is actually missing, so a value you have already set is never overwritten, and inputs that hold no number (a Geometry input) are left alone. If an input still cannot be placed, the System Console names it; Diagnose Display Storage is the next step.


Create Ground Surface

Drapes a regular grid over the cloud to build a drivable ground surface. Distance controls are given in metres (1 unit = 1 m).

This is the setting that decides whether a wood comes out. Spike Reject compares each cell against a local ground reference built by opening the grid at this width, so an object *wider* than the setting carries the reference up with it and is read as grade — the spikes stay, and no amount of lowering Spike Reject (Above) will touch them. A belt of trees is routinely 20–40 m across, so a scan full of vegetation spikes usually wants Spike Width raised to comfortably exceed the widest continuous stand, not Spike Reject lowered. The cost is that real rises narrower than the setting are flattened too, so it wants to exceed the vegetation and stay under the terrain: a wide belt of trees on genuinely rolling ground is the case where clipping the cloud beats tuning either number.

Aerial image (replace the point-cloud colour)

You can drape one or more aligned aerials / orthophotos over a created surface instead of the colour baked from the point cloud — useful when a recent aerial reads better than the scan colours. Both textures are kept, so you can switch back at any time. This works on ground and 3D surfaces.

  1. For each aerial, add a reference and align it over the surface in top view: the simplest is a Plane (Add → Mesh → Plane) given the aerial as an image-texture material, scaled and positioned to cover that aerial's area. (An Empty → Image reference also works.)
  2. Select every aerial plane, then the surface last so it is active. (For a single aerial you can instead set Aerial Reference to the one plane, and optionally Aerial Image to override the image.)
  3. Click Apply Aerial Image. Each surface face is textured by the aerial whose footprint covers it, with top-down planar UVs computed from that plane's world extent, so every orthophoto lands by geographic position. Because these are real textures (their own UV layer and one material per aerial), they export cleanly.
  4. Show Point-Cloud Texture / Show Aerial Image toggles the whole surface between the two — the original point-cloud texture (and, for a joined surface, each tile's own texture) is preserved.

If the cloud was recentered on import, aligning the aerials visually over the surface already puts them in the right (shifted) space — no coordinate math needed. Tip: if your aerials are just tiles of one orthomosaic, merging them into a single image first (e.g. QGIS / gdal_merge) lets you use one plane instead.

Tuning & troubleshooting (ground surface)

Adjust one setting at a time and re-create the surface to see its effect.

If you see… Try
Too many low points / the surface dips into potholes or drops below the roadwayLower Below-Grade Reject (e.g. 0.5 → 0.2 m) so stray below-ground returns are cut and refilled; if whole areas sag, raise Ground Percentile a little (e.g. 10 → 20) so it samples higher.
Spikes or bumps sticking up from trees, poles, walls, or parked carsLower Spike Reject (Above) (e.g. 1.0 → 0.5 m) so shorter spikes are caught.
A whole stand of trees comes through as spikes, and lowering Spike Reject changes nothingRaise Spike Width (Max) past the width of the stand (20–40 m is normal for a tree belt). Anything wider than this setting is read as grade, so the height threshold never applies to it.
Real curbs, embankments, or hills being flattenedRaise Spike Reject (Above) (less aggressive) and/or lower Spike Width (Max) so only narrow objects are removed.
The road colour is tinted by vehicles or foliageLower Color Height Tolerance (e.g. 0.25 → 0.1 m) so only near-ground points contribute colour.
Gaps or holes in the surfaceEnable Fill Holes and raise Max Fill Distance to bridge farther.
Surface invented over a true void (e.g. across a ditch or off the road edge)Lower Max Fill Distance, or set Clip To Object to the area of interest.
Surface is too heavy / slow to work withRaise Resolution (Cell Size), enable Subsample (Voxel), or add a Decimate modifier.
Blurry textureRaise Texture Resolution, or use Texture Tiles for more total pixels.

Create 3D Surface

Full 3D reconstruction via Open3D (installed automatically on first run) for vertical and overhanging geometry — walls, embankments, vehicles, structures. For drivable ground, Create Ground Surface remains the better tool. Distance controls are given in metres (1 unit = 1 m).

Post-build tools (shown when a reconstructed surface is selected)

These appear only when a built 3D surface is the active object. After a build the cloud is often what is selected, and the panel says so rather than simply not showing them.

This is a different fault from a bulge, and Trim Bulges cannot reach it. A triangle spanning a hole has all three corners on real scanned points, so measuring vertices against the cloud finds nothing wrong with it. Its *edges* are what give it away.

Max Edge Length at 0 measures the surface itself — a low quantile of its edge lengths, times a wide factor — so the same setting works whether the scan is in metres or feet, and however dense it is. A low quantile rather than the median on purpose: once webbing is a large fraction of the surface, the median lands *between* the good and bad triangles and the automatic threshold floats out of reach of both. Type a length when you want to be precise; the operator reports how many faces it removed, and refuses rather than emptying the object if every face exceeds the threshold. Unlike Trim Bulges it needs no Open3D.

Tuning & troubleshooting (3D reconstruction)

Poisson is the usual starting point; change one control at a time and rebuild.

If you see… Try
Surface balloons out past the scan (Poisson invents geometry in empty areas)Raise Density Trim (e.g. 0.05 → 0.2), or run Trim Bulges (To Cloud) after the build; lowering Poisson Depth also helps.
Webbing across holes, doorways or scan shadows (long thin triangles bridging a gap)Run Trim Long Triangles after the build. Trim Bulges will not remove these — their corners are all on the cloud.
Holes or gaps in the surfaceBall Pivoting: raise BPA Radius Multiplier to span wider gaps. Alpha Shape: raise Alpha. Poisson: lower the depth.
Surface is too smooth / fine detail lostRaise Poisson Depth (e.g. 9 → 10–11).
Surface is noisy or lumpyLower Poisson Depth, or raise Normal Neighbors (k) for smoother normals.
Walls or overhangs look inside-out or patchySet Normal Orientation to Consistent (the Up option can misorient vertical faces).
Reconstruction is very slowTurn on Use Existing Normals (if the cloud has them), use the Up orientation, and/or Subsample (Voxel) first. The first run also caches its normals, so later rebuilds skip the slow step.
Blurry textureRaise Texture Resolution or use Texture Tiles; for flat, top-down terrain, Planar UV is the sharpest.

Documentation & provenance report

The Documentation panel has an Open User Guide button (this guide) and a Provenance Report (Active) button. The report writes a self-contained HTML document for the active cloud or surface — the source file and its SHA-256 hash, point/geometry counts, coordinate extents in both Blender and original (georeferenced) space, the import scale and global shift, and the tool/Blender versions — for documentation and chain-of-custody. It's saved next to the .blend (or a temp folder if unsaved) and opened in your browser. The "Prepared by" field is left blank for you to fill in; it is not taken from the OS login.


Optional dependencies

Optional Python packages install themselves into Blender's Python when first needed — no manual pip work is required. An internet connection is needed the first time each feature is used.

Package Needed for When it installs
open3d3D reconstruction, compressed PCDFirst Reconstruct 3D Surface (large download; may need a Blender restart)
pye57E57 importFirst E57 file opened, or the install button in the panel
laspy[lazrs]LAZ importFirst LAZ file opened, or the install button in the panel

Tips & troubleshooting


License & support

Point Cloud Toolkit is © Engineering Dynamics Company, written by Anthony Cornetto, and is free software licensed under the GNU General Public License, version 2 or later — see the bundled LICENSE file. Official builds, updates, and support are provided by Engineering Dynamics Company; visit edccorp.com or contact EDC support.