What is SVF2 and how it works.

Your app already translates to SVF2 and opens it with the streaming api, so this is the pipeline you are running.

SVF2 is the public name. Inside the viewer it is called OTG, and the loader classes carry that name. The key idea is that a model is no longer a package you download. It is a small index plus a content-addressed store of geometry, and the viewer pulls pieces of that store on demand.

What the translation produces. When your server posts the job with output type svf2, the derivative service converts the design into three kinds of things:

  • A fragment list per model. One record per drawable fragment: a transform, a bounding box, a material reference, a geometry reference and the dbId it belongs to. Compact binary, no geometry inside.
  • A shared geometry and material store. Every unique mesh is stored once, in its own local coordinates, under a hash of its contents. Same for materials and textures. Ten identical valves in one model, or the same door family across twenty models of the account, are one entry. The fragment list points at those hashes.
  • The property database and the object tree. Same structure SVF had. Properties are per model, not shared.

Deduplication works because the geometry is stored without placement. Two instances differ only by the matrix in the fragment list, so their hashes match.

How the viewer boots a model. Roughly this sequence:

  1. Document.load fetches the derivative manifest for the urn. For SVF2 that manifest points at an OTG-specific manifest, which lists the fragment list, the hash tables and the root of the shared storage.
  2. The fragment list is downloaded and parsed in a worker. This alone lets the viewer know every bounding box, so it builds the BVH client-side before a single triangle exists. That is why the model structure and the camera fit appear before anything is drawn.
  3. The loader walks the BVH from the current camera and requests geometry by hash, biggest and nearest first. Requests are batched. The viewer opens a WebSocket to the derivative CDN and streams many hashes per message, falling back to plain HTTP if the socket fails.
  4. Each mesh arrives as a compact binary: interleaved vertices, quantized positions and packed normals. A worker decodes it and the main thread uploads it to the GPU. Every fragment pointing at that hash becomes drawable in the next frame, which is the progressive fill you see.
  5. A resource cache in memory is shared across every model in the viewer session. A second model of the same project loads faster because most of its hashes are already resident.

What changes for you compared to SVF. SVF grouped meshes into pack files and downloaded whole packs, so the first pixel waited for a large fetch, and every model carried its own copy of every repeated mesh. SVF2 trades that for many small, cacheable, deduplicated fetches. The cost is that there is no self-contained package to copy offline. Geometry lives behind the CDN and every request carries the access token your server issues, which is why the viewer needs the streamingV2 api rather than derivativeV2.

The parts I am confident about are the shared hashed store, the fragment list, the manifest chain and the client-side BVH. The exact vertex encoding and the WebSocket batching are from reading viewer internals some time ago, so treat those two as likely rather than guaranteed.

Leave a Reply

Your email address will not be published. Required fields are marked *