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)
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:
- A header file (
<name>.ptfx): 48-byte binary header containing global metadata. - 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). - 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:
open(path, maxParticles, frameCount, bboxMin, bboxMax, scalarFields)writeFrame(ids, positions, scalarArrays): call once per timestepclose(): 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.