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.

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.