architwin 1.15.4 → 1.15.5

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.
@@ -387,14 +387,14 @@ i18n
387
387
  "SuccessPartitionDelete": "削除しました",
388
388
  "NoPartitionDeleted": "削除できる区画がありません",
389
389
  "Saving": "保存",
390
- "DeletePartition": "パーティション削除",
390
+ "DeletePartition": "区画削除",
391
391
  "ModifyPartition": "パーティションの変更",
392
392
  "InvalidNaN": "値が不正です。正しい数値を入力してくさい。",
393
393
  "CannotPlaceInArea": "ここには設定できません。位置を変えて試してください。",
394
394
  "SuccessWallHeight": "壁の高さが正常に更新されました",
395
395
  "Edge": "辺長",
396
396
  "Area": "面積",
397
- "DeleteWall": "ウォール削除",
397
+ "DeleteWall": "壁削除",
398
398
  "SuccessWallDelete": "削除しました",
399
399
  "WarnLowFloor": "Tマークされたエリアは、スペースの床よりも低い場合があります",
400
400
  "Settings": "BIM/CAD設定",
@@ -13,7 +13,7 @@ export function renderPreviewModal() {
13
13
  element.setAttribute('id', 'at-preview-modal-overlay');
14
14
  element.setAttribute('data-cy', 'at-preview-modal-overlay');
15
15
  element.innerHTML = `
16
- <div class="at_preview_modal">
16
+ <div class="at_preview_modal" id="at-preview-modal">
17
17
  <div class="at_preview_modal-header">
18
18
  <h2 class="at_preview_modal-title" id="at-preview-modal-content-heading" data-cy="at-preview-modal-content-heading"></h2>
19
19
  <button class="at_preview_modal-close-btn" data-cy="at-preview-modal-close-btn">&times;</button>
@@ -22,6 +22,14 @@ export function renderPreviewModal() {
22
22
  <div class="at_preview_modal-content" id="at-preview-modal-content-subheading" data-cy="at-preview-modal-content-subheading">
23
23
  </div>
24
24
  </div>
25
+ <div class="at_preview_modal-resize-handle at_preview_modal-resize-handle--top" data-resize-direction="top"></div>
26
+ <div class="at_preview_modal-resize-handle at_preview_modal-resize-handle--right" data-resize-direction="right"></div>
27
+ <div class="at_preview_modal-resize-handle at_preview_modal-resize-handle--bottom" data-resize-direction="bottom"></div>
28
+ <div class="at_preview_modal-resize-handle at_preview_modal-resize-handle--left" data-resize-direction="left"></div>
29
+ <div class="at_preview_modal-resize-handle at_preview_modal-resize-handle--top-left" data-resize-direction="top-left"></div>
30
+ <div class="at_preview_modal-resize-handle at_preview_modal-resize-handle--top-right" data-resize-direction="top-right"></div>
31
+ <div class="at_preview_modal-resize-handle at_preview_modal-resize-handle--bottom-left" data-resize-direction="bottom-left"></div>
32
+ <div class="at_preview_modal-resize-handle at_preview_modal-resize-handle--bottom-right" data-resize-direction="bottom-right"></div>
25
33
  </div>
26
34
  `;
27
35
  document.body.appendChild(element);
@@ -1,4 +1,4 @@
1
- import { FORM_MODE, PartitionNode, PolygonData, IObjectData } from "../../../../types";
1
+ import { FORM_MODE, PartitionNode, PolygonData, WallPolyData, IObjectData } from "../../../../types";
2
2
  export declare let isEditWindow: boolean;
3
3
  export declare function renderRoomFormPane(): HTMLDivElement;
4
4
  /**
@@ -30,6 +30,7 @@ export declare function displayPartitionFormMode(): void;
30
30
  * @param event - The click event from the edit button, used to identify which partition to edit
31
31
  */
32
32
  export declare function handlePartitionRowEditBtnClickEvent(partitions: Array<PartitionNode>, targetElement: HTMLElement): void;
33
+ export declare function displayWall(wall: WallPolyData): HTMLElement;
33
34
  /**
34
35
  * Clears the partition form by resetting UI elements and internal data.
35
36
  * - Navigates back to the partition list view.
@@ -103,6 +104,7 @@ export declare function getCurrentPolygonData(): PolygonData;
103
104
  * partition with its corresponding UUID, space UUID, and polygon data.
104
105
  */
105
106
  export declare function setCurrentPartitionData(): Promise<void>;
107
+ export declare function removeWindow(index?: number): void;
106
108
  export declare function getCurrentPartitionData(): PartitionNode;
107
109
  export declare function getNewlyAddedPartition(): Array<PartitionNode>;
108
110
  export declare function getDeletedSavedPartitionArray(): Array<PartitionNode>;
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  import i18n from '../i18n';
11
11
  import { SPACE_EVENTS } from "../../../../types";
12
12
  import { batchAddEventListenerByClassName } from "../../../events";
13
- import { startDraw, cancelDraw, disposeModel, _3DXObjects, getCurrentPolygon, dispatchSpaceEvent, enableVerticeControls, setCurrentPolygon, setMeshChildrenMaterialProperty, get3DXObjects, getChildrenOfModel, clearSelectedObject, renderPolygon, addUndoDrawActions, setWallBaseHeight, clearWallBaseHeight, setDrawingConfig, resetDrawingConfig, goToPosition, clearFloorBaseHeight } from '../../../../architwin';
13
+ import { startDraw, cancelDraw, disposeModel, _3DXObjects, getCurrentPolygon, dispatchSpaceEvent, enableVerticeControls, setCurrentPolygon, setMeshChildrenMaterialProperty, get3DXObjects, getChildrenOfModel, clearSelectedObject, renderPolygon, addUndoDrawActions, setWallBaseHeight, clearWallBaseHeight, setDrawingConfig, resetDrawingConfig, goToPosition, clearFloorBaseHeight, clearDrawActionHistory } from '../../../../architwin';
14
14
  import { generateUUID, extractUUID } from '../../../../utils';
15
15
  import { getCurrentEditRoomData } from './roomTreePane';
16
16
  import { toggleModal, setModalAction } from "../modal";
@@ -798,7 +798,7 @@ function displayFaces(polygon) {
798
798
  wallConfirmMaterial.style.display = "inline-flex";
799
799
  });
