How to convert STL to PLY
- Detect binary or ASCII STLSelect a .stl file. The parser distinguishes the 84-byte binary header plus uint32 facet count from the solid keyword of ASCII files, then reads facets from either representation.
- Weld coincident cornersEach facet's three corners are hashed by position and normal. Corners that match exactly reuse the first vertex index, which collapses the threefold duplication STL imposes and produces the vertex list the face element needs.
- Keep or recompute normalsFacet normals from the STL are carried onto their corners when they are consistent with the winding; degenerate or zero normals are recomputed from the triangle edges so shading stays correct.
- Write binary PLYThe exporter emits a text header declaring the vertex element with float x, y, z, nx, ny, nz properties and the face element as a uchar count plus int indices, then writes little-endian binary payloads.
- Download the .plyThe result opens in Blender, MeshLab and CloudCompare, and is typically tens of percent smaller than the source STL thanks to indexing.
What happens when STL is converted to PLY
What each format actually stores
Binary STL is a header, a facet count and then fifty bytes per triangle: twelve floats for normal and corners plus a padding word. Nothing is shared between facets, so a sphere with 10,000 triangles stores 30,000 vertex triplets. PLY separates the vertex element from the face element; faces are index lists, so shared corners are stored once. That structural difference is the whole point of the conversion.
What survives the conversion
Positions and normals survive, welded and indexed. Colours do not: STL has no standard colour to begin with, and the converter does not invent vertex colours in the PLY. Units do not exist in either format, so numeric values pass through unchanged.
Welding rules and their limits
Vertices merge only when position and normal both match exactly. Two facets of the same smooth surface weld; facets meeting at a hard edge keep separate normals and therefore separate vertices, which is correct shading behaviour. Above 300,000 triangles the converter switches to direct expansion to bound memory, and the PLY face list then references unshared corners.
Why binary PLY and not ASCII
ASCII PLY stores numbers as text, which is larger and slower to parse. The binary little-endian layout is the interchange default for tools like MeshLab and CloudCompare, and every mainstream package reads it.
STL vs PLY
| STL source | PLY output | |
|---|---|---|
| Feature | STL source | PLY output |
| Container | Header plus flat facet records | Text header plus binary elements |
| Vertices | Duplicated per facet corner | Welded, indexed once |
| Faces | Implicit, one record per facet | Explicit index list |
| Normals | Per facet | Per vertex, x y z nx ny nz |
| Indexing | None | Zero-based int indices |
| Colour | No standard field | Not emitted here |
| Units | None | None |
| Endianness | Little-endian floats | Little-endian payload |
| Output files | One .stl | One .ply |
Supported formats
| Format | Read | Write | Notes |
|---|---|---|---|
| STEP (.step .stp) | Yes | – | ISO 10303 B-rep, AP203 / AP214 / AP242 |
| IGES (.iges .igs) | Yes | – | Entity-based surfaces, up to 5.3 |
| BREP (.brep) | Yes | – | OpenCascade native B-rep |
| STL (.stl) | Yes | Yes | Binary and ASCII triangles, no units |
| OBJ (.obj) | Yes | Yes | v / vn / f records; .mtl references ignored |
| PLY (.ply) | Yes | Yes | Binary position and normal arrays |
| GLB / glTF (.glb .gltf) | Yes | Yes | glTF 2.0, binary or JSON with data URI |
| 3MF (.3mf) | Yes | Yes | OPC/ZIP package, declares millimetres |
| FBX (.fbx) | Yes | – | Binary and ASCII, static mesh only |
| DAE (.dae) | Yes | Yes | Collada scene graph is flattened |
| 3DS (.3ds) | Yes | – | Legacy chunk-based 3D Studio format |
| AMF (.amf) | Yes | – | XML, ZIP-compressed packages supported |
| USDZ (.usdz) | Yes | Yes | ZIP containing a USD stage |
Known limitations and why a conversion can fail
Colour is not invented
Some slicers write non-standard colour bytes into the STL attribute word; those bytes are ignored. The PLY is written without colour properties rather than guessing.
Huge meshes skip welding
Above 300,000 triangles the hash-based weld is skipped for memory reasons. Output stays valid but keeps per-corner vertices, so the size advantage shrinks.
Non-manifold input stays non-manifold
Welding merges coincident corners but does not repair holes, self-intersections or flipped facets. Run a mesh-repair pass in your tool if the STL was broken to begin with.
Frequently asked questions
Can I convert on this page itself?
No. This page is the reference for the STL to PLY path, and the conversion itself runs in the workspace that the button above opens, with both formats already selected. Your file is read in that browser tab and the download is written locally, so there is no upload stage in either place. Keeping the documentation and the engine on separate addresses lets file support and detail levels change behind one workspace without breaking the page you are reading.
Why is the PLY smaller than the STL?
Indexing. Shared corners are stored once instead of three times per facet, and the face list references them by four-byte integers. Typical gains are twenty to forty percent on closed meshes.
Will Blender show it correctly?
Yes. Binary little-endian PLY with position and normal properties is the most common variant and imports directly.
Is the triangle order preserved?
Facet order is preserved in the face list, and welding never changes geometry. Only the vertex storage changes.
Can I get ASCII PLY instead?
This converter writes binary PLY for size and speed. Most tools that accept PLY read the binary form.
References
Related converters
All converters
Last updated: