pcb-scene3d-viewer 1.1.19 → 1.1.21

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.
@@ -2,6 +2,7 @@ import { PcbScene3dBoardSolderMaskFactory } from './PcbScene3dBoardSolderMaskFac
2
2
  import { PcbScene3dBodyColor } from './PcbScene3dBodyColor.mjs'
3
3
  import { PcbScene3dCameraRig } from './PcbScene3dCameraRig.mjs'
4
4
  import { PcbScene3dCircuitJsonAdapter } from './PcbScene3dCircuitJsonAdapter.mjs'
5
+ import { PcbScene3dComponentVisibility } from './PcbScene3dComponentVisibility.mjs'
5
6
  import { PcbScene3dComponentAdjustment } from './PcbScene3dComponentAdjustment.mjs'
6
7
  import { PcbScene3dComponentAdjustmentRegistry } from './PcbScene3dComponentAdjustmentRegistry.mjs'
7
8
  import { PcbScene3dCopperDetailGroupBuilder } from './PcbScene3dCopperDetailGroupBuilder.mjs'
@@ -15,6 +16,7 @@ import { PcbScene3dMountRig } from './PcbScene3dMountRig.mjs'
15
16
  import { PcbScene3dModelSearchPlacement } from './PcbScene3dModelSearchPlacement.mjs'
16
17
  import { PcbScene3dPresetState } from './PcbScene3dPresetState.mjs'
17
18
  import { PcbScene3dRenderGroupVisibility } from './PcbScene3dRenderGroupVisibility.mjs'
19
+ import { PcbScene3dRenderScheduler } from './PcbScene3dRenderScheduler.mjs'
18
20
  import { PcbScene3dRuntimeBoardMeshes } from './PcbScene3dRuntimeBoardMeshes.mjs'
19
21
  import { PcbScene3dSilkscreenChunkedFactory } from './PcbScene3dSilkscreenChunkedFactory.mjs'
20
22
  import { PcbScene3dTrueTypeTextFactory } from './PcbScene3dTrueTypeTextFactory.mjs'