800
800
  }
801
- function displayWall(wall) {
801
+ export function displayWall(wall) {
802
802
  log.info("displayWall()", wall);
803
803
  // Extract the wall name from the format "_wall-{number}" using regex
804
804
  const match = wall.name.match(/wall-(\d+)$/);
@@ -1161,7 +1161,7 @@ function displayFloor(floor, walls, floorModel) {
1161
1161
  <span class="mdi mdi-chevron-up" id="at-expand-btn-${floor.uuid}" data-cy="at-expand-btn-${floor.uuid}" model-id="${floorModelUUID}"></span>
1162
1162
  </div>
1163
1163
  <div class="at_subitem_right">
1164
- <span class="mdi mdi-delete-outline"></span>
1164
+ <!-- <span class="mdi mdi-delete-outline"></span> -->
1165
1165
  </div>
1166
1166
  </div>
1167
1167
 
@@ -1522,7 +1522,7 @@ export function setCurrentPartitionData() {
1522
1522
  if (drawingMode === 'partition') {
1523
1523
  displayFaceLists();
1524
1524
  currentObject = currentObjectData;
1525
- log.info("JAMES currentObject", currentObject);
1525
+ log.info("currentObject", currentObject);
1526
1526
  }
1527
1527
  }, 50); // Check every 50ms
1528
1528
  });
