{
  "slug": "ply-to-obj",
  "name": "gizza-ai/ply-to-obj",
  "version": "0.1.0",
  "title": "PLY to OBJ Converter — convert PLY meshes and point clouds to Wavefront OBJ — gizza.ai",
  "description": "Convert a Stanford PLY mesh or point cloud to Wavefront OBJ. Reads ascii and binary PLY, keeps vertex colors, normals and UVs, scales and reorients axes.",
  "tags": [
    "ply to obj",
    "ply converter",
    "wavefront obj",
    "point cloud",
    "3d model converter",
    "mesh converter",
    "vertex colors",
    "binary ply"
  ],
  "category": "utilities",
  "urls": {
    "page": "https://gizza.ai/tools/ply-to-obj/",
    "markdown": "https://gizza.ai/tools/ply-to-obj/index.md",
    "descriptor": "https://gizza.ai/tools/ply-to-obj/tool.json",
    "deep_link_example": "https://gizza.ai/tools/ply-to-obj/?ply=ply%0Aformat%20ascii%201.0%0Aelement%20vertex%203%0Aproperty%20float%20x%0Aproperty%20float%20y%0Aproperty%20float%20z%0Aelement%20face%201%0Aproperty%20list%20uchar%20int%20vertex_indices%0Aend_header%0A0%200%200%0A1%200%200%0A0%201%200%0A3%200%201%202&input_format=auto&colors=true&normals=true&uvs=true&triangulate=true&scale=1&axis=keep&name=mesh&output=obj"
  },
  "cli": "gizza tool ply-to-obj \"ply\nformat ascii 1.0\nelement vertex 3\nproperty float x\nproperty float y\nproperty float z\nelement face 1\nproperty list uchar int vertex_indices\nend_header\n0 0 0\n1 0 0\n0 1 0\n3 0 1 2\"",
  "tool": {
    "description": "Convert a Stanford PLY mesh or point cloud into a Wavefront OBJ file. All three PLY encodings are read: ascii, binary_little_endian and binary_big_endian. Paste an ASCII PLY as text; a binary PLY is not text, so paste its bytes as base64 or hex (a data:…;base64,… URL works too) and input_format=auto will detect it. Per-vertex extras are carried over when the file declares them: colors become the OBJ 'v x y z r g b' extension with r/g/b in 0..1 (uchar 0..255 channels are divided by 255), normals become 'vn' lines and s/t, u/v or texture_u/texture_v become 'vt' lines, with faces written as f v/vt/vn accordingly; set colors, normals or uvs to false to drop any of them. A PLY with no face element is a point cloud and emits 'v' lines only. Faces keep their original corner count as OBJ n-gons unless triangulate=true fan-triangulates them for printers and engines that need triangles. Unknown elements (edges, materials, scanner data) and unmapped vertex properties are skipped without desynchronising the file. scale multiplies every vertex position (e.g. 0.001 mm->m) and axis reorients between graphics Y-up and 3D-print/CAD Z-up. output=summary returns a report on the source file — encoding, mesh vs point cloud, counts, which properties were present and written, and what was ignored — instead of the OBJ. No .mtl material file is written (PLY stores no materials) and per-vertex alpha is dropped (OBJ has no alpha channel). Limits: 200000 vertices and 200000 faces. Runs fully locally, no network access.",
    "parameters": {
      "additionalProperties": false,
      "properties": {
        "axis": {
          "default": "keep",
          "description": "Coordinate-frame reorientation. 'keep' (default) leaves axes as-is; 'y-up-to-z-up' rotates a graphics Y-up model to 3D-print/CAD Z-up; 'z-up-to-y-up' does the reverse. Positions and normals rotate together.",
          "enum": [
            "keep",
            "y-up-to-z-up",
            "z-up-to-y-up"
          ],
          "type": "string"
        },
        "colors": {
          "default": true,
          "description": "Carry per-vertex colors over when the PLY has red/green/blue properties (default true). They are written as the widely-supported OBJ extension 'v x y z r g b' with r/g/b in 0..1, which MeshLab, CloudCompare and Blender read. Set false for a strict 'v x y z' OBJ. Integer color channels (uchar 0..255) are divided by 255; float channels are used as-is.",
          "type": "boolean"
        },
        "input_format": {
          "default": "auto",
          "description": "How the pasted input is encoded. 'auto' (default) detects it: text starting with 'ply' is read as ASCII PLY, otherwise the input is decoded as hex, then as base64, and must yield bytes starting with the PLY magic word. Set 'ascii', 'base64' or 'hex' to force one.",
          "enum": [
            "auto",
            "ascii",
            "base64",
            "hex"
          ],
          "type": "string"
        },
        "name": {
          "default": "mesh",
          "description": "Object name written on the OBJ 'o' line. Default 'mesh'. Use it to label a scan or part, e.g. 'scan_01'.",
          "type": "string"
        },
        "normals": {
          "default": true,
          "description": "Carry per-vertex normals over when the PLY has nx/ny/nz properties (default true), written as 'vn' lines with faces referencing them as 'f v//vn' (or 'f v/vt/vn' when texture coordinates are kept too). Set false to omit them.",
          "type": "boolean"
        },
        "output": {
          "default": "obj",
          "description": "What to return. 'obj' (default) is the converted Wavefront OBJ text. 'summary' is a report about the source file instead: its PLY encoding, whether it is a mesh or a point cloud, vertex/face/polygon counts, which of colors/normals/texture coordinates it declared and which were written, every header element, and the vertex properties that were ignored.",
          "enum": [
            "obj",
            "summary"
          ],
          "type": "string"
        },
        "ply": {
          "description": "The PLY file to convert. An ASCII PLY is pasted as text (it starts with the word 'ply' on its own line). A BINARY PLY is not text — paste its bytes as base64 or hex instead (a data:…;base64,… URL works too). All three PLY encodings are read: ascii, binary_little_endian and binary_big_endian. Up to 200000 vertices and 200000 faces.",
          "type": "string"
        },
        "scale": {
          "default": 1.0,
          "description": "Uniform scale factor applied to every vertex position (default 1.0 = unchanged). Use e.g. 0.001 to convert millimetres to metres, or 25.4 for inches to millimetres. Normals are direction vectors and are not scaled.",
          "type": "number"
        },
        "triangulate": {
          "default": false,
          "description": "Split faces with more than 3 corners into triangles by fan triangulation. Default false keeps them as OBJ n-gons, which OBJ supports natively and is the faithful conversion. Set true for 3D printers, game engines or slicers that only accept triangles.",
          "type": "boolean"
        },
        "uvs": {
          "default": true,
          "description": "Carry per-vertex texture coordinates over when the PLY has s/t, u/v or texture_u/texture_v properties (default true), written as 'vt' lines with faces referencing them as 'f v/vt'. Set false to omit them. No .mtl material file is written — PLY stores no material definitions.",
          "type": "boolean"
        }
      },
      "required": [
        "ply"
      ],
      "type": "object"
    }
  }
}