Read and write 3-D point cloud data using Lidar Toolbox file I/O. Covers PLY, PCD, LAS/LAZ, PCAP (Velodyne/Ouster/Hesai), E57, and IDC (Ibeo) formats. Use when loading point clouds from disk, saving to disk, choosing the correct reader or writer for a file format, extracting or preserving lidar point attributes, reading Ibeo IDC sensor recordings, or converting between formats.
npx skills add https://github.com/matlab/matlab-agentic-toolkit --skill matlab-point-cloud-file-io
Read and write 3-D point cloud data in MATLAB using Lidar Toolbox file I/O functions, covering PLY, PCD, LAS/LAZ, sensor PCAP, E57, and IDC (Ibeo) formats.
pointCloud objectpointCloud object to disk in any supported formatvelodynelidar, ousterlidar, sicklidar)pcdownsample, pcdenoise)readSurfaceMesh, writeSurfaceMesh)save)pcshow, pcplayer, pcviewer)pcread ONLY supports .ply and .pcd files. For .las/.laz use lasFileReader + readPointCloud. For .pcap use the sensor-specific file reader (velodyneFileReader, ousterFileReader, or hesaiFileReader). For .e57 use e57FileReader. Calling pcread on a LAS or PCAP file produces an error, not a warning. Similarly, pcwrite ONLY writes PLY and PCD — for LAS/LAZ output use lasFileWriter + writePointCloud.velodyneFileReader requires a DeviceModel string (e.g., "HDL32E"). hesaiFileReader requires a DeviceModel string (e.g., "PandarXT32"). ousterFileReader requires a CalibrationFile path (JSON). If the user has not specified the device model or calibration file, ASK — do not assume a default. There is no default value; omitting it causes an error.[ptCloud, ptAttributes] = readPointCloud(reader) returns a lidarPointAttributes object containing Classification, GPSTimeStamp, LaserReturn, NumReturns, ScanAngle, and more. The single-output form discards these attributes permanently. Intensity is on the pointCloud object (.Intensity property), NOT on lidarPointAttributes.writePointCloud(writer, ptCloud, ptAttributes) preserves Classification, GPSTimeStamp, and other lidar attributes in LAS/LAZ output. The two-argument form writePointCloud(writer, ptCloud) discards all attributes. If the user has attributes from lasFileReader/readPointCloud, always pass them through.pcwrite(ptCloud, "file.ply", Encoding="compressed") throws an error. Only "ascii" and "binary" are valid for PLY. The "compressed" encoding is exclusive to PCD format. Defaults (R2026a+): PLY="binary", PCD="compressed"."text") for all literal text arguments (filenames, device models, encoding values, Name=Value values). Use Name=Value syntax for all name-value pairs. Never use character vectors ('text') or legacy 'Name','Value' pair syntax.references/INDEX.md for each (function-level + task-level tables)Preflight: quick-ref/xxx.md, quick-ref/yyy.md (or Preflight: none required)| Function | Purpose | Format | Key Constraint |
|---|---|---|---|
| pcread | Read point cloud from file | PLY, PCD | Single call, returns pointCloud |
| pcwrite | Write point cloud to file | PLY, PCD | Encoding varies by format |
| lasFileReader | Create LAS/LAZ reader object | LAS, LAZ | Two-step: create reader, then readPointCloud |
| lasFileWriter | Create LAS/LAZ writer object | LAS, LAZ | Two-step: create writer, then writePointCloud |
| velodyneFileReader | Create Velodyne PCAP reader | PCAP | Mandatory DeviceModel (2nd arg) |
| ousterFileReader | Create Ouster PCAP reader | PCAP | Mandatory CalibrationFile (2nd arg) |
| hesaiFileReader | Create Hesai PCAP reader | PCAP | Mandatory DeviceModel (2nd arg) |
| e57FileReader | Create E57 reader object | E57 | Use readPointCloud(reader, idx) for multi-scan |
| ibeoLidarReader | Create Ibeo IDC reader object | IDC | Use readMessages to read scan data |
READING — What is the file extension?
├── .ply / .pcd → pcread(filename)
├── .las / .laz → lasFileReader(filename) + readPointCloud(reader)
├── .pcap (Velodyne) → velodyneFileReader(filename, deviceModel)
├── .pcap (Ouster) → ousterFileReader(filename, calibrationFile)
├── .pcap (Hesai) → hesaiFileReader(filename, deviceModel)
├── .e57 → e57FileReader(filename) + readPointCloud(reader, idx)
└── .idc (Ibeo) → ibeoLidarReader(filename) + readMessages(reader)
WRITING — What output format does the user need?
├── .ply → pcwrite(ptCloud, "file.ply")
│ Encoding: "ascii" or "binary" (default: binary)
├── .pcd → pcwrite(ptCloud, "file.pcd")
│ Encoding: "ascii", "binary", or "compressed" (default: compressed)
├── .las → lasFileWriter("file.las") + writePointCloud(writer, ptCloud)
└── .laz → lasFileWriter("file.laz") + writePointCloud(writer, ptCloud)
Optional: pass ptAttributes as 3rd arg to preserve attributes
PCAP sensor identification: If the user says "Velodyne", "Ouster", or "Hesai" — use the matching reader. If they just say "PCAP file" without specifying the sensor, ASK which sensor produced it.
Ibeo IDC files: If the user has an .idc file, use ibeoLidarReader. Unlike other readers, it uses readMessages (not readPointCloud or readFrame) and returns message-based scan data.
Velodyne device models: VLP16, PuckLITE, PuckHiRes, VLP32C, HDL32E, HDL64E, VLS128, VelarrayH800
Hesai device models: Pandar128E3X, Pandar64, PandarQT, PandarXT32
pcread called on LAS/LAZ filepcread only supports PLY and PCD formats. Attempting to use it on LAS, LAZ, PCAP, or E57 files throws an error.
% WRONG: pcread does not support LAS
ptCloud = pcread("survey.las");
% CORRECT: Use lasFileReader for LAS/LAZ
reader = lasFileReader("survey.las");
ptCloud = readPointCloud(reader);
The "compressed" encoding is only valid for PCD format. PLY supports only "ascii" and "binary".
% WRONG: compressed not supported for PLY
pcwrite(ptCloud, "output.ply", Encoding="compressed");
% CORRECT: use binary for compact PLY
pcwrite(ptCloud, "output.ply", Encoding="binary");
% CORRECT: compressed is valid for PCD
pcwrite(ptCloud, "output.pcd", Encoding="compressed");
pcwrite does not support LAS or LAZ format. It only handles PLY and PCD.
% WRONG: pcwrite cannot write LAS
pcwrite(ptCloud, "output.las");
% CORRECT: use lasFileWriter for LAS/LAZ
writer = lasFileWriter("output.las");
writePointCloud(writer, ptCloud);
When writing LAS/LAZ, the two-argument form discards lidar point attributes. Always pass the attributes object if available.
% WRONG: attributes are discarded
reader = lasFileReader("input.laz");
[ptCloud, ptAttr] = readPointCloud(reader);
writer = lasFileWriter("output.laz");
writePointCloud(writer, ptCloud); % ptAttr lost!
% CORRECT: preserve attributes with 3-argument form
reader = lasFileReader("input.laz");
[ptCloud, ptAttr] = readPointCloud(reader);
writer = lasFileWriter("output.laz");
writePointCloud(writer, ptCloud, ptAttr);
Classification, GPSTimeStamp, LaserReturn, and other lidar-specific attributes are on lidarPointAttributes, not on pointCloud. The pointCloud object holds Intensity (and Location, Color, Normal).
% WRONG: pointCloud does not have Classification
reader = lasFileReader("data.laz");
ptCloud = readPointCloud(reader);
labels = ptCloud.Classification; % Error
% CORRECT: Use two-output syntax
reader = lasFileReader("data.laz");
[ptCloud, ptAttributes] = readPointCloud(reader);
labels = ptAttributes.Classification;
intensity = ptCloud.Intensity; % Intensity is on pointCloud
PCAP readers are frame-based iterators. There is no single function to load all frames at once.
% WRONG: No readAll or similar function
reader = velodyneFileReader("lidarData_ConstructionRoad.pcap", "HDL32E");
allPoints = readPointCloud(reader); % readPointCloud is not a method
% CORRECT: Loop with hasFrame/readFrame
reader = velodyneFileReader("lidarData_ConstructionRoad.pcap", "HDL32E");
while hasFrame(reader)
ptCloud = readFrame(reader);
end
ptCloud = pcread("scene.ply");
fprintf("Points: %d\n", ptCloud.Count);
fprintf("X range: [%.2f, %.2f]\n", ptCloud.XLimits);
reader = lasFileReader("aerial.laz");
[ptCloud, ptAttributes] = readPointCloud(reader, Classification=[2 6]);
labels = ptAttributes.Classification;
fprintf("Ground + building points: %d\n", ptCloud.Count);
reader = velodyneFileReader("lidarData_ConstructionRoad.pcap", "HDL32E");
fprintf("Total frames: %d\n", reader.NumberOfFrames);
while hasFrame(reader)
ptCloud = readFrame(reader);
end
reader = e57FileReader("building.e57");
fprintf("Scans in file: %d\n", reader.NumPointClouds);
for idx = 1:reader.NumPointClouds
ptCloud = readPointCloud(reader, idx);
fprintf("Scan %d: %d points\n", idx, ptCloud.Count);
end
ptCloud = pointCloud(rand(1000,3), Color=uint8(rand(1000,3)*255));
pcwrite(ptCloud, fullfile(tempdir, "output.ply"), Encoding="binary");
ptCloud = pcread(fullfile(toolboxdir("lidar"), "lidardata", "highwayScene.pcd"));
pcwrite(ptCloud, fullfile(tempdir, "scene_compressed.pcd"), Encoding="compressed");
reader = lasFileReader("input.las");
[ptCloud, ptAttr] = readPointCloud(reader);
writer = lasFileWriter(fullfile(tempdir, "output.laz"));
writePointCloud(writer, ptCloud, ptAttr);
ptCloud = pcread("scene.pcd");
pcwrite(ptCloud, fullfile(tempdir, "scene.ply"), Encoding="binary");
reader = lasFileReader("survey.las");
ptCloud = readPointCloud(reader);
pcwrite(ptCloud, fullfile(tempdir, "survey.pcd"), Encoding="compressed");
reader = ibeoLidarReader("sensor_data.idc");
fprintf("Message types: %s\n", strjoin(reader.MessageTypes, ", "));
fprintf("Total messages: %d\n", reader.NumMessages);
% Read all messages — returns array of pointCloud objects
ptClouds = readMessages(reader);
% Two-output form: get message metadata (timestamps, labels, plane info)
[ptClouds, messageData] = readMessages(reader);
% Filter by message type: "Scan" or "PointCloudPlane"
ptClouds = readMessages(reader, Messages="Scan");
% Filter by time range
tStart = reader.FileInfo.TimeStamps{1}(1);
tEnd = tStart + seconds(10);
ptClouds = readMessages(reader, Time=[tStart tEnd]);
ibeoLidarReader key details:
"Scan" (data type 0x2205) and "PointCloudPlane" (data type 0x7510)readMessages returns an array of pointCloud objects (one per message)messageData is a cell array of structs with MessageType, TimeStamp, and (for PointCloudPlane) Label, ReferencePoint, PlaneOrientationFileInfo property is a table with columns: MessageType, DataType, Description, NumMessages, TimeStampstempdir for output paths in examples and tests to avoid permission issuesEncoding="binary" for PLY and omit encoding for PCD (default compressed is best)"text") and Name=Value syntax — never character vectors or 'Name','Value' pairslasFileWriter only supports unorganized pointCloud objects| Load when... | Reference |
|---|---|
| Reading or writing LAS/LAZ files, need filtering NV-pairs, attribute details, or writer properties | references/quick-ref/las-io.md |
| Reading PCAP files from Velodyne, Ouster, or Hesai sensors | references/quick-ref/pcap-readers.md |
----
Copyright 2026 The MathWorks, Inc.
----
Integration with protocols.io API for managing scientific protocols. This skill should be used when working with protocols.io to search, create, update, or publish protocols; manage protocol steps and materials; handle discussions and comments; organize workspaces; upload and manage files; or integrate protocols.io functionality into workflows. Applicable for protocol discovery, collaborative protocol development, experiment tracking, lab protocol management, and scientific documentation.
Analyzes job descriptions and generates tailored resumes that highlight relevant experience, skills, and achievements to maximize interview chances
Generate Excalidraw diagrams from natural language descriptions. Use when asked to "create a diagram", "make a flowchart", "visualize a process", "draw a system architecture", "create a mind map", or "generate an Excalidraw file". Supports flowcharts, relationship diagrams, mind maps, and system architecture diagrams. Outputs .excalidraw JSON files that can be opened directly in Excalidraw.
Build and distribute Expo development clients locally or via TestFlight
Use when you have a written implementation plan to execute in a separate session with review checkpoints
Data structure for annotated matrices in single-cell analysis. Use when working with .h5ad files or integrating with the scverse ecosystem. This is the data format skill—for analysis workflows use scanpy; for probabilistic models use scvi-tools; for population-scale queries use cellxgene-census.
Benchling R&D platform integration. Access registry (DNA, proteins), inventory, ELN entries, workflows via API, build Benchling Apps, query Data Warehouse, for lab data management automation.
Comprehensive molecular biology toolkit. Use for sequence manipulation, file parsing (FASTA/GenBank/PDB), phylogenetics, and programmatic NCBI/PubMed access (Bio.Entrez). Best for batch processing, custom bioinformatics pipelines, BLAST automation. For quick lookups use gget; for multi-service integration use bioservices.
Take matlab/matlab-point-cloud-file-io from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.