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