{"record":{"id":"e29215d7d90aa42b","repo":"BabylonJS/Babylon.js","slug":"ply-mesh-doesn-t-contain-face-informations","errorCode":null,"errorMessage":"PLY mesh doesn't contain face informations.","messagePattern":"PLY mesh doesn't contain face informations\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/loaders/src/SPLAT/splatFileLoader.pure.ts","lineNumber":369,"sourceCode":"                    case Mode.PointCloud:\r\n                        {\r\n                            const pointcloud = new PointsCloudSystem(\"PointCloud\", 1, scene);\r\n                            if (SPLATFileLoader._BuildPointCloud(pointcloud, parsedPLY.data)) {\r\n                                // eslint-disable-next-line github/no-then\r\n                                await pointcloud.buildMeshAsync().then((mesh) => {\r\n                                    babylonMeshesArray.push(mesh);\r\n                                });\r\n                            } else {\r\n                                pointcloud.dispose();\r\n                            }\r\n                        }\r\n                        break;\r\n                    case Mode.Mesh:\r\n                        {\r\n                            if (parsedPLY.faces) {\r\n                                babylonMeshesArray.push(SPLATFileLoader._BuildMesh(scene, parsedPLY));\r\n                            } else {\r\n                                throw new Error(\"PLY mesh doesn't contain face informations.\");\r\n                            }\r\n                        }\r\n                        break;\r\n                    default:\r\n                        throw new Error(\"Unsupported Splat mode\");\r\n                }\r\n                scene._blockEntityCollection = false;\r\n                this.applyAutoCameraLimits(SPLATFileLoader._ExtractSafeOrbitLimits(parsedPLY), scene);\r\n                resolve(babylonMeshesArray);\r\n            });\r\n        };\r\n\r\n        // Check for gzip (before SPZ V4) and NGSP (SPZ V4+) magic bytes to detect SPZ format\r\n        const isGZipped = u8[0] === 0x1f && u8[1] === 0x8b;\r\n        const isNGSP = u8[0] === 0x4e && u8[1] === 0x47 && u8[2] === 0x53 && u8[3] === 0x50;\r\n        if (!isGZipped && !isNGSP) {\r\n            return new Promise((resolve) => {\r\n                handlePLY(resolve);\r","sourceCodeStart":351,"sourceCodeEnd":387,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/loaders/src/SPLAT/splatFileLoader.pure.ts#L351-L387","documentation":"This error is thrown by the SPLAT file loader when a PLY file is parsed in Mesh mode but the parsed PLY data lacks face (index) information. The loader needs faces to build a regular mesh; a PLY that only contains vertex data (point cloud) cannot be converted into a mesh. It is thrown inside handlePLY during _parseAsync.","triggerScenarios":"Loading a .ply via SPLATFileLoader with mode set to Mode.Mesh while the PLY file has no 'face' element (e.g. vertex-only PLY or SPLAT/point-cloud PLY).","commonSituations":"Exporting a Gaussian splat / point cloud from tools like Polycam or Luma as PLY (these contain vertices + splat attributes but no faces), then loading it with Mesh mode instead of Point cloud or Splat mode; hand-authored PLY missing the face section.","solutions":["Check the PLY header for a 'element face' entry; if absent, the file is a point cloud","Switch the loader mode from Mode.Mesh to the point-cloud/splat mode appropriate for the file","Re-export the PLY from the source tool with faces included if a mesh is truly required","Convert the point cloud to a mesh with surface reconstruction before loading"],"exampleFix":"// before\nloader.loadAsync(\"scene.ply\"); // Mode.Mesh\n// after\nconst loader = new SPLATFileLoader(Mode.Point); // or Splat mode for face-less PLY","handlingStrategy":"validation","validationCode":"const header = plyText.slice(0, plyText.indexOf('end_header'));\nif (!/element face\\s+\\d+/.test(header)) {\n  // load as point cloud instead of mesh\n}","typeGuard":"function plyHasFaces(parsed: { faces?: unknown }): parsed is { faces: unknown[] } {\n  return Array.isArray(parsed.faces) && parsed.faces.length > 0;\n}","tryCatchPattern":"try {\n  await splatLoader.loadAsync(url, Mode.Mesh);\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"face informations\")) {\n    await splatLoader.loadAsync(url, Mode.Point);\n  } else throw e;\n}","preventionTips":["Inspect the PLY header for 'element face' before choosing Mesh mode","Use point/splat mode for splat or point-cloud PLY exports","Pre-validate assets in a pipeline with glTF/PLY validators","Standardize exporter settings to include faces when mesh mode is intended"],"tags":["ply","splat","loader","mesh"],"backgroundTag":"ply-missing-face-data","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}