@mcp-b/aec-components 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MCP-B contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,20 @@
1
+ # @mcp-b/aec-components
2
+
3
+ Lit web components for AEC/BIM viewing. Currently `<sigvelo-ifc-viewer>`, an IFC
4
+ model viewer built on `@thatopen/components` and three.js.
5
+
6
+ `three`, `web-ifc`, `@thatopen/components`, and `@thatopen/fragments` are peer
7
+ dependencies — install them alongside this package.
8
+
9
+ ## Storybook fixture
10
+
11
+ The stories render a 4.5KB IFC4 conformance model from `fixtures/column.ifc`. The shared
12
+ Storybook in `packages/web-components` mounts that directory at the site root,
13
+ so a story loads it as `/column.ifc`.
14
+
15
+ The fixture comes from buildingSMART's Sample-Test-Files repository and is
16
+ licensed under CC BY 4.0; attribution and the immutable upstream source are in
17
+ `fixtures/README.md`. Larger IFC files remain gitignored.
18
+
19
+ To use a different model, put it in `fixtures/` and update the `src` attribute
20
+ in `src/components/ifc-viewer/ifc-viewer.stories.ts`.
@@ -0,0 +1,73 @@
1
+ import { CSSResultGroup, PropertyValues } from "lit";
2
+ import { SigveloElement } from "@mcp-b/wc-support/base/sigvelo-element";
3
+
4
+ //#region src/components/ifc-viewer/ifc-viewer.d.ts
5
+ /**
6
+ * An IFC 3D model viewer powered by ThatOpen engine. Loads and displays
7
+ * Industry Foundation Classes (IFC) building models in an interactive
8
+ * 3D viewport with orbit camera controls.
9
+ *
10
+ * @tag sigvelo-ifc-viewer
11
+ * @summary IFC building model viewer with 3D navigation.
12
+ * @status experimental
13
+ * @since 0.0.0
14
+ *
15
+ * @event sigvelo-ifc-load - Fired when an IFC model finishes loading.
16
+ * @event sigvelo-ifc-error - Fired when IFC loading fails.
17
+ * @event sigvelo-ifc-progress - Fired during IFC loading with progress updates.
18
+ *
19
+ * @csspart container - The 3D viewport container element.
20
+ *
21
+ * @example Default viewer
22
+ * ```html
23
+ * <sigvelo-ifc-viewer
24
+ * src="/model.ifc"
25
+ * style="height: 500px;"
26
+ * ></sigvelo-ifc-viewer>
27
+ * ```
28
+ *
29
+ * @example Without grid
30
+ * ```html
31
+ * <sigvelo-ifc-viewer
32
+ * src="/model.ifc"
33
+ * .grid=${false}
34
+ * style="height: 500px;"
35
+ * ></sigvelo-ifc-viewer>
36
+ * ```
37
+ */
38
+ declare class SigveloIfcViewer extends SigveloElement {
39
+ static styles: CSSResultGroup;
40
+ /** URL of the IFC file to load. */
41
+ src: string;
42
+ /** Background color of the 3D scene. */
43
+ backgroundColor: string;
44
+ /** Whether orbit camera controls are enabled. */
45
+ cameraControls: boolean;
46
+ /** Whether to display a ground grid. */
47
+ grid: boolean;
48
+ /** Path to the directory containing web-ifc WASM files. Consumers must host the WASM files from the web-ifc package. */
49
+ wasmPath: string;
50
+ /** URL to the @thatopen/fragments worker script. Consumers must host the worker from @thatopen/fragments/dist/Worker/worker.mjs. */
51
+ workerUrl: string;
52
+ private _components;
53
+ private _world;
54
+ private _resizeObserver;
55
+ firstUpdated(): Promise<void>;
56
+ updated(changed: PropertyValues<this>): Promise<void>;
57
+ disconnectedCallback(): void;
58
+ /** Load an IFC model from a URL. */
59
+ loadUrl(url: string): Promise<void>;
60
+ /** Load an IFC model from a File object. */
61
+ loadFile(file: File): Promise<void>;
62
+ private _initViewer;
63
+ private _loadSrc;
64
+ private _updateBackgroundColor;
65
+ render(): import("lit-html").TemplateResult<1>;
66
+ }
67
+ declare global {
68
+ interface HTMLElementTagNameMap {
69
+ "sigvelo-ifc-viewer": SigveloIfcViewer;
70
+ }
71
+ }
72
+ //#endregion
73
+ export { SigveloIfcViewer };
@@ -0,0 +1,36 @@
1
+ //#region src/components/ifc-viewer/ifc-viewer.events.d.ts
2
+ /**
3
+ * Fired when an IFC model finishes loading.
4
+ *
5
+ * @event sigvelo-ifc-load
6
+ */
7
+ declare class SigveloIfcLoadEvent extends Event {
8
+ constructor();
9
+ }
10
+ /**
11
+ * Fired when IFC loading fails.
12
+ *
13
+ * @event sigvelo-ifc-error
14
+ */
15
+ declare class SigveloIfcErrorEvent extends Event {
16
+ readonly error: Error;
17
+ constructor(error: Error);
18
+ }
19
+ /**
20
+ * Fired during IFC loading with progress updates.
21
+ *
22
+ * @event sigvelo-ifc-progress
23
+ */
24
+ declare class SigveloIfcProgressEvent extends Event {
25
+ readonly progress: number;
26
+ constructor(progress: number);
27
+ }
28
+ declare global {
29
+ interface GlobalEventHandlersEventMap {
30
+ "sigvelo-ifc-load": SigveloIfcLoadEvent;
31
+ "sigvelo-ifc-error": SigveloIfcErrorEvent;
32
+ "sigvelo-ifc-progress": SigveloIfcProgressEvent;
33
+ }
34
+ }
35
+ //#endregion
36
+ export { SigveloIfcErrorEvent, SigveloIfcLoadEvent, SigveloIfcProgressEvent };
@@ -0,0 +1,47 @@
1
+ //#region src/components/ifc-viewer/ifc-viewer.events.ts
2
+ /**
3
+ * Fired when an IFC model finishes loading.
4
+ *
5
+ * @event sigvelo-ifc-load
6
+ */
7
+ var SigveloIfcLoadEvent = class extends Event {
8
+ constructor() {
9
+ super("sigvelo-ifc-load", {
10
+ bubbles: true,
11
+ cancelable: false,
12
+ composed: true
13
+ });
14
+ }
15
+ };
16
+ /**
17
+ * Fired when IFC loading fails.
18
+ *
19
+ * @event sigvelo-ifc-error
20
+ */
21
+ var SigveloIfcErrorEvent = class extends Event {
22
+ constructor(error) {
23
+ super("sigvelo-ifc-error", {
24
+ bubbles: true,
25
+ cancelable: false,
26
+ composed: true
27
+ });
28
+ this.error = error;
29
+ }
30
+ };
31
+ /**
32
+ * Fired during IFC loading with progress updates.
33
+ *
34
+ * @event sigvelo-ifc-progress
35
+ */
36
+ var SigveloIfcProgressEvent = class extends Event {
37
+ constructor(progress) {
38
+ super("sigvelo-ifc-progress", {
39
+ bubbles: true,
40
+ cancelable: false,
41
+ composed: true
42
+ });
43
+ this.progress = progress;
44
+ }
45
+ };
46
+ //#endregion
47
+ export { SigveloIfcErrorEvent, SigveloIfcLoadEvent, SigveloIfcProgressEvent };
@@ -0,0 +1,3 @@
1
+ import "./ifc-viewer.events.js";
2
+ import { t as SigveloIfcViewer } from "../../ifc-viewer-Co1EAZcX.js";
3
+ export { SigveloIfcViewer };
@@ -0,0 +1,372 @@
1
+ {
2
+ "schemaVersion": "1.0.0",
3
+ "readme": "",
4
+ "modules": [
5
+ {
6
+ "kind": "javascript-module",
7
+ "path": "src/components/ifc-viewer/ifc-viewer.events.ts",
8
+ "declarations": [
9
+ {
10
+ "kind": "class",
11
+ "description": "Fired when IFC loading fails.",
12
+ "name": "SigveloIfcErrorEvent",
13
+ "members": [
14
+ {
15
+ "kind": "field",
16
+ "name": "error",
17
+ "type": {
18
+ "text": "Error"
19
+ },
20
+ "readonly": true,
21
+ "default": "error"
22
+ }
23
+ ],
24
+ "events": [],
25
+ "superclass": {
26
+ "name": "Event",
27
+ "module": "src/components/ifc-viewer/ifc-viewer.events.ts"
28
+ }
29
+ },
30
+ {
31
+ "kind": "class",
32
+ "description": "Fired when an IFC model finishes loading.",
33
+ "name": "SigveloIfcLoadEvent",
34
+ "events": [],
35
+ "superclass": {
36
+ "name": "Event",
37
+ "module": "src/components/ifc-viewer/ifc-viewer.events.ts"
38
+ }
39
+ },
40
+ {
41
+ "kind": "class",
42
+ "description": "Fired during IFC loading with progress updates.",
43
+ "name": "SigveloIfcProgressEvent",
44
+ "members": [
45
+ {
46
+ "kind": "field",
47
+ "name": "progress",
48
+ "type": {
49
+ "text": "number"
50
+ },
51
+ "readonly": true,
52
+ "default": "progress"
53
+ }
54
+ ],
55
+ "events": [],
56
+ "superclass": {
57
+ "name": "Event",
58
+ "module": "src/components/ifc-viewer/ifc-viewer.events.ts"
59
+ }
60
+ }
61
+ ],
62
+ "exports": [
63
+ {
64
+ "kind": "js",
65
+ "name": "SigveloIfcErrorEvent",
66
+ "declaration": {
67
+ "name": "SigveloIfcErrorEvent",
68
+ "module": "src/components/ifc-viewer/ifc-viewer.events.ts"
69
+ }
70
+ },
71
+ {
72
+ "kind": "js",
73
+ "name": "SigveloIfcLoadEvent",
74
+ "declaration": {
75
+ "name": "SigveloIfcLoadEvent",
76
+ "module": "src/components/ifc-viewer/ifc-viewer.events.ts"
77
+ }
78
+ },
79
+ {
80
+ "kind": "js",
81
+ "name": "SigveloIfcProgressEvent",
82
+ "declaration": {
83
+ "name": "SigveloIfcProgressEvent",
84
+ "module": "src/components/ifc-viewer/ifc-viewer.events.ts"
85
+ }
86
+ }
87
+ ]
88
+ },
89
+ {
90
+ "kind": "javascript-module",
91
+ "path": "src/components/ifc-viewer/ifc-viewer.ts",
92
+ "declarations": [
93
+ {
94
+ "kind": "class",
95
+ "description": "An IFC 3D model viewer powered by ThatOpen engine. Loads and displays\nIndustry Foundation Classes (IFC) building models in an interactive\n3D viewport with orbit camera controls.",
96
+ "name": "SigveloIfcViewer",
97
+ "cssParts": [
98
+ {
99
+ "description": "The 3D viewport container element.",
100
+ "name": "container"
101
+ }
102
+ ],
103
+ "members": [
104
+ {
105
+ "kind": "field",
106
+ "name": "_components",
107
+ "type": {
108
+ "text": "OBC.Components | null"
109
+ },
110
+ "privacy": "private",
111
+ "default": "null"
112
+ },
113
+ {
114
+ "kind": "method",
115
+ "name": "_initViewer",
116
+ "privacy": "private"
117
+ },
118
+ {
119
+ "kind": "method",
120
+ "name": "_loadSrc",
121
+ "privacy": "private"
122
+ },
123
+ {
124
+ "kind": "field",
125
+ "name": "_resizeObserver",
126
+ "type": {
127
+ "text": "ResizeObserver | null"
128
+ },
129
+ "privacy": "private",
130
+ "default": "null"
131
+ },
132
+ {
133
+ "kind": "method",
134
+ "name": "_updateBackgroundColor",
135
+ "privacy": "private"
136
+ },
137
+ {
138
+ "kind": "field",
139
+ "name": "_world",
140
+ "type": {
141
+ "text": "OBC.SimpleWorld<OBC.SimpleScene, OBC.SimpleCamera, OBC.SimpleRenderer> | null"
142
+ },
143
+ "privacy": "private",
144
+ "default": "null"
145
+ },
146
+ {
147
+ "kind": "field",
148
+ "name": "backgroundColor",
149
+ "type": {
150
+ "text": "string"
151
+ },
152
+ "default": "\"#202932\"",
153
+ "description": "Background color of the 3D scene.",
154
+ "attribute": "background-color"
155
+ },
156
+ {
157
+ "kind": "field",
158
+ "name": "cameraControls",
159
+ "type": {
160
+ "text": "boolean"
161
+ },
162
+ "default": "true",
163
+ "description": "Whether orbit camera controls are enabled.",
164
+ "attribute": "camera-controls"
165
+ },
166
+ {
167
+ "kind": "field",
168
+ "name": "grid",
169
+ "type": {
170
+ "text": "boolean"
171
+ },
172
+ "default": "true",
173
+ "description": "Whether to display a ground grid.",
174
+ "attribute": "grid"
175
+ },
176
+ {
177
+ "kind": "method",
178
+ "name": "loadFile",
179
+ "privacy": "public",
180
+ "return": {
181
+ "type": {
182
+ "text": "Promise<void>"
183
+ }
184
+ },
185
+ "parameters": [
186
+ {
187
+ "name": "file",
188
+ "type": {
189
+ "text": "File"
190
+ }
191
+ }
192
+ ],
193
+ "description": "Load an IFC model from a File object."
194
+ },
195
+ {
196
+ "kind": "method",
197
+ "name": "loadUrl",
198
+ "privacy": "public",
199
+ "return": {
200
+ "type": {
201
+ "text": "Promise<void>"
202
+ }
203
+ },
204
+ "parameters": [
205
+ {
206
+ "name": "url",
207
+ "type": {
208
+ "text": "string"
209
+ }
210
+ }
211
+ ],
212
+ "description": "Load an IFC model from a URL."
213
+ },
214
+ {
215
+ "kind": "field",
216
+ "name": "src",
217
+ "type": {
218
+ "text": "string"
219
+ },
220
+ "default": "\"\"",
221
+ "description": "URL of the IFC file to load.",
222
+ "attribute": "src"
223
+ },
224
+ {
225
+ "kind": "field",
226
+ "name": "wasmPath",
227
+ "default": "\"/\"",
228
+ "description": "Path to the directory containing web-ifc WASM files. Consumers must host the WASM files from the web-ifc package.",
229
+ "attribute": "wasm-path",
230
+ "type": {
231
+ "text": "string"
232
+ }
233
+ },
234
+ {
235
+ "kind": "field",
236
+ "name": "workerUrl",
237
+ "type": {
238
+ "text": "string"
239
+ },
240
+ "default": "\"/worker.mjs\"",
241
+ "description": "URL to the",
242
+ "attribute": "worker-url"
243
+ }
244
+ ],
245
+ "events": [
246
+ {
247
+ "description": "Fired when IFC loading fails.",
248
+ "name": "sigvelo-ifc-error"
249
+ },
250
+ {
251
+ "description": "Fired when an IFC model finishes loading.",
252
+ "name": "sigvelo-ifc-load"
253
+ },
254
+ {
255
+ "description": "Fired during IFC loading with progress updates.",
256
+ "name": "sigvelo-ifc-progress"
257
+ }
258
+ ],
259
+ "attributes": [
260
+ {
261
+ "name": "background-color",
262
+ "type": {
263
+ "text": "string"
264
+ },
265
+ "default": "\"#202932\"",
266
+ "description": "Background color of the 3D scene.",
267
+ "fieldName": "backgroundColor"
268
+ },
269
+ {
270
+ "name": "camera-controls",
271
+ "type": {
272
+ "text": "boolean"
273
+ },
274
+ "default": "true",
275
+ "description": "Whether orbit camera controls are enabled.",
276
+ "fieldName": "cameraControls"
277
+ },
278
+ {
279
+ "name": "grid",
280
+ "type": {
281
+ "text": "boolean"
282
+ },
283
+ "default": "true",
284
+ "description": "Whether to display a ground grid.",
285
+ "fieldName": "grid"
286
+ },
287
+ {
288
+ "name": "src",
289
+ "type": {
290
+ "text": "string"
291
+ },
292
+ "default": "\"\"",
293
+ "description": "URL of the IFC file to load.",
294
+ "fieldName": "src"
295
+ },
296
+ {
297
+ "name": "wasm-path",
298
+ "default": "DEFAULT_WASM_PATH",
299
+ "description": "Path to the directory containing web-ifc WASM files. Consumers must host the WASM files from the web-ifc package.",
300
+ "fieldName": "wasmPath"
301
+ },
302
+ {
303
+ "name": "worker-url",
304
+ "type": {
305
+ "text": "string"
306
+ },
307
+ "default": "\"/worker.mjs\"",
308
+ "description": "URL to the",
309
+ "fieldName": "workerUrl"
310
+ }
311
+ ],
312
+ "superclass": {
313
+ "name": "SigveloElement",
314
+ "package": "@mcp-b/wc-support/base/sigvelo-element"
315
+ },
316
+ "tagName": "sigvelo-ifc-viewer",
317
+ "customElement": true,
318
+ "summary": "IFC building model viewer with 3D navigation.",
319
+ "modulePath": "src/components/ifc-viewer/ifc-viewer.ts",
320
+ "definitionPath": "src/components/ifc-viewer/ifc-viewer.ts"
321
+ }
322
+ ],
323
+ "exports": [
324
+ {
325
+ "kind": "custom-element-definition",
326
+ "name": "sigvelo-ifc-viewer",
327
+ "declaration": {
328
+ "name": "SigveloIfcViewer",
329
+ "module": "src/components/ifc-viewer/ifc-viewer.ts"
330
+ }
331
+ },
332
+ {
333
+ "kind": "js",
334
+ "name": "SigveloIfcViewer",
335
+ "declaration": {
336
+ "name": "SigveloIfcViewer",
337
+ "module": "src/components/ifc-viewer/ifc-viewer.ts"
338
+ }
339
+ }
340
+ ]
341
+ },
342
+ {
343
+ "kind": "javascript-module",
344
+ "path": "src/index.ts",
345
+ "declarations": [],
346
+ "exports": [
347
+ {
348
+ "kind": "js",
349
+ "name": "*",
350
+ "declaration": {
351
+ "name": "*",
352
+ "module": "src/components/ifc-viewer/ifc-viewer.js"
353
+ }
354
+ },
355
+ {
356
+ "kind": "js",
357
+ "name": "*",
358
+ "declaration": {
359
+ "name": "*",
360
+ "module": "src/components/ifc-viewer/ifc-viewer.events.js"
361
+ }
362
+ }
363
+ ]
364
+ }
365
+ ],
366
+ "package": {
367
+ "name": "@mcp-b/aec-components",
368
+ "description": "AEC (Architecture, Engineering, Construction) web components for Sigvelo, built with Lit.",
369
+ "version": "0.2.0",
370
+ "license": "MIT"
371
+ }
372
+ }
@@ -0,0 +1,167 @@
1
+ import { SigveloIfcErrorEvent, SigveloIfcLoadEvent } from "./components/ifc-viewer/ifc-viewer.events.js";
2
+ import { css, html } from "lit";
3
+ import { customElement, property } from "lit/decorators.js";
4
+ import { SigveloElement } from "@mcp-b/wc-support/base/sigvelo-element";
5
+ import hostStyles from "@mcp-b/wc-support/styles/host.styles";
6
+ import * as OBC from "@thatopen/components";
7
+ import * as THREE from "three";
8
+ //#region src/components/ifc-viewer/ifc-viewer.styles.ts
9
+ var ifc_viewer_styles_default = css`
10
+ :host {
11
+ display: block;
12
+ position: relative;
13
+ min-height: 400px;
14
+ }
15
+
16
+ .viewer-container {
17
+ width: 100%;
18
+ height: 100%;
19
+ position: absolute;
20
+ inset: 0;
21
+ overflow: hidden;
22
+ }
23
+ `;
24
+ //#endregion
25
+ //#region \0@oxc-project+runtime@0.138.0/helpers/esm/decorate.js
26
+ function __decorate(decorators, target, key, desc) {
27
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
28
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
29
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
30
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
31
+ }
32
+ //#endregion
33
+ //#region src/components/ifc-viewer/ifc-viewer.ts
34
+ const DEFAULT_WASM_PATH = "/";
35
+ let SigveloIfcViewer = class SigveloIfcViewer extends SigveloElement {
36
+ constructor(..._args) {
37
+ super(..._args);
38
+ this.src = "";
39
+ this.backgroundColor = "#202932";
40
+ this.cameraControls = true;
41
+ this.grid = true;
42
+ this.wasmPath = DEFAULT_WASM_PATH;
43
+ this.workerUrl = "/worker.mjs";
44
+ this._components = null;
45
+ this._world = null;
46
+ this._resizeObserver = null;
47
+ }
48
+ static {
49
+ this.styles = [hostStyles, ifc_viewer_styles_default];
50
+ }
51
+ async firstUpdated() {
52
+ await this._initViewer();
53
+ }
54
+ async updated(changed) {
55
+ if (changed.has("src") && this._components && changed.get("src") !== void 0) await this._loadSrc();
56
+ if (changed.has("backgroundColor") && this._world) this._updateBackgroundColor();
57
+ }
58
+ disconnectedCallback() {
59
+ super.disconnectedCallback();
60
+ this._resizeObserver?.disconnect();
61
+ this._resizeObserver = null;
62
+ this._components?.dispose();
63
+ this._components = null;
64
+ this._world = null;
65
+ }
66
+ /** Load an IFC model from a URL. */
67
+ async loadUrl(url) {
68
+ if (!this._components) return;
69
+ try {
70
+ const ifcLoader = this._components.get(OBC.IfcLoader);
71
+ await ifcLoader.setup({
72
+ autoSetWasm: false,
73
+ wasm: {
74
+ path: this.wasmPath,
75
+ absolute: true
76
+ }
77
+ });
78
+ const response = await fetch(url);
79
+ if (!response.ok) throw new Error(`Failed to fetch IFC file: ${response.status} ${response.statusText}`);
80
+ const buffer = new Uint8Array(await response.arrayBuffer());
81
+ const name = url.split("/").pop()?.replace(".ifc", "") ?? "model";
82
+ await ifcLoader.load(buffer, true, name);
83
+ this.dispatchEvent(new SigveloIfcLoadEvent());
84
+ } catch (err) {
85
+ const error = err instanceof Error ? err : new Error(String(err));
86
+ this.dispatchEvent(new SigveloIfcErrorEvent(error));
87
+ }
88
+ }
89
+ /** Load an IFC model from a File object. */
90
+ async loadFile(file) {
91
+ if (!this._components) return;
92
+ try {
93
+ const ifcLoader = this._components.get(OBC.IfcLoader);
94
+ await ifcLoader.setup({
95
+ autoSetWasm: false,
96
+ wasm: {
97
+ path: this.wasmPath,
98
+ absolute: true
99
+ }
100
+ });
101
+ const buffer = new Uint8Array(await file.arrayBuffer());
102
+ const name = file.name.replace(".ifc", "");
103
+ await ifcLoader.load(buffer, true, name);
104
+ this.dispatchEvent(new SigveloIfcLoadEvent());
105
+ } catch (err) {
106
+ const error = err instanceof Error ? err : new Error(String(err));
107
+ this.dispatchEvent(new SigveloIfcErrorEvent(error));
108
+ }
109
+ }
110
+ async _initViewer() {
111
+ const container = this.renderRoot.querySelector(".viewer-container");
112
+ if (!container) return;
113
+ this._components = new OBC.Components();
114
+ const worlds = this._components.get(OBC.Worlds);
115
+ this._world = worlds.create();
116
+ this._world.scene = new OBC.SimpleScene(this._components);
117
+ this._world.renderer = new OBC.SimpleRenderer(this._components, container);
118
+ this._world.camera = new OBC.SimpleCamera(this._components);
119
+ this._components.init();
120
+ this._world.scene.setup();
121
+ this._updateBackgroundColor();
122
+ if (this.grid) this._components.get(OBC.Grids).create(this._world);
123
+ const fragments = this._components.get(OBC.FragmentsManager);
124
+ const workerBlob = await (await fetch(this.workerUrl)).blob();
125
+ const workerFile = new File([workerBlob], "worker.mjs", { type: "text/javascript" });
126
+ const workerObjectUrl = URL.createObjectURL(workerFile);
127
+ fragments.init(workerObjectUrl);
128
+ fragments.list.onItemSet.add(({ value: model }) => {
129
+ if (!this._world) return;
130
+ model.useCamera(this._world.camera.three);
131
+ this._world.scene.three.add(model.object);
132
+ fragments.core.update(true);
133
+ });
134
+ this._world.camera.controls.addEventListener("update", () => {
135
+ fragments.core.update();
136
+ });
137
+ await this._world.camera.controls.setLookAt(12, 6, 8, 0, 0, -10);
138
+ this._resizeObserver = new ResizeObserver(() => {
139
+ this._world?.renderer?.resize();
140
+ });
141
+ this._resizeObserver.observe(container);
142
+ if (this.src) await this._loadSrc();
143
+ }
144
+ async _loadSrc() {
145
+ if (this.src) await this.loadUrl(this.src);
146
+ }
147
+ _updateBackgroundColor() {
148
+ if (!this._world?.scene) return;
149
+ const threeScene = this._world.scene.three;
150
+ threeScene.background = new THREE.Color(this.backgroundColor);
151
+ }
152
+ render() {
153
+ return html`<div class="viewer-container" part="container"></div>`;
154
+ }
155
+ };
156
+ __decorate([property()], SigveloIfcViewer.prototype, "src", void 0);
157
+ __decorate([property({ attribute: "background-color" })], SigveloIfcViewer.prototype, "backgroundColor", void 0);
158
+ __decorate([property({
159
+ attribute: "camera-controls",
160
+ type: Boolean
161
+ })], SigveloIfcViewer.prototype, "cameraControls", void 0);
162
+ __decorate([property({ type: Boolean })], SigveloIfcViewer.prototype, "grid", void 0);
163
+ __decorate([property({ attribute: "wasm-path" })], SigveloIfcViewer.prototype, "wasmPath", void 0);
164
+ __decorate([property({ attribute: "worker-url" })], SigveloIfcViewer.prototype, "workerUrl", void 0);
165
+ SigveloIfcViewer = __decorate([customElement("sigvelo-ifc-viewer")], SigveloIfcViewer);
166
+ //#endregion
167
+ export { SigveloIfcViewer as t };
@@ -0,0 +1,3 @@
1
+ import { SigveloIfcViewer } from "./components/ifc-viewer/ifc-viewer.js";
2
+ import { SigveloIfcErrorEvent, SigveloIfcLoadEvent, SigveloIfcProgressEvent } from "./components/ifc-viewer/ifc-viewer.events.js";
3
+ export { SigveloIfcErrorEvent, SigveloIfcLoadEvent, SigveloIfcProgressEvent, SigveloIfcViewer };
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ import { SigveloIfcErrorEvent, SigveloIfcLoadEvent, SigveloIfcProgressEvent } from "./components/ifc-viewer/ifc-viewer.events.js";
2
+ import { t as SigveloIfcViewer } from "./ifc-viewer-Co1EAZcX.js";
3
+ export { SigveloIfcErrorEvent, SigveloIfcLoadEvent, SigveloIfcProgressEvent, SigveloIfcViewer };
package/package.json ADDED
@@ -0,0 +1,81 @@
1
+ {
2
+ "name": "@mcp-b/aec-components",
3
+ "version": "0.2.0",
4
+ "description": "AEC (Architecture, Engineering, Construction) web components for Sigvelo, built with Lit.",
5
+ "keywords": [
6
+ "aec",
7
+ "bim",
8
+ "custom-elements",
9
+ "ifc",
10
+ "lit-element",
11
+ "web-components",
12
+ "webgl"
13
+ ],
14
+ "license": "MIT",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/WebMCP-org/design-system.git",
18
+ "directory": "packages/aec-components"
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "type": "module",
24
+ "types": "dist/index.d.ts",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "import": "./dist/index.js"
29
+ },
30
+ "./components/*": "./dist/components/*",
31
+ "./custom-elements.json": "./dist/docs/custom-elements.json"
32
+ },
33
+ "publishConfig": {
34
+ "access": "public"
35
+ },
36
+ "dependencies": {
37
+ "@mcp-b/wc-support": "0.2.0"
38
+ },
39
+ "devDependencies": {
40
+ "@custom-elements-manifest/analyzer": "^0.10.4",
41
+ "@storybook/addon-a11y": "^10.5.2",
42
+ "@storybook/addon-docs": "^10.5.2",
43
+ "@storybook/addon-vitest": "^10.5.2",
44
+ "@storybook/web-components-vite": "10.5.2",
45
+ "@thatopen/components": "^3.3.3",
46
+ "@thatopen/fragments": "^3.3.0",
47
+ "@types/three": "^0.183.0",
48
+ "@vitest/browser-playwright": "^4.1.10",
49
+ "@vitest/coverage-v8": "^4.1.10",
50
+ "@wc-toolkit/cem-inheritance": "^1.2.2",
51
+ "@wc-toolkit/cem-sorter": "^1.0.1",
52
+ "@wc-toolkit/type-parser": "^1.2.0",
53
+ "camera-controls": "^3.1.2",
54
+ "playwright": "~1.61.0",
55
+ "storybook": "^10.5.2",
56
+ "three": "^0.183.0",
57
+ "tinyglobby": "^0.2.15",
58
+ "typescript": "^6.0.3",
59
+ "vite": "npm:@voidzero-dev/vite-plus-core@0.2.4",
60
+ "vite-plugin-static-copy": "^3.3.0",
61
+ "vitest": "^4.1.10",
62
+ "web-ifc": "^0.0.77"
63
+ },
64
+ "peerDependencies": {
65
+ "@thatopen/components": "^3.0.0",
66
+ "lit": "^3.0.0",
67
+ "lit-html": "^3.0.0",
68
+ "three": ">=0.175.0",
69
+ "web-ifc": ">=0.0.74"
70
+ },
71
+ "customElements": "dist/docs/custom-elements.json",
72
+ "scripts": {
73
+ "analyze": "cem analyze",
74
+ "analyze:dev": "cem analyze --watch",
75
+ "build": "tsc -p tsconfig.prod.json && vp run build:lib && vp run analyze",
76
+ "build:lib": "vp pack",
77
+ "storybook": "vp run @mcp-b/web-components#storybook",
78
+ "test": "vp run @mcp-b/web-components#test",
79
+ "typecheck": "tsc --noEmit"
80
+ }
81
+ }