architwin 1.15.5 → 1.16.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.
@@ -8,7 +8,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { actionBar, renderObjectCards, renderLibraryCards, renderTags, renderTagRow, getTagFormData, addClickEventToTagRow, setActiveCard, setActiveMenu, removeObjectCard, clearActiveMenu, setTagCategoriesOption, toggleDropdown, tagFormMode, selectedTag, renderRecepientOptions, renderTagMessages, createTagMessage, setTagLink, setTagMessagingDetails, renderCategoryDropdownOptions, clearTagFormDropdown, clearActiveActionBtn, clearActiveCard, toggleActionBarButtons, selectedCategoryFilterId, selectedSubCategoryFilterId, filterTagList, toggleModal, setModalAction, } from "./components/toolbar";
11
- import { getTargetPosition, addMediaScreen, _3DXObjects, selectedObject, setTransformControls, copyObject, revertTransform, clearSelectedObject, removeTransformControls, getLibrary, getMpTags, renderTag, captureSpaceScreenshot, moveTag, subscribeSpaceEvent, setModelVisibility, disposeModel, disposeTag, _tags, _tagCategories, dispatchSpaceEvent, editTagLabel, editTagDescription, setTagMessageRecepients, setTagMessages, setSelectedTagUuid, renderMeetingSidebar, setTagIcon, setObjectTransformation, getSelectedObject, _atwin, isCdnMapDataAvailable, captureScreenshotAndCameraDetails, _mpConfig, cancelModelPlacement, _modelDetails, actionHistory, get3DXObjects, transformHistory, goToModel, themeManager, _partitionNodes, setSpacePartitionNodes, getSpaceId, setFloorBaseHeight, toggleWallVisibility, getChildrenOfModel, toggleFloorVisibility, renderPolygon, getCurrentPolygon, getFloorBaseHeight, setSelectedObject, redoDrawAction, undoDrawAction, setWallBaseHeight, clearWallBaseHeight, clearFloorBaseHeight, isToolbarFeatureEnabled, captureCurrentView, getCurrentFloor, _spaceUsers, setPipeCategories, setPipes, detachTagMedia, getTagDataCollection, setVertexPath, _screenSharingHostUser, _tagIotCategoryTypes, getIoTDeviceTagIcons, toggleMeshChildrenVisibility, set3DXObjects } from "../architwin";
11
+ import { getTargetPosition, addMediaScreen, _3DXObjects, selectedObject, setTransformControls, copyObject, revertTransform, clearSelectedObject, removeTransformControls, getLibrary, getMpTags, renderTag, captureSpaceScreenshot, moveTag, subscribeSpaceEvent, setModelVisibility, disposeModel, disposeTag, _tags, _tagCategories, dispatchSpaceEvent, editTagLabel, editTagDescription, setTagMessageRecepients, setTagMessages, setSelectedTagUuid, renderMeetingSidebar, setTagIcon, setObjectTransformation, getSelectedObject, _atwin, isCdnMapDataAvailable, captureScreenshotAndCameraDetails, _mpConfig, cancelModelPlacement, _modelDetails, actionHistory, get3DXObjects, transformHistory, goToModel, themeManager, _partitionNodes, setSpacePartitionNodes, getSpaceId, setFloorBaseHeight, toggleWallVisibility, getChildrenOfModel, toggleFloorVisibility, renderPolygon, getCurrentPolygon, getFloorBaseHeight, setSelectedObject, redoDrawAction, undoDrawAction, setWallBaseHeight, clearWallBaseHeight, clearFloorBaseHeight, isToolbarFeatureEnabled, captureCurrentView, getCurrentFloor, _spaceUsers, setPipeCategories, setPipes, detachTagMedia, getTagDataCollection, setVertexPath, _screenSharingHostUser, toggleVisibilityTag, _tagIotCategoryTypes, getIoTDeviceTagIcons, toggleMeshChildrenVisibility, set3DXObjects, partitionHistory,
12
+ // polygonHistory
13
+ } from "../architwin";
12
14
  import { Notyf } from 'notyf';
13
15
  import 'notyf/notyf.min.css';
14
16
  import { SPACE_EVENTS, COORDINATE_SYSTEM, UNITS, DEGREE, MAP_OPTIONS, sortTagOptions, sortObjectOptions, CUSTOM_MAP_MODE, TAG_TYPE } from "../types";
