Skip to main content
Version: Next

Prioritize nodes for loading

A developer may assign nodes of a model as "prioritized" in relation to geometry loading. By giving nodes a "prioritization weight", a developer can influence Reveal to load, or keep loaded, certain parts of a model when it would otherwise discard them in favor of e.g. geometry that is closer to the camera. Note that assigning prioritization weights to nodes does not guarantee that they will be loaded at all times; the loader will still account for the rendering budget.

Nodes are given load priority through the node styling API. The NodeAppearance type (see Cad Styling) includes the optional field prioritizedForLoadingHint which can be used to provide a load priority to the node collection. Higher values will make the related geometry more likely to be loaded. While any number can be used as the load priority, it is recommended to use values between 1 and 10. 5 is considered a reasonable default value.

Not all node collection types support the priority hint. An overview of current support is provided in the following table.

NodeCollectionTypeSupports prioritizedForLoadingHint?
TreeIndexNodeCollectionMust be manually provided, see below
PropertyFilterNodeCollectionYes
SinglePropertyFilterNodeCollectionYes
AssetNodeCollectionYes
InvertedNodeCollectionNo
UnionNodeCollectionYes
IntersectionNodeCollectionYes
note

Currently, TreeIndexNodeCollection does not take responsibility to compute the location of the geometry it holds, which the loader needs to prioritize the geometry. Alternatively, the developer may supply this information themselves by using the addAreaPoints() and addAreas() methods on the TreeIndexNodeCollection.

A node collection that is the result of an operation (e.g. a union) involving another node collection that does not support prioritizedForLoadingHint, will not support the prioritizedForLoadingHint field either.

Prioritize highlighted nodes for loading

Many use cases in Reveal involve highlighting a few nodes while the rest of the model is hidden or ghosted. These use cases can benefit from the prioritization feature. Assigning a priority to the nodes of interest in addition to the hightlighting, makes them more likely to be loaded even when the camera is far away:

// import { SinglePropertyFilterNodeCollection } from '@cognite/reveal'

const nodeSet = new SinglePropertyFilterNodeCollection(sdk, model, { requestPartitions: 10 });
const names = ['/60-EL-9016-Q200-E01', '/60-EL-9016-Q200-E02', '/60-EL-9016-Q200-E03'];
nodeSet.executeFilter('Item', 'Name', names);

model.setDefaultNodeAppearance(DefaultNodeAppearance.Ghosted);
model.assignStyledNodeCollection(nodeSet, { ...DefaultNodeAppearance.Highlighted, prioritizedForLoadingHint: 5 });

High-detail output for a pre-computed node subset

Prerequisite

This feature requires a gltf-prioritized-nodes-directory output to exist for the model revision. This output is produced by a separate backend job — Reveal does not trigger that job. If the output does not exist, addCadModel will throw an error.

In addition to the hint-based prioritization above, Reveal supports loading a pre-computed high-detail geometry output for a specific subset of nodes. This output (File3dFormat.GltfPrioritizedNodes) contains full-resolution geometry only for the nodes that were included in the backend job, making it suited for inspection-style use cases where selected objects must always be rendered at maximum detail.

Three usage patterns are supported, and they can be combined depending on the use case.

Option 1 — Replace the model

Swap the entire model to the prioritized output. The original model is removed and the prioritized version is loaded in its place. This is the simplest approach when the use case is a dedicated high-detail view.

// import { File3dFormat } from '@cognite/reveal'

// Remove the standard model first
viewer.removeModel(mainModel);

// Load the prioritized output in its place
const prioritizedModel = await viewer.addCadModel({
modelId,
revisionId,
outputFormat: File3dFormat.GltfPrioritizedNodes
});

viewer.loadCameraFromModel(prioritizedModel);

To revert, remove prioritizedModel and reload without outputFormat:

viewer.removeModel(prioritizedModel);
const standardModel = await viewer.addCadModel({ modelId, revisionId });

Option 2 — Overlay specific nodes

Load the prioritized output as a second model on top of the original, then use styling to ghost the background and show only the selected nodes at full detail. This keeps the surrounding model visible as context.

// import { File3dFormat, NodeIdNodeCollection, DefaultNodeAppearance } from '@cognite/reveal'

const nodeIds = [/* ... */];

// Load prioritized output as overlay
const overlayModel = await viewer.addCadModel({
modelId,
revisionId,
outputFormat: File3dFormat.GltfPrioritizedNodes
});

// Ghost the original model and hide the selected nodes within it
// (they will be shown at full detail by the overlay instead)
mainModel.setDefaultNodeAppearance(DefaultNodeAppearance.Ghosted);
const mainNodeSet = new NodeIdNodeCollection(client, mainModel);
await mainNodeSet.executeFilter(nodeIds);
mainModel.assignStyledNodeCollection(mainNodeSet, { visible: false });

// In the overlay, hide everything except the selected nodes
overlayModel.setDefaultNodeAppearance({ visible: false });
const overlayNodeSet = new NodeIdNodeCollection(client, overlayModel);
await overlayNodeSet.executeFilter(nodeIds);
overlayModel.assignStyledNodeCollection(overlayNodeSet, DefaultNodeAppearance.Default);

To remove the overlay and restore the original appearance:

viewer.removeModel(overlayModel);
mainModel.setDefaultNodeAppearance(DefaultNodeAppearance.Default);
mainModel.removeAllStyledNodeCollections();
note

If any of the supplied nodeIds do not exist in the model/revision, NodeIdNodeCollection.executeFilter will silently return an empty set for those IDs. Check that the resolved IndexSet is non-empty before proceeding.


Option 3 — Lock sectors on the main model

Prevent specific nodes' sectors from being evicted when the CAD render budget is reduced. Locked sectors remain loaded regardless of camera position or budget pressure.

Node locking uses tree indices, not node IDs. Use NodeIdNodeCollection to resolve node IDs to tree indices first:

// import { NodeIdNodeCollection, DefaultNodeAppearance } from '@cognite/reveal'

const nodeIds = [/* ... */];

const nodeCollection = new NodeIdNodeCollection(client, mainModel);
await nodeCollection.executeFilter(nodeIds);

const treeIndices = nodeCollection.getIndexSet().toIndexArray();

if (treeIndices.length === 0) {
// None of the node IDs exist in this model/revision
return;
}

// Style and lock
mainModel.assignStyledNodeCollection(nodeCollection, DefaultNodeAppearance.Default);
mainModel.lockTreeIndices(treeIndices);

Locking is reactive: if a locked tree index's geometry is discovered in a new sector during loading, that sector is automatically locked as well.

To unlock individual tree indices:

mainModel.unlockTreeIndices(treeIndices);

To remove all locks at once:

mainModel.unlockAllTreeIndices();
mainModel.removeAllStyledNodeCollections();

Limitations

LimitationDetail
Backend prerequisiteA gltf-prioritized-nodes-directory output must already exist for the revision. Reveal does not trigger backend jobs.
Locked sectors count toward render budgetLocked sectors are never evicted, but they still contribute to the total render cost. Locking many sectors may degrade performance on lower-end devices.
lockTreeIndices requires tree indicesNode IDs must be resolved to tree indices first (e.g. via NodeIdNodeCollection).
Lock mode does not increase geometry detailLocking sectors on the standard model prevents eviction but does not load higher-detail geometry. For higher detail, use the prioritized output (Option 1 or 2).
GltfPrioritizedNodes contains only a subsetThe prioritized output only contains geometry for the nodes included in the backend job. It cannot be used as a full model replacement if coverage of all nodes is required.