Leverage Instancing in the HOOPS Communicator Authoring Library

The concept of instancing in HOOPS Communicator is quite simple and built-in to the way you define mesh’s for visualization in the HOOPS Communicator. The goal is to leverage the ability to define your geometry/mesh once and then reuse it many times over within your model making any overrides at the instance level. With instancing, a single mesh only uses the memory needed to store its base information, such as vertex positions and normals. All other instances of like geometry can reference this single definition, and then apply unique style and attribute data (colors, transformations, materials, etc) to that referenced geometry, allowing for a much smaller memory footprint. On the contrary, without using instancing, your computer allocates memory for every single identical mesh you include in your scene – this duplicates data, increases processing times, and hinders streaming. To demonstrate, we generated two sets of N number of cubes using the authoring library – one set uses instancing, and the other does not. The processing times for the model data can be found below:

image002

This is an extremely important feature when using the authoring library in HOOPS Communicator to generate your own Stream Cache files. For example, if you have a model that includes 500 copies of the same exact screw, you will only want to create a single copy of the screw’s tessellation for visualizing and then reference that for instance so you can minimize the size of your SC file to be sent across the network while maximizing the performance in the HOOPS Communicator client for the best end-user performance in your application. The steps and process to add instances is outlined below.

First you must create your mesh:

SC::Store::Mesh mesh;

float point_data = {

0.0f, 0.0f, 0.0f, // Point 0

1.0f, 0.0f, 0.0f, // Point 1

1.0f, 1.0f, 0.0f, // Point 2

};

mesh.point_count = 3;

mesh.points = (SC::Store::Point const *)point_data;

Second, you must add your base mesh to the model:

SC::Store::MeshKey mesh_key = model.Insert(mesh);

Finally, you must instance your mesh to all the locations that it should be placed in your model along with any other modifications required to the base mesh:

SC::Store::InstanceKey instance_key_1 = model.Instance(mesh_key);

SC::Store::InstanceKey instance_key_2 = model.Instance(mesh_key, matrix_key);

SC::Store::InstanceKey instance_key_3 = model.Instance(mesh_key, matrix_key, material_key_blue);

SC::Store::InstanceKey instance_key_4 = model.Instance(

mesh_key,

matrix_key,

material_key_red,

material_key_green,

material_key_blue,

SC::Store::MaterialMapKey(),

SC::Store::MaterialMapKey(),

SC::Store::MaterialMapKey(),

SC::Store::Visibility(SC::Store::Visibility::Face));

For any questions about instancing with the HOOPS Communicator Authoring library post below or check out our detailed documentation on the topic: HOOPS Communicator Documentation — HOOPS Communicator 2023 SP2 U2 Documentation.

2 Likes

Thanks C. Pillion for contributing to the post!

2 Likes

A few tidbits on the instancing test reported figures:

  • Each mesh is a cube represented by two triangles on each face, for a total of 12 triangles in the mesh (120 million triangles in the most straining test input).
  • For instanced meshes, the “Creation” time has two time values. The first is the time it initially took to author the first mesh object. The second time is the time it took to instance (N-1) more of the same mesh, transformed in world space by a small amount.
  • For Individual Meshes, the “Creation” time is the time it took to create N identical mesh objects.
  • The prepareStream column reports the time it takes for PrepareStream to run. This function is what optimizes and prepares the SC model file to render quickly and efficiently in the Web Viewer.
2 Likes

Great post!

An additional question that might arise is how instancing is handled when using the “loadSubtreeFrom…” functionality, in particular when the same model is loaded multiple times. In the case of the streaming server if you load a model with the same name again (e.g. to place it in multiple locations within your scene) all the meshes within that model are indeed instanced from the first occurrence of that model and are not streamed again. This is also the case for all referenced stream cache models if you use the loadSubtreeFromXML functions.

However, for scs loading (without the streaming server) the behavior is a bit different. Only when using the loadSubtreeFromScsXML… functions, the referenced models in the XML will be instanced if they share the same filename. If you load a model with the regular LoadSubtreeFromScsFile/Buffer function the meshes in the model will be duplicated, even if it has the same name as a previously loaded model.

1 Like