@@ -24,11 +26,11 @@ import log from 'loglevel';
24
26
  import * as minimap from '../minimap';
25
27
  import { clearActiveThemeCard, getSelectedTheme } from "./components/toolbar/themePane";
26
28
  import { getCurrentEditRoomData, displayRoomTree, updatePartitionVisibilityUI, getSelectedPartitionId, updatePolygonVisibilityData, toggleVisibilityState, setFilteredDisplay, updateRoomVisibilityUI, highlightSelectedPartitionChild, highlightSelectedWindow, getRoomData } from "./components/toolbar/spacePartition/roomTreePane";
27
- import { toggleDrawPartitionButton, displayPartitionFormMode, setPartitionFormMode, clearPartitionForm, setPolygonData, getPartitionFormData, getPartitionSavingMode, setPartitionSavingMode, getPartitionFormMode, getNewlyAddedPartition, setCurrentPartitionData, getCurrentPartitionData, getTempCurrentPolygon, clearTempCurrentPolygon, toggleDrawWindowButton, getIsDrawing, getDrawingMode, getCurrentPolygonData, setTempCurrentRoomEditData } from "./components/toolbar/spacePartition/roomFormPane";
29
+ import { toggleDrawPartitionButton, displayPartitionFormMode, setPartitionFormMode, clearPartitionForm, setPolygonData, getPartitionFormData, getPartitionSavingMode, setPartitionSavingMode, getPartitionFormMode, getNewlyAddedPartition, setCurrentPartitionData, getCurrentPartitionData, getTempCurrentPolygon, clearTempCurrentPolygon, toggleDrawWindowButton, getIsDrawing, getDrawingMode, getCurrentPolygonData, setTempCurrentRoomEditData, toggleUndoRedoButtons, getCurrentWall, currentWindow } from "./components/toolbar/spacePartition/roomFormPane";
28
30
  import { actionSettingsSelectOption, getTempCoordinateSystem, getTempMeasurementUnit, getTempRotationUnit, setCoordinateSystem, setMeasurementUnit, setRotationUnit, initSettingsValues, setTempCoordinateSystem, setTempMeasurementUnit, setTempRotationUnit, toggleActionSettingsDropdown, toggleCalibrateBasepoint, setScaleFactor, getTempScaleFactor, setTempScaleFactor, setBasepoint, getTempBasepoint, setTempBasepoint, getBasepoint, toggleActionSettings, getBasepointObjectPayload, displayConvertedCoordinates, getCoordinateSystem, getScaleFactor, getMeasurementUnit, getRotationUnit, setBasepointObjectPayload } from "./components/toolbar/actionSettingsPane";
29
31
  import { getBasepointCalibrateBpCoordinateValues, getBasepointCalibrateMpCoordinateValues, initBsepointCalibratePane, toggleBasepointCalibratePane } from "./components/toolbar/basepointCalibratePane";
30
32
  import { toggleGeneralMapOptions, initGeneralSelectedMap, getSelectedMapOption } from './components/toolbar/generalSettingsMenuPane';
31
- import { searchTagList, setSearchTagTerm, searchClearfield, getSearchTagTerm, sortTags, updateSelectedTagSortOption, resetSelectedTagSortOption, filterIotTagList, setTagPaneActive, isTagPaneActive, setCurrentTagPaneMode, currentTagPaneMode, selectedTagSortOption } from './components/toolbar/tagListPane';
33
+ import { searchTagList, setSearchTagTerm, searchClearfield, getSearchTagTerm, sortTags, updateSelectedTagSortOption, resetSelectedTagSortOption, filterIotTagList, setTagPaneActive, isTagPaneActive, setCurrentTagPaneMode, currentTagPaneMode, selectedTagSortOption, tagVisibility, updateShowAllButton, saveTagVisibilityToStorage, initializeTagVisibility } from './components/toolbar/tagListPane';
32
34
  import { renderUserRows } from "./components/toolbar/spaceUserListPane";
33
35
  import { handleRemoteViewResponsiveChanges, renderRemoteSpaceViewing } from "./components/toolbar/viewingRemoteSpace";
34
36
  import { PipeList } from "./components/toolbar/pipeListPane";
