@sequent-org/ifc-viewer 1.2.4-ci.27.0 → 1.2.4-ci.29.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sequent-org/ifc-viewer",
3
3
  "private": false,
4
- "version": "1.2.4-ci.27.0",
4
+ "version": "1.2.4-ci.29.0",
5
5
  "type": "module",
6
6
  "description": "IFC 3D model viewer component for web applications - fully self-contained with local IFCLoader",
7
7
  "main": "src/index.js",
package/src/IfcViewer.js CHANGED
@@ -85,6 +85,7 @@ export class IfcViewer {
85
85
  quality: 'medium', // 'low' | 'medium' | 'high'
86
86
  edgesVisible: false,
87
87
  flatShading: true,
88
+ shadowsEnabled: true,
88
89
  clipping: {
89
90
  x: false,
90
91
  y: false,
@@ -301,13 +302,34 @@ export class IfcViewer {
301
302
  </div>
302
303
 
303
304
  <!-- Верхняя панель управления -->
304
- <div id="ifcToolbar" class="d-flex px-4" style="border:0px red solid; width: 250px; position: absolute; z-index: 60; justify-content:space-between; bottom: 10px; left: calc(50% - 125px); ">
305
+ <div id="ifcToolbar" class="d-flex px-4" style="border:0px red solid; width: 350px; position: absolute; z-index: 60; justify-content:space-between; bottom: 10px; left: calc(50% - 175px); ">
305
306
 
306
307
  <div class="navbar-end flex gap-2">
307
308
 
308
309
  <!-- Стили отображения -->
309
310
  <div class="join">
310
311
  <button class="btn btn-sm join-item" id="ifcToggleEdges"><svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" class="c-tree__icon c-tree__icon--3d"><g fill="#252A3F" fill-rule="nonzero"><path d="M12.5 5L6.005 8.75v7.5L12.5 20l6.495-3.75v-7.5L12.5 5zm0-1.155l7.495 4.328v8.654L12.5 21.155l-7.495-4.328V8.173L12.5 3.845z"></path><path d="M12 12v8.059h1V12z"></path><path d="M5.641 9.157l7.045 4.025.496-.868-7.045-4.026z"></path><path d="M18.863 8.288l-7.045 4.026.496.868 7.045-4.025z"></path></g></svg></button>
312
+ <button class="btn btn-sm join-item btn-active" id="ifcToggleShadows" title="Тени">
313
+ <svg width="24" height="24" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
314
+ <path fill="#000000" d="M207.39 0.00 C 212.56 0.44 217.91 0.57 222.85 1.13 C 262.70 5.63 300.04 25.42 325.92 56.02 Q 361.61 98.22 364.04 153.58 A 0.23 0.22 11.8 0 1 363.71 153.79 L 349.62 146.87 A 0.90 0.90 0.0 0 1 349.13 146.22 C 347.61 137.34 346.80 130.78 344.73 123.45 C 332.00 78.38 299.83 39.42 256.32 20.94 C 235.21 11.97 211.55 8.21 189.00 11.72 Q 153.18 17.30 128.20 42.72 Q 110.60 60.63 102.05 85.78 C 88.10 126.83 95.83 172.91 118.73 209.60 Q 122.30 215.32 127.44 222.49 A 1.70 1.70 0.0 0 1 127.76 223.45 L 128.09 298.58 A 0.23 0.23 0.0 0 1 127.75 298.78 C 82.71 273.41 52.38 228.77 46.61 177.37 C 41.26 129.73 57.69 81.88 91.39 47.83 Q 129.76 9.07 184.30 1.42 C 189.99 0.63 196.32 0.47 202.38 0.00 L 207.39 0.00 Z"/>
315
+ <path fill="#000000" d="M312.50 512.00 L 311.56 512.00 Q 309.05 511.43 307.15 509.96 A 2.09 2.07 -19.8 0 0 306.27 509.55 Q 304.17 509.09 303.52 508.75 Q 206.21 457.82 153.89 430.39 Q 152.01 429.41 151.14 427.04 Q 150.58 425.52 150.56 422.64 Q 150.42 393.12 149.69 237.76 Q 149.69 236.82 150.36 233.09 Q 150.86 230.31 153.63 228.87 Q 250.38 178.34 303.97 150.48 Q 307.28 148.76 310.46 150.29 Q 339.28 164.17 462.71 224.01 Q 466.51 225.85 466.51 230.76 Q 466.50 321.20 466.49 424.75 C 466.49 428.40 464.08 430.42 460.80 432.20 Q 425.93 451.10 315.52 510.97 A 0.87 0.80 -65.8 0 1 315.31 511.06 L 312.50 512.00 Z M 444.21 230.96 A 0.32 0.32 0.0 0 0 444.19 230.39 L 307.84 163.41 A 0.32 0.32 0.0 0 0 307.55 163.42 L 171.77 234.43 A 0.32 0.32 0.0 0 0 171.78 235.00 L 311.71 304.85 A 0.32 0.32 0.0 0 0 312.01 304.85 L 444.21 230.96 Z M 318.55 493.80 A 0.34 0.34 0.0 0 0 319.05 494.10 L 453.17 421.35 A 0.34 0.34 0.0 0 0 453.35 421.05 L 453.35 241.55 A 0.34 0.34 0.0 0 0 452.84 241.25 L 318.72 316.20 A 0.34 0.34 0.0 0 0 318.55 316.50 L 318.55 493.80 Z"/>
316
+ </svg>
317
+ </button>
318
+ <button class="btn btn-sm join-item" id="ifcToggleProjection" title="Перспектива / Ортогонально (переключение)">
319
+ <!-- По умолчанию Ortho, поэтому показываем действие: включить Perspective -->
320
+ <svg width="24" height="24" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
321
+ <path fill="#000000" d="M365.50 333.29 A 0.30 0.30 0.0 0 0 365.95 333.55 L 492.36 259.80 A 0.47 0.47 0.0 0 0 492.51 259.12 Q 489.74 255.31 492.90 252.78 A 0.30 0.30 0.0 0 0 492.83 252.27 C 489.14 250.57 490.13 245.43 493.90 244.50 C 496.33 243.90 501.93 247.88 504.97 249.79 A 1.50 1.48 -85.3 0 1 505.54 250.47 L 505.97 251.53 A 0.72 0.71 76.6 0 0 506.67 251.97 C 509.70 251.84 512.28 254.84 511.15 257.67 Q 510.77 258.62 508.18 260.14 C 355.38 349.68 251.70 410.06 149.28 469.74 A 3.94 3.93 -44.9 0 1 145.31 469.74 Q 7.70 389.45 2.96 386.69 C 0.09 385.02 0.50 382.93 0.50 379.49 Q 0.50 259.79 0.50 128.77 C 0.50 127.21 1.85 125.96 3.27 125.13 Q 68.02 87.24 145.61 41.87 C 146.90 41.11 148.92 41.81 150.33 42.63 Q 219.34 82.64 289.83 124.16 C 291.25 125.00 292.80 126.11 294.76 127.15 Q 299.89 129.89 301.84 131.37 C 305.49 134.15 301.99 140.40 297.26 138.18 Q 295.67 137.42 294.41 136.58 A 0.26 0.26 0.0 0 0 294.00 136.80 L 294.00 209.83 A 0.44 0.44 0.0 0 0 294.36 210.26 Q 340.50 219.23 361.26 223.22 C 366.12 224.15 365.53 227.44 365.51 232.03 Q 365.50 234.52 365.49 251.11 A 0.73 0.73 0.0 0 0 366.22 251.84 L 370.02 251.84 A 3.64 3.64 0.0 0 1 373.66 255.48 L 373.66 256.72 A 3.45 3.44 0.0 0 1 370.21 260.16 L 366.15 260.16 A 0.65 0.65 0.0 0 0 365.50 260.81 L 365.50 333.29 Z M 9.05 131.40 A 0.30 0.30 0.0 0 0 8.90 131.66 L 8.90 380.18 A 0.30 0.30 0.0 0 0 9.05 380.44 L 142.74 458.43 A 0.30 0.30 0.0 0 0 143.19 458.17 L 143.19 53.67 A 0.30 0.30 0.0 0 0 142.74 53.41 L 9.05 131.40 Z M 285.68 380.52 A 0.32 0.32 0.0 0 0 285.84 380.25 L 285.84 131.66 A 0.32 0.32 0.0 0 0 285.68 131.39 L 151.98 53.39 A 0.32 0.32 0.0 0 0 151.50 53.67 L 151.50 458.24 A 0.32 0.32 0.0 0 0 151.98 458.52 L 285.68 380.52 Z M 294.62 218.77 A 0.36 0.36 0.0 0 0 294.19 219.13 L 294.19 374.90 A 0.36 0.36 0.0 0 0 294.73 375.21 L 357.13 338.81 A 0.36 0.36 0.0 0 0 357.31 338.50 L 357.31 231.30 A 0.36 0.36 0.0 0 0 357.02 230.94 L 294.62 218.77 Z"/>
322
+ <path fill="#000000" d="M 331.8028 153.6467 A 4.00 4.00 0.0 0 1 326.3286 155.0726 L 318.9110 150.7207 A 4.00 4.00 0.0 0 1 317.4851 145.2465 L 317.6572 144.9533 A 4.00 4.00 0.0 0 1 323.1314 143.5274 L 330.5490 147.8793 A 4.00 4.00 0.0 0 1 331.9749 153.3535 L 331.8028 153.6467 Z"/>
323
+ <path fill="#000000" d="M 360.6890 170.5463 A 4.00 4.00 0.0 0 1 355.2099 171.9531 L 347.8247 167.5855 A 4.00 4.00 0.0 0 1 346.4179 162.1064 L 346.5910 161.8137 A 4.00 4.00 0.0 0 1 352.0701 160.4069 L 359.4553 164.7745 A 4.00 4.00 0.0 0 1 360.8621 170.2536 L 360.6890 170.5463 Z"/>
324
+ <path fill="#000000" d="M 389.5811 187.4643 A 3.99 3.99 0.0 0 1 384.1181 188.8771 L 376.8287 184.5833 A 3.99 3.99 0.0 0 1 375.4159 179.1204 L 375.6189 178.7757 A 3.99 3.99 0.0 0 1 381.0819 177.3629 L 388.3713 181.6567 A 3.99 3.99 0.0 0 1 389.7841 187.1196 L 389.5811 187.4643 Z"/>
325
+ <path fill="#000000" d="M 418.5914 204.3586 A 3.99 3.99 0.0 0 1 413.1235 205.7523 L 405.7288 201.3617 A 3.99 3.99 0.0 0 1 404.3350 195.8938 L 404.5086 195.6014 A 3.99 3.99 0.0 0 1 409.9765 194.2077 L 417.3712 198.5983 A 3.99 3.99 0.0 0 1 418.7650 204.0662 L 418.5914 204.3586 Z"/>
326
+ <path fill="#000000" d="M 447.6480 221.1624 A 3.99 3.99 0.0 0 1 442.2027 222.6419 L 434.7225 218.3579 A 3.99 3.99 0.0 0 1 433.2431 212.9126 L 433.4120 212.6176 A 3.99 3.99 0.0 0 1 438.8573 211.1381 L 446.3375 215.4221 A 3.99 3.99 0.0 0 1 447.8169 220.8674 L 447.6480 221.1624 Z"/>
327
+ <path fill="#000000" d="M 476.5002 238.1477 A 3.99 3.99 0.0 0 1 471.0372 239.5605 L 463.6099 235.1855 A 3.99 3.99 0.0 0 1 462.1971 229.7225 L 462.3798 229.4123 A 3.99 3.99 0.0 0 1 467.8428 227.9995 L 475.2701 232.3745 A 3.99 3.99 0.0 0 1 476.6829 237.8375 L 476.5002 238.1477 Z"/>
328
+ <path fill="#000000" d="M 407.4604 256.3255 A 3.98 3.98 0.0 0 1 403.4873 260.3125 L 394.8874 260.3275 A 3.98 3.98 0.0 0 1 390.9004 256.3545 L 390.8996 255.8945 A 3.98 3.98 0.0 0 1 394.8727 251.9075 L 403.4726 251.8925 A 3.98 3.98 0.0 0 1 407.4596 255.8655 L 407.4604 256.3255 Z"/>
329
+ <path fill="#000000" d="M 440.9596 256.3545 A 3.98 3.98 0.0 0 1 436.9726 260.3275 L 428.3727 260.3125 A 3.98 3.98 0.0 0 1 424.3996 256.3255 L 424.4004 255.8655 A 3.98 3.98 0.0 0 1 428.3874 251.8925 L 436.9873 251.9075 A 3.98 3.98 0.0 0 1 440.9604 255.8945 L 440.9596 256.3545 Z"/>
330
+ <path fill="#000000" d="M 474.4604 256.3255 A 3.98 3.98 0.0 0 1 470.4873 260.3125 L 461.8874 260.3275 A 3.98 3.98 0.0 0 1 457.9004 256.3545 L 457.8996 255.8945 A 3.98 3.98 0.0 0 1 461.8727 251.9075 L 470.4726 251.8925 A 3.98 3.98 0.0 0 1 474.4596 255.8655 L 474.4604 256.3255 Z"/>
331
+ </svg>
332
+ </button>
311
333
  </div>
312
334
 
313
335
  <!-- Секущие плоскости -->
@@ -480,6 +502,9 @@ export class IfcViewer {
480
502
  this._addEventListener('#ifcToggleEdges', 'click', () => {
481
503
  this._toggleEdges();
482
504
  });
505
+ this._addEventListener('#ifcToggleShadows', 'click', () => {
506
+ this._toggleShadows();
507
+ });
483
508
  this._addEventListener('#ifcToggleShading', 'click', () => {
484
509
  this._toggleShading();
485
510
  });
@@ -681,6 +706,18 @@ export class IfcViewer {
681
706
  }
682
707
  }
683
708
 
709
+ /**
710
+ * Переключает тени (вкл/выкл) для сцены.
711
+ * @private
712
+ */
713
+ _toggleShadows() {
714
+ if (!this.viewer) return;
715
+ this.viewerState.shadowsEnabled = !this.viewerState.shadowsEnabled;
716
+ try { this.viewer.setShadowsEnabled(this.viewerState.shadowsEnabled); } catch (_) {}
717
+ const btn = this.containerElement.querySelector('#ifcToggleShadows');
718
+ if (btn) btn.classList.toggle('btn-active', this.viewerState.shadowsEnabled);
719
+ }
720
+
684
721
  /**
685
722
  * Переключает плоское затенение
686
723
  * @private
package/src/main.js CHANGED
@@ -176,9 +176,14 @@ if (app) {
176
176
  // Дефолт (из текущих подобранных значений)
177
177
  shadowToggle.checked = true;
178
178
  viewer.setShadowsEnabled(true);
179
+ // синхронизируем тулбар-кнопку, если есть
180
+ const _btn = document.getElementById("ifcToggleShadows");
181
+ if (_btn) _btn.classList.toggle('btn-active', true);
179
182
  shadowToggle.addEventListener("change", (e) => {
180
183
  const on = !!e.target.checked;
181
184
  viewer.setShadowsEnabled(on);
185
+ const btn = document.getElementById("ifcToggleShadows");
186
+ if (btn) btn.classList.toggle('btn-active', on);
182
187
  // UI градиента имеет смысл только когда тени включены
183
188
  if (shadowGradToggle) shadowGradToggle.disabled = !on;
184
189
  if (shadowGradLen) shadowGradLen.disabled = !on;
@@ -538,11 +543,15 @@ if (app) {
538
543
  const qualLow = document.getElementById("qualLow");
539
544
  const qualMed = document.getElementById("qualMed");
540
545
  const qualHigh = document.getElementById("qualHigh");
541
- const toggleEdges = document.getElementById("toggleEdges");
546
+ // Нижний тулбар пакета (index.html): Edges
547
+ const toggleEdges = document.getElementById("ifcToggleEdges");
548
+ // Нижний тулбар пакета (index.html): Shadows
549
+ const toggleShadowsBtn = document.getElementById("ifcToggleShadows");
542
550
  const toggleShading = document.getElementById("toggleShading");
543
- const clipXBtn = document.getElementById("clipX");
544
- const clipYBtn = document.getElementById("clipY");
545
- const clipZBtn = document.getElementById("clipZ");
551
+ // Нижний тулбар пакета (index.html): секущие плоскости
552
+ const clipXBtn = document.getElementById("ifcClipX");
553
+ const clipYBtn = document.getElementById("ifcClipY");
554
+ const clipZBtn = document.getElementById("ifcClipZ");
546
555
  const clipXRange = document.getElementById("clipXRange");
547
556
  const clipYRange = document.getElementById("clipYRange");
548
557
  const clipZRange = document.getElementById("clipZRange");
@@ -559,6 +568,21 @@ if (app) {
559
568
  let edgesOn = false;
560
569
  viewer.setEdgesVisible(edgesOn);
561
570
  toggleEdges?.addEventListener("click", () => { edgesOn = !edgesOn; viewer.setEdgesVisible(edgesOn); });
571
+
572
+ // Тени по умолчанию включены (как и в левой панели)
573
+ const setToolbarShadowsActive = (on) => {
574
+ if (toggleShadowsBtn) toggleShadowsBtn.classList.toggle('btn-active', !!on);
575
+ };
576
+ setToolbarShadowsActive(true);
577
+ toggleShadowsBtn?.addEventListener("click", () => {
578
+ const next = !(shadowToggle ? !!shadowToggle.checked : true);
579
+ // Меняем состояние у Viewer
580
+ viewer.setShadowsEnabled(next);
581
+ // Синхронизируем UI слева, если он есть
582
+ if (shadowToggle) shadowToggle.checked = next;
583
+ setToolbarShadowsActive(next);
584
+ });
585
+
562
586
  let flatOn = true;
563
587
  toggleShading?.addEventListener("click", () => { flatOn = !flatOn; viewer.setFlatShading(flatOn); });
564
588
 
@@ -629,7 +629,7 @@ export class Viewer {
629
629
  // Тени управляются единообразно через setShadowsEnabled()
630
630
  node.castShadow = !!this.shadowsEnabled;
631
631
  // Самозатенение включается только в пресете "Тест"
632
- node.receiveShadow = !!this._testPreset?.enabled;
632
+ node.receiveShadow = !!this.shadowsEnabled && !!this._testPreset?.enabled;
633
633
  // Стекло/прозрачность: рендерим после непрозрачных (уменьшает мерцание сортировки)
634
634
  try {
635
635
  const mats = Array.isArray(node.material) ? node.material : [node.material];
@@ -1093,7 +1093,7 @@ export class Viewer {
1093
1093
  if (!node?.isMesh) return;
1094
1094
  node.castShadow = next;
1095
1095
  // Самозатенение включается только в пресете "Тест"
1096
- node.receiveShadow = !!this._testPreset?.enabled;
1096
+ node.receiveShadow = next && !!this._testPreset?.enabled;
1097
1097
  });
1098
1098
  }
1099
1099
  }