* Point clouds: colour and filter by any property of a PLY file, on range tracks (#5151) A PLY file's other vertex properties are kept as named numbers on the points (whole-numbered for integer types; a comment `property: 0 name, 1 name` names a label's values). A cloud is coloured by any of them, a ramp or a palette for whole numbers, and filtered by up to eight, each a range or a set of named values. The GPU colours and filters the points itself, so editing a range uploads nothing. In the Edit Point Cloud card each range is a track, as in an audio editor: a histogram of the property over what the other filters keep, stacked by colour, under an overview strip. Ranges are drawn, moved, snapped to colour changes, typed (Start, End, Length, relative values) and played (Space or Play). The automatic colour range is exactly the values the property takes over what the filters keep. pointcloud.insert and pointcloud.edit take color_by: <property>, color_range and filters; pointcloud.list reports them with the properties. docs/point-clouds.md describes it all. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Point clouds: note the saved properties, colouring and filters as a pending format change (#8816) A design now saves a cloud's per-point columns and their value names, colouring by a property and filters; an older release must refuse it instead of dropping them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
6.6 KiB
Point clouds
A point cloud is scanned points kept in the design as a reference to model from (#5151): a lidar or SLAM map, a photogrammetry result, a part from a handheld scanner. It is drawn as dots in the viewport, depth-tested with the bodies, and never becomes a body; nothing in the timeline depends on it.
Files
| Extension | What is read |
|---|---|
.ply |
ASCII, binary little-endian and binary big-endian PLY: the vertex element's x, y, z (any numeric type) and its red, green, blue when present (bytes, 16-bit or 0…1 floats). Every other scalar vertex property (intensity, a class, a time…) is kept, by its name in the file, to colour and filter the cloud by; it is whole-numbered when its type is an integer. Other elements are passed over. |
.xyz, .pts |
Text, a point per line: x y z, optionally followed by r g b (six numbers) or by an intensity and r g b (seven or more, as PTS files write it). Spaces, tabs, commas or semicolons separate the numbers; # and // start comments; a PTS file's first line (its count) is skipped. |
A PLY file that also has faces can be inserted as a mesh body instead with Insert Mesh
(file.insert_mesh); Insert Point Cloud then mentions it in its warnings.
Point cloud files say nothing about their length unit. units (mm, cm, m, in, ft)
says what it is; the default is millimetres, as for every other import. Lidar and SLAM maps are
usually in metres. The unit can be changed afterwards (Browser › Point Clouds › Edit Point Cloud,
or pointcloud.edit with units): the points are scaled from the unit they came in as.
Colours
Color By in the Edit Point Cloud card (or color_by) says how the points are coloured:
file(the default): the file's colour of each point, grey when it has none.single: one colour (color) for every point.height: a ramp by design Z, blue low through cyan, green and yellow to red high. It runs between two heights (color_range, mm). By default they are worked out from the points: all but the lowest and highest 2 %, so a few stray points don't flatten the ramp.- any property's name (
x,y,zor one of the file's): the same ramp over the property's values or, for a whole-numbered property, a palette of ten colours (its value modulo ten; negative values grey). By default the ramp runs exactly over the values the property takes on the points every filter keeps, so filtering re-spreads the colours over what is left.
A ramp's range is a range track in the card; touching it sets the range and
turns Automatic Range off, and ticking the box (or a double click beside the range) gives
it back. color_range: null does the same from a command.
A whole-numbered property may name its values with a PLY comment, property: 0 name, 1 other name, -1 none (for example comment role: 0 outer wall, 1 inner wall). Coloured by it, the
card shows a legend, a swatch and a name per value; clicking a name shows or hides that value.
Filters
A filter keeps the points whose property lies in a range (both ends included) or, for a property with named values, is one of a set of values. Only what every filter keeps is shown; a cloud has at most 8 filters, and the view applies the first 4. Filter by in the card adds one over a property's whole span (or with all its named values); × removes it. Filters change what is drawn, never the points the design holds.
Range tracks
Each range filter, and a ramp's range, is edited on a track, as a range is in an audio editor. The track draws how much of the cloud lies at each value: a histogram of the property over what the other filters keep, stacked by colour, so it is also the colour legend. A thin strip above it shows the property's whole span, with the part the track shows framed.
- Drag an end or the band between them to move them; drag elsewhere to draw a new range. Shift-click brings the nearer end to the pointer.
- Double-click the band to fit the track to it; double-click beside it for the whole span. The wheel or a pinch zooms around the pointer, a sideways scroll pans, and dragging in the strip moves the framed part.
- An end snaps to a value where the colour changes when no other change is near at this zoom; a whole-numbered property's ends snap to whole numbers. ⌥ moves ten times slower, without snapping.
- Once the track is touched, ← and → bring the part touched last to the previous or next colour change (one pixel with ⌥, or where there is none).
- Start, End and Length are fields too; Length keeps the start. A value typed with a
sign is relative:
+30moves it by 30. - ▶ Play (or Space) moves the part touched last across the track in 20 seconds: an upper end grows the range, the band slides it, a lower end wipes it. The track follows it, and an automatic colour range follows it too. Touching the range stops it.
Size
A cloud keeps at most max_points points (5,000,000 unless asked, at most 20,000,000); a larger
file is thinned evenly, one point in n, and the result says how many were kept. Files up to
1 GiB are read. The points are stored single precision relative to the cloud's first point (kept
double precision), so a scan far from the origin keeps its detail; they travel inside the design
file as a binary part (12 bytes a point, 3 more with colours).
Commands
pointcloud.insert—path;name?,units?,max_points?,center?(move the middle of its base to the origin),point_size?(pixels),color_by?(file,single,heightor a property's name),color?([r, g, b]0…1; alone it meanssingle,nullmeansfile),color_range?([low, high], ornullfor the automatic range;height_rangeis the same),filters?([{"property": …, "range": [low, high]}or{"property": …, "values": [whole numbers]}], ornullfor none).pointcloud.edit—cloud(id or name);name?,visible?,point_size?,color_by?,color?,color_range?,filters?,units?,matrix?(a rigid placement, asoccurrence.movetakes it).pointcloud.delete.pointcloud.list— each cloud with its properties (name, whole-numbered or not, span, named values), its filters and its ramp's range as drawn (color_range).doc.openopens a point cloud file as a new design holding it; dropping one on the window adds it to the open design.
Example
{"command": "pointcloud.insert", "params": {"path": "glim-points.ply", "units": "m", "color_by": "height"}}
{"command": "pointcloud.edit", "params": {"cloud": "glim-points", "color_by": "intensity", "filters": [{"property": "z", "range": [0, 2500]}]}}