@@ -38,6 +40,7 @@ import { PipeForm } from "./components/toolbar/pipeFormPane";
38
40
  import { toggleIoTCategoryOptions, toggleIoTDevicesOptions, setSelectedIoTSystemRadio, clearIoTDropdowns, initIoTFormData, setIotCategoryOptions, getIotTagFormData, iotTagFormMode, selectedIotTag, clearIotFields, getIotCategoryOption } from './components/toolbar/tagIotFormPane';
39
41
  import { getTheseTagMessages, timedoutComment, unsendComment } from "./components/toolbar/tagMessagingPane";
40
42
  import { handleScreenShareResponsiveChanges, handleScreenShareAcceptRequest, handleScreenShareBackUserListPane, handleScreenShareEndSessionEvent, handleScreenShareUsersUpdated, renderScreenShareLeaveConfirmationModal } from "./components/toolbar/screenSharePane";
43
+ import _ from "lodash";
41
44
  const pipeList = new PipeList();
42
45
  const pipeForm = new PipeForm();
43
46
  let activeToolbarItem, activeActionItem, activePane, activeActionPane, cancelTagPlacementPrompt, cancelModelPlacementPrompt;
@@ -62,6 +65,7 @@ let isCustomMapControlsVisible = false;
62
65
  let _currentSandboxId = undefined;
63
66
  let isNotyfExecuted = false; // flag for notification
64
67
  let pipeColor = "";
68
+ let allTagsVisible = true;
65
69
  function batchAddEventListenerByClassName(className, callback) {
66
70
  if (className) {
67
71
  const elements = document.querySelectorAll(`.${className}`);
@@ -370,6 +374,7 @@ function renderTagPaneContent() {
370
374
  }
371
375
  if (tags.length > 0) {
372
376
  searchTagList(tags);
377
+ updateShowAllButton();
373
378
  }
374
379
  });
375
380
  }
@@ -530,6 +535,7 @@ function setupIndividualEventListeners() {
530
535
  handlePipeForm();
531
536
  handlePipeList();
532
537
  handleResponsiveChanges();
538
+ handleToggleVisibilityTags();
533
539
  handlePreviewModalResize();
534
540
  }
535
541
  //================ OBJECT EVENT HANDLERS ===============//s
@@ -1224,6 +1230,65 @@ function handleSaveTag() {
1224
1230
  setTagFormMode("NONE" /* FORM_MODE.NONE */);
1225
1231
  }));
1226
1232
  }
