architwin 1.15.1 → 1.15.3

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.
@@ -1114,12 +1114,31 @@ export class BufferGeometry {
1114
1114
  const p2 = new THREE.Vector3(path3D[2].x, path3D[2].y, path3D[2].z);
1115
1115
  const v1 = new THREE.Vector3().subVectors(p1, p0);
1116
1116
  const v2 = new THREE.Vector3().subVectors(p2, p0);
1117
- const normal = new THREE.Vector3().crossVectors(v1, v2);
1117
+ let normal = new THREE.Vector3().crossVectors(v1, v2);
1118
1118
  const normalLen = normal.length();
1119
1119
  if (normalLen === 0) {
1120
1120
  continue;
1121
1121
  }
1122
1122
  normal.divideScalar(normalLen);
1123
+ // CRITICAL FIX: Ensure normal points outward from the wall
1124
+ // Calculate the centroid of the main polygon (floor)
1125
+ const centroid = new THREE.Vector3();
1126
+ for (const point of this.inputs.path) {
1127
+ centroid.add(new THREE.Vector3(point.x, point.y, point.z));
1128
+ }
1129
+ centroid.divideScalar(this.inputs.path.length);
1130
+ // Calculate window center
1131
+ const windowCenter = new THREE.Vector3();
1132
+ for (const point of path3D) {
1133
+ windowCenter.add(new THREE.Vector3(point.x, point.y, point.z));
1134
+ }
1135
+ windowCenter.divideScalar(path3D.length);
1136
+ // Vector from centroid to window center
1137
+ const outwardVector = new THREE.Vector3().subVectors(windowCenter, centroid);
1138
+ // If normal points inward (dot product < 0), flip it
1139
+ if (normal.dot(outwardVector) < 0) {
1140
+ normal.negate();
1141
+ }
1123
1142
  const uAxis = v1.clone().normalize();
1124
1143
  const vAxis = new THREE.Vector3().crossVectors(normal, uAxis).normalize();
1125
1144
  const shapePoints2D = [];
@@ -1140,8 +1159,8 @@ export class BufferGeometry {
1140
1159
  const basisMatrix = new THREE.Matrix4().makeBasis(uAxis, vAxis, normal);
1141
1160
  const translation = new THREE.Matrix4().makeTranslation(p0.x, p0.y, p0.z);
1142
1161
  const worldMatrix = new THREE.Matrix4().multiplyMatrices(translation, basisMatrix);
1143
- // Apply a small offset along the wall normal to avoid z-fighting with coplanar planes
1144
- const offset = -0.05;
1162
+ // Apply a small offset along the wall normal to avoid z-fighting
1163
+ const offset = -0.08;
1145
1164
  const offsetMatrix = new THREE.Matrix4().makeTranslation(normal.x * offset, normal.y * offset, normal.z * offset);
1146
1165
  const finalMatrix = new THREE.Matrix4().multiplyMatrices(offsetMatrix, worldMatrix);
1147
1166
  windowGeometry.applyMatrix4(finalMatrix);
@@ -1192,7 +1211,6 @@ export class BufferGeometry {
1192
1211
  let windowLabelText = windows[i].name ? `${windows[i].name}` : windowMesh.name;
1193
1212
  windowLabelText = windows[i].material ? `${windowLabelText}_${windows[i].material}: ${windowDimension.area.toFixed(2)}m²` : `${windowLabelText}: ${windowDimension.area.toFixed(2)}m²`;
1194
1213
  log.info("windowLabelText ", windowLabelText);
1195
- //const windowLabel = windows[i].name ? `${windows[i].name}_${windows[i].material}` : `Window ${i}_${windows[i].material}`
1196
1214
  const windowCanvas = this.createLabelCanvas(windowLabelText);
1197
1215
  const windowArea = Math.abs(twiceSignedArea * 0.5);
1198
1216
  const labelWidth = Math.max(0.5, Math.min(2, Math.sqrt(Math.max(0.0001, windowArea))));
@@ -1209,11 +1227,12 @@ export class BufferGeometry {
1209
1227
  .addScaledVector(vAxis, centerV)
1210
1228
  .add(p0);
1211
1229
  const labelOffset = 0.01;
1230
+ // Position label slightly offset from window, facing inward (opposite to normal)
1212
1231
  windowCenterLabel.position.copy(center3D).addScaledVector(normal.clone().negate(), labelOffset);
1213
1232
  windowCenterLabel.name = windowMesh.name;
1214
1233
  windowCenterLabel.visible = windows[i].options ? windows[i].options.is_visible : true;
1234
+ // Make label face inward (opposite direction of the outward normal)
1215
1235
  windowCenterLabel.lookAt(windowCenterLabel.position.clone().add(normal.clone().negate()));
1216
- //windowCenterLabel.name = windows[i].uuid ? `${windows[i].uuid}_windowLabel` : `windowLabel-${i}`;
1217
1236
  this.groupedMesh.add(windowCenterLabel);
1218
1237
  }
1219
1238
  catch (e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "architwin",
3
- "version": "1.15.1",
3
+ "version": "1.15.3",
4
4
  "description": "ArchiTwin Library for Matterport",
5
5
  "main": "./lib/architwin.js",
6
6
  "types": "./lib/architwin.d.ts",
@@ -257,9 +257,9 @@
257
257
  margin-bottom: 0 20px;
258
258
  }
259
259
 
260
- .at_collapse-content{
261
- /* height: 400px; */
262
- }
260
+ /* .at_collapse-content{
261
+ height: 400px;
262
+ } */
263
263
 
264
264
  .at_collapsible_container {
265
265
  width: 100%;
@@ -1253,6 +1253,139 @@
1253
1253
  transform: translateY(-100%);
1254
1254
  }
1255
1255
 
1256
+ #at-preview-modal-overlay {
1257
+ display: none;
1258
+ position: fixed;
1259
+ top: 0;
1260
+ left: 0;
1261
+ width: 100%;
1262
+ height: 100%;
1263
+ background: rgba(0, 0, 0, 0.8);
1264
+ z-index: 1000;
1265
+ justify-content: center;
1266
+ align-items: center;
1267
+ animation: at_fade-in 0.3s ease;
1268
+ }
1269
+
1270
+ #at-preview-modal-overlay.show {
1271
+ display: flex;
1272
+ }
1273
+
1274
+ @keyframes at_fade-in {
1275
+ from {
1276
+ opacity: 0;
1277
+ }
1278
+ to {
1279
+ opacity: 1;
1280
+ }
1281
+ }
1282
+
1283
+ .at_preview_modal {
1284
+ background-color: #222222;
1285
+ color: var(--text-color-light);
1286
+ border-radius: var(--border-radius);
1287
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
1288
+ width: 95vw;
1289
+ height: 95vh;
1290
+ max-width: 95vw;
1291
+ max-height: 95vh;
1292
+ overflow: hidden;
1293
+ position: relative;
1294
+ animation: at_slide-up 0.4s cubic-bezier(.39, .575, .565, 1.000) both;
1295
+ display: flex;
1296
+ flex-direction: column;
1297
+ }
1298
+
1299
+ @keyframes at_slide-up {
1300
+ from {
1301
+ transform: translateY(50px);
1302
+ opacity: 0;
1303
+ }
1304
+ to {
1305
+ transform: translateY(0);
1306
+ opacity: 1;
1307
+ }
1308
+ }
1309
+
1310
+ .at_preview_modal-header {
1311
+ display: flex;
1312
+ justify-content: space-between;
1313
+ align-items: center;
1314
+ padding: 12px 16px;
1315
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
1316
+ flex-shrink: 0;
1317
+ min-height: 50px;
1318
+ }
1319
+
1320
+ .at_preview_modal-title {
1321
+ margin: 0;
1322
+ font-size: 1.5rem;
1323
+ font-weight: 600;
1324
+ color: var(--text-color-light);
1325
+ word-break: break-word;
1326
+ }
1327
+
1328
+ .at_preview_modal-close-btn {
1329
+ background: none;
1330
+ border: none;
1331
+ color: var(--text-color-light);
1332
+ font-size: 1.5rem;
1333
+ cursor: pointer;
1334
+ padding: 4px 8px;
1335
+ border-radius: 4px;
1336
+ transition: all 0.2s ease;
1337
+ display: flex;
1338
+ align-items: center;
1339
+ justify-content: center;
1340
+ min-width: 32px;
1341
+ min-height: 32px;
1342
+ }
1343
+
1344
+ .at_preview_modal-close-btn:hover {
1345
+ background-color: var(--bg-accent);
1346
+ color: var(--text-color-dark);
1347
+ }
1348
+
1349
+ .at_preview_modal-body {
1350
+ padding: 0;
1351
+ overflow: hidden;
1352
+ flex: 1;
1353
+ display: flex;
1354
+ flex-direction: column;
1355
+ height: calc(100% - 50px);
1356
+ width: 100%;
1357
+ }
1358
+
1359
+ .at_preview_modal-content {
1360
+ color: var(--text-color-light);
1361
+ line-height: 1.6;
1362
+ font-size: 1rem;
1363
+ padding: 20px;
1364
+ overflow-y: auto;
1365
+ flex: 1;
1366
+ }
1367
+
1368
+ .at_preview_modal-iframe {
1369
+ border: none;
1370
+ border-radius: 0;
1371
+ background: white;
1372
+ width: 100%;
1373
+ height: 100%;
1374
+ flex: 1;
1375
+ display: block;
1376
+ min-width: 0;
1377
+ min-height: 0;
1378
+ }
1379
+
1380
+ .at_preview_modal-footer {
1381
+ padding: 16px 20px;
1382
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
1383
+ display: flex;
1384
+ justify-content: flex-end;
1385
+ gap: 12px;
1386
+ flex-shrink: 0;
1387
+ }
1388
+
1256
1389
  @keyframes slide-down {
1257
1390
  from {
1258
1391
  transform: translateY(-100%);
@@ -1587,6 +1720,7 @@
1587
1720
  background-color: #0F0E0E;
1588
1721
  padding-right: 5px;
1589
1722
  border-radius: 4px;
1723
+ border: 2px solid white;
1590
1724
  }
1591
1725
 
1592
1726
  .at_room_tree .hidden {
@@ -2495,14 +2629,16 @@ li.at_partition_wall_row_item {
2495
2629
 
2496
2630
  .at_partition_child_header.selected {
2497
2631
  padding-right: 5px !important;
2632
+ border: 2px solid white;
2498
2633
  }
2499
2634
 
2500
2635
  .at_hidden {
2501
2636
  display: none;
2502
2637
  }
2503
2638
 
2504
- .at_wall_window_row_item.selected {
2639
+ .at_window_row_item.selected {
2505
2640
  padding-left: 5px;
2641
+ border: 2px solid white;
2506
2642
  }
2507
2643
 
2508
2644
  .at_save_button {
@@ -2524,3 +2660,201 @@ li.at_partition_wall_row_item {
2524
2660
  margin-left: 4px;
2525
2661
  box-sizing: border-box;
2526
2662
  }
2663
+
2664
+ /* FLEXIBLE MODAL CLASSES */
2665
+
2666
+ .at_flexible_modal-overlay {
2667
+ display: none;
2668
+ position: fixed;
2669
+ top: 0;
2670
+ left: 0;
2671
+ width: 100%;
2672
+ height: 100%;
2673
+ background: rgba(0, 0, 0, 0.8);
2674
+ z-index: 1000;
2675
+ justify-content: center;
2676
+ align-items: center;
2677
+ animation: at_fade-in 0.3s ease;
2678
+ }
2679
+
2680
+ .at_flexible_modal-overlay.show {
2681
+ display: flex;
2682
+ }
2683
+
2684
+ @keyframes at_fade-in {
2685
+ from {
2686
+ opacity: 0;
2687
+ }
2688
+ to {
2689
+ opacity: 1;
2690
+ }
2691
+ }
2692
+
2693
+ .at_flexible_modal {
2694
+ background-color: #222222;
2695
+ color: var(--text-color-light);
2696
+ border-radius: var(--border-radius);
2697
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
2698
+ max-width: 90%;
2699
+ max-height: 90vh;
2700
+ overflow: hidden;
2701
+ position: relative;
2702
+ animation: at_slide-up 0.4s cubic-bezier(.39, .575, .565, 1.000) both;
2703
+ display: flex;
2704
+ flex-direction: column;
2705
+ }
2706
+
2707
+ @keyframes at_slide-up {
2708
+ from {
2709
+ transform: translateY(50px);
2710
+ opacity: 0;
2711
+ }
2712
+ to {
2713
+ transform: translateY(0);
2714
+ opacity: 1;
2715
+ }
2716
+ }
2717
+
2718
+ .at_flexible_modal-header {
2719
+ display: flex;
2720
+ justify-content: space-between;
2721
+ align-items: center;
2722
+ padding: 16px 20px;
2723
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
2724
+ flex-shrink: 0;
2725
+ }
2726
+
2727
+ .at_flexible_modal-title {
2728
+ margin: 0;
2729
+ font-size: 1.5rem;
2730
+ font-weight: 600;
2731
+ color: var(--text-color-light);
2732
+ word-break: break-word;
2733
+ }
2734
+
2735
+ .at_flexible_modal-close-btn {
2736
+ background: none;
2737
+ border: none;
2738
+ color: var(--text-color-light);
2739
+ font-size: 1.5rem;
2740
+ cursor: pointer;
2741
+ padding: 4px 8px;
2742
+ border-radius: 4px;
2743
+ transition: all 0.2s ease;
2744
+ display: flex;
2745
+ align-items: center;
2746
+ justify-content: center;
2747
+ min-width: 32px;
2748
+ min-height: 32px;
2749
+ }
2750
+
2751
+ .at_flexible_modal-close-btn:hover {
2752
+ background-color: var(--bg-accent);
2753
+ color: var(--text-color-dark);
2754
+ }
2755
+
2756
+ .at_flexible_modal-body {
2757
+ padding: 20px;
2758
+ overflow-y: auto;
2759
+ flex: 1;
2760
+ display: flex;
2761
+ flex-direction: column;
2762
+ gap: 16px;
2763
+ }
2764
+
2765
+ .at_flexible_modal-content {
2766
+ color: var(--text-color-light);
2767
+ line-height: 1.6;
2768
+ font-size: 1rem;
2769
+ }
2770
+
2771
+ .at_flexible_modal-content h1,
2772
+ .at_flexible_modal-content h2,
2773
+ .at_flexible_modal-content h3,
2774
+ .at_flexible_modal-content h4 {
2775
+ color: var(--text-color-light);
2776
+ margin-top: 0;
2777
+ margin-bottom: 12px;
2778
+ font-weight: 600;
2779
+ }
2780
+
2781
+ .at_flexible_modal-content h1 { font-size: 1.8rem; }
2782
+ .at_flexible_modal-content h2 { font-size: 1.5rem; }
2783
+ .at_flexible_modal-content h3 { font-size: 1.3rem; }
2784
+ .at_flexible_modal-content h4 { font-size: 1.1rem; }
2785
+
2786
+ .at_flexible_modal-iframe {
2787
+ border: none;
2788
+ border-radius: 4px;
2789
+ background: white;
2790
+ width: 100%;
2791
+ height: 100%;
2792
+ min-height: 400px;
2793
+ }
2794
+
2795
+ .at_flexible_modal-footer {
2796
+ padding: 16px 20px;
2797
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
2798
+ display: flex;
2799
+ justify-content: flex-end;
2800
+ gap: 12px;
2801
+ flex-shrink: 0;
2802
+ }
2803
+
2804
+ /* Responsive design */
2805
+ @media screen and (max-width: 768px) {
2806
+ .at_flexible_modal {
2807
+ max-width: 95%;
2808
+ margin: 10px;
2809
+ }
2810
+
2811
+ .at_flexible_modal-header {
2812
+ padding: 12px 16px;
2813
+ }
2814
+
2815
+ .at_flexible_modal-body {
2816
+ padding: 16px;
2817
+ }
2818
+
2819
+ .at_flexible_modal-footer {
2820
+ padding: 12px 16px;
2821
+ }
2822
+
2823
+ .at_flexible_modal-title {
2824
+ font-size: 1.2rem;
2825
+ }
2826
+
2827
+ .at_flexible_modal-iframe {
2828
+ min-height: 300px;
2829
+ }
2830
+ }
2831
+
2832
+ @media screen and (max-width: 480px) {
2833
+ .at_flexible_modal {
2834
+ max-width: 98%;
2835
+ margin: 5px;
2836
+ }
2837
+
2838
+ .at_flexible_modal-header,
2839
+ .at_flexible_modal-body,
2840
+ .at_flexible_modal-footer {
2841
+ padding: 12px;
2842
+ }
2843
+
2844
+ .at_flexible_modal-title {
2845
+ font-size: 1.1rem;
2846
+ }
2847
+
2848
+ .at_flexible_modal-close-btn {
2849
+ font-size: 1.2rem;
2850
+ min-width: 28px;
2851
+ min-height: 28px;
2852
+ }
2853
+ }
2854
+ span.at_room_name_text.toggle.selectable.selected {
2855
+ border: none !important;
2856
+ }
2857
+
2858
+ span.at_partition_name_text.toggle.selectable.selected {
2859
+ border: none !important;
2860
+ }
@@ -716,4 +716,7 @@
716
716
  .at_border_yellowgreen_900 { border-color: #365314; }
717
717
  .at_border_yellowgreen_950 { border-color: #1a2e05; }
718
718
 
719
-
719
+ .at_bg-gray-800 {
720
+ background-color: #222222 !important;
721
+ }
722
+