# Server for Particle Models (PtServer)

## Getting Started with ParticleModel (Particle Simulation Playback)

The prerequisites for the particle server can be found in Supported Platforms.

The PtServer is a stateless REST server: unlike UgServer (WebSocket-based), no sticky sessions are required and the server can be horizontally scaled behind a load balancer. Multiple clients can connect to the same server concurrently, sharing cached dataset readers.

1. Download and extract HOOPS Envision for Web distribution archive from the Tech Soft 3D Developer Zone: https://developer.techsoft3d.com/

2. Specify your license, either by modifying server/PtServer/Main.js to specify your license code:

       ptServer.setLicenseCode(myCode);

   or by copying the hoops_license.h file downloaded from the developer zone into the server/PtServer folder, or by specifying the `CEW_TECH_SOFT_LICENSE_FILE` environment variable to point to the hoops_license.h, or by setting the `CEW_TECH_SOFT_LICENSE_CODE` environment variable directly.

3. With a terminal prompt, go to the `server/PtServer` folder inside the distribution.

4. Execute the following command to install dependencies:

       > npm install

5. Start the server using npm:

   Start the server with the appropriate command for your platform:

       > npm run server:pt:linux
       > npm run server:pt:win
       > npm run server:pt:mac

   Node will then run Main.js, and the server will start on port 8999 by default. The port can be changed by setting the `CEW_PT_PORT` environment variable.

   You can verify that the server is running by opening http://localhost:8999 in a browser. You should then see a message like this:

       HOOPS Envision PtServer is alive
        Server ver: 1.0.0-abcdef12
        Node.js ver: v20.11.0 (linux|x64)

6. We have included a simple http server for hosting the example web apps. To start the http server, go to the Examples/HttpServer folder and run:

       > npm install

   Then start the server by running:

       > npm start

   This will start the server on port 8000. This can be changed by the PORT environment variable or editing the HttpServer.js file.

   Open http://localhost:8000 in your browser and navigate to the particle example (e.g. Examples/MinimalPtTypeScript).

7. Please refer to the documentation to learn more about HOOPS Envision for Web. The central classes are:

   - `CloudSession`: Applications will typically create a single instance of CloudSession for managing viewers.
   - `Viewer`: Handles user interaction (pan/rotate/zoom), picking and other view related functions.
   - `ParticleModel`: The main class for interacting with particle datasets. Handles model opening, frame fetching, scalar field selection, and animation. ParticleModel requires the presence of a running PtServer.
   - `Animation`: Time-step animation controller with configurable frame rate, looping, and preloading support.

## Configuring the PtServer

The PtServer is configured via environment variables. All variables use the `CEW_PT_` prefix.

Server configuration:

Environment Variable | Default | Description
--- | --- | ---
`CEW_PT_PORT` | `8999` | TCP port the server listens on.
`CEW_PT_USE_HTTPS` | `false` | Enable HTTPS. Requires `MyDomain_private.key` and `MyDomain.crt` in the server folder.
`CEW_PT_MODEL_PATH` | `./test-data/particles` | Directory containing particle datasets (PTFX/VTP files or subdirectories).
`CEW_PT_ENABLE_REST_API_QUERY` | `true` | Enable the query endpoints (list models, get info, get frames, switch scalar).
`CEW_PT_ENABLE_REST_API_UPLOAD` | `false` | Enable the upload/delete endpoints. Disabled by default for security.
`CEW_PT_ENABLE_CORS` | `false` | Enable Cross-Origin Resource Sharing headers.
`CEW_PT_READER_PLUGIN_FOLDER` | (empty) | Path to folder containing reader plugin shared libraries (`cpt_*.dll/.so/.dylib`).
`CEW_PT_COMPRESSION_LEVEL` | `6` | Gzip compression level for binary responses (0 = disabled, 1-9).
`CEW_PT_COMPRESSION_THRESHOLD` | `1024` | Minimum response size in bytes before compression is applied.
`CEW_PT_MAX_UPLOAD_SIZE` | `5368709120` (5 GB) | Maximum upload file size in bytes.
`CEW_PT_MAX_CONCURRENT_UPLOADS` | `3` | Maximum number of concurrent upload requests.
`CEW_PT_CACHE_MEMORY_LIMIT_MB` | `0` | Server-side C++ frame cache memory limit in MB. 0 = use C++ default (5 GB).

## Logging in PtServer

The PtServer supports logging to console and file in two different formats: Standard (more human readable) and JSON (for easy processing or consumption by e.g. Logstash).

The logging output of the PtServer can be controlled via the following environment variables:

- `CEW_PT_LOG_CONSOLE_OUTPUT_TYPE`: Format for console log. Possible values: “standard”, “json”, “none”. Default: “standard”.
- `CEW_PT_LOG_FILE_OUTPUT_TYPE`: Format for file log. Possible values: “standard”, “json”, “none”. Default: “json”.
- `CEW_PT_LOG_FILENAME`: If file output type is not NONE, use this to specify the name of the log file. Default: “c3_pt_server.log”.
- `CEW_PT_LOG_LEVEL`: Specify what to log. Possible values: 1: Error, 2: Warning, 3: Info, 4: Debug. A 3 will log Error, Info and Warning, but not any debug messages. This is default.
- `CEW_PT_LOG_HTTP`: Log every HTTP request. Default: “false”.

