# Inquiry on Multi-Model Loading with SC Server Setup

**URL:** <https://forum.techsoft3d.com/t/inquiry-on-multi-model-loading-with-sc-server-setup/4673>\
**Category:** HOOPS Visualize Web\
**Tags:** code, knowledge-base, how-to\
**Created:** [May 19, 2025, 2:06pm UTC](https://forum.techsoft3d.com/t/inquiry-on-multi-model-loading-with-sc-server-setup/4673 "2025-05-19T14:06:33Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![cad-developer](https://avatars.discourse-cdn.com/v4/letter/c/f0a364/32.png) [@cad-developer](https://forum.techsoft3d.com/u/cad-developer)\
**Post date:** [May 19, 2025, 2:06pm UTC](https://forum.techsoft3d.com/t/inquiry-on-multi-model-loading-with-sc-server-setup/4673/1 "2025-05-19T14:06:33Z")

</div>

Hello TechSoft3D Team,

I have a question regarding the _Model Loading and Aggregation_ section in your documentation.

> **[Model Loading and Aggregation — HOOPS Communicator Documentation](https://docs.techsoft3d.com/communicator/latest/tutorials/basic-app/model-loading.html)**

In the example provided for multi-model loading, the combined models are loaded from local files. However, in our setup, we are using the SC Server and client architecture, where models are loaded via a WebSocket connection.

Currently, we are able to load only one model at a time. Could you please guide us on how to implement multi-model loading using the SC Server setup?

Looking forward to your guidance.

---

<div class="post-metadata">

**Author:** ![tino](https://avatars.discourse-cdn.com/v4/letter/t/9dc877/32.png) [@tino](https://forum.techsoft3d.com/u/tino)\
**Post date:** [May 19, 2025, 4:42pm UTC](https://forum.techsoft3d.com/t/inquiry-on-multi-model-loading-with-sc-server-setup/4673/2 "2025-05-19T16:42:22Z")

</div>

It’s unclear what you mean by “local files.” In the file _HOOPS\_Communicator\_2025.3.0\quick\_start\server\_config.js_, there are two parameters which control where files are loaded from. These parameters, with their default values, are:

```auto
modelDirs: [
        "./quick_start/converted_models/user/sc_models",
        "./quick_start/converted_models/authoring_samples_data",
        "./quick_start/converted_models/standard/sc_models",
    ],

```

and:

```auto
fileServerStaticDirs: [
        "./web_viewer",
        "./web_viewer/examples",
        "./web_viewer/demo-app",
        "./quick_start/converted_models/user/scs_models",
        "./quick_start/converted_models/standard",
        "./quick_start/converted_models/standard/scs_models",
        "./quick_start"
    ],

```

Worth noting is that `modelDirs` is for Stream Cache files (SC/SCZ). And `fileServerStaticDirs` is for SCS (the file-based variant of SC/SCZ). When you aggregate models by calling either `loadSubtree*` or `loadSubtreeFromScs*`, the models are being loaded from the directories referenced above.

Based on your description of only being able to load models one at a time, this sounds like the model when the Web Viewer (hwv) object is first intitialized/started and controlled by the parameter [WebViewerConfig.model](https://docs.techsoft3d.com/communicator/latest/api_ref/viewing/interfaces/WebViewerConfig.html#WebViewerConfig.model).

---

<div class="post-metadata">

**Author:** ![cad-developer](https://avatars.discourse-cdn.com/v4/letter/c/f0a364/32.png) [@cad-developer](https://forum.techsoft3d.com/u/cad-developer)\
**Post date:** [May 21, 2025, 5:53am UTC](https://forum.techsoft3d.com/t/inquiry-on-multi-model-loading-with-sc-server-setup/4673/3 "2025-05-21T05:53:12Z")

</div>

Client Code -

```
  const viewer = new WebViewer({
    containerId: divId,
    endpointUri,
    model: model?.modelName,
    rendererType: renererType,
  });

```

Server Code -

export function spawnViewer(project: string, model: string, res: any): void {  
const modelDir = `${modelDirectory}/${project}`;  
const spawnId = uuidv4();  
const wsPort = allocateWsPort();  
const args = [  
“–id”,  
spawnId,  
“–sc-port”,  
wsPort.toString(),  
“–liveliness-endpoint”,  
`http://${host}:${port}/liveliness`,  
“–model-search-directories”,  
modelDir,  
“–license”,  
license,  
“–initial-use-duration”,  
“0”,  
];

console.log(host, port, wsPort, modelDir, license);

const options = { env: { DISPLAY: “:0” } };  
let process: ChildProcess;

if (renderType === “ssr”) {  
args.push(“–ssr”, “true”);  
}

try {  
process = spawn(executablePath, args, options);  
} catch (err) {  
const message = err instanceof Error ? err.message : String(err);  
console.error(`[ERROR] Failed to spawn viewer: ${message}`);  
res.status(500).json({ error: “Failed to start viewer” });  
return;  
}

const spawnInfo: SpawnInfo = {  
spawnId,  
wsPort,  
rendererType: renderType === “csr” ? “csr” : “ssr”,  
response: res,  
startTime: new Date(),  
process,  
modelDir,  
modelName: model,  
};

spawnArray.push(spawnInfo);  
setupProcessListeners(spawnInfo);  
}

// Handles liveliness updates (ready, disconnect, ping) from a viewer process.  
export function handleLiveliness(  
spawnId: string,  
updateType: string,  
res: any,  
wsHost: string,  
): void {  
const spawnInfo = spawnArray.find((e) =\> e.spawnId === spawnId);  
if (!spawnInfo) {  
res.status(404).json({ error: `No active spawn with ID ${spawnId}` });  
return;  
}

switch (updateType) {  
case “ready”:  
console.log(“ready”);  
spawnInfo.response?.status(201).json({  
endpoint: `ws://${wsHost}:${spawnInfo.wsPort}`,  
wsPort: spawnInfo.wsPort,  
rendererType: spawnInfo.rendererType,  
spawnId,  
modelName: spawnInfo.modelName,  
});  
spawnInfo.response = null;  
break;  
case “disconnect”:  
console.log(“disconnect”);  
cleanupSpawn(spawnId, spawnInfo.wsPort);  
res.status(200).end();  
break;  
case “ping”:  
console.log(“ping”);  
res.status(200).json({ message: `Ping received for ${spawnId}` });  
break;  
default:  
console.log(“default”);  
cleanupSpawn(spawnId, spawnInfo.wsPort);  
res.status(400).json({ error: “Invalid liveliness value” });  
}  
}

This is the current implementation of the Client Viewer WebSocket connection, which is set up to load only a single model at a time. How can I modify this to support **multi-model loading** , as demonstrated in the **Model Loading and Aggregation** section of your example code?

---

<div class="post-metadata">

**Author:** ![tino](https://avatars.discourse-cdn.com/v4/letter/t/9dc877/32.png) [@tino](https://forum.techsoft3d.com/u/tino)\
**Post date:** [May 21, 2025, 8:21am UTC](https://forum.techsoft3d.com/t/inquiry-on-multi-model-loading-with-sc-server-setup/4673/4 "2025-05-21T08:21:24Z")

</div>

Quite crucial to aggregating models are calls to `loadSubtreeFrom*` and its different variants. In your reference to our docs, this is covered in the section [Loading two models](https://docs.techsoft3d.com/communicator/latest/tutorials/basic-app/model-loading.html#loading-two-models).

There is also an example of model assembly in the [quickstart](https://docs.techsoft3d.com/communicator/latest/overview/quickstart.html#quickstart) module of the Communicator package. To view this example, please do the following:

- Launch the server by double-clicking _start\_server.bat_ in the directory _HOOPS\_Communicator\_2025.3.0\quick\_start_
- View the example in the Web Viewer via this URL:  
[http://localhost:11180/assembly\_building.html?viewer=csr](http://localhost:11180/assembly_building.html?viewer=csr)

If you want to load models after the Web Viewer object starts, you can make the necessary calls to `loadSubtreeFrom*` from the [modelStructureReady](https://docs.techsoft3d.com/communicator/latest/api_ref/viewing/interfaces/CallbackMap.html#CallbackMap.modelStructureReady) callback.
