@ifc-lite/viewer 1.17.4 → 1.18.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/.turbo/turbo-build.log +20 -17
- package/.turbo/turbo-typecheck.log +1 -1
- package/CHANGELOG.md +630 -0
- package/DESKTOP_CONTRACT_VERSION +1 -1
- package/dist/assets/{basketViewActivator-BmnNtVfZ.js → basketViewActivator-Cm1QEk_R.js} +1 -1
- package/dist/assets/drawing-2d-DoxKMqbO.js +257 -0
- package/dist/assets/{exporters-ChAtBmlj.js → exporters-B_OBqIyD.js} +3479 -2845
- package/dist/assets/{geometry.worker-BQ0rzNo-.js → geometry.worker-xHHy-9DV.js} +1 -1
- package/dist/assets/ids-DQ5jY0E8.js +1 -0
- package/dist/assets/ifc-lite_bg-ADjKXSms.wasm +0 -0
- package/dist/assets/{index-Co8E2-FE.js → index-BKq-M3Mk.js} +55873 -40593
- package/dist/assets/index-COnQRuqY.css +1 -0
- package/dist/assets/{native-bridge-BRvbckFQ.js → native-bridge-SHXiQwFW.js} +104 -104
- package/dist/assets/sandbox-jez21HtV.js +9627 -0
- package/dist/assets/{server-client-BV8zHZ7Y.js → server-client-ncOQVNso.js} +1 -1
- package/dist/assets/{wasm-bridge-g01g7T9b.js → wasm-bridge-DyfBSB8z.js} +1 -1
- package/dist/index.html +8 -7
- package/index.html +1 -0
- package/package.json +13 -13
- package/src/App.tsx +16 -2
- package/src/apache-arrow.d.ts +30 -0
- package/src/components/viewer/AddElementPanel.tsx +758 -0
- package/src/components/viewer/BulkPropertyEditor.tsx +7 -0
- package/src/components/viewer/CesiumOverlay.tsx +62 -19
- package/src/components/viewer/ChatPanel.tsx +259 -93
- package/src/components/viewer/CommandPalette.tsx +56 -7
- package/src/components/viewer/EntityContextMenu.tsx +168 -4
- package/src/components/viewer/ExportChangesButton.tsx +25 -5
- package/src/components/viewer/ExportDialog.tsx +19 -1
- package/src/components/viewer/MainToolbar.tsx +73 -13
- package/src/components/viewer/PropertiesPanel.tsx +237 -23
- package/src/components/viewer/SearchInline.tsx +669 -0
- package/src/components/viewer/SearchModal.filter.builder.tsx +766 -0
- package/src/components/viewer/SearchModal.filter.tsx +514 -0
- package/src/components/viewer/SearchModal.text.tsx +388 -0
- package/src/components/viewer/SearchModal.tsx +235 -0
- package/src/components/viewer/SettingsPage.tsx +252 -101
- package/src/components/viewer/ThemeSwitch.tsx +63 -7
- package/src/components/viewer/ToolOverlays.tsx +5 -0
- package/src/components/viewer/ViewerLayout.tsx +25 -4
- package/src/components/viewer/Viewport.tsx +25 -3
- package/src/components/viewer/ViewportContainer.tsx +51 -64
- package/src/components/viewer/ViewportOverlays.tsx +5 -2
- package/src/components/viewer/annotations/AnnotationDropInput.tsx +203 -0
- package/src/components/viewer/annotations/AnnotationLayer.tsx +287 -0
- package/src/components/viewer/annotations/AnnotationPin.tsx +90 -0
- package/src/components/viewer/annotations/AnnotationPopover.tsx +296 -0
- package/src/components/viewer/bcf/BCFTopicDetail.tsx +4 -4
- package/src/components/viewer/chat/ModelSelector.tsx +90 -54
- package/src/components/viewer/lists/ListPanel.tsx +14 -21
- package/src/components/viewer/properties/GeoreferencingPanel.tsx +113 -51
- package/src/components/viewer/properties/LocationMap.tsx +9 -7
- package/src/components/viewer/properties/ModelMetadataPanel.tsx +1 -1
- package/src/components/viewer/properties/RawStepCard.tsx +332 -0
- package/src/components/viewer/properties/RawStepRow.tsx +261 -0
- package/src/components/viewer/properties/ScheduleCard.tsx +224 -0
- package/src/components/viewer/properties/TaskEditCard.tsx +510 -0
- package/src/components/viewer/properties/raw-step-format.ts +193 -0
- package/src/components/viewer/schedule/AnimationSettingsPopover.tsx +542 -0
- package/src/components/viewer/schedule/GanttDependencyArrows.tsx +89 -0
- package/src/components/viewer/schedule/GanttDragTooltip.tsx +48 -0
- package/src/components/viewer/schedule/GanttEmptyState.tsx +97 -0
- package/src/components/viewer/schedule/GanttPanel.tsx +295 -0
- package/src/components/viewer/schedule/GanttTaskBar.tsx +199 -0
- package/src/components/viewer/schedule/GanttTaskTree.tsx +250 -0
- package/src/components/viewer/schedule/GanttTimeline.tsx +305 -0
- package/src/components/viewer/schedule/GanttToolbar.tsx +406 -0
- package/src/components/viewer/schedule/GenerateAdvancedPanel.tsx +147 -0
- package/src/components/viewer/schedule/GenerateScheduleDialog.tsx +392 -0
- package/src/components/viewer/schedule/HeightStrategyPanel.tsx +120 -0
- package/src/components/viewer/schedule/generate-schedule.test.ts +439 -0
- package/src/components/viewer/schedule/generate-schedule.ts +648 -0
- package/src/components/viewer/schedule/schedule-animator.test.ts +452 -0
- package/src/components/viewer/schedule/schedule-animator.ts +488 -0
- package/src/components/viewer/schedule/schedule-selection.test.ts +148 -0
- package/src/components/viewer/schedule/schedule-selection.ts +163 -0
- package/src/components/viewer/schedule/schedule-utils.ts +223 -0
- package/src/components/viewer/schedule/useConstructionSequence.ts +156 -0
- package/src/components/viewer/schedule/useGanttBarDrag.test.ts +90 -0
- package/src/components/viewer/schedule/useGanttBarDrag.ts +305 -0
- package/src/components/viewer/schedule/useGanttSelection3DHighlight.ts +152 -0
- package/src/components/viewer/schedule/useOverlayCompositor.ts +108 -0
- package/src/components/viewer/selectionHandlers.ts +446 -0
- package/src/components/viewer/tools/AddElementOverlay.tsx +540 -0
- package/src/components/viewer/tools/SectionCapControls.tsx +237 -0
- package/src/components/viewer/tools/SectionPanel.tsx +39 -18
- package/src/components/viewer/useAnimationLoop.ts +9 -1
- package/src/components/viewer/useDuplicateShortcut.ts +77 -0
- package/src/components/viewer/useMouseControls.ts +9 -1
- package/src/components/viewer/useRenderUpdates.ts +1 -1
- package/src/hooks/ids/idsDataAccessor.ts +60 -24
- package/src/hooks/ingest/viewerModelIngest.ts +7 -2
- package/src/hooks/useIfcFederation.ts +326 -71
- package/src/hooks/useIfcLoader.ts +23 -10
- package/src/hooks/useKeyboardShortcuts.ts +25 -0
- package/src/hooks/useSandbox.ts +1 -1
- package/src/hooks/useSearchIndex.ts +125 -0
- package/src/hooks/useViewControls.ts +13 -5
- package/src/index.css +550 -10
- package/src/lib/desktop-entitlement.ts +2 -4
- package/src/lib/geo/cesium-bridge.ts +15 -7
- package/src/lib/geo/effective-georef.test.ts +73 -0
- package/src/lib/geo/effective-georef.ts +111 -0
- package/src/lib/geo/reproject.ts +105 -19
- package/src/lib/llm/byok-guard.test.ts +77 -0
- package/src/lib/llm/byok-guard.ts +39 -0
- package/src/lib/llm/free-models.test.ts +0 -6
- package/src/lib/llm/models.ts +104 -42
- package/src/lib/llm/stream-client.ts +74 -110
- package/src/lib/llm/stream-direct.test.ts +130 -0
- package/src/lib/llm/stream-direct.ts +316 -0
- package/src/lib/llm/system-prompt.test.ts +14 -0
- package/src/lib/llm/system-prompt.ts +102 -1
- package/src/lib/llm/types.ts +20 -2
- package/src/lib/recent-files.ts +38 -4
- package/src/lib/scripts/templates/bim-globals.d.ts +136 -114
- package/src/lib/scripts/templates/construction-schedule.ts +223 -0
- package/src/lib/scripts/templates.ts +7 -0
- package/src/lib/search/common-ifc-types.ts +36 -0
- package/src/lib/search/filter-evaluate.test.ts +537 -0
- package/src/lib/search/filter-evaluate.ts +610 -0
- package/src/lib/search/filter-rules.test.ts +119 -0
- package/src/lib/search/filter-rules.ts +198 -0
- package/src/lib/search/filter-schema.test.ts +233 -0
- package/src/lib/search/filter-schema.ts +146 -0
- package/src/lib/search/recent-searches.test.ts +116 -0
- package/src/lib/search/recent-searches.ts +93 -0
- package/src/lib/search/result-export.test.ts +101 -0
- package/src/lib/search/result-export.ts +104 -0
- package/src/lib/search/saved-filters.test.ts +118 -0
- package/src/lib/search/saved-filters.ts +154 -0
- package/src/lib/search/tier0-scan.test.ts +196 -0
- package/src/lib/search/tier0-scan.ts +237 -0
- package/src/lib/search/tier1-index.test.ts +242 -0
- package/src/lib/search/tier1-index.ts +448 -0
- package/src/main.tsx +1 -10
- package/src/sdk/adapters/export-adapter.test.ts +434 -1
- package/src/sdk/adapters/export-adapter.ts +404 -1
- package/src/sdk/adapters/export-schedule-splice.test.ts +127 -0
- package/src/sdk/adapters/export-schedule-splice.ts +87 -0
- package/src/sdk/adapters/model-compat.ts +8 -2
- package/src/sdk/adapters/schedule-adapter.ts +73 -0
- package/src/sdk/adapters/store-adapter.ts +201 -0
- package/src/sdk/adapters/visibility-adapter.ts +3 -0
- package/src/sdk/local-backend.ts +16 -8
- package/src/services/api-keys.ts +73 -0
- package/src/services/desktop-export.ts +3 -1
- package/src/services/desktop-native-metadata.ts +41 -18
- package/src/services/file-dialog.ts +4 -1
- package/src/services/tauri-modules.d.ts +25 -0
- package/src/store/basketVisibleSet.ts +3 -0
- package/src/store/constants.ts +20 -2
- package/src/store/globalId.ts +4 -1
- package/src/store/index.ts +82 -6
- package/src/store/slices/addElementMeshes.ts +365 -0
- package/src/store/slices/addElementSlice.ts +275 -0
- package/src/store/slices/annotationsSlice.test.ts +133 -0
- package/src/store/slices/annotationsSlice.ts +251 -0
- package/src/store/slices/cesiumSlice.ts +5 -0
- package/src/store/slices/chatSlice.test.ts +6 -76
- package/src/store/slices/chatSlice.ts +17 -58
- package/src/store/slices/dataSlice.test.ts +23 -4
- package/src/store/slices/dataSlice.ts +1 -1
- package/src/store/slices/modelSlice.test.ts +67 -9
- package/src/store/slices/modelSlice.ts +39 -7
- package/src/store/slices/mutationSlice.ts +964 -3
- package/src/store/slices/overlayCompositor.test.ts +164 -0
- package/src/store/slices/overlaySlice.test.ts +93 -0
- package/src/store/slices/overlaySlice.ts +151 -0
- package/src/store/slices/pinboardSlice.test.ts +6 -1
- package/src/store/slices/playbackSlice.ts +128 -0
- package/src/store/slices/schedule-edit-helpers.test.ts +97 -0
- package/src/store/slices/schedule-edit-helpers.ts +179 -0
- package/src/store/slices/scheduleSlice.test.ts +694 -0
- package/src/store/slices/scheduleSlice.ts +1330 -0
- package/src/store/slices/searchSlice.test.ts +342 -0
- package/src/store/slices/searchSlice.ts +341 -0
- package/src/store/slices/sectionSlice.test.ts +87 -7
- package/src/store/slices/sectionSlice.ts +151 -5
- package/src/store/slices/selectionSlice.test.ts +46 -0
- package/src/store/slices/selectionSlice.ts +20 -0
- package/src/store/slices/uiSlice.ts +28 -5
- package/src/store/types.ts +26 -0
- package/src/store.ts +14 -0
- package/src/utils/nativeSpatialDataStore.ts +4 -1
- package/src/utils/viewportUtils.ts +7 -2
- package/src/vite-env.d.ts +0 -4
- package/dist/assets/drawing-2d-gWfpdfYe.js +0 -257
- package/dist/assets/ids-B4jTqB1O.js +0 -1
- package/dist/assets/ifc-lite_bg-BX4E7TX8.wasm +0 -0
- package/dist/assets/index-DckuDqlv.css +0 -1
- package/dist/assets/sandbox-DZiNLNMk.js +0 -5933
- package/src/components/viewer/UpgradePage.tsx +0 -71
- package/src/lib/desktop/ClerkDesktopEntitlementSync.tsx +0 -175
- package/src/lib/llm/ClerkChatSync.tsx +0 -74
- package/src/lib/llm/clerk-auth.ts +0 -62
package/src/index.css
CHANGED
|
@@ -379,6 +379,43 @@ body {
|
|
|
379
379
|
color: var(--color-primary) !important;
|
|
380
380
|
}
|
|
381
381
|
|
|
382
|
+
/* Raw STEP tab — terminal-flavoured dev affordance.
|
|
383
|
+
Compact (icon-only </>), separates visually from the three "human"
|
|
384
|
+
tabs with a left divider and a green active state that nods to a
|
|
385
|
+
shell cursor. Stays width-stable at narrow panel widths because
|
|
386
|
+
it explicitly opts out of `flex: 1` (uses an `auto`-ish width
|
|
387
|
+
driven by the </> glyph plus padding). */
|
|
388
|
+
.properties-tab-trigger.raw-step-tab-trigger {
|
|
389
|
+
flex: 0 0 auto;
|
|
390
|
+
min-width: 2.25rem;
|
|
391
|
+
padding-left: 0.5rem;
|
|
392
|
+
padding-right: 0.5rem;
|
|
393
|
+
border-left: 1px solid var(--tabs-border);
|
|
394
|
+
letter-spacing: 0;
|
|
395
|
+
color: color-mix(in srgb, var(--tab-text) 70%, transparent) !important;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.properties-tab-trigger.raw-step-tab-trigger:hover {
|
|
399
|
+
background-color: color-mix(in srgb, #10b981 16%, var(--tabs-bg)) !important;
|
|
400
|
+
color: #047857 !important;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
.dark .properties-tab-trigger.raw-step-tab-trigger:hover {
|
|
404
|
+
background-color: color-mix(in srgb, #10b981 22%, var(--tabs-bg)) !important;
|
|
405
|
+
color: #34d399 !important;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
.properties-tab-trigger.raw-step-tab-trigger[data-state="active"] {
|
|
409
|
+
background-color: color-mix(in srgb, #10b981 14%, var(--tab-active-bg)) !important;
|
|
410
|
+
color: #047857 !important;
|
|
411
|
+
border-top-color: #10b981 !important;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
.dark .properties-tab-trigger.raw-step-tab-trigger[data-state="active"] {
|
|
415
|
+
color: #34d399 !important;
|
|
416
|
+
border-top-color: #34d399 !important;
|
|
417
|
+
}
|
|
418
|
+
|
|
382
419
|
/* Quantity cards - cyan accent */
|
|
383
420
|
.dark .border-blue-200,
|
|
384
421
|
.dark .border-blue-800,
|
|
@@ -412,6 +449,490 @@ body {
|
|
|
412
449
|
background-color: rgba(115, 218, 202, 0.05) !important;
|
|
413
450
|
}
|
|
414
451
|
|
|
452
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
453
|
+
COLORFUL MODE — Brutalist Aurora
|
|
454
|
+
Shift+click the toggle. The same sharp, functional, dense UI — but the
|
|
455
|
+
sky opened up. An aurora gradient behind the 3D scene, frosted-glass
|
|
456
|
+
panels, and the full Tokyo Night accent palette in its natural places.
|
|
457
|
+
No decorative borders. No gradient buttons. Just atmosphere.
|
|
458
|
+
═══════════════════════════════════════════════════════════════════════════ */
|
|
459
|
+
|
|
460
|
+
@custom-variant colorful (&:where(.colorful, .colorful *));
|
|
461
|
+
|
|
462
|
+
.colorful {
|
|
463
|
+
/* Tokyo Night accent palette — used only where colour already exists */
|
|
464
|
+
--cf-blue: #7aa2f7;
|
|
465
|
+
--cf-cyan: #7dcfff;
|
|
466
|
+
--cf-teal: #73daca;
|
|
467
|
+
--cf-magenta: #bb9af7;
|
|
468
|
+
--cf-purple: #9d7cd8;
|
|
469
|
+
--cf-orange: #ff9e64;
|
|
470
|
+
--cf-pink: #f7768e;
|
|
471
|
+
--cf-green: #9ece6a;
|
|
472
|
+
--cf-yellow: #e0af68;
|
|
473
|
+
|
|
474
|
+
/* Glass */
|
|
475
|
+
--cf-glass: rgba(255, 255, 255, 0.48);
|
|
476
|
+
--cf-glass-strong: rgba(255, 255, 255, 0.68);
|
|
477
|
+
|
|
478
|
+
/* ── Semantic tokens ── */
|
|
479
|
+
--color-background: #e0e6f0 !important;
|
|
480
|
+
--color-foreground: #1a1b2e !important;
|
|
481
|
+
--color-card: var(--cf-glass) !important;
|
|
482
|
+
--color-card-foreground: #1a1b2e !important;
|
|
483
|
+
--color-popover: var(--cf-glass-strong) !important;
|
|
484
|
+
--color-popover-foreground: #1a1b2e !important;
|
|
485
|
+
--color-primary: var(--cf-purple) !important;
|
|
486
|
+
--color-primary-foreground: #fff !important;
|
|
487
|
+
--color-secondary: rgba(157, 124, 216, 0.10) !important;
|
|
488
|
+
--color-secondary-foreground: #2e3050 !important;
|
|
489
|
+
--color-muted: rgba(0, 0, 0, 0.04) !important;
|
|
490
|
+
--color-muted-foreground: #555b78 !important;
|
|
491
|
+
--color-accent: rgba(157, 124, 216, 0.10) !important;
|
|
492
|
+
--color-accent-foreground: #2e3050 !important;
|
|
493
|
+
--color-destructive: var(--cf-pink) !important;
|
|
494
|
+
--color-destructive-foreground: #fff !important;
|
|
495
|
+
/* Borders: neutral, semi-transparent — NOT coloured */
|
|
496
|
+
--color-border: rgba(0, 0, 0, 0.10) !important;
|
|
497
|
+
--color-input: rgba(0, 0, 0, 0.06) !important;
|
|
498
|
+
--color-ring: var(--cf-purple) !important;
|
|
499
|
+
|
|
500
|
+
/* Hierarchy — lavender tints */
|
|
501
|
+
--hierarchy-selected-bg: rgba(157, 124, 216, 0.12);
|
|
502
|
+
--hierarchy-selected-text: #1a1b2e;
|
|
503
|
+
--hierarchy-text: #40445e;
|
|
504
|
+
--hierarchy-hover-bg: rgba(200, 195, 230, 0.15);
|
|
505
|
+
|
|
506
|
+
/* Tabs — warm peach undertone */
|
|
507
|
+
--tabs-bg: rgba(235, 215, 195, 0.25);
|
|
508
|
+
--tabs-border: rgba(0, 0, 0, 0.08);
|
|
509
|
+
--tab-text: #555b78;
|
|
510
|
+
--tab-active-bg: rgba(245, 230, 210, 0.55);
|
|
511
|
+
--tab-active-text: #1a1b2e;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/* ── Page background ── */
|
|
515
|
+
.colorful body,
|
|
516
|
+
.colorful #root {
|
|
517
|
+
background: #dde3f0 !important;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/* ── Toolbar: cool violet-tinted glass ── */
|
|
521
|
+
.colorful .border-b.bg-white,
|
|
522
|
+
.colorful .border-b.dark\:bg-black {
|
|
523
|
+
background: rgba(230, 225, 245, 0.60) !important;
|
|
524
|
+
backdrop-filter: blur(20px) saturate(1.5) !important;
|
|
525
|
+
-webkit-backdrop-filter: blur(20px) saturate(1.5) !important;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/* ── Panels & cards: frosted glass (neutral base) ── */
|
|
529
|
+
.colorful .bg-white,
|
|
530
|
+
.colorful .bg-card,
|
|
531
|
+
.colorful .bg-background {
|
|
532
|
+
background: var(--cf-glass) !important;
|
|
533
|
+
backdrop-filter: blur(16px) saturate(1.3) !important;
|
|
534
|
+
-webkit-backdrop-filter: blur(16px) saturate(1.3) !important;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
.colorful .bg-zinc-50,
|
|
538
|
+
.colorful .bg-zinc-100 {
|
|
539
|
+
background-color: rgba(255, 255, 255, 0.25) !important;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
.colorful .bg-zinc-900,
|
|
543
|
+
.colorful .bg-zinc-950,
|
|
544
|
+
.colorful .bg-black {
|
|
545
|
+
background: var(--cf-glass) !important;
|
|
546
|
+
backdrop-filter: blur(16px) saturate(1.3) !important;
|
|
547
|
+
-webkit-backdrop-filter: blur(16px) saturate(1.3) !important;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/* ── Tinted glass per panel — colour echoes the aurora ── */
|
|
551
|
+
|
|
552
|
+
/* Left panel: cool lavender tint (echoes aurora top) */
|
|
553
|
+
.colorful .panel-container:first-of-type,
|
|
554
|
+
.colorful [id="left-panel"] > .panel-container,
|
|
555
|
+
.colorful [id="left-panel"] > div {
|
|
556
|
+
background: rgba(200, 195, 230, 0.38) !important;
|
|
557
|
+
backdrop-filter: blur(16px) saturate(1.4) !important;
|
|
558
|
+
-webkit-backdrop-filter: blur(16px) saturate(1.4) !important;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/* Right panel: warm peach/amber tint (echoes aurora bottom) */
|
|
562
|
+
.colorful [id="right-panel"] > .panel-container,
|
|
563
|
+
.colorful [id="right-panel"] > div {
|
|
564
|
+
background: rgba(235, 215, 195, 0.40) !important;
|
|
565
|
+
backdrop-filter: blur(16px) saturate(1.4) !important;
|
|
566
|
+
-webkit-backdrop-filter: blur(16px) saturate(1.4) !important;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/* Resize handles: thin, tinted */
|
|
570
|
+
.colorful [data-panel-group-direction="horizontal"] > [data-resize-handle] {
|
|
571
|
+
background-color: rgba(157, 124, 216, 0.18) !important;
|
|
572
|
+
transition: background-color 0.15s;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
.colorful [data-panel-group-direction="horizontal"] > [data-resize-handle]:hover {
|
|
576
|
+
background-color: rgba(157, 124, 216, 0.35) !important;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
.colorful [data-panel-group-direction="horizontal"] > [data-resize-handle][data-resize-handle-active] {
|
|
580
|
+
background-color: rgba(157, 124, 216, 0.50) !important;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/* ── Borders: single neutral tone everywhere ── */
|
|
584
|
+
.colorful .border-zinc-100,
|
|
585
|
+
.colorful .border-zinc-200,
|
|
586
|
+
.colorful .border-zinc-300,
|
|
587
|
+
.colorful .border-zinc-400,
|
|
588
|
+
.colorful .border-zinc-500,
|
|
589
|
+
.colorful .border-zinc-600,
|
|
590
|
+
.colorful .border-zinc-700,
|
|
591
|
+
.colorful .border-zinc-800,
|
|
592
|
+
.colorful .border-zinc-900,
|
|
593
|
+
.colorful .border-zinc-950 {
|
|
594
|
+
border-color: rgba(0, 0, 0, 0.10) !important;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
.colorful .border,
|
|
598
|
+
.colorful .border-b,
|
|
599
|
+
.colorful .border-t,
|
|
600
|
+
.colorful .border-l,
|
|
601
|
+
.colorful .border-r,
|
|
602
|
+
.colorful .border-border {
|
|
603
|
+
border-color: rgba(0, 0, 0, 0.10) !important;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/* Purple borders (property editor) stay purple but softened */
|
|
607
|
+
.colorful .border-purple-200,
|
|
608
|
+
.colorful .border-purple-300\/50,
|
|
609
|
+
.colorful .border-purple-500\/30,
|
|
610
|
+
.colorful .border-purple-700,
|
|
611
|
+
.colorful .border-purple-800 {
|
|
612
|
+
border-color: rgba(157, 124, 216, 0.25) !important;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/* ── Text ── */
|
|
616
|
+
.colorful .text-zinc-900,
|
|
617
|
+
.colorful .text-zinc-800,
|
|
618
|
+
.colorful .text-zinc-700,
|
|
619
|
+
.colorful .text-zinc-100 {
|
|
620
|
+
color: #1a1b2e !important;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
.colorful .text-zinc-500,
|
|
624
|
+
.colorful .text-zinc-400,
|
|
625
|
+
.colorful .text-zinc-600 {
|
|
626
|
+
color: #555b78 !important;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
.colorful .text-zinc-200,
|
|
630
|
+
.colorful .text-zinc-300 {
|
|
631
|
+
color: #40445e !important;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
/* ── Primary: purple (from Tokyo Night magenta/purple family) ── */
|
|
635
|
+
.colorful .bg-primary {
|
|
636
|
+
background-color: var(--cf-purple) !important;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
.colorful .text-primary {
|
|
640
|
+
color: var(--cf-purple) !important;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
.colorful .border-primary {
|
|
644
|
+
border-color: var(--cf-purple) !important;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/* ── Shadows ── */
|
|
648
|
+
.colorful .shadow-lg,
|
|
649
|
+
.colorful .shadow-xl {
|
|
650
|
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08) !important;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/* ── Selection ── */
|
|
654
|
+
.colorful ::selection {
|
|
655
|
+
background-color: rgba(157, 124, 216, 0.25);
|
|
656
|
+
color: #1a1b2e;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/* ── Scrollbars ── */
|
|
660
|
+
.colorful .scrollbar-thin {
|
|
661
|
+
scrollbar-color: rgba(0, 0, 0, 0.15) transparent;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
.colorful .scrollbar-thin::-webkit-scrollbar-thumb {
|
|
665
|
+
background-color: rgba(0, 0, 0, 0.15);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
.colorful .scrollbar-thin::-webkit-scrollbar-thumb:hover {
|
|
669
|
+
background-color: rgba(0, 0, 0, 0.25);
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
/* ── Hovers: tinted to match panel context ── */
|
|
673
|
+
.colorful .hover\:bg-primary:hover {
|
|
674
|
+
background-color: var(--cf-purple) !important;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
.colorful .hover\:bg-zinc-50:hover,
|
|
678
|
+
.colorful .hover\:bg-zinc-100:hover,
|
|
679
|
+
.colorful .hover\:bg-zinc-200:hover,
|
|
680
|
+
.colorful .hover\:bg-white:hover {
|
|
681
|
+
background-color: rgba(200, 195, 230, 0.18) !important;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/* ── Active tabs ── */
|
|
685
|
+
.colorful [data-state="active"] {
|
|
686
|
+
background-color: var(--cf-glass-strong) !important;
|
|
687
|
+
color: #1a1b2e !important;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
.colorful .data-\[state\=active\]\:bg-white[data-state="active"],
|
|
691
|
+
.colorful .data-\[state\=active\]\:bg-zinc-100[data-state="active"] {
|
|
692
|
+
background-color: var(--cf-glass-strong) !important;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/* Properties tabs: warm orange accent on active (echoes aurora horizon) */
|
|
696
|
+
.colorful .properties-tab-trigger[data-state="active"] {
|
|
697
|
+
border-top-color: var(--cf-orange) !important;
|
|
698
|
+
background: rgba(245, 230, 210, 0.50) !important;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
/* ── Tabs container: warmer tint to match right panel ── */
|
|
702
|
+
.colorful .properties-tabs-list {
|
|
703
|
+
background-color: rgba(235, 215, 195, 0.30) !important;
|
|
704
|
+
border-bottom-color: rgba(0, 0, 0, 0.08) !important;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
/* ── Tree selection: purple tint with left accent ── */
|
|
708
|
+
.colorful .tree-node.selected {
|
|
709
|
+
background-color: rgba(157, 124, 216, 0.12) !important;
|
|
710
|
+
border-left-color: var(--cf-purple) !important;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
.colorful .hierarchy-item.selected {
|
|
714
|
+
background-color: rgba(157, 124, 216, 0.12) !important;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
/* ── Hierarchy hover: subtle lavender ── */
|
|
718
|
+
.colorful .hierarchy-item:not(.selected):hover {
|
|
719
|
+
background-color: rgba(200, 195, 230, 0.20) !important;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
/* ── Quantity cards ── */
|
|
723
|
+
.colorful .border-blue-200,
|
|
724
|
+
.colorful .border-blue-800,
|
|
725
|
+
.colorful .border-blue-900 {
|
|
726
|
+
border-color: rgba(122, 162, 247, 0.25) !important;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
.colorful .text-blue-700,
|
|
730
|
+
.colorful .text-blue-400 {
|
|
731
|
+
color: #6a8fd6 !important;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
.colorful .bg-blue-50\/20,
|
|
735
|
+
.colorful .bg-blue-950\/20 {
|
|
736
|
+
background-color: rgba(122, 162, 247, 0.06) !important;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
/* ── Success / Location ── */
|
|
740
|
+
.colorful .border-emerald-500\/30 {
|
|
741
|
+
border-color: rgba(115, 218, 202, 0.25) !important;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
.colorful .text-emerald-800,
|
|
745
|
+
.colorful .text-emerald-400 {
|
|
746
|
+
color: #3d9e88 !important;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
.colorful .bg-emerald-50\/50,
|
|
750
|
+
.colorful .bg-emerald-900\/10 {
|
|
751
|
+
background-color: rgba(115, 218, 202, 0.06) !important;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
/* ── Toolbar buttons ── */
|
|
755
|
+
.colorful .toolbar-button:hover {
|
|
756
|
+
background-color: rgba(200, 195, 230, 0.25) !important;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
.colorful .toolbar-button.active {
|
|
760
|
+
background-color: var(--cf-purple) !important;
|
|
761
|
+
color: #fff !important;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
/* ── Status bar (bottom): warm tint ── */
|
|
765
|
+
.colorful .border-t.bg-white,
|
|
766
|
+
.colorful .border-t.dark\:bg-black {
|
|
767
|
+
background: rgba(240, 225, 210, 0.50) !important;
|
|
768
|
+
backdrop-filter: blur(16px) saturate(1.3) !important;
|
|
769
|
+
-webkit-backdrop-filter: blur(16px) saturate(1.3) !important;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/* ── Drop overlay ── */
|
|
773
|
+
.colorful .bg-\[\#9ece6a\]\/10 {
|
|
774
|
+
background-color: rgba(115, 218, 202, 0.10) !important;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
.colorful .border-\[\#9ece6a\] {
|
|
778
|
+
border-color: var(--cf-teal) !important;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
.colorful .text-\[\#9ece6a\] {
|
|
782
|
+
color: var(--cf-teal) !important;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
/* ── Popover / dropdown menus: glass ── */
|
|
786
|
+
.colorful [data-radix-popper-content-wrapper] [role="menu"],
|
|
787
|
+
.colorful [data-radix-popper-content-wrapper] [role="listbox"],
|
|
788
|
+
.colorful [data-radix-popper-content-wrapper] [data-radix-collection-item] {
|
|
789
|
+
background: var(--cf-glass-strong) !important;
|
|
790
|
+
backdrop-filter: blur(20px) saturate(1.4) !important;
|
|
791
|
+
-webkit-backdrop-filter: blur(20px) saturate(1.4) !important;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
795
|
+
COLORFUL — Component-specific colour variations
|
|
796
|
+
Each section gets a subtle tint from the Tokyo palette, mapped to its
|
|
797
|
+
semantic role. Tasteful, not overwhelming.
|
|
798
|
+
═══════════════════════════════════════════════════════════════════════════ */
|
|
799
|
+
|
|
800
|
+
/* ── Section headers in hierarchy: cool lavender bg ── */
|
|
801
|
+
.colorful .bg-zinc-100.border-b,
|
|
802
|
+
.colorful .bg-zinc-900.border-b {
|
|
803
|
+
background-color: rgba(200, 195, 230, 0.30) !important;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
/* ── Section headers in properties: warm peach bg ── */
|
|
807
|
+
.colorful .bg-zinc-50.border-b {
|
|
808
|
+
background-color: rgba(240, 220, 195, 0.35) !important;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
/* Properties section header text: warmer dark tone */
|
|
812
|
+
.colorful .bg-zinc-50 .text-zinc-700,
|
|
813
|
+
.colorful .bg-zinc-50 .text-zinc-600 {
|
|
814
|
+
color: #5a4a3a !important;
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
/* ── FILE INFORMATION / STATISTICS / PROJECT INFO section containers ── */
|
|
818
|
+
/* Alternate warm tints for each section in the properties panel */
|
|
819
|
+
.colorful .bg-zinc-50.dark\:bg-zinc-900\/50 {
|
|
820
|
+
background-color: rgba(240, 220, 195, 0.30) !important;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
/* ── LOCATION section: teal/green tint (geography = nature) ── */
|
|
824
|
+
.colorful [class*="border-emerald"] {
|
|
825
|
+
border-color: rgba(115, 218, 202, 0.25) !important;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
/* ── Landing page / empty state — orange-tinted grid world ── */
|
|
829
|
+
|
|
830
|
+
/* Viewport container bg — only the wrapper div, NOT the canvas.
|
|
831
|
+
The canvas has data-viewport="main"; we exclude it so the
|
|
832
|
+
inline aurora gradient isn't overridden by !important. */
|
|
833
|
+
.colorful div[data-viewport=""]:not(:has(canvas)),
|
|
834
|
+
.colorful div[data-viewport]:not([data-viewport="main"]) {
|
|
835
|
+
background-color: rgba(245, 235, 220, 0.60) !important;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
/* Orange grid only on the empty-state overlay (no model loaded).
|
|
839
|
+
This div only exists when the landing page renders. */
|
|
840
|
+
.colorful [data-viewport] > .absolute.z-10 {
|
|
841
|
+
background-image:
|
|
842
|
+
linear-gradient(rgba(255, 158, 100, 0.08) 1px, transparent 1px),
|
|
843
|
+
linear-gradient(90deg, rgba(255, 158, 100, 0.08) 1px, transparent 1px);
|
|
844
|
+
background-size: 32px 32px;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
/* Main landing card: warm glass with orange border */
|
|
848
|
+
.colorful .border-zinc-300.dark\:border-\[\#3b4261\] {
|
|
849
|
+
border-color: rgba(255, 158, 100, 0.28) !important;
|
|
850
|
+
background: rgba(255, 248, 240, 0.65) !important;
|
|
851
|
+
backdrop-filter: blur(16px) !important;
|
|
852
|
+
-webkit-backdrop-filter: blur(16px) !important;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
/* Logo background layer: warm tint */
|
|
856
|
+
.colorful .-rotate-3.border {
|
|
857
|
+
background-color: rgba(255, 225, 195, 0.30) !important;
|
|
858
|
+
border-color: rgba(255, 158, 100, 0.18) !important;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
/* Feature grid cards (SELECT / FILTER / ANALYZE): warm glass */
|
|
862
|
+
.colorful .bg-zinc-100.dark\:bg-\[\#1f2335\] {
|
|
863
|
+
background-color: rgba(255, 230, 200, 0.35) !important;
|
|
864
|
+
border-color: rgba(255, 158, 100, 0.20) !important;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
/* Feature card icon boxes */
|
|
868
|
+
.colorful .bg-zinc-100 .bg-white.border,
|
|
869
|
+
.colorful .bg-zinc-100 .dark\:bg-\[\#16161e\].border {
|
|
870
|
+
background-color: rgba(255, 245, 230, 0.55) !important;
|
|
871
|
+
border-color: rgba(255, 158, 100, 0.15) !important;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
/* Recent files list */
|
|
875
|
+
.colorful .bg-zinc-50.dark\:bg-\[\#1f2335\] {
|
|
876
|
+
background-color: rgba(255, 235, 210, 0.30) !important;
|
|
877
|
+
border-color: rgba(255, 158, 100, 0.15) !important;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
/* Shortcuts badge */
|
|
881
|
+
.colorful .bg-zinc-100.dark\:bg-\[\#1f2335\].border.border-zinc-300 {
|
|
882
|
+
background-color: rgba(255, 230, 200, 0.35) !important;
|
|
883
|
+
border-color: rgba(255, 158, 100, 0.20) !important;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
/* "Open .ifc file" hover */
|
|
887
|
+
.colorful .hover\:border-primary:hover {
|
|
888
|
+
border-color: var(--cf-orange) !important;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
.colorful .hover\:text-primary:hover {
|
|
892
|
+
color: var(--cf-orange) !important;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
/* Empty state dashed borders: orange */
|
|
896
|
+
.colorful .border-dashed {
|
|
897
|
+
border-color: rgba(255, 158, 100, 0.35) !important;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
/* Empty state icon boxes (NO MODEL / NO SELECTION) */
|
|
901
|
+
.colorful .border-dashed.border-2 {
|
|
902
|
+
border-color: rgba(255, 158, 100, 0.30) !important;
|
|
903
|
+
background-color: rgba(255, 235, 210, 0.25) !important;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
/* ── Hierarchy SPATIAL/CLASS/TYPE toggle ── */
|
|
907
|
+
/* Outline buttons: lavender tint */
|
|
908
|
+
.colorful [data-variant="outline"] {
|
|
909
|
+
border-color: rgba(157, 124, 216, 0.22) !important;
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
.colorful [data-variant="outline"]:hover {
|
|
913
|
+
background-color: rgba(200, 195, 230, 0.22) !important;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
/* ── Properties panel collapsible sections hover (right panel only) ── */
|
|
917
|
+
.colorful [id="right-panel"] .hover\:bg-zinc-50:hover,
|
|
918
|
+
.colorful [id="right-panel"] .hover\:bg-zinc-900:hover {
|
|
919
|
+
background-color: rgba(240, 220, 195, 0.25) !important;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
/* ── Properties subsection backgrounds ── */
|
|
923
|
+
.colorful .bg-zinc-50\/50,
|
|
924
|
+
.colorful .dark\:bg-zinc-900\/50 {
|
|
925
|
+
background-color: rgba(240, 225, 205, 0.25) !important;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
/* ── Tooltip: dark, sharp ── */
|
|
929
|
+
.colorful [role="tooltip"] {
|
|
930
|
+
background: rgba(26, 27, 46, 0.90) !important;
|
|
931
|
+
color: #e0e6f0 !important;
|
|
932
|
+
backdrop-filter: blur(8px) !important;
|
|
933
|
+
-webkit-backdrop-filter: blur(8px) !important;
|
|
934
|
+
}
|
|
935
|
+
|
|
415
936
|
/* Fix Radix ScrollArea viewport inner div: by default it uses display:table
|
|
416
937
|
which expands to content width, preventing text truncation in flex children.
|
|
417
938
|
Force block layout so width constraints cascade correctly. */
|
|
@@ -513,6 +1034,35 @@ body {
|
|
|
513
1034
|
cursor: not-allowed;
|
|
514
1035
|
}
|
|
515
1036
|
|
|
1037
|
+
/* Annotation pin idle introduction — fires once on mount, then settles.
|
|
1038
|
+
Driven by a `prefers-reduced-motion` guard so accessibility users
|
|
1039
|
+
don't get hit by the pulse. */
|
|
1040
|
+
@keyframes annotation-pin-idle {
|
|
1041
|
+
0% {
|
|
1042
|
+
transform: scale(0.7);
|
|
1043
|
+
box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.55);
|
|
1044
|
+
}
|
|
1045
|
+
60% {
|
|
1046
|
+
transform: scale(1.08);
|
|
1047
|
+
box-shadow: 0 0 0 8px rgba(245, 158, 11, 0);
|
|
1048
|
+
}
|
|
1049
|
+
100% {
|
|
1050
|
+
transform: scale(1);
|
|
1051
|
+
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35),
|
|
1052
|
+
0 0 0 1px rgba(0, 0, 0, 0.15);
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
.annotation-pin-idle {
|
|
1057
|
+
animation: annotation-pin-idle 360ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1061
|
+
.annotation-pin-idle {
|
|
1062
|
+
animation: none;
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
|
|
516
1066
|
/* Loading skeleton animation */
|
|
517
1067
|
@keyframes skeleton-pulse {
|
|
518
1068
|
0%, 100% {
|
|
@@ -528,13 +1078,3 @@ body {
|
|
|
528
1078
|
border-radius: 0.25rem;
|
|
529
1079
|
animation: skeleton-pulse 2s ease-in-out infinite;
|
|
530
1080
|
}
|
|
531
|
-
|
|
532
|
-
/* Clerk overlays (billing/sidebar/modal) should always stack above app overlays. */
|
|
533
|
-
.cl-portalRoot,
|
|
534
|
-
.cl-modalBackdrop,
|
|
535
|
-
.cl-modalContent,
|
|
536
|
-
.cl-drawerRoot,
|
|
537
|
-
.cl-drawerBackdrop,
|
|
538
|
-
.cl-drawerContent {
|
|
539
|
-
z-index: 100000 !important;
|
|
540
|
-
}
|
|
@@ -26,10 +26,8 @@ interface ResolvedDesktopEntitlement {
|
|
|
26
26
|
|
|
27
27
|
export function resolveDesktopEntitlement(options: ResolveDesktopEntitlementOptions): ResolvedDesktopEntitlement {
|
|
28
28
|
// NOTE: `token`, `has`, `publicMetadata`, and `now` are accepted but
|
|
29
|
-
// intentionally unused in this
|
|
30
|
-
//
|
|
31
|
-
// token validation, and time-based expiry via `now`) will be wired up once
|
|
32
|
-
// the Clerk integration is available in the desktop shell.
|
|
29
|
+
// intentionally unused in this implementation. They are kept for future
|
|
30
|
+
// extensibility if a desktop-specific entitlement provider is added.
|
|
33
31
|
const { userId } = options;
|
|
34
32
|
const entitlement: DesktopEntitlement = {
|
|
35
33
|
...getDefaultDesktopEntitlement(),
|
|
@@ -70,6 +70,7 @@ export async function createCesiumBridge(
|
|
|
70
70
|
mapConversion: MapConversion,
|
|
71
71
|
projectedCRS: ProjectedCRS,
|
|
72
72
|
coordinateInfo?: CoordinateInfo,
|
|
73
|
+
lengthUnitScale = 1,
|
|
73
74
|
): Promise<CesiumBridge | null> {
|
|
74
75
|
const projDef = await resolveProjection(projectedCRS);
|
|
75
76
|
if (!projDef) return null;
|
|
@@ -98,9 +99,13 @@ export async function createCesiumBridge(
|
|
|
98
99
|
const oIfcX = owx;
|
|
99
100
|
const oIfcY = -owz;
|
|
100
101
|
const oIfcZ = owy;
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
// Geometry coordinates (oIfcX/Y/Z) are already in metres (the geometry engine
|
|
103
|
+
// converts from the IFC file's native unit during extraction). MapConversion
|
|
104
|
+
// values use the unit from IfcProjectedCRS.MapUnit; fall back to project unit.
|
|
105
|
+
const mapScale = projectedCRS.mapUnitScale ?? lengthUnitScale;
|
|
106
|
+
const oEasting = mapConversion.eastings * mapScale + hScale * (absc * oIfcX - ordi * oIfcY);
|
|
107
|
+
const oNorthing = mapConversion.northings * mapScale + hScale * (ordi * oIfcX + absc * oIfcY);
|
|
108
|
+
const oHeight = mapConversion.orthogonalHeight * mapScale + oIfcZ;
|
|
104
109
|
|
|
105
110
|
let originLon: number, originLat: number;
|
|
106
111
|
try {
|
|
@@ -131,6 +136,8 @@ export async function createCesiumBridge(
|
|
|
131
136
|
// So M = [hScale*absc, 0, hScale*ordi ]
|
|
132
137
|
// [hScale*ordi, 0, -hScale*absc ]
|
|
133
138
|
// [0, 1, 0 ]
|
|
139
|
+
// Viewer-space deltas are already in metres (geometry engine converts during
|
|
140
|
+
// extraction), so no lengthUnitScale needed here.
|
|
134
141
|
const m00 = hScale * absc; // east from vx
|
|
135
142
|
const m01 = 0; // east from vy
|
|
136
143
|
const m02 = hScale * ordi; // east from vz
|
|
@@ -138,7 +145,7 @@ export async function createCesiumBridge(
|
|
|
138
145
|
const m11 = 0; // north from vy
|
|
139
146
|
const m12 = -hScale * absc; // north from vz
|
|
140
147
|
const m20 = 0; // up from vx
|
|
141
|
-
const m21 = 1; // up from vy
|
|
148
|
+
const m21 = 1; // up from vy (vertical = viewer Y, already metres)
|
|
142
149
|
const m22 = 0; // up from vz
|
|
143
150
|
|
|
144
151
|
// ── Cache for ECEF objects ──
|
|
@@ -288,9 +295,10 @@ export async function createCesiumBridge(
|
|
|
288
295
|
const ifcX = wx;
|
|
289
296
|
const ifcY = -wz;
|
|
290
297
|
const ifcZ = wy;
|
|
291
|
-
|
|
292
|
-
const
|
|
293
|
-
const
|
|
298
|
+
// Viewer coords (ifcX/Y/Z) are already in metres; only MapConversion values need scaling
|
|
299
|
+
const easting = mapConversion.eastings * mapScale + hScale * (absc * ifcX - ordi * ifcY);
|
|
300
|
+
const northing = mapConversion.northings * mapScale + hScale * (ordi * ifcX + absc * ifcY);
|
|
301
|
+
const height = mapConversion.orthogonalHeight * mapScale + ifcZ;
|
|
294
302
|
try {
|
|
295
303
|
const [lon, lat] = proj4(projDef!, 'WGS84', [easting, northing]);
|
|
296
304
|
if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;
|