1233
+ // Toggle all tags visibility
1234
+ function handleToggleVisibilityTags() {
1235
+ const toggleVisibilityBtn = document.getElementById('at-visibility-tag-btn');
1236
+ if (!toggleVisibilityBtn)
1237
+ return;
1238
+ // Initialize tag visibility on load
1239
+ initializeTagVisibility();
1240
+ const updateAll = (visible) => __awaiter(this, void 0, void 0, function* () {
1241
+ // Determine which tags to update based on current mode
1242
+ const tagsToUpdate = currentTagPaneMode
1243
+ ? _tags.filter(tag => tag.tag_type === currentTagPaneMode)
1244
+ : _tags;
1245
+ for (const tag of tagsToUpdate) {
1246
+ const tagType = tag.tag_type || TAG_TYPE.MP;
1247
+ const tagId = tag.json_data.id;
1248
+ // Initialize type object if it doesn't exist
1249
+ if (!tagVisibility[tagType]) {
1250
+ tagVisibility[tagType] = {};
1251
+ }
1252
+ // Update visibility state
1253
+ tagVisibility[tagType][tagId] = visible;
1254
+ yield toggleVisibilityTag({ tagId: tagId, visibility: visible });
1255
+ // Update button icon
1256
+ const btn = document.getElementById(`at-visibility-tag-${tagId}`);
1257
+ if (btn) {
1258
+ btn.classList.toggle("mdi-eye", visible);
1259
+ btn.classList.toggle("mdi-eye-off-outline", !visible);
1260
+ }
1261
+ }
1262
+ // Update the main toggle button
1263
+ updateShowAllButton();
1264
+ // Save to localStorage
1265
+ saveTagVisibilityToStorage(tagVisibility);
1266
+ });
1267
+ toggleVisibilityBtn.addEventListener('click', () => {
1268
+ // Check if all visible tags in current mode are hidden
1269
+ let allHidden = false;
1270
+ if (currentTagPaneMode === TAG_TYPE.IOT) {
1271
+ // Check only IOT tags
1272
+ const iotVisibility = Object.values(tagVisibility[TAG_TYPE.IOT] || {});
1273
+ allHidden = iotVisibility.length > 0 && iotVisibility.every(v => v === false);
1274
+ }
1275
+ else if (currentTagPaneMode === TAG_TYPE.MP) {
1276
+ // Check only MP tags
1277
+ const mpVisibility = Object.values(tagVisibility[TAG_TYPE.MP] || {});
1278
+ allHidden = mpVisibility.length > 0 && mpVisibility.every(v => v === false);
1279
+ }
1280
+ else {
1281
+ // Check all tags (both MP and IOT)
1282
+ const allValues = [
1283
+ ...Object.values(tagVisibility[TAG_TYPE.MP] || {}),
1284
+ ...Object.values(tagVisibility[TAG_TYPE.IOT] || {})
1285
+ ];
1286
+ allHidden = allValues.length > 0 && allValues.every(v => v === false);
1287
+ }
1288
+ // Toggle: if all hidden, show all; if any visible, hide all
1289
+ updateAll(allHidden);
1290
+ });
1291
+ }
1227
1292
  function handleScreenshot() {
1228
1293
  var _a, _b, _c, _d, _e, _f, _g, _h;
1229
1294
  const screenshotBtn = document.getElementById('at-screenshot-btn');
@@ -1505,9 +1570,8 @@ function setupSpaceEventSubscriptions() {
1505
1570
  subscribeSpaceEvent(SPACE_EVENTS.TAGPLACER_CREATED, handleTagPlacerCreated);
1506
1571
  subscribeSpaceEvent(SPACE_EVENTS.UPDATE_ROOM_TREE, handleUpdateRoomTree);
1507
1572
  subscribeSpaceEvent(SPACE_EVENTS.PARTITION_CLICKED, handlePartitionSelected);
1508
- subscribeSpaceEvent(SPACE_EVENTS.VERTEX_DRAG_END, setCurrentPartitionData);
1573
+ subscribeSpaceEvent(SPACE_EVENTS.VERTEX_DRAG_END, handleVertexDragEnd);
1509
1574
  subscribeSpaceEvent(SPACE_EVENTS.VERTEX_PLACED, handleVertexPlace);
1510
- subscribeSpaceEvent(SPACE_EVENTS.DRAW_HISTORY, handleDrawHistory);
1511
1575
  subscribeSpaceEvent(SPACE_EVENTS.FLOOR_IMAGE_UPLOADED, handleCustomMapFloorImageUploaded);
1512
1576
  subscribeSpaceEvent(SPACE_EVENTS.FLOOR_IMAGE_UPLOAD_FAILED, handleCustomMapFloorUploadFailed);
1513
1577
  subscribeSpaceEvent(SPACE_EVENTS.TAG_SANDBOX_REGISTERED, handleSandboxRegistered);
@@ -1518,6 +1582,31 @@ function setupSpaceEventSubscriptions() {
1518
1582
  subscribeSpaceEvent(SPACE_EVENTS.SCREEN_SHARE_ACCEPT_REQUEST, handleScreenShareAcceptRequest);
1519
1583
  subscribeSpaceEvent(SPACE_EVENTS.SCREEN_SHARE_BACK_USER_LIST_PANE, handleScreenShareBackUserListPane);
1520
1584
  }
1585
+ function handleVertexDragEnd(payload) {
1586
+ log.info("handleVertexDragEnd()", payload);
1587
+ setCurrentPartitionData();
1588
+ if (isToolbarFeatureEnabled("roomCreation")) {
1589
+ let data;
1590
+ const currentPartitionData = _.cloneDeep(getCurrentPartitionData());
1591
+ const currentPolygonData = _.cloneDeep(getCurrentPolygonData());
1592
+ const currentWall = getCurrentWall();
1593
+ const wallIndex = currentPolygonData.walls.findIndex(w => w.uuid == currentWall.uuid);
1594
+ if (currentPartitionData) {
1595
+ data = {
1596
+ polygon: {
1597
+ uuid: currentPartitionData.uuid,
1598
+ polygon_json: currentPolygonData
1599
+ },
1600
+ verticePath: currentPolygonData.walls[wallIndex].windows[currentWindow.index].path
1601
+ };
1602
+ partitionHistory.addToHistory(JSON.parse(JSON.stringify(data)));
1603
+ }
1604
+ log.info("all history", partitionHistory.getAllHistory());
1605
+ }
1606
+ // partitionHistory.addToHistory(data)
1607
+ // polygonHistory.addToHistory(payload)
1608
+ // toggleUndoRedoButtons(polygonHistory.canUndo(), polygonHistory.canRedo())
1609
+ }
1521
1610
  function handlePartitionColiderClickSelected(payload) {
1522
1611
  return __awaiter(this, void 0, void 0, function* () {
1523
1612
  const polygonId = extractUUID(payload.collider.name);
@@ -1586,43 +1675,10 @@ function handleDragEnd(payload) {
1586
1675
  };
1587
1676
  setCurrentTransformationValues(transformValues);
1588
1677
  }
1589
- function handleDrawHistory(payload) {
1590
- console.log("handleDrawHistory", payload);
1591
- const undoCount = (payload.undoDrawActions).length;
1592
- const redoCount = (payload.redoDrawActions).length;
1593
- if (undoCount == 0) {
1594
- const undoBtn = document.getElementById('at-draw-undo-btn');
1595
- undoBtn.classList.add('at_disabled');
1596
- }
1597
- else {
1598
- const undoBtn = document.getElementById('at-draw-undo-btn');
1599
- undoBtn.classList.remove('at_disabled');
1600
- }
1601
- if (redoCount == 0) {
1602
- const redoBtn = document.getElementById('at-draw-redo-btn');
1603
- redoBtn.classList.add('at_disabled');
1604
- }
1605
- else {
1606
- const redoBtn = document.getElementById('at-draw-redo-btn');
1607
- redoBtn.classList.remove('at_disabled');
1608
- }
1609
- console.log("undoCount", undoCount);
1610
- console.log("redoCount", redoCount);
1611
- }
1612
1678
  function handleVertexPlace(payload) {
1613
1679
  console.log("handleVertexPlace ==>", payload);
1614
1680
  if (isToolbarFeatureEnabled('roomCreation')) {
1615
- log.info("getDrawingMode()", getDrawingMode());
1616
- if (getDrawingMode() === 'window') {
1617
- log.info("current polygon", getCurrentPolygon());
1618
- }
1619
- if (getDrawingMode() === 'partition') {
1620
- // setCurrentPartitionData()
1621
- }
1622
- const undoBtn = document.getElementById('at-draw-undo-btn');
1623
- undoBtn.classList.remove('at_disabled');
1624
- const redoBtn = document.getElementById('at-draw-redo-btn');
1625
- redoBtn.classList.add('at_disabled');
1681
+ toggleUndoRedoButtons(partitionHistory.canUndo(), partitionHistory.canRedo());
1626
1682
  }
1627
1683
  if (isToolbarFeatureEnabled('pipe')) {
1628
1684
  pipeForm.setPipeVertices(payload.path);
@@ -2338,11 +2394,6 @@ function handleCancelPartition() {
2338
2394
  clearSelectedObject();
2339
2395
  clearFloorBaseHeight();
2340
2396
  toggleDisplayPane('at-cancel-room-form-btn');
2341
- const drawHistory = {
2342
- redoDrawActions: [],
2343
- undoDrawActions: [],
2344
- };
2345
- handleDrawHistory(drawHistory);
2346
2397
  }));
2347
2398
  }
2348
2399
  /**
@@ -3944,6 +3995,7 @@ function handlePreviewModalResize() {
3944
3995
  // Handle horizontal resizing
3945
3996
  if (direction === null || direction === void 0 ? void 0 : direction.includes('right')) {
3946
3997
  newWidth = Math.max(minWidth, Math.min(maxWidth, startWidth + deltaX));
3998
+ // Don't change left position for right resize
3947
3999
  }
3948
4000
  else if (direction === null || direction === void 0 ? void 0 : direction.includes('left')) {
3949
4001
  const potentialWidth = startWidth - deltaX;
@@ -3991,4 +4043,4 @@ activeToolbarItem, activeActionItem, cancelModelPlacementPrompt, isCustomMapCont
3991
4043
  //methods
3992
4044
  batchAddEventListenerById, batchAddEventListenerByClassName, batchAddEventListenerByClassNames, batchAddEventListenerByDataAttribute, setActiveToolbarItem, toggleDisplayPane, toggleActionBar, setupIndividualEventListeners, setupSpaceEventSubscriptions, handleModelVisibility, handleDeleteModel, handleShowMinimap, handleScrollToView, handleRenderMeetingUI, handleShowCustomMinimap, renderTagPaneContent,
3993
4045
  // partition
3994
- handlePartitionVisibility, handlePolygonVisibility, handleDeletePartition, handleDisplayElements, handleWindowVisibility, clearActivePane };
4046
+ handlePartitionVisibility, handlePolygonVisibility, handleDeletePartition, handleToggleVisibilityTags, handleDisplayElements, handleWindowVisibility, clearActivePane };
@@ -76,6 +76,7 @@ export declare class Vertice {
76
76
  texture: THREE.CanvasTexture;
77
77
  pointerSub: MpSdk.ISubscription;
78
78
  pointerIntersection: MpSdk.Pointer.Intersection;
79
+ cachedWallNormal: THREE.Vector3 | null;
79
80
  constructor(mpSdk: MpSdk);
80
81
  inputs: {
81
82
  index: any;
@@ -98,6 +99,7 @@ export declare class Vertice {
98
99
  'INTERACTION.HOVER': boolean;
99
100
  };
100
101
  onInputsUpdated: (prevInputs: any) => void;
102
+ calculateWallNormalFromVertices(): THREE.Vector3 | null;
101
103
  onEvent(eventType: any, data: any): void;
102
104
  onInit: () => void;
103
105
  renderVertice: (hovered?: boolean) => void;
@@ -184,6 +184,10 @@ export class TubeLine {
184
184
  if (this.panel) {
185
185
  this.panel.refresh();
186
186
  }
187
+ dispatchSpaceEvent(SPACE_EVENTS.PATH_UPDATED, {
188
+ path: this.inputs.path,
189
+ textColor: this.inputs.textColor
190
+ });
187
191
  };
188
192
  this.setBillboard = (value) => {
189
193
  this.billboard = value;
@@ -367,6 +371,7 @@ export const tubeLineFactory = function (mpSdk) {
367
371
  };
368
372
  export class Vertice {
369
373
  constructor(mpSdk) {
374
+ this.cachedWallNormal = null;
370
375
  this.inputs = {
371
376
  index: null,
372
377
  radius: 0.1,
@@ -418,6 +423,25 @@ export class Vertice {
418
423
  };
419
424
  this.mpSdk = mpSdk;
420
425
  }
426
+ calculateWallNormalFromVertices() {
427
+ const vertexPath = getVertexPath();
428
+ if (!vertexPath || vertexPath.length < 3) {
429
+ return null;
430
+ }
431
+ const THREE = this.context.three;
432
+ const p0 = new THREE.Vector3(vertexPath[0].x, vertexPath[0].y, vertexPath[0].z);
433
+ const p1 = new THREE.Vector3(vertexPath[1].x, vertexPath[1].y, vertexPath[1].z);
434
+ const p2 = new THREE.Vector3(vertexPath[2].x, vertexPath[2].y, vertexPath[2].z);
435
+ const v1 = new THREE.Vector3().subVectors(p1, p0);
436
+ const v2 = new THREE.Vector3().subVectors(p2, p0);
437
+ const normal = new THREE.Vector3().crossVectors(v1, v2);
438
+ const normalLen = normal.length();
439
+ if (normalLen === 0) {
440
+ // Vertices are collinear, can't determine plane
441
+ return null;
442
+ }
443
+ return normal.normalize();
444
+ }
421
445
  onEvent(eventType, data) {
422
446
  var _a;
423
447
  if (eventType === 'INTERACTION.DRAG') {
@@ -438,24 +462,30 @@ export class Vertice {
438
462
  if (drawingConfig && drawingConfig.lineTypeComponentConfig.drawingMode == 'window') {
439
463
  const firstVertex = getVertexPath()[0];
440
464
  // Skip constraint for first vertex (index 0) - it defines the wall plane
441
- if (this.inputs.index !== 0 && firstVertex && this.pointerIntersection.normal) {
465
+ if (this.inputs.index !== 0 && firstVertex) {
442
466
  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;
467
+ // Use cached normal if available, otherwise fall back to pointer normal
468
+ let wallNormal = this.cachedWallNormal;
469
+ if (!wallNormal && this.pointerIntersection.normal) {
470
+ // Fallback for when we don't have 3 vertices yet
471
+ wallNormal = new THREE.Vector3(this.pointerIntersection.normal.x, this.pointerIntersection.normal.y, this.pointerIntersection.normal.z).normalize();
472
+ }
473
+ if (wallNormal) {
474
+ // First vertex position defines a point on the wall plane
475
+ const planePoint = new THREE.Vector3(firstVertex.x, firstVertex.y, firstVertex.z);
476
+ // Current drag position
477
+ const dragPosition = new THREE.Vector3(e.x, e.y, e.z);
478
+ // Vector from plane point to drag position
479
+ const vecToPoint = new THREE.Vector3().subVectors(dragPosition, planePoint);
480
+ // Calculate distance from point to plane along normal
481
+ const distanceToPlane = vecToPoint.dot(wallNormal);
482
+ // Project point onto plane by removing the perpendicular component
483
+ const projectedPosition = new THREE.Vector3().subVectors(dragPosition, wallNormal.clone().multiplyScalar(distanceToPlane));
484
+ // Update e with constrained position (stays on wall plane)
485
+ e.x = projectedPosition.x;
486
+ e.y = projectedPosition.y;
487
+ e.z = projectedPosition.z;
488
+ }
459
489
  }
460
490
  }
461
491
  this.mesh.position.set(e.x, e.y, e.z);
@@ -480,6 +510,11 @@ export class Vertice {
480
510
  this.pointerIntersection = data;
481
511
  });
482
512
  }
513
+ // Cache wall normal for window mode
514
+ const drawingConfig = getDrawingConfig();
515
+ if (drawingConfig && drawingConfig.lineTypeComponentConfig.drawingMode === 'window') {
516
+ this.cachedWallNormal = this.calculateWallNormalFromVertices();
517
+ }
483
518
  //@ts-expect-error
484
519
  this.notify('changed', {
485
520
  index: this.inputs.index,
@@ -493,6 +528,8 @@ export class Vertice {
493
528
  this.mesh.scale.set(1, 1, 1);
494
529
  this.mpSdk.Pointer.setVisible(true);
495
530
  (_a = this.pointerSub) === null || _a === void 0 ? void 0 : _a.cancel();
531
+ // Clear cached wall normal
532
+ this.cachedWallNormal = null;
496
533
  //renderPolygonFromPath()
497
534
  //@ts-expect-error
498
535
  this.notify('changed', {
package/lib/tag.d.ts CHANGED
@@ -95,4 +95,9 @@ declare function attachSandbox(payload: {
95
95
  sandboxId: string;
96
96
  messenger: MpSdk.Tag.IMessenger;
97
97
  }>;
98
- export { renderTag, disposeTag, moveTag, attachTagMedia, detachTagMedia, setTagIcon, editBillboard, editStem, editColor, saveTagDb, deleteTag, getTagColorCodeID, getEmbedlyData, cancelMoveTag, handleTagPlacerCreated, attachSandbox, registerSandbox };
98
+ declare function toggleTagVisibility(payload: {
99
+ tagId: string;
100
+ sdk: MpSdk;
101
+ visibility: boolean;
102
+ }): void;
103
+ export { renderTag, disposeTag, moveTag, attachTagMedia, detachTagMedia, setTagIcon, editBillboard, editStem, editColor, saveTagDb, deleteTag, getTagColorCodeID, getEmbedlyData, cancelMoveTag, handleTagPlacerCreated, attachSandbox, registerSandbox, toggleTagVisibility };
package/lib/tag.js CHANGED
@@ -432,7 +432,14 @@ function attachSandbox(payload) {
432
432
  }
433
433
  });
434
434
  }
435
- export { renderTag, disposeTag, moveTag, attachTagMedia, detachTagMedia, setTagIcon, editBillboard, editStem, editColor, saveTagDb, deleteTag, getTagColorCodeID, getEmbedlyData, cancelMoveTag, handleTagPlacerCreated, attachSandbox, registerSandbox };
435
+ function toggleTagVisibility(payload) {
436
+ payload.sdk.Tag.editOpacity(payload.tagId, payload.visibility ? 1 : 0);
437
+ payload.sdk.Tag.allowAction(payload.tagId, {
438
+ opening: payload.visibility,
439
+ navigating: true
440
+ });
441
+ }
442
+ export { renderTag, disposeTag, moveTag, attachTagMedia, detachTagMedia, setTagIcon, editBillboard, editStem, editColor, saveTagDb, deleteTag, getTagColorCodeID, getEmbedlyData, cancelMoveTag, handleTagPlacerCreated, attachSandbox, registerSandbox, toggleTagVisibility };
436
443
  // # -------------------------------------------------------------------------
437
444
  // # tag
438
445
  // # -------------------------------------------------------------------------
package/lib/types.d.ts CHANGED
@@ -154,6 +154,7 @@ export interface IMPConfig {
154
154
  };
155
155
  restrictionConfig?: {
156
156
  isTagReadOnly?: boolean;
157
+ isIoTtagReadonly?: boolean;
157
158
  isTagToggleSharing?: boolean;
158
159
  };
159
160
  sweepPuckConfig?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "architwin",
3
- "version": "1.15.5",
3
+ "version": "1.16.0",
4
4
  "description": "ArchiTwin Library for Matterport",
5
5
  "main": "./lib/architwin.js",
6
6
  "types": "./lib/architwin.d.ts",
@@ -676,12 +676,19 @@
676
676
 
677
677
  .at_table_button_row {
678
678
  display: flex;
679
- flex-wrap: nowrap;
680
- flex-direction: row;
681
- justify-content: space-between;
682
- align-items: auto;
683
- align-content: start;
684
- margin-right: 0.5em;
679
+ justify-content: end;
680
+ width: fit-content;
681
+ }
682
+
683
+ .at_table_label_row{
684
+ width: 130px;
685
+ }
686
+
687
+ .at_table_label_row span {
688
+ display: block;
689
+ overflow: hidden;
690
+ text-overflow: ellipsis;
691
+ white-space: nowrap;
685
692
  }
686
693
 
687
694
  /*Form Classes*/
@@ -769,8 +776,8 @@
769
776
  margin-top: 1px;
770
777
  margin-left: 4px;
771
778
  height: 2.45rem;
772
- /* width: 9rem; */
773
- width: 13rem
779
+ width: 100%;
780
+ /* width: 11.75rem */
774
781
  }
775
782
 
776
783
  .at_field_search_input:focus {
@@ -1262,7 +1269,7 @@
1262
1269
  height: 100%;
1263
1270
  background: rgba(0, 0, 0, 0.8);
1264
1271
  z-index: 1000;
1265
- justify-content: center;
1272
+ justify-content: flex-start;
1266
1273
  align-items: center;
1267
1274
  animation: at_fade-in 0.3s ease;
1268
1275
  }
@@ -1285,15 +1292,16 @@
1285
1292
  color: var(--text-color-light);
1286
1293
  border-radius: var(--border-radius);
1287
1294
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
1288
- width: 95vw;
1295
+ width: 66.5vw;
1289
1296
  height: 95vh;
1290
- max-width: 95vw;
1297
+ max-width: 66.5vw;
1291
1298
  max-height: 95vh;
1292
1299
  overflow: hidden;
1293
1300
  position: relative;
1294
1301
  animation: at_slide-up 0.4s cubic-bezier(.39, .575, .565, 1.000) both;
1295
1302
  display: flex;
1296
1303
  flex-direction: column;
1304
+ margin-left: 0.5vw;
1297
1305
  }
1298
1306
 
1299
1307
  @keyframes at_slide-up {
@@ -1689,7 +1697,7 @@
1689
1697
  .at_tag_list_pane {
1690
1698
  margin: 6px 6px 0px 6px !important;
1691
1699
  gap: 0px !important;
1692
- padding: 10px 10px 5px 10px !important;
1700
+ padding: 0px 5px 5px 10px !important;
1693
1701
  }
1694
1702
 
1695
1703
  /* Basic styling for the tree */
@@ -2382,11 +2390,6 @@ dialog#at-screen-share-request-modal::backdrop {
2382
2390
  margin-top: 1px;
2383
2391
  }
2384
2392
 
2385
- #at-tag-sort-icon {
2386
- background-color: var(--bg-secondary);
2387
- margin-bottom: 15px;
2388
- margin-right: -15px;
2389
- }
2390
2393
 
2391
2394
  #at-object-sort-icon {
2392
2395
  background-color: var(--bg-secondary);