@@ -52,6 +54,7 @@ export class PcbScene3dRuntime {
52
54
  #pointer
53
55
  #pointerDownPosition
54
56
  #selectionRoots
57
+ #hiddenComponentDesignators
55
58
  #componentAdjustmentRegistry
56
59
  #fallbackBodyRoots
57
60
  #loadedExternalModelDesignators
@@ -64,6 +67,7 @@ export class PcbScene3dRuntime {
64
67
  #readyPromise
65
68
  #resolveReadyPromise
66
69
  #hasSettledReady
70
+ #renderScheduler
67
71
  /**
68
72
  * @param {HTMLElement} viewportNode
69
73
  * @param {any} sceneDescription Scene description or CircuitJSON model.
@@ -96,6 +100,7 @@ export class PcbScene3dRuntime {
96
100
  this.#pointer = null
97
101
  this.#pointerDownPosition = null
98
102
  this.#selectionRoots = new Map()
103
+ this.#hiddenComponentDesignators = new Set()
99
104
  this.#componentAdjustmentRegistry =
100
105
  new PcbScene3dComponentAdjustmentRegistry(() => this.#three)
101
106
  this.#fallbackBodyRoots = new Map()
@@ -108,6 +113,11 @@ export class PcbScene3dRuntime {
108
113
  this.#presetState = new PcbScene3dPresetState()
109
114
  this.#isDisposed = false
110
115
  this.#hasSettledReady = false
116
+ this.#renderScheduler = new PcbScene3dRenderScheduler(() => {
117
+ if (!this.#isDisposed) {
118
+ this.#render()
119
+ }
120
+ })
111
121
  this.#resolveReadyPromise = null
112
122
  this.#readyPromise = new Promise((resolve) => {
113
123
  this.#resolveReadyPromise = resolve
@@ -124,10 +134,14 @@ export class PcbScene3dRuntime {
124
134
  setPreset(preset) {
125
135
  const normalizedPreset = this.#presetState.set(preset)
126
136
  this.#applyViewScale(normalizedPreset)
137
+ PcbScene3dInteractionHints.configureControls(
138
+ this.#controls,
139
+ this.#three,
140
+ normalizedPreset
141
+ )
127
142
  if (!this.#camera) {
128
143
  return
129
144
  }
130
-
131
145
  PcbScene3dCameraRig.applyPreset(
132
146
  this.#camera,
133
147
  this.#controls,
@@ -141,7 +155,6 @@ export class PcbScene3dRuntime {
141
155
  if (!(toggleName in this.#toggles)) {
142
156
  return
143
157
  }
144
-
145
158
  this.#toggles[toggleName] = enabled
146
159
  this.#applyToggleVisibility()
147
160
  this.#render()
@@ -150,6 +163,27 @@ export class PcbScene3dRuntime {
150
163
  setSelectedDesignator(designator) {
151
164
  this.#setSelectedDesignator(designator)
152
165
  }
166
+ /** @param {string} designator @param {boolean} hidden */
167
+ setComponentHidden(designator, hidden) {
168
+ if (
169
+ !PcbScene3dComponentVisibility.setHidden(
170
+ this.#hiddenComponentDesignators,
171
+ designator,
172
+ hidden
173
+ )
174
+ ) {
175
+ return
176
+ }
177
+ this.#applyToggleVisibility()
178
+ this.#render()
179
+ }
180
+ /** @param {string} designator @returns {boolean} */
181
+ isComponentHidden(designator) {
182
+ return PcbScene3dComponentVisibility.isHidden(
183
+ this.#hiddenComponentDesignators,
184
+ designator
185
+ )
186
+ }
153
187
  /**
154
188
  * Applies a live model-local adjustment to one component.
155
189
  * @param {string} designator Component designator.
@@ -172,6 +206,7 @@ export class PcbScene3dRuntime {
172
206
  /** @returns {void} */
173
207
  dispose() {
174
208
  this.#isDisposed = true
209
+ this.#renderScheduler.cancel()
175
210
  this.#listeners.forEach(({ node, type, listener }) => {
176
211
  node.removeEventListener?.(type, listener)
177
212
  })
@@ -196,6 +231,7 @@ export class PcbScene3dRuntime {
196
231
  this.#pointer = null
197
232
  this.#pointerDownPosition = null
198
233
  this.#selectionRoots.clear()
234
+ this.#hiddenComponentDesignators.clear()
199
235
  this.#componentAdjustmentRegistry.clear()
200
236
  this.#fallbackBodyRoots.clear()
201
237
  this.#loadedExternalModelDesignators.clear()
@@ -636,7 +672,11 @@ export class PcbScene3dRuntime {
636
672
  this.#controls.minDistance = 140
637
673
  this.#controls.maxDistance = this.#initialRadius * 8
638
674
  this.#controls.target.set(0, 0, 0)
639
- PcbScene3dInteractionHints.configureControls(this.#controls, THREE)
675
+ PcbScene3dInteractionHints.configureControls(
676
+ this.#controls,
677
+ THREE,
678
+ this.#presetState.get()
679
+ )
640
680
 
641
681
  PcbScene3dCameraRig.applyPreset(
642
682
  this.#camera,
@@ -645,7 +685,9 @@ export class PcbScene3dRuntime {
645
685
  this.#sceneDescription
646
686
  )
647
687
 
648
- this.#bindListener(this.#controls, 'change', () => this.#render())
688
+ this.#bindListener(this.#controls, 'change', () => {
689
+ this.#renderScheduler.schedule()
690
+ })
649
691
  this.#bindListener(domElement, 'contextmenu', (event) => {
650
692
  event.preventDefault?.()
651
693
  })
@@ -726,6 +768,16 @@ export class PcbScene3dRuntime {
726
768
  modelSearchExternalModelRoots: this.#modelSearchExternalModelRoots,
727
769
  hasLoadedBoardAssemblyModel: this.#hasLoadedBoardAssemblyModel
728
770
  })
771
+ PcbScene3dComponentVisibility.apply({
772
+ selectionRoots: this.#selectionRoots,
773
+ hiddenDesignators: this.#hiddenComponentDesignators,
774
+ fallbackBodyRoots: this.#fallbackBodyRoots,
775
+ loadedExternalModelDesignators:
776
+ this.#loadedExternalModelDesignators,
777
+ modelSearchExternalModelRoots: this.#modelSearchExternalModelRoots,
778
+ toggles: this.#toggles,
779
+ hasLoadedBoardAssemblyModel: this.#hasLoadedBoardAssemblyModel
780
+ })
729
781
  }
730
782
 
