Nodes/ComfyUI CV/CV Write PLY (Point Cloud)
ComfyUI Node

CV Write PLY (Point Cloud)

Getting a numpy point cloud out of the graph and onto your screen

By bmad4ever·Created 4 months ago·Updated 15 days ago· 1
CV Write PLY (Point Cloud)
  • points
  • colors
  • ply

Reconstruction nodes hand you an Nx3 numpy array and you have no way to look at it. Numbers in a console are not geometry: a cloud that's 90% correct and a cloud that's garbage read almost the same as a shape printout, and you can't tell a scale error from a registration error without seeing it.

CV Write PLY (Point Cloud) is the bridge. It takes positions (and optionally colours), writes a binary PLY to a temp file, and hands back a FILE_3D_PLY object that ComfyUI's core 3D nodes actually accept - Preview Point Cloud for a look, or Save 3D Model for a file.

How it works

PLY is one of the least glamorous formats in existence: an ASCII header ("here come N vertices, each with x, y, z as float32 and red, green, blue as uchar"), then a binary blob of exactly that. The node builds it in memory with numpy structured arrays, which is why it's instant even for a million points.

Two pieces of housekeeping inside, both worth knowing about because they change what you'll see:

  • Non-finite vertices get filtered out. An infinity or a NaN in a cloud - and cv2.reprojectImageTo3D on a bad disparity map produces plenty - blows up any viewer's bounding box. The node drops them and logs how many and what percentage, so a cloud that looks thinner than you expected has an answer in the console.
  • Colours are auto-scaled. Pass 0-255 uint8 and they're used as-is; pass 0-1 float and they're multiplied by 255 first. Disconnect colors entirely and every vertex comes out white. The colours array must have the same row count as the points, or exactly one row, which broadcasts.

An empty cloud, or one where every point is non-finite, raises rather than writing a zero-vertex file. That's the one hard failure in here, and it's the right call - a silently empty PLY is worse.

Inputs and output

  • points - Nx3 float positions, or Nx1x3. This is the one required input. Natural feeders: cv2_reprojectImageTo3D on a disparity map, CV Triangulate Points (Two-View), CV Depth to 3D Points, or the depth-to-points subgraph.
  • colors - optional Nx3 or Nx1x3 RGB per vertex, aligned row-for-row with the points. This is what makes a reconstruction readable: colouring points from the source image makes the shape legible at a glance, and it's the standard trick for spotting a bad registration (the two halves disagree in colour, not just position).
  • ply - the output, a FILE_3D_PLY ready for Preview Point Cloud or Save 3D Model.

Worth saying plainly: the PLY goes to a temp file. This is a viewer-and-inspector node. If you want an asset you keep, that's the save node's job.

Reading the preview without fooling yourself

A point cloud preview hides its own problems, so check two things every time. Scale - the unit is whatever the reconstruction produced, and for a monocular pipeline that's an arbitrary factor, so a cloud that looks like a room could be 20 cm across. Density - one stray vertex a kilometre from the rest shrinks the whole thing to a dot in the viewer's auto-fit, usually a bad-but-finite depth that wasn't filtered rather than a real feature. The pack's Inspect CV Data node is the other half: numbers on the array itself, before you go looking at a picture.

Installing it

Manager → ComfyUI CV, or:

cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv

Restart. Python ≥ 3.12, a recent ComfyUI on the V3 node API, and opencv-contrib-python-headless~=5.0.0.93. Nothing to download for this node, and unlike the mesh generators in the wider 3D ecosystem there are no CUDA extensions or compiled wheels in the way - it's a file format writer. If you've ever lost an evening to a 3D node pack that needed Visual Studio Build Tools, that contrast is the appeal.

GPL-3.0, forked from opencv-comfyui, LLM-assisted code with the author's standing "not for production without review" note.

Where people get burned

A colour array with the wrong length. It must match the point count or be a single row. Mismatched arrays raise rather than silently wrapping; if you filtered the points upstream, filter the colours the same way.

A mis-ordered colour array. Row i of the colours goes on row i of the points, always - which is why CV Transform Points 3D preserves point order instead of sorting anything.

Expecting a mesh. A PLY point cloud is vertices with no faces. It previews and it exports, but a mesh consumer (a printer slicer, a game engine) wants triangles, and the round trip through Gaussian splats or reconstructed points to a printable mesh is a separate, lossy job. That distinction is the single biggest source of "why won't this import" frustration in the whole 3D area.

Forgetting the temp file. The PLY lives in a temp location, so if your workflow's output is an artefact you hand to someone, add the save step explicitly.

Categoryimage/CV/low-level

Inputs (2)

NameTypeDefaultDescription
pointsNPARRAYNx3 or Nx1x3 float array of 3-D vertex positions (e.g. from cv2.reprojectImageTo3D, Triangulate Points, or the depth-to-points subgraph).
colorsoptNPARRAYNx3 or Nx1x3 array of per-vertex RGB colors. uint8 0-255 or float 0-1 (auto-scaled). If disconnected, vertices are white.

Outputs (1)

NameTypeDescription
plyFILE_3D_PLYBinary PLY point cloud. Feed into 'Preview Point Cloud' or 'Save 3D Model'.