Viewer: add clash visibility mode (ifcurl-982)

viewer.html: add 'clash' option to the visibility <select> dropdown.

viewer.js: add clash branch in applySelector for both the simple
type-selector path and the complex server-side GUID path. Selected
elements are coloured 0xdc3232 (red, matching render.py's _CLASH_COLOR);
non-selected elements remain at their normal material colours, consistent
with highlight mode behaviour.

https://claude.ai/code/session_01NBsytCd6L7UQPiKbcLn4kn
This commit is contained in:
Claude 2026-05-09 09:03:11 +00:00
parent 277c74e3d3
commit 43a76ab642
No known key found for this signature in database
3 changed files with 7 additions and 2 deletions

View file

@ -49,7 +49,7 @@
{"_type":"issue","id":"ifcurl-ei8","title":"Fix syncCameraUrl: convert WebGL coords to IFC world space","description":"syncCameraUrl in viewer.py currently records camera.position/direction/up directly from Three.js, which are in WebGL/Three.js coordinate space (Y-up, different scale/orientation than IFC). The ifc:// URL spec expects IFC world coordinates (Z-up, matching BCF viewpoint conventions). Need to find the IFC→Three.js transform that @thatopen/components applies when loading a model, then apply its inverse in syncCameraUrl before serialising the camera params. Repos cloned for reference: ~/src/engine_components and ~/src/engine_fragment.","status":"closed","priority":2,"issue_type":"bug","owner":"bruno@postle.net","created_at":"2026-04-23T05:53:06Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:14:36Z","closed_at":"2026-04-23T06:14:36Z","close_reason":"Split into atomic tasks: ifcurl-ldk, ifcurl-j2s, ifcurl-cmd","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-ei8","title":"Fix syncCameraUrl: convert WebGL coords to IFC world space","description":"syncCameraUrl in viewer.py currently records camera.position/direction/up directly from Three.js, which are in WebGL/Three.js coordinate space (Y-up, different scale/orientation than IFC). The ifc:// URL spec expects IFC world coordinates (Z-up, matching BCF viewpoint conventions). Need to find the IFC→Three.js transform that @thatopen/components applies when loading a model, then apply its inverse in syncCameraUrl before serialising the camera params. Repos cloned for reference: ~/src/engine_components and ~/src/engine_fragment.","status":"closed","priority":2,"issue_type":"bug","owner":"bruno@postle.net","created_at":"2026-04-23T05:53:06Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:14:36Z","closed_at":"2026-04-23T06:14:36Z","close_reason":"Split into atomic tasks: ifcurl-ldk, ifcurl-j2s, ifcurl-cmd","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"ifcurl-i1s","title":"Test Phase 3b web viewer end-to-end","description":"After deploying the footer template (ifcurl-ach), test the full flow: open an .ifc file in Forgejo at localhost:3000, click 'View in 3D', verify the viewer loads the model. CDN versions (@thatopen/components 2.4.0, three 0.160.0, web-ifc 0.0.66) may need adjustment if the API has changed.","status":"closed","priority":2,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-23T05:48:01Z","created_by":"Bruno Postle","updated_at":"2026-04-23T20:05:04Z","started_at":"2026-04-23T19:54:56Z","closed_at":"2026-04-23T20:05:04Z","close_reason":"Closed","dependencies":[{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-49o","type":"blocks","created_at":"2026-04-23T07:14:12Z","created_by":"Claude","metadata":"{}"},{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-4yu","type":"blocks","created_at":"2026-04-23T07:14:11Z","created_by":"Claude","metadata":"{}"},{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-ach","type":"blocks","created_at":"2026-04-23T06:48:10Z","created_by":"Claude","metadata":"{}"},{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-ahd","type":"blocks","created_at":"2026-04-23T07:02:54Z","created_by":"Claude","metadata":"{}"}],"dependency_count":4,"dependent_count":1,"comment_count":0} {"_type":"issue","id":"ifcurl-i1s","title":"Test Phase 3b web viewer end-to-end","description":"After deploying the footer template (ifcurl-ach), test the full flow: open an .ifc file in Forgejo at localhost:3000, click 'View in 3D', verify the viewer loads the model. CDN versions (@thatopen/components 2.4.0, three 0.160.0, web-ifc 0.0.66) may need adjustment if the API has changed.","status":"closed","priority":2,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-23T05:48:01Z","created_by":"Bruno Postle","updated_at":"2026-04-23T20:05:04Z","started_at":"2026-04-23T19:54:56Z","closed_at":"2026-04-23T20:05:04Z","close_reason":"Closed","dependencies":[{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-49o","type":"blocks","created_at":"2026-04-23T07:14:12Z","created_by":"Claude","metadata":"{}"},{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-4yu","type":"blocks","created_at":"2026-04-23T07:14:11Z","created_by":"Claude","metadata":"{}"},{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-ach","type":"blocks","created_at":"2026-04-23T06:48:10Z","created_by":"Claude","metadata":"{}"},{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-ahd","type":"blocks","created_at":"2026-04-23T07:02:54Z","created_by":"Claude","metadata":"{}"}],"dependency_count":4,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"ifcurl-ach","title":"Deploy Phase 3b footer template to Forgejo","description":"The footer.tmpl file that injects a 'View in 3D' button on .ifc file pages has been written but not yet deployed. Deploy it to /etc/forgejo/templates/custom/footer.tmpl and verify the button appears when viewing an .ifc file on localhost:3000.","status":"closed","priority":2,"issue_type":"task","owner":"bruno@postle.net","created_at":"2026-04-23T05:47:53Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:14:35Z","closed_at":"2026-04-23T06:14:35Z","close_reason":"Split into atomic tasks: ifcurl-ohq, ifcurl-49o","dependencies":[{"issue_id":"ifcurl-ach","depends_on_id":"ifcurl-ahd","type":"blocks","created_at":"2026-04-23T07:02:40Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0} {"_type":"issue","id":"ifcurl-ach","title":"Deploy Phase 3b footer template to Forgejo","description":"The footer.tmpl file that injects a 'View in 3D' button on .ifc file pages has been written but not yet deployed. Deploy it to /etc/forgejo/templates/custom/footer.tmpl and verify the button appears when viewing an .ifc file on localhost:3000.","status":"closed","priority":2,"issue_type":"task","owner":"bruno@postle.net","created_at":"2026-04-23T05:47:53Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:14:35Z","closed_at":"2026-04-23T06:14:35Z","close_reason":"Split into atomic tasks: ifcurl-ohq, ifcurl-49o","dependencies":[{"issue_id":"ifcurl-ach","depends_on_id":"ifcurl-ahd","type":"blocks","created_at":"2026-04-23T07:02:40Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"ifcurl-982","title":"Viewer: implement clash visibility mode display","description":"Implement visibility=clash in the Bonsai viewer. Selected elements (GUIDs pre-identified as clashing, typically sourced from the server /clash endpoint) should be displayed with a solid red clash-indicator style (full opacity, distinct red material) while all other elements render normally — equivalent to highlight mode but using red rather than orange for selected elements. The viewer should be able to construct ifc://...\u0026visibility=clash URLs from a set of GUID pairs returned by /clash. When exporting to BCF, clash is treated as highlight (BCF has no equivalent distinction).","status":"open","priority":3,"issue_type":"feature","owner":"noreply@anthropic.com","created_at":"2026-05-09T08:08:45Z","created_by":"Claude","updated_at":"2026-05-09T08:28:44Z","dependencies":[{"issue_id":"ifcurl-982","depends_on_id":"ifcurl-k0x","type":"blocks","created_at":"2026-05-09T08:28:57Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-982","title":"Viewer: implement clash visibility mode display","description":"Implement visibility=clash in the Bonsai viewer. Selected elements (GUIDs pre-identified as clashing, typically sourced from the server /clash endpoint) should be displayed with a solid red clash-indicator style (full opacity, distinct red material) while all other elements render normally — equivalent to highlight mode but using red rather than orange for selected elements. The viewer should be able to construct ifc://...\u0026visibility=clash URLs from a set of GUID pairs returned by /clash. When exporting to BCF, clash is treated as highlight (BCF has no equivalent distinction).","status":"in_progress","priority":3,"issue_type":"feature","assignee":"Claude","owner":"noreply@anthropic.com","created_at":"2026-05-09T08:08:45Z","created_by":"Claude","updated_at":"2026-05-09T09:02:27Z","started_at":"2026-05-09T09:02:27Z","dependencies":[{"issue_id":"ifcurl-982","depends_on_id":"ifcurl-k0x","type":"blocks","created_at":"2026-05-09T08:28:57Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"ifcurl-4u3","title":"Viewer: query creation and editing UI","description":"Add UI controls in the Bonsai viewer for composing and modifying queries. Users need: a text field for the selector expression, a text field for the query path (dot-notation, e.g. Pset_WallCommon.FireRating), and an Apply button that updates the active ifc:// URL and triggers a re-query. The UI should also provide a copy-URL button. Changing the selector or query fields should update the URL in the address bar and the displayed 3D view/table without requiring a full page reload.","status":"open","priority":3,"issue_type":"feature","owner":"noreply@anthropic.com","created_at":"2026-05-09T08:08:42Z","created_by":"Claude","updated_at":"2026-05-09T08:08:42Z","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-4u3","title":"Viewer: query creation and editing UI","description":"Add UI controls in the Bonsai viewer for composing and modifying queries. Users need: a text field for the selector expression, a text field for the query path (dot-notation, e.g. Pset_WallCommon.FireRating), and an Apply button that updates the active ifc:// URL and triggers a re-query. The UI should also provide a copy-URL button. Changing the selector or query fields should update the URL in the address bar and the displayed 3D view/table without requiring a full page reload.","status":"open","priority":3,"issue_type":"feature","owner":"noreply@anthropic.com","created_at":"2026-05-09T08:08:42Z","created_by":"Claude","updated_at":"2026-05-09T08:08:42Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"ifcurl-2iv","title":"Viewer: display query results in a table panel","description":"When an ifc:// URL contains a query parameter, the viewer (Bonsai) should call the preview service /query endpoint and display the returned {GlobalId: value} mapping in a table panel alongside the 3D view. The table should have columns for element GlobalId (or Name if resolvable from the model) and the queried value. When both query and camera/visibility parameters are present, show the 3D view and property table together. The table should update whenever the URL's selector or query changes.","status":"open","priority":3,"issue_type":"feature","owner":"noreply@anthropic.com","created_at":"2026-05-09T08:08:39Z","created_by":"Claude","updated_at":"2026-05-09T08:08:39Z","dependencies":[{"issue_id":"ifcurl-2iv","depends_on_id":"ifcurl-8rf","type":"blocks","created_at":"2026-05-09T08:08:49Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-2iv","title":"Viewer: display query results in a table panel","description":"When an ifc:// URL contains a query parameter, the viewer (Bonsai) should call the preview service /query endpoint and display the returned {GlobalId: value} mapping in a table panel alongside the 3D view. The table should have columns for element GlobalId (or Name if resolvable from the model) and the queried value. When both query and camera/visibility parameters are present, show the 3D view and property table together. The table should update whenever the URL's selector or query changes.","status":"open","priority":3,"issue_type":"feature","owner":"noreply@anthropic.com","created_at":"2026-05-09T08:08:39Z","created_by":"Claude","updated_at":"2026-05-09T08:08:39Z","dependencies":[{"issue_id":"ifcurl-2iv","depends_on_id":"ifcurl-8rf","type":"blocks","created_at":"2026-05-09T08:08:49Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"ifcurl-xfi","title":"Implement OpenCDE document picker (select-documents flow)","description":"The OpenCDE Documents API defines a browser-redirect flow for document discovery. Implement POST /documents/1.0/select-documents which returns a select_documents_url. That URL serves a small HTML page: owner/repo selector then file-tree browser. When user selects an IFC file, generate the document_id and redirect to the callback_url with document_ids[] params.","status":"open","priority":3,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-29T20:38:16Z","created_by":"Bruno Postle","updated_at":"2026-04-29T20:38:16Z","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-xfi","title":"Implement OpenCDE document picker (select-documents flow)","description":"The OpenCDE Documents API defines a browser-redirect flow for document discovery. Implement POST /documents/1.0/select-documents which returns a select_documents_url. That URL serves a small HTML page: owner/repo selector then file-tree browser. When user selects an IFC file, generate the document_id and redirect to the callback_url with document_ids[] params.","status":"open","priority":3,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-29T20:38:16Z","created_by":"Bruno Postle","updated_at":"2026-04-29T20:38:16Z","dependency_count":0,"dependent_count":0,"comment_count":0}
@ -118,5 +118,5 @@
{"_type":"issue","id":"ifcurl-vam","title":"Phase 6: Bonsai offer ifc:// URL when saving linked model reference","description":"When saving an IFCDOCUMENTREFERENCE in Bonsai, offer the option to write the location as an ifc:// URL rather than a relative path. When a relative path would traverse above the repository root, prompt the user to convert it to an ifc:// URL. Requires Phase 4 federation (ifcurl-bqt).","status":"deferred","priority":4,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-23T05:49:16Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:15:13Z","defer_until":"2026-12-01T00:00:00Z","dependencies":[{"issue_id":"ifcurl-vam","depends_on_id":"ifcurl-bqt","type":"blocks","created_at":"2026-04-23T06:49:23Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-vam","title":"Phase 6: Bonsai offer ifc:// URL when saving linked model reference","description":"When saving an IFCDOCUMENTREFERENCE in Bonsai, offer the option to write the location as an ifc:// URL rather than a relative path. When a relative path would traverse above the repository root, prompt the user to convert it to an ifc:// URL. Requires Phase 4 federation (ifcurl-bqt).","status":"deferred","priority":4,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-23T05:49:16Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:15:13Z","defer_until":"2026-12-01T00:00:00Z","dependencies":[{"issue_id":"ifcurl-vam","depends_on_id":"ifcurl-bqt","type":"blocks","created_at":"2026-04-23T06:49:23Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"ifcurl-9k2","title":"Phase 5: IFC Viewer integration (equivalent of Phase 4)","description":"Add ifc:// OS protocol handler and 'Copy view URL' button to the IFC Viewer desktop application, equivalent to the Bonsai Phase 4 integration. Depends on Phase 4 being complete as a reference implementation.","status":"deferred","priority":4,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-23T05:49:08Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:15:12Z","defer_until":"2026-12-01T00:00:00Z","dependencies":[{"issue_id":"ifcurl-9k2","depends_on_id":"ifcurl-0oj","type":"blocks","created_at":"2026-04-23T06:49:14Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-9k2","title":"Phase 5: IFC Viewer integration (equivalent of Phase 4)","description":"Add ifc:// OS protocol handler and 'Copy view URL' button to the IFC Viewer desktop application, equivalent to the Bonsai Phase 4 integration. Depends on Phase 4 being complete as a reference implementation.","status":"deferred","priority":4,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-23T05:49:08Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:15:12Z","defer_until":"2026-12-01T00:00:00Z","dependencies":[{"issue_id":"ifcurl-9k2","depends_on_id":"ifcurl-0oj","type":"blocks","created_at":"2026-04-23T06:49:14Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"ifcurl-prc","title":"Phase 3c: 3D diff view for IFC PR merges","description":"After a PR merge completes, surface a 'View merge in 3D' button using the Phase 3b viewer. Use @thatopen/components highlighter to colour added, removed, and modified elements differently, driven by comparing the merged IFC against either parent. Requires Phase 3b viewer (ifcurl-i1s) to be working.","status":"closed","priority":4,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-23T05:48:30Z","created_by":"Bruno Postle","updated_at":"2026-04-26T17:15:07Z","closed_at":"2026-04-26T17:15:07Z","close_reason":"Rendered diff already implemented in footer.tmpl Case 3; static PNG via /render_diff endpoint, not interactive 3D","dependencies":[{"issue_id":"ifcurl-prc","depends_on_id":"ifcurl-i1s","type":"blocks","created_at":"2026-04-23T06:48:36Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-prc","title":"Phase 3c: 3D diff view for IFC PR merges","description":"After a PR merge completes, surface a 'View merge in 3D' button using the Phase 3b viewer. Use @thatopen/components highlighter to colour added, removed, and modified elements differently, driven by comparing the merged IFC against either parent. Requires Phase 3b viewer (ifcurl-i1s) to be working.","status":"closed","priority":4,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-23T05:48:30Z","created_by":"Bruno Postle","updated_at":"2026-04-26T17:15:07Z","closed_at":"2026-04-26T17:15:07Z","close_reason":"Rendered diff already implemented in footer.tmpl Case 3; static PNG via /render_diff endpoint, not interactive 3D","dependencies":[{"issue_id":"ifcurl-prc","depends_on_id":"ifcurl-i1s","type":"blocks","created_at":"2026-04-23T06:48:36Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"_type":"memory","key":"torawurl-in-viewer-url-js-must-support-github","value":"toRawUrl in viewer-url.js must support GitHub, GitLab, Forgejo/Gitea (codeberg.org, self-hosted), and localhost. Tests in forgejo/tests/viewer-url.test.js cover all four. The localhost check (http vs https) is based on host.startsWith('localhost'), so subdomain.localhost gets https."}
{"_type":"memory","key":"forgejo-build-and-deploy-procedure-go-build-c","value":"Forgejo build and deploy procedure: go build -C /home/bruno/src/forgejo -tags 'sqlite sqlite_unlock_notify' -ldflags \"-X 'forgejo.org/modules/setting.StaticRootPath=/usr/share/forgejo'\" -o /home/bruno/src/forgejo/forgejo . — then sudo cp forgejo /usr/bin/forgejo. StaticRootPath=/usr/share/forgejo. CustomPath=/var/lib/forgejo/custom. Custom templates go to /var/lib/forgejo/custom/templates/custom/ (e.g. footer.tmpl → /var/lib/forgejo/custom/templates/custom/footer.tmpl). Custom static files go to /var/lib/forgejo/custom/public/assets/ (NOT /etc/forgejo/public/assets/) and are served at /assets/*."} {"_type":"memory","key":"forgejo-build-and-deploy-procedure-go-build-c","value":"Forgejo build and deploy procedure: go build -C /home/bruno/src/forgejo -tags 'sqlite sqlite_unlock_notify' -ldflags \"-X 'forgejo.org/modules/setting.StaticRootPath=/usr/share/forgejo'\" -o /home/bruno/src/forgejo/forgejo . — then sudo cp forgejo /usr/bin/forgejo. StaticRootPath=/usr/share/forgejo. CustomPath=/var/lib/forgejo/custom. Custom templates go to /var/lib/forgejo/custom/templates/custom/ (e.g. footer.tmpl → /var/lib/forgejo/custom/templates/custom/footer.tmpl). Custom static files go to /var/lib/forgejo/custom/public/assets/ (NOT /etc/forgejo/public/assets/) and are served at /assets/*."}
{"_type":"memory","key":"torawurl-in-viewer-url-js-must-support-github","value":"toRawUrl in viewer-url.js must support GitHub, GitLab, Forgejo/Gitea (codeberg.org, self-hosted), and localhost. Tests in forgejo/tests/viewer-url.test.js cover all four. The localhost check (http vs https) is based on host.startsWith('localhost'), so subdomain.localhost gets https."}

View file

@ -191,6 +191,7 @@
<option value="highlight">highlight</option> <option value="highlight">highlight</option>
<option value="ghost">ghost</option> <option value="ghost">ghost</option>
<option value="isolate">isolate</option> <option value="isolate">isolate</option>
<option value="clash">clash</option>
</select> </select>
</div> </div>
</div> </div>

View file

@ -501,6 +501,8 @@ async function applySelector(components, model, selectorStr, srcUrl, visibility
new THREE.Color(0x888888), 0.15); new THREE.Color(0x888888), 0.15);
} else if (visibility === "isolate") { } else if (visibility === "isolate") {
await hider.isolate(matching); await hider.isolate(matching);
} else if (visibility === "clash") {
await applyFragmentStyle(components, matching, new THREE.Color(0xdc3232), 1);
} else { } else {
// highlight (default): colour-overlay the selected elements, all others visible. // highlight (default): colour-overlay the selected elements, all others visible.
await applyFragmentStyle(components, matching, new THREE.Color(0xff8800), 1); await applyFragmentStyle(components, matching, new THREE.Color(0xff8800), 1);
@ -536,6 +538,8 @@ async function applySelector(components, model, selectorStr, srcUrl, visibility
new THREE.Color(0x888888), 0.15); new THREE.Color(0x888888), 0.15);
} else if (visibility === "isolate") { } else if (visibility === "isolate") {
await hider.isolate(matchingMap); await hider.isolate(matchingMap);
} else if (visibility === "clash") {
await applyFragmentStyle(components, matchingMap, new THREE.Color(0xdc3232), 1);
} else { } else {
await applyFragmentStyle(components, matchingMap, new THREE.Color(0xff8800), 1); await applyFragmentStyle(components, matchingMap, new THREE.Color(0xff8800), 1);
} }