@@ -1628,10 +1628,6 @@ function onModeDetectFloorInput(event) {
1628
1628
  floorConfirmMaterial.style.display = "none";
1629
1629
  }
1630
1630
  }
1631
- function setFloorMaterial(material) {
1632
- console.log('setFloorMaterial()', material);
1633
- floorMaterial = material;
1634
- }
1635
1631
  function onModeDetectWallInput(event) {
1636
1632
  console.log('onModeDetectWallInput()', event);
1637
1633
  const target = event.target;
@@ -1648,6 +1644,21 @@ function onModeDetectWallInput(event) {
1648
1644
  wallConfirmMaterial.style.display = "none";
1649
1645
  }
1650
1646
  }
1647
+ export function removeWindow(index = -1) {
1648
+ if (index <= -1) {
1649
+ currentWall.windows.pop();
1650
+ }
1651
+ else {
1652
+ currentWall.windows.splice(index, 1);
1653
+ }
1654
+ const faceVertexContainer = document.getElementById('at-face-vertex-container');
1655
+ faceVertexContainer.innerHTML = '';
1656
+ faceVertexContainer.append(displayWall(currentWall));
1657
+ }
1658
+ function setFloorMaterial(material) {
1659
+ console.log('setFloorMaterial()', material);
1660
+ floorMaterial = material;
1661
+ }
1651
1662
  function setWallMaterial(material) {
1652
1663
  console.log('setWallMaterial()');
1653
1664
  wallMaterial = material;
@@ -1774,6 +1785,7 @@ export function handlePartitionWallEditBtn(wallUuid) {
1774
1785
  currentPolygonData = JSON.parse(currentPartitionData.polygon_json);
1775
1786
  setDrawingMode(false);
1776
1787
  cancelDrawing();
1788
+ clearDrawActionHistory();
1777
1789
  });
1778
1790
  }
