# Supported File Formats (ParticleModel)

The PtServer supports reading of the following particle data formats out of the box:

- PTFX: HOOPS Envision binary particle format (*.ptfx)
- VTP: VTK PolyData XML particle format (*.vtp)

Additional file formats can be added at runtime through reader plugins. See Particle Reader Plugins for details.

On this page

- PTFX (Binary Particle Format)
  - Header layout (48 bytes, little-endian)
  - Per-frame binary layout
  - Sidecar JSON
  - Writing PTFX data
- VTP (VTK PolyData XML)
  - Supported subset
  - Example VTP file
- Custom Formats via Reader Plugins

## PTFX (Binary Particle Format)

PTFX is the native high-performance binary format for particle simulation data in HOOPS Envision. It is designed for fast sequential frame streaming and supports an arbitrary number of scalar fields per particle.

A PTFX dataset consists of:

1. A header file (`<name>.ptfx`): 48-byte binary header containing global metadata.
2. Per-frame binary files (`<name>_0000.bin`, `<name>_0001.bin`, …) - one file per timestep. Both 4-digit and 6-digit zero-padded indices are supported (auto-detected).
3. An optional sidecar JSON (`<name>.ptfx.json`): scalar field names and range metadata.

### Header layout (48 bytes, little-endian)

Offset | Type | Description
--- | --- | ---
0 | char[4] | Signature: `"PTFX"`
4 | uint32 | Format version (currently `1`)
8 | uint32 | Maximum particle count across all frames
12 | uint32 | Timestep (frame) count
16 | float32 x 3 | Bounding-box minimum (x, y, z)
28 | float32 x 3 | Bounding-box maximum (x, y, z)
40 | float32 | Scalar range minimum (legacy single-field; use sidecar JSON for multi-field datasets)
44 | float32 | Scalar range maximum

### Per-frame binary layout

Each frame file (`<name>_NNNN.bin`) has:

- First 4 bytes: `particleCount` (uint32, little-endian): number of particles in this frame.

- Particle records (array-of-structures): one record per particle, each record containing:

  Field | Type | Description
  --- | --- | ---
  id | uint32 | Unique particle identifier (persistent across frames)
  x | float32 | X position
  y | float32 | Y position
  z | float32 | Z position
  scalar0 … scalarn | float32 each | One value per scalar field defined in the sidecar JSON

  Total bytes per particle: `16 + 4 x scalarFieldCount`.

### Sidecar JSON

An optional JSON file alongside the header provides multi-scalar metadata:

    {
      "scalarFields": [
        { "name": "Temperature", "min": 290.0, "max": 1200.0 },
        { "name": "Velocity",    "min": 0.0,   "max": 35.5 }
      ]
    }

If the sidecar is absent, the reader falls back to a single scalar field named “Scalar” with the min/max stored in the header.

### Writing PTFX data

The `PtfxDatasetWriter` class in the desktop SDK (`CeeParticleModel` library) provides a simple API for converting proprietary particle data to PTFX:

1. `open(path, maxParticles, frameCount, bboxMin, bboxMax, scalarFields)`
2. `writeFrame(ids, positions, scalarArrays)`: call once per timestep
3. `close()`: finalizes the header with observed ranges

See the Server for Particle Models (PtServer) getting-started section for a complete workflow, and the PTFX converter example in the desktop SDK documentation for a step-by-step tutorial.

## VTP (VTK PolyData XML)

The PtServer supports reading time-series particle data stored as a sequence of VTK PolyData XML files (`.vtp`). One `.vtp` file represents one frame; files are sorted alphabetically to determine frame order (e.g. `particles_0000.vtp`, `particles_0001.vtp`, …).

### Supported subset

Feature | Support
--- | ---
Encoding | ASCII only. Binary, appended, and base64-encoded VTP files are not supported.
Points | `<DataArray NumberOfComponents="3">` inside `<Points>`, interleaved XYZ (float).
Particle count | Taken from `<Piece NumberOfPoints="N">`.
Particle IDs | A `<DataArray>` named `"Id"` (case-insensitive) in `<PointData>`. If absent, sequential IDs `[0, 1, 2, ...]` are generated automatically.
Scalar fields | All single-component `<DataArray>` elements in `<PointData>` are treated as scalar fields, excluding the ID array.
Active scalar | Determined by the `Scalars` attribute on the `<PointData>` element. If unset, the first scalar field is activated by default.

Note

Only the subset above is read by the PtServer. Advanced VTP features such as cell data, connectivity, strips, or multi-component vector arrays are ignored.

### Example VTP file

    <?xml version="1.0"?>
    <VTKFile type="PolyData" version="0.1" byte_order="LittleEndian">
      <PolyData>
        <Piece NumberOfPoints="3" NumberOfVerts="0" NumberOfLines="0"
               NumberOfStrips="0" NumberOfPolys="0">
          <PointData Scalars="Temperature">
            <DataArray type="Float32" Name="Id" NumberOfComponents="1"
                       format="ascii">
              0 1 2
            </DataArray>
            <DataArray type="Float32" Name="Temperature" NumberOfComponents="1"
                       format="ascii">
              300.0 450.5 1100.2
            </DataArray>
          </PointData>
          <Points>
            <DataArray type="Float32" NumberOfComponents="3" format="ascii">
              0.0 0.0 0.0
              1.0 2.0 0.5
              3.0 1.0 1.5
            </DataArray>
          </Points>
        </Piece>
      </PolyData>
    </VTKFile>

## Custom Formats via Reader Plugins

Arbitrary particle file formats can be supported by implementing a reader plugin and placing it in the folder specified by the `CEW_PT_READER_PLUGIN_FOLDER` environment variable. Plugins follow the naming convention `cpt_{NAME}.dll` / `.so` / `.dylib` and are discovered automatically at server startup.

For a complete guide on developing reader plugins: including the C++ ABI, discovery mechanism, and desktop SDK integration: see Particle Reader Plugins.

Conversation saved
HOOPSY BETA

### Hello! I'm HOOPSY

Your multilingual generative AI assistant for documentation. Ask me anything about HOOPS Envision for Web in your own language, or choose a sample question below to start a conversation:

What is HOOPS Envision for Web?
What are the latest release notes for HOOPS Envision for Web?
How do I start evaluating HOOPS Envision for Web?
How do I write my first sample application?
How can I get assistance?

HOOPSY may store conversations according to OpenAI's policy. Responses may not always be accurate.

HOOPSY is thinking...