731
783
  /** @returns {void} */
@@ -46,12 +46,13 @@ export class PcbScene3dSelectionInspectorRenderer {
46
46
 
47
47
  /**
48
48
  * Renders selected component details and optional editable transform controls.
49
- * @param {{ designator: string, selection?: { sourceType?: string } | null, selectionEntry: { component: any | null, externalPlacement: any | null }, adjustment: { scale: { x: number, y: number, z: number }, rotationDeg: { x: number, y: number, z: number }, offsetMil: { x: number, y: number, z: number } }, includeControls?: boolean, translate: (key: string) => string }} options Render options.
49
+ * @param {{ designator: string, hidden?: boolean, selection?: { sourceType?: string } | null, selectionEntry: { component: any | null, externalPlacement: any | null }, adjustment: { scale: { x: number, y: number, z: number }, rotationDeg: { x: number, y: number, z: number }, offsetMil: { x: number, y: number, z: number } }, includeControls?: boolean, translate: (key: string) => string }} options Render options.
50
50
  * @returns {string}
51
51
  */
52
52
  static renderSelected(options) {
53
53
  const component = options.selectionEntry.component
54
54
  const externalPlacement = options.selectionEntry.externalPlacement
55
+ const hidden = options.hidden === true
55
56
  const fields = [
56
57
  [options.translate('scene3d.designator'), options.designator],
57
58
  [
@@ -127,11 +128,18 @@ export class PcbScene3dSelectionInspectorRenderer {
127
128
  ].filter(([, value]) => String(value || '').trim())
128
129
 
129
130
  return (
130
- '<h4 class="scene-3d__selection-title">' +
131
+ '<div class="scene-3d__selection-header"><h4 class="scene-3d__selection-title">' +
131
132
  PcbScene3dSelectionInspectorRenderer.#escapeHtml(
132
133
  options.translate('scene3d.componentInspector')
133
134
  ) +
134
- '</h4><dl class="scene-3d__selection-list">' +
135
+ '</h4>' +
136
+ PcbScene3dSelectionInspectorRenderer.#renderVisibilityToggle(
137
+ options.designator,
138
+ options.selection?.sourceType || '',
139
+ hidden,
140
+ options.translate
141
+ ) +
142
+ '</div><dl class="scene-3d__selection-list">' +
135
143
  fields
136
144
  .map(
137
145
  ([label, value]) =>
@@ -461,6 +469,59 @@ export class PcbScene3dSelectionInspectorRenderer {
461
469
  )
462
470
  }
463
471
 
472
+ /**
473
+ * Renders the selected-component visibility toggle.
474
+ * @param {string} designator Selected component designator.
475
+ * @param {string} sourceType Selection source type.
476
+ * @param {boolean} hidden Whether the component is hidden.
477
+ * @param {(key: string) => string} translate Translation lookup.
478
+ * @returns {string}
479
+ */
480
+ static #renderVisibilityToggle(designator, sourceType, hidden, translate) {
481
+ const label = hidden
482
+ ? translate('scene3d.showSelectedComponent')
483
+ : translate('scene3d.hideSelectedComponent')
484
+ const iconClass = hidden
485
+ ? 'scene-3d__selection-eye-icon scene-3d__selection-eye-off-icon'
486
+ : 'scene-3d__selection-eye-icon'
487
+
488
+ return (
489
+ '<button class="scene-3d__selection-visibility" type="button" data-scene-3d-component-visibility="' +
490
+ PcbScene3dSelectionInspectorRenderer.#escapeHtml(designator) +
491
+ '" data-scene-3d-component-source="' +
492
+ PcbScene3dSelectionInspectorRenderer.#escapeHtml(sourceType) +
493
+ '" aria-label="' +
494
+ PcbScene3dSelectionInspectorRenderer.#escapeHtml(label) +
495
+ '" title="' +
496
+ PcbScene3dSelectionInspectorRenderer.#escapeHtml(label) +
497
+ '" aria-pressed="' +
498
+ (hidden ? 'true' : 'false') +
499
+ '"><span class="' +
500
+ iconClass +
501
+ '" aria-hidden="true">' +
502
+ PcbScene3dSelectionInspectorRenderer.#renderVisibilityIcon(
503
+ !hidden
504
+ ) +
505
+ '</span></button>'
506
+ )
507
+ }
508
+
509
+ /**
510
+ * Renders an eye icon for component visibility state.
511
+ * @param {boolean} visible Whether the component is visible.
512
+ * @returns {string}
513
+ */
514
+ static #renderVisibilityIcon(visible) {
515
+ const slash = visible ? '' : '<path d="M4 4l16 16" />'
516
+ return (
517
+ '<svg class="icon" viewBox="0 0 24 24" aria-hidden="true">' +
518
+ '<path d="M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6-10-6-10-6z" />' +
519
+ '<circle cx="12" cy="12" r="2.5" />' +
520
+ slash +
521
+ '</svg>'
522
+ )
523
+ }
524
+
464
525
  /**
465
526
  * Formats a model file label.
466
527
  * @param {any} externalPlacement External placement.
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Binds the selected-component visibility toggle in the inspector.
3
+ */
4
+ export class PcbScene3dSelectionVisibilityBinder {
5
+ /** @type {HTMLElement | null} */
6
+ #selectionNode
7
+
8
+ /** @type {{ node: EventTarget, type: string, listener: (event: any) => void } | null} */
9
+ #listenerRecord
10
+
11
+ /** @type {() => string} */
12
+ #resolveDesignator
13
+
14
+ /** @type {(designator: string) => boolean} */
15
+ #resolveHidden
16
+
17
+ /** @type {(designator: string, hidden: boolean) => void} */
18
+ #setHidden
19
+
20
+ /** @type {(designator: string, sourceType: string) => void} */
21
+ #refreshSelection
22
+
23
+ /**
24
+ * @param {{ resolveDesignator: () => string, resolveHidden: (designator: string) => boolean, setHidden: (designator: string, hidden: boolean) => void, refreshSelection: (designator: string, sourceType: string) => void }} options Binder callbacks.
25
+ */
26
+ constructor(options) {
27
+ this.#selectionNode = null
28
+ this.#listenerRecord = null
29
+ this.#resolveDesignator = options.resolveDesignator
30
+ this.#resolveHidden = options.resolveHidden
31
+ this.#setHidden = options.setHidden
32
+ this.#refreshSelection = options.refreshSelection
33
+ }
34
+
35
+ /**
36
+ * Binds delegated visibility toggles in the selection inspector.
37
+ * @param {HTMLElement | null} selectionNode Inspector node.
38
+ * @returns {void}
39
+ */
40
+ bindSelectionNode(selectionNode) {
41
+ this.dispose()
42
+ this.#selectionNode =
43
+ selectionNode && typeof selectionNode === 'object'
44
+ ? selectionNode
45
+ : null
46
+ if (!this.#selectionNode) {
47
+ return
48
+ }
49
+
50
+ const listener = (event) => this.#handleClick(event)
51
+ this.#selectionNode.addEventListener?.('click', listener)
52
+ this.#listenerRecord = {
53
+ node: this.#selectionNode,
54
+ type: 'click',
55
+ listener
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Removes the active delegated click listener.
61
+ * @returns {void}
62
+ */
63
+ dispose() {
64
+ if (this.#listenerRecord) {
65
+ const { node, type, listener } = this.#listenerRecord
66
+ node.removeEventListener?.(type, listener)
67
+ }
68
+ this.#listenerRecord = null
69
+ this.#selectionNode = null
70
+ }
71
+
72
+ /**
73
+ * Handles one delegated visibility-button click.
74
+ * @param {any} event DOM event.
75
+ * @returns {void}
76
+ */
77
+ #handleClick(event) {
78
+ const button =
79
+ PcbScene3dSelectionVisibilityBinder.#closestVisibilityButton(
80
+ event?.target
81
+ )
82
+ if (!button) {
83
+ return
84
+ }
85
+
86
+ event?.preventDefault?.()
87
+ const designator = String(
88
+ button?.getAttribute?.('data-scene-3d-component-visibility') ||
89
+ this.#resolveDesignator() ||
90
+ ''
91
+ ).trim()
92
+ if (!designator) {
93
+ return
94
+ }
95
+
96
+ this.#setHidden(designator, !this.#resolveHidden(designator))
97
+ this.#refreshSelection(
98
+ designator,
99
+ String(
100
+ button?.getAttribute?.('data-scene-3d-component-source') || ''
101
+ )
102
+ )
103
+ }
104
+
105
+ /**
106
+ * Finds a visibility button from an event target.
107
+ * @param {any} target Event target.
108
+ * @returns {any | null}
109
+ */
110
+ static #closestVisibilityButton(target) {
111
+ const closest = target?.closest?.(
112
+ '[data-scene-3d-component-visibility]'
113
+ )
114
+ return closest ||
115
+ target?.getAttribute?.('data-scene-3d-component-visibility')
116
+ ? closest || target
117
+ : null
118
+ }
119
+ }
@@ -22,6 +22,7 @@ const FALLBACK_MESSAGES = {
22
22
  'scene3d.fallbackBody': 'Fallback body',
23
23
  'scene3d.fallbackBodies': 'Fallback bodies',
24
24
  'scene3d.footprint': 'Footprint',
25
+ 'scene3d.hideSelectedComponent': 'Hide selected component',
25
26
  'scene3d.inspectPrompt': 'Click a component to inspect it.',
26
27
  'scene3d.interactiveViewAria': 'Interactive 3D PCB view',
27
28
  'scene3d.isometric': 'Isometric',
@@ -39,11 +40,12 @@ const FALLBACK_MESSAGES = {
39
40
  'scene3d.picked': 'Picked',
40
41
  'scene3d.placements': 'Placements',
41
42
  'scene3d.pointerHint':
42
- 'Drag to orbit, right-drag to pan, and use the wheel to zoom.',
43
+ 'Drag pans in Top/Bottom and orbits in Isometric; right-drag uses the alternate action. Use the wheel to zoom.',
43
44
  'scene3d.offset': 'Offset',
44
45
  'scene3d.resetTransform': 'Reset',
45
46
  'scene3d.rotation': 'Rotation',
46
47
  'scene3d.scale': 'Scale',
48
+ 'scene3d.showSelectedComponent': 'Show selected component',
47
49
  'scene3d.skipped': 'Skipped',
48
50
  'scene3d.source': 'Source',
49
51
  'scene3d.startFailed': '3D preview could not start:',
@@ -53,7 +55,7 @@ const FALLBACK_MESSAGES = {
53
55
  'scene3d.toolbarAria': '3D camera presets',
54
56
  'scene3d.top': 'Top',
55
57
  'scene3d.touchHint':
56
- 'Drag with one finger to orbit, pinch to zoom, and drag with two fingers to pan.',
58
+ 'One-finger drag pans in Top/Bottom and orbits in Isometric. Pinch to zoom.',
57
59
  'scene3d.unresolved': 'unresolved'
58
60
  }
59
61
 
package/src/scene3d.mjs CHANGED
@@ -1,4 +1,13 @@
1
1
  export { PcbModelArchiveExporter } from './PcbModelArchiveExporter.mjs'
2
+ export { PcbAssemblyBoardSubstrateBuilder } from './PcbAssemblyBoardSubstrateBuilder.mjs'
3
+ export { PcbAssemblyExportCoordinateFrame } from './PcbAssemblyExportCoordinateFrame.mjs'
4
+ export { PcbAssemblyGeometryBuildProgress } from './PcbAssemblyGeometryBuildProgress.mjs'
5
+ export { PcbAssemblyGeometryBuilder } from './PcbAssemblyGeometryBuilder.mjs'
6
+ export { PcbAssemblyMeshUtils } from './PcbAssemblyMeshUtils.mjs'
7
+ export { PcbAssemblyModelMeshLoader } from './PcbAssemblyModelMeshLoader.mjs'
8
+ export { PcbAssemblyPolygonTriangulator } from './PcbAssemblyPolygonTriangulator.mjs'
9
+ export { PcbAssemblyStepWriter } from './PcbAssemblyStepWriter.mjs'
10
+ export { PcbAssemblyWrlWriter } from './PcbAssemblyWrlWriter.mjs'
2
11
  export { PcbScene3dBoardAssemblyPlacement } from './PcbScene3dBoardAssemblyPlacement.mjs'
3
12
  export { PcbScene3dBoardAssemblyPresentation } from './PcbScene3dBoardAssemblyPresentation.mjs'
4
13
  export { PcbScene3dBoardEdgeCutoutBuilder } from './PcbScene3dBoardEdgeCutoutBuilder.mjs'
@@ -8,6 +17,7 @@ export { PcbScene3dBoardSolderMaskFactory } from './PcbScene3dBoardSolderMaskFac
8
17
  export { PcbScene3dCameraRig } from './PcbScene3dCameraRig.mjs'
9
18
  export { PcbScene3dController } from './PcbScene3dController.mjs'
10
19
  export { PcbScene3dCircuitJsonAdapter } from './PcbScene3dCircuitJsonAdapter.mjs'
20
+ export { PcbScene3dComponentVisibility } from './PcbScene3dComponentVisibility.mjs'
11
21
  export { PcbScene3dCopperDetailFilter } from './PcbScene3dCopperDetailFilter.mjs'
12
22
  export { PcbScene3dCopperFactory } from './PcbScene3dCopperFactory.mjs'
13
23
  export { PcbScene3dCopperTextFactory } from './PcbScene3dCopperTextFactory.mjs'
@@ -25,9 +35,11 @@ export { PcbScene3dOutlineBuilder } from './PcbScene3dOutlineBuilder.mjs'
25
35
  export { PcbScene3dPadFactory } from './PcbScene3dPadFactory.mjs'
26
36
  export { PcbScene3dPresetState } from './PcbScene3dPresetState.mjs'
27
37
  export { PcbScene3dRenderGroupVisibility } from './PcbScene3dRenderGroupVisibility.mjs'
38
+ export { PcbScene3dRenderScheduler } from './PcbScene3dRenderScheduler.mjs'
28
39
  export { PcbScene3dRuntime } from './PcbScene3dRuntime.mjs'
29
40
  export { PcbScene3dRuntimeBoardMeshes } from './PcbScene3dRuntimeBoardMeshes.mjs'
30
41
  export { PcbScene3dSelectionStyler } from './PcbScene3dSelectionStyler.mjs'
42
+ export { PcbScene3dSelectionVisibilityBinder } from './PcbScene3dSelectionVisibilityBinder.mjs'
31
43
  export { PcbScene3dShapePathFactory } from './PcbScene3dShapePathFactory.mjs'
32
44
  export { PcbScene3dShellRenderer } from './PcbScene3dShellRenderer.mjs'
33
45
  export { PcbScene3dSilkscreenFactory } from './PcbScene3dSilkscreenFactory.mjs'
@@ -173,11 +173,59 @@ body.is-viewer-mode.is-viewer-3d .scene-3d {
173
173
  border: 1px solid rgba(95, 112, 124, 0.12);
174
174
  }
175
175
 
176
+ .scene-3d__selection-header {
177
+ display: grid;
178
+ grid-template-columns: minmax(0, 1fr) 2.1rem;
179
+ align-items: center;
180
+ gap: 0.5rem;
181
+ }
182
+
176
183
  .scene-3d__selection-title {
177
184
  margin: 0;
178
185
  font-size: 0.9rem;
179
186
  }
180
187
 
188
+ .scene-3d__selection-visibility {
189
+ display: inline-flex;
190
+ align-items: center;
191
+ justify-content: center;
192
+ width: 2.1rem;
193
+ height: 2.1rem;
194
+ border: 1px solid rgba(95, 112, 124, 0.16);
195
+ border-radius: 8px;
196
+ background: rgba(255, 255, 255, 0.78);
197
+ color: #425d70;
198
+ cursor: pointer;
199
+ }
200
+
201
+ .scene-3d__selection-visibility:hover,
202
+ .scene-3d__selection-visibility[aria-pressed='true'] {
203
+ border-color: rgba(184, 90, 37, 0.34);
204
+ color: var(--accent);
205
+ }
206
+
207
+ .scene-3d__selection-eye-icon {
208
+ width: 1.1rem;
209
+ height: 1.1rem;
210
+ display: inline-flex;
211
+ align-items: center;
212
+ justify-content: center;
213
+ }
214
+
215
+ .scene-3d__selection-eye-icon .icon {
216
+ width: 1.05rem;
217
+ height: 1.05rem;
218
+ }
219
+
220
+ .scene-3d__selection-eye-icon .icon path,
221
+ .scene-3d__selection-eye-icon .icon circle {
222
+ fill: none;
223
+ stroke: currentColor;
224
+ stroke-width: 1.8;
225
+ stroke-linecap: round;
226
+ stroke-linejoin: round;
227
+ }
228
+
181
229
  .scene-3d__selection-empty {
182
230
  margin: 0;
183
231
  color: var(--muted);