1779
1791
  export function getTempCurrentRoomEditData() {
@@ -530,6 +530,7 @@ function setupIndividualEventListeners() {
530
530
  handlePipeForm();
531
531
  handlePipeList();
532
532
  handleResponsiveChanges();
533
+ handlePreviewModalResize();
533
534
  }
534
535
  //================ OBJECT EVENT HANDLERS ===============//s
535
536
  function handleResponsiveChanges() {
@@ -1586,7 +1587,7 @@ function handleDragEnd(payload) {
1586
1587
  setCurrentTransformationValues(transformValues);
1587
1588
  }
1588
1589
  function handleDrawHistory(payload) {
1589
- console.log("payload", payload);
1590
+ console.log("handleDrawHistory", payload);
1590
1591
  const undoCount = (payload.undoDrawActions).length;
1591
1592
  const redoCount = (payload.redoDrawActions).length;
1592
1593
  if (undoCount == 0) {
@@ -3896,6 +3897,94 @@ function clearActivePane() {
3896
3897
  paneElement.style.display = 'none';
3897
3898
  }
3898
3899
  }
3900
+ function handlePreviewModalResize() {
3901
+ const modal = document.getElementById('at-preview-modal');
3902
+ const resizeHandles = document.querySelectorAll('.at_preview_modal-resize-handle');
3903
+ if (!modal || !resizeHandles.length)
3904
+ return;
3905
+ let isResizing = false;
3906
+ let currentHandle = null;
3907
+ let startX = 0;
3908
+ let startY = 0;
3909
+ let startWidth = 0;
3910
+ let startHeight = 0;
3911
+ let startLeft = 0;
3912
+ let startTop = 0;
3913
+ const minWidth = 400;
3914
+ const minHeight = 300;
3915
+ const maxWidth = window.innerWidth * 0.95;
3916
+ const maxHeight = window.innerHeight * 0.95;
3917
+ resizeHandles.forEach((handle) => {
3918
+ handle.addEventListener('mousedown', (e) => {
3919
+ e.preventDefault();
3920
+ e.stopPropagation();
3921
+ isResizing = true;
3922
+ currentHandle = handle;
3923
+ startX = e.clientX;
3924
+ startY = e.clientY;
3925
+ const rect = modal.getBoundingClientRect();
3926
+ startWidth = rect.width;
3927
+ startHeight = rect.height;
3928
+ startLeft = rect.left;
3929
+ startTop = rect.top;
3930
+ document.body.style.cursor = window.getComputedStyle(handle).cursor;
3931
+ document.body.style.userSelect = 'none';
3932
+ });
3933
+ });
3934
+ document.addEventListener('mousemove', (e) => {
3935
+ if (!isResizing || !currentHandle)
3936
+ return;
3937
+ const direction = currentHandle.getAttribute('data-resize-direction');
3938
+ const deltaX = e.clientX - startX;
3939
+ const deltaY = e.clientY - startY;
3940
+ let newWidth = startWidth;
3941
+ let newHeight = startHeight;
3942
+ let newLeft = startLeft;
3943
+ let newTop = startTop;
3944
+ // Handle horizontal resizing
3945
+ if (direction === null || direction === void 0 ? void 0 : direction.includes('right')) {
3946
+ newWidth = Math.max(minWidth, Math.min(maxWidth, startWidth + deltaX));
3947
+ }
3948
+ else if (direction === null || direction === void 0 ? void 0 : direction.includes('left')) {
3949
+ const potentialWidth = startWidth - deltaX;
3950
+ if (potentialWidth >= minWidth && potentialWidth <= maxWidth) {
3951
+ newWidth = potentialWidth;
3952
+ newLeft = startLeft + deltaX;
3953
+ }
3954
+ }
3955
+ // Handle vertical resizing
3956
+ if (direction === null || direction === void 0 ? void 0 : direction.includes('bottom')) {
3957
+ newHeight = Math.max(minHeight, Math.min(maxHeight, startHeight + deltaY));
3958
+ }
3959
+ else if (direction === null || direction === void 0 ? void 0 : direction.includes('top')) {
3960
+ const potentialHeight = startHeight - deltaY;
3961
+ if (potentialHeight >= minHeight && potentialHeight <= maxHeight) {
3962
+ newHeight = potentialHeight;
3963
+ newTop = startTop + deltaY;
3964
+ }
3965
+ }
3966
+ // Apply new dimensions
3967
+ modal.style.width = `${newWidth}px`;
3968
+ modal.style.height = `${newHeight}px`;
3969
+ modal.style.maxWidth = `${newWidth}px`;
3970
+ modal.style.maxHeight = `${newHeight}px`;
3971
+ // For top/left resizing, we need to reposition the modal
3972
+ if ((direction === null || direction === void 0 ? void 0 : direction.includes('left')) || (direction === null || direction === void 0 ? void 0 : direction.includes('top'))) {
3973
+ modal.style.position = 'fixed';
3974
+ modal.style.left = `${newLeft}px`;
3975
+ modal.style.top = `${newTop}px`;
3976
+ modal.style.transform = 'none';
3977
+ }
3978
+ });
3979
+ document.addEventListener('mouseup', () => {
3980
+ if (isResizing) {
3981
+ isResizing = false;
3982
+ currentHandle = null;
3983
+ document.body.style.cursor = '';
3984
+ document.body.style.userSelect = '';
3985
+ }
3986
+ });
3987
+ }
3899
3988
  export {
3900
3989
  //state
3901
3990
  activeToolbarItem, activeActionItem, cancelModelPlacementPrompt, isCustomMapControlsVisible, pipeColor,
@@ -1,5 +1,5 @@
1
1
  import { Pane } from 'tweakpane';
2
- import { dispatchSpaceEvent, renderPolygon, getPolygonFloorOffset, getCurrentFloor, getWallBaseHeight, getFloorBaseHeight, isToolbarFeatureEnabled } from "../architwin";
2
+ import { dispatchSpaceEvent, renderPolygon, getPolygonFloorOffset, getCurrentFloor, getWallBaseHeight, getFloorBaseHeight, isToolbarFeatureEnabled, getDrawingConfig, getVertexPath } from "../architwin";
3
3
  import { SPACE_EVENTS } from "../types";
4
4
  import { getPolygonArea } from "../utils";
5
5
  import { PolygonCalculator, WallCalculator } from "../math";
@@ -373,7 +373,7 @@ export class Vertice {
373
373
  position: null,
374
374
  fillColor: 'rgb(0,255,0)',
375
375
  hoverColor: 'rgb(255,0,0)',
376
- ringVisibility: false
376
+ ringVisibility: false,
377
377
  };
378
378
  this.emits = {
379
379
  active: true,
@@ -424,12 +424,39 @@ export class Vertice {
424
424
  //this.pointerIntersection.object === 'intersectedobject.model'
425
425
  if (this.pointerIntersection.object) {
426
426
  let e = Object.assign({}, this.pointerIntersection.position);
427
- const floorLevel = getFloorBaseHeight();
428
- if (floorLevel != undefined) {
429
- e.y = floorLevel;
427
+ const drawingConfig = getDrawingConfig();
428
+ // Apply floor level constraint only for non-window modes
429
+ if (!drawingConfig || drawingConfig.lineTypeComponentConfig.drawingMode !== 'window') {
430
+ const floorLevel = getFloorBaseHeight();
431
+ if (floorLevel != undefined) {
432
+ e.y = floorLevel;
433
+ }
434
+ else {
435
+ e.y = this.mesh.position.y;
436
+ }
430
437
  }
431
- else {
432
- e.y = this.mesh.position.y;
438
+ if (drawingConfig && drawingConfig.lineTypeComponentConfig.drawingMode == 'window') {
439
+ const firstVertex = getVertexPath()[0];
440
+ // Skip constraint for first vertex (index 0) - it defines the wall plane
441
+ if (this.inputs.index !== 0 && firstVertex && this.pointerIntersection.normal) {
442
+ const THREE = this.context.three;
443
+ // Get wall normal from pointer intersection
444
+ const wallNormal = new THREE.Vector3(this.pointerIntersection.normal.x, this.pointerIntersection.normal.y, this.pointerIntersection.normal.z).normalize();
445
+ // First vertex position defines a point on the wall plane
446
+ const planePoint = new THREE.Vector3(firstVertex.x, firstVertex.y, firstVertex.z);
447
+ // Current drag position
448
+ const dragPosition = new THREE.Vector3(e.x, e.y, e.z);
449
+ // Vector from plane point to drag position
450
+ const vecToPoint = new THREE.Vector3().subVectors(dragPosition, planePoint);
451
+ // Calculate distance from point to plane along normal
452
+ const distanceToPlane = vecToPoint.dot(wallNormal);
453
+ // Project point onto plane by removing the perpendicular component
454
+ const projectedPosition = new THREE.Vector3().subVectors(dragPosition, wallNormal.clone().multiplyScalar(distanceToPlane));
455
+ // Update e with constrained position (stays on wall plane)
456
+ e.x = projectedPosition.x;
457
+ e.y = projectedPosition.y;
458
+ e.z = projectedPosition.z;
459
+ }
433
460
  }
434
461
  this.mesh.position.set(e.x, e.y, e.z);
435
462
  //this.mesh.children[0].position.set(e.x, e.y, e.z)
@@ -1209,9 +1236,11 @@ export class BufferGeometry {
1209
1236
  }
1210
1237
  // Calculate window area using the projected 2D coordinates
1211
1238
  const windowDimension = this.calculateWindowDimensions(windows[i].path);
1212
- let windowLabelText = windows[i].name ? `${windows[i].name}` : windowMesh.name;
1239
+ const windowLabel = windows[i].name.split(" ");
1240
+ const windowName = windowLabel[0] == 'Window' ? i18n.t('Window') + ' ' + windowLabel[1] : windows[i].name;
1241
+ let windowLabelText = windows[i].name ? `${windowName}` : windowMesh.name;
1213
1242
  windowLabelText = windows[i].material ? `${windowLabelText}_${windows[i].material}: ${windowDimension.area.toFixed(2)}m²` : `${windowLabelText}: ${windowDimension.area.toFixed(2)}m²`;
1214
- log.info("windowLabelText ", windowLabelText);
1243
+ log.info("windowLabelText ", windowLabelText, windows[i].name, windowMesh.name, i18n.t('Window'));
1215
1244
  const windowCanvas = this.createLabelCanvas(windowLabelText);
1216
1245
  const windowArea = Math.abs(twiceSignedArea * 0.5);
1217
1246
  const labelWidth = Math.max(0.5, Math.min(2, Math.sqrt(Math.max(0.0001, windowArea))));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "architwin",
3
- "version": "1.15.4",
3
+ "version": "1.15.5",
4
4
  "description": "ArchiTwin Library for Matterport",
5
5
  "main": "./lib/architwin.js",
6
6
  "types": "./lib/architwin.d.ts",
@@ -1386,6 +1386,76 @@
1386
1386
  flex-shrink: 0;
1387
1387
  }
1388
1388
 
1389
+ /* Resize handles for preview modal */
1390
+ .at_preview_modal-resize-handle {
1391
+ position: absolute;
1392
+ z-index: 10;
1393
+ }
1394
+
1395
+ .at_preview_modal-resize-handle--top,
1396
+ .at_preview_modal-resize-handle--bottom {
1397
+ left: 8px;
1398
+ right: 8px;
1399
+ height: 8px;
1400
+ cursor: ns-resize;
1401
+ }
1402
+
1403
+ .at_preview_modal-resize-handle--left,
1404
+ .at_preview_modal-resize-handle--right {
1405
+ top: 8px;
1406
+ bottom: 8px;
1407
+ width: 8px;
1408
+ cursor: ew-resize;
1409
+ }
1410
+
1411
+ .at_preview_modal-resize-handle--top {
1412
+ top: 0;
1413
+ }
1414
+
1415
+ .at_preview_modal-resize-handle--right {
1416
+ right: 0;
1417
+ }
1418
+
1419
+ .at_preview_modal-resize-handle--bottom {
1420
+ bottom: 0;
1421
+ }
1422
+
1423
+ .at_preview_modal-resize-handle--left {
1424
+ left: 0;
1425
+ }
1426
+
1427
+ .at_preview_modal-resize-handle--top-left,
1428
+ .at_preview_modal-resize-handle--top-right,
1429
+ .at_preview_modal-resize-handle--bottom-left,
1430
+ .at_preview_modal-resize-handle--bottom-right {
1431
+ width: 16px;
1432
+ height: 16px;
1433
+ }
1434
+
1435
+ .at_preview_modal-resize-handle--top-left {
1436
+ top: 0;
1437
+ left: 0;
1438
+ cursor: nwse-resize;
1439
+ }
1440
+
1441
+ .at_preview_modal-resize-handle--top-right {
1442
+ top: 0;
1443
+ right: 0;
1444
+ cursor: nesw-resize;
1445
+ }
1446
+
1447
+ .at_preview_modal-resize-handle--bottom-left {
1448
+ bottom: 0;
1449
+ left: 0;
1450
+ cursor: nesw-resize;
1451
+ }
1452
+
1453
+ .at_preview_modal-resize-handle--bottom-right {
1454
+ bottom: 0;
1455
+ right: 0;
1456
+ cursor: nwse-resize;
1457
+ }
1458
+
1389
1459
  @keyframes slide-down {
1390
1460
  from {
1391
1461
  transform: translateY(-100%);