Note

Unlike UgServer, PtServer does not support client-side log-context key/value injection (i.e. there is no equivalent of `RemoteModel.setServerLogContextKeyValueArr()`). Each REST request is independent and carries no session state.

On Linux, logging of segmentation faults is also added to help debugging situations where the server crashes.

## Session Model / Scalability

The PtServer architecture differs fundamentally from UgServer in its session model:

- UgServer (WebSocket): maintains one session per socket, with a 1:1 `VizDataExtractor` per client. State is tied to the socket connection.
- PtServer (REST): completely stateless HTTP. No session concept. N clients share M cached dataset readers via a `DatasetReaderFactory` with ref-counting and LRU eviction.

Key implications:

- Horizontal scaling: PtServer instances can be placed behind a standard HTTP load balancer with no sticky-session requirement.
- Multi-client: Multiple clients requesting the same model share one reader instance (concurrent access serialized by a C++ mutex). Different models get separate readers from the factory cache.
- No reconnection handling needed: Because PtServer is stateless, there is no equivalent of UgServer’s `CEW_UG_MAX_DISCONNECT_DURATION_MS`. Each request is self-contained.

## REST API Reference

All endpoints are prefixed with `/api/v1`. The query endpoints require `CEW_PT_ENABLE_REST_API_QUERY=true` (default). The upload/delete endpoints require `CEW_PT_ENABLE_REST_API_UPLOAD=true`.

Query endpoints:

Method | Path | Description
--- | --- | ---
GET | `/api/v1/models` | List all available models in the configured model path. Returns a JSON array of model keys.
GET | `/api/v1/models/:modelKey/info` | Get dataset metadata: modelKey, maxParticleCount, frameCount, boundingBox, scalarFieldNames, activeScalarField, hasScalarData, scalarRange.
GET | `/api/v1/models/:modelKey/frame/:frameIndex` | Fetch a binary frame buffer. Optional query parameter `decimation` (0.0-1.0) for LOD reduction. Response header `X-Particle-Count` indicates actual particle count in the buffer.
PUT | `/api/v1/models/:modelKey/scalar/:fieldName` | Switch the active scalar field for subsequent frame requests.
DELETE | `/api/v1/models/:modelKey/scalar` | Clear the active scalar field (position-only mode).

Upload/delete endpoints (requires `CEW_PT_ENABLE_REST_API_UPLOAD=true`):

Method | Path | Description
--- | --- | ---
POST | `/api/v1/models` | Upload a new model (multipart form data). Subject to `CEW_PT_MAX_UPLOAD_SIZE` and `CEW_PT_MAX_CONCURRENT_UPLOADS` limits.
DELETE | `/api/v1/models/:modelKey` | Delete a model from the server. Symlinks are rejected for safety.

Health endpoint:

Method | Path | Description
--- | --- | ---
GET | `/` | Returns server-alive message with version info (non-production mode).

## Binary Wire Format

Frame data is transmitted in a compact binary SOA (Structure of Arrays) format optimized for bandwidth:

- Particle count (uint32): number of particles in this frame.
- IDs (int32[]): delta-encoded particle identifiers.
- X positions (uint16[]): quantized X coordinates.
- Y positions (uint16[]): quantized Y coordinates.
- Z positions (uint16[]): quantized Z coordinates.
- Scalars (uint16[], optional): quantized scalar values (only present when a scalar field is active).

Quantization formula: `quantized = round((value - min) / (max - min) x 65535)`

Without scalars the format uses 10 bytes per particle; with scalars 12 bytes per particle. Combined with gzip compression, this typically achieves 4x bandwidth savings compared to full-precision float transmission.

Note

This is an internal wire protocol. SDK users do not need to decode it: the `ParticleModel` client class handles decoding and dequantization automatically.

## Request Cancellation

Because PtServer uses REST (not WebSockets), there is no socket reconnection handling. However, the client-side `ParticleModel` implements request cancellation:

Calling `setFrame` automatically cancels any previous inflight frame request using an `AbortController` pattern. This ensures that rapid frame seeking (e.g. during scrubbing or animation) does not queue up stale responses, and only the most recent frame request completes.

## Particle Reader Plugins

The PtServer supports dynamic loading of reader plugins for custom particle file formats. Plugins are discovered from the folder specified by `CEW_PT_READER_PLUGIN_FOLDER` and must follow the naming convention `cpt_{NAME}.dll` (Windows), `cpt_{NAME}.so` (Linux), or `cpt_{NAME}.dylib` (macOS).

See Particle Reader Plugins for full details on the plugin API and development workflow.

## Examples

A minimal TypeScript example demonstrating PtServer usage is included in the distribution at `Examples/MinimalPtTypeScript/`. See Examples for a full list of included examples.

## Cross-References

- Modules: module overview including `cee.pt`.
- Distribution Content: distribution layout including `server/PtServer`.
- Particle Reader Plugins: reader plugin development for PtServer.
- Class Index: API reference for `cee.pt.ParticleModel`, `cee.pt.Animation`, and other classes.

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...