matterviz 0.3.2 → 0.3.4

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.
Files changed (281) hide show
  1. package/dist/EmptyState.svelte +10 -2
  2. package/dist/FilePicker.svelte +123 -82
  3. package/dist/Icon.svelte +18 -12
  4. package/dist/MillerIndexInput.svelte +27 -21
  5. package/dist/api/optimade.js +6 -6
  6. package/dist/app.css +216 -207
  7. package/dist/brillouin/BrillouinZone.svelte +292 -149
  8. package/dist/brillouin/BrillouinZone.svelte.d.ts +1 -1
  9. package/dist/brillouin/BrillouinZoneControls.svelte +32 -5
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte +69 -42
  11. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
  12. package/dist/brillouin/BrillouinZoneInfoPane.svelte +99 -68
  13. package/dist/brillouin/BrillouinZoneScene.svelte +275 -163
  14. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  15. package/dist/brillouin/BrillouinZoneTooltip.svelte +17 -7
  16. package/dist/brillouin/compute.js +11 -6
  17. package/dist/chempot-diagram/ChemPotDiagram.svelte +162 -27
  18. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +451 -281
  19. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +2148 -1642
  20. package/dist/chempot-diagram/ChemPotScene3D.svelte +8 -5
  21. package/dist/chempot-diagram/async-compute.svelte.d.ts +3 -0
  22. package/dist/chempot-diagram/async-compute.svelte.js +77 -0
  23. package/dist/chempot-diagram/chempot-worker.d.ts +1 -0
  24. package/dist/chempot-diagram/chempot-worker.js +11 -0
  25. package/dist/chempot-diagram/color.js +1 -2
  26. package/dist/chempot-diagram/compute.d.ts +10 -0
  27. package/dist/chempot-diagram/compute.js +250 -88
  28. package/dist/chempot-diagram/index.d.ts +2 -1
  29. package/dist/chempot-diagram/index.js +2 -1
  30. package/dist/chempot-diagram/temperature.js +8 -9
  31. package/dist/chempot-diagram/types.d.ts +3 -0
  32. package/dist/chempot-diagram/types.js +1 -0
  33. package/dist/colors/index.d.ts +1 -1
  34. package/dist/colors/index.js +5 -3
  35. package/dist/composition/BarChart.svelte +128 -55
  36. package/dist/composition/BubbleChart.svelte +102 -49
  37. package/dist/composition/Composition.svelte +100 -79
  38. package/dist/composition/Formula.svelte +108 -62
  39. package/dist/composition/FormulaFilter.svelte +665 -537
  40. package/dist/composition/PieChart.svelte +183 -108
  41. package/dist/composition/format.d.ts +5 -0
  42. package/dist/composition/format.js +20 -3
  43. package/dist/composition/parse.js +14 -9
  44. package/dist/convex-hull/ConvexHull.svelte +93 -40
  45. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  46. package/dist/convex-hull/ConvexHull2D.svelte +549 -360
  47. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  48. package/dist/convex-hull/ConvexHull3D.svelte +1296 -827
  49. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  50. package/dist/convex-hull/ConvexHull4D.svelte +1004 -688
  51. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  52. package/dist/convex-hull/ConvexHullControls.svelte +115 -28
  53. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +1 -1
  54. package/dist/convex-hull/ConvexHullInfoPane.svelte +29 -3
  55. package/dist/convex-hull/ConvexHullStats.svelte +425 -328
  56. package/dist/convex-hull/ConvexHullTooltip.svelte +40 -16
  57. package/dist/convex-hull/GasPressureControls.svelte +104 -61
  58. package/dist/convex-hull/StructurePopup.svelte +25 -4
  59. package/dist/convex-hull/TemperatureSlider.svelte +45 -25
  60. package/dist/convex-hull/barycentric-coords.js +13 -7
  61. package/dist/convex-hull/demo-temperature.js +8 -4
  62. package/dist/convex-hull/gas-thermodynamics.js +17 -12
  63. package/dist/convex-hull/helpers.d.ts +9 -0
  64. package/dist/convex-hull/helpers.js +77 -34
  65. package/dist/convex-hull/thermodynamics.js +61 -56
  66. package/dist/convex-hull/types.d.ts +9 -14
  67. package/dist/convex-hull/types.js +0 -17
  68. package/dist/coordination/CoordinationBarPlot.svelte +227 -154
  69. package/dist/element/BohrAtom.svelte +55 -12
  70. package/dist/element/ElementHeading.svelte +7 -2
  71. package/dist/element/ElementPhoto.svelte +15 -9
  72. package/dist/element/ElementStats.svelte +10 -4
  73. package/dist/element/ElementTile.svelte +137 -73
  74. package/dist/element/Nucleus.svelte +39 -11
  75. package/dist/element/data.js +1 -1
  76. package/dist/feedback/ClickFeedback.svelte +16 -5
  77. package/dist/feedback/DragOverlay.svelte +10 -2
  78. package/dist/feedback/Spinner.svelte +4 -2
  79. package/dist/feedback/StatusMessage.svelte +8 -2
  80. package/dist/fermi-surface/FermiSlice.svelte +118 -88
  81. package/dist/fermi-surface/FermiSurface.svelte +328 -187
  82. package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
  83. package/dist/fermi-surface/FermiSurfaceControls.svelte +113 -46
  84. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  85. package/dist/fermi-surface/FermiSurfaceScene.svelte +535 -342
  86. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  87. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +14 -5
  88. package/dist/fermi-surface/compute.js +16 -20
  89. package/dist/fermi-surface/parse.js +24 -14
  90. package/dist/fermi-surface/symmetry.js +2 -7
  91. package/dist/fermi-surface/types.d.ts +3 -5
  92. package/dist/heatmap-matrix/HeatmapMatrix.svelte +1019 -765
  93. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +1 -1
  94. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +76 -22
  95. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +2 -3
  96. package/dist/icons.js +47 -0
  97. package/dist/index.d.ts +2 -1
  98. package/dist/index.js +2 -1
  99. package/dist/io/decompress.js +1 -1
  100. package/dist/io/export.d.ts +3 -0
  101. package/dist/io/export.js +129 -143
  102. package/dist/io/is-binary.js +2 -3
  103. package/dist/io/url-drop.js +1 -2
  104. package/dist/isosurface/Isosurface.svelte +202 -148
  105. package/dist/isosurface/IsosurfaceControls.svelte +46 -28
  106. package/dist/isosurface/parse.js +34 -29
  107. package/dist/isosurface/slice.js +5 -10
  108. package/dist/isosurface/types.d.ts +2 -1
  109. package/dist/isosurface/types.js +61 -12
  110. package/dist/labels.js +11 -8
  111. package/dist/layout/FullscreenToggle.svelte +11 -2
  112. package/dist/layout/InfoCard.svelte +38 -6
  113. package/dist/layout/InfoTag.svelte +63 -32
  114. package/dist/layout/PropertyFilter.svelte +82 -37
  115. package/dist/layout/SettingsSection.svelte +85 -55
  116. package/dist/layout/SubpageGrid.svelte +10 -2
  117. package/dist/layout/json-tree/JsonNode.svelte +183 -138
  118. package/dist/layout/json-tree/JsonTree.svelte +499 -413
  119. package/dist/layout/json-tree/JsonValue.svelte +127 -99
  120. package/dist/layout/json-tree/utils.js +4 -2
  121. package/dist/marching-cubes.js +25 -2
  122. package/dist/math.d.ts +13 -17
  123. package/dist/math.js +133 -67
  124. package/dist/overlays/ContextMenu.svelte +65 -40
  125. package/dist/overlays/DraggablePane.svelte +211 -139
  126. package/dist/periodic-table/PeriodicTable.svelte +278 -145
  127. package/dist/periodic-table/PeriodicTableControls.svelte +178 -128
  128. package/dist/periodic-table/PropertySelect.svelte +25 -7
  129. package/dist/periodic-table/TableInset.svelte +8 -3
  130. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +446 -309
  131. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
  132. package/dist/phase-diagram/PhaseDiagramControls.svelte +102 -43
  133. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  134. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +63 -40
  135. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +71 -28
  136. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +1 -1
  137. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +158 -101
  138. package/dist/phase-diagram/TdbInfoPanel.svelte +28 -4
  139. package/dist/phase-diagram/build-diagram.js +9 -9
  140. package/dist/phase-diagram/colors.js +1 -3
  141. package/dist/phase-diagram/parse.js +10 -9
  142. package/dist/phase-diagram/svg-to-diagram.js +53 -49
  143. package/dist/phase-diagram/utils.d.ts +1 -0
  144. package/dist/phase-diagram/utils.js +80 -25
  145. package/dist/plot/AxisLabel.svelte +28 -3
  146. package/dist/plot/BarPlot.svelte +1182 -734
  147. package/dist/plot/BarPlot.svelte.d.ts +2 -2
  148. package/dist/plot/BarPlotControls.svelte +31 -5
  149. package/dist/plot/BarPlotControls.svelte.d.ts +1 -1
  150. package/dist/plot/ColorBar.svelte +479 -329
  151. package/dist/plot/ColorScaleSelect.svelte +27 -6
  152. package/dist/plot/ElementScatter.svelte +36 -15
  153. package/dist/plot/FillArea.svelte +152 -95
  154. package/dist/plot/Histogram.svelte +934 -571
  155. package/dist/plot/Histogram.svelte.d.ts +1 -1
  156. package/dist/plot/HistogramControls.svelte +53 -9
  157. package/dist/plot/HistogramControls.svelte.d.ts +1 -1
  158. package/dist/plot/InteractiveAxisLabel.svelte +34 -11
  159. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +1 -1
  160. package/dist/plot/Line.svelte +63 -28
  161. package/dist/plot/PlotControls.svelte +157 -114
  162. package/dist/plot/PlotControls.svelte.d.ts +1 -1
  163. package/dist/plot/PlotLegend.svelte +174 -91
  164. package/dist/plot/PlotTooltip.svelte +45 -6
  165. package/dist/plot/PortalSelect.svelte +175 -147
  166. package/dist/plot/ReferenceLine.svelte +76 -22
  167. package/dist/plot/ReferenceLine3D.svelte +132 -107
  168. package/dist/plot/ReferencePlane.svelte +146 -121
  169. package/dist/plot/ScatterPlot.svelte +1681 -1091
  170. package/dist/plot/ScatterPlot.svelte.d.ts +2 -2
  171. package/dist/plot/ScatterPlot3D.svelte +256 -131
  172. package/dist/plot/ScatterPlot3D.svelte.d.ts +2 -2
  173. package/dist/plot/ScatterPlot3DControls.svelte +113 -63
  174. package/dist/plot/ScatterPlot3DControls.svelte.d.ts +2 -1
  175. package/dist/plot/ScatterPlot3DScene.svelte +608 -403
  176. package/dist/plot/ScatterPlot3DScene.svelte.d.ts +2 -2
  177. package/dist/plot/ScatterPlotControls.svelte +65 -25
  178. package/dist/plot/ScatterPlotControls.svelte.d.ts +1 -1
  179. package/dist/plot/ScatterPoint.svelte +98 -26
  180. package/dist/plot/ScatterPoint.svelte.d.ts +1 -0
  181. package/dist/plot/SpacegroupBarPlot.svelte +142 -85
  182. package/dist/plot/Surface3D.svelte +159 -108
  183. package/dist/plot/ZeroLines.svelte +55 -3
  184. package/dist/plot/ZoomRect.svelte +4 -2
  185. package/dist/plot/axis-utils.js +1 -3
  186. package/dist/plot/data-cleaning.js +12 -28
  187. package/dist/plot/data-transform.js +2 -1
  188. package/dist/plot/fill-utils.js +2 -0
  189. package/dist/plot/layout.d.ts +4 -1
  190. package/dist/plot/layout.js +33 -14
  191. package/dist/plot/reference-line.d.ts +2 -2
  192. package/dist/plot/reference-line.js +7 -5
  193. package/dist/plot/scales.js +24 -36
  194. package/dist/plot/types.d.ts +11 -23
  195. package/dist/plot/types.js +6 -11
  196. package/dist/plot/utils/label-placement.d.ts +32 -15
  197. package/dist/plot/utils/label-placement.js +227 -66
  198. package/dist/plot/utils/series-visibility.js +2 -3
  199. package/dist/rdf/RdfPlot.svelte +143 -91
  200. package/dist/rdf/calc-rdf.js +4 -5
  201. package/dist/sanitize.d.ts +4 -0
  202. package/dist/sanitize.js +107 -0
  203. package/dist/settings.d.ts +18 -6
  204. package/dist/settings.js +46 -16
  205. package/dist/spectral/Bands.svelte +632 -453
  206. package/dist/spectral/BandsAndDos.svelte +90 -49
  207. package/dist/spectral/BrillouinBandsDos.svelte +151 -93
  208. package/dist/spectral/Dos.svelte +389 -258
  209. package/dist/spectral/helpers.js +55 -43
  210. package/dist/state.svelte.d.ts +1 -1
  211. package/dist/state.svelte.js +3 -2
  212. package/dist/structure/Arrow.svelte +59 -20
  213. package/dist/structure/AtomLegend.svelte +215 -134
  214. package/dist/structure/Bond.svelte +73 -47
  215. package/dist/structure/CanvasTooltip.svelte +10 -2
  216. package/dist/structure/CellSelect.svelte +72 -45
  217. package/dist/structure/Cylinder.svelte +33 -17
  218. package/dist/structure/Lattice.svelte +88 -33
  219. package/dist/structure/Structure.svelte +1063 -797
  220. package/dist/structure/Structure.svelte.d.ts +1 -1
  221. package/dist/structure/StructureControls.svelte +349 -118
  222. package/dist/structure/StructureExportPane.svelte +124 -89
  223. package/dist/structure/StructureExportPane.svelte.d.ts +1 -1
  224. package/dist/structure/StructureInfoPane.svelte +304 -237
  225. package/dist/structure/StructureScene.svelte +879 -443
  226. package/dist/structure/StructureScene.svelte.d.ts +15 -7
  227. package/dist/structure/atom-properties.js +8 -8
  228. package/dist/structure/bonding.js +6 -7
  229. package/dist/structure/export.js +14 -29
  230. package/dist/structure/ferrox-wasm.js +1 -1
  231. package/dist/structure/index.d.ts +13 -3
  232. package/dist/structure/index.js +83 -23
  233. package/dist/structure/measure.d.ts +2 -2
  234. package/dist/structure/measure.js +4 -44
  235. package/dist/structure/parse.js +113 -141
  236. package/dist/structure/partial-occupancy.js +7 -10
  237. package/dist/structure/pbc.d.ts +1 -0
  238. package/dist/structure/pbc.js +16 -6
  239. package/dist/structure/supercell.d.ts +2 -2
  240. package/dist/structure/supercell.js +12 -22
  241. package/dist/structure/validation.js +1 -2
  242. package/dist/symmetry/SymmetryStats.svelte +84 -41
  243. package/dist/symmetry/WyckoffTable.svelte +26 -6
  244. package/dist/symmetry/cell-transform.js +5 -3
  245. package/dist/symmetry/index.js +8 -7
  246. package/dist/symmetry/spacegroups.js +148 -148
  247. package/dist/table/HeatmapTable.svelte +790 -554
  248. package/dist/table/HeatmapTable.svelte.d.ts +1 -1
  249. package/dist/table/ToggleMenu.svelte +125 -92
  250. package/dist/table/index.js +2 -4
  251. package/dist/theme/ThemeControl.svelte +21 -12
  252. package/dist/time.js +4 -1
  253. package/dist/tooltip/TooltipContent.svelte +33 -8
  254. package/dist/trajectory/Trajectory.svelte +758 -558
  255. package/dist/trajectory/TrajectoryError.svelte +14 -3
  256. package/dist/trajectory/TrajectoryExportPane.svelte +137 -83
  257. package/dist/trajectory/TrajectoryInfoPane.svelte +272 -143
  258. package/dist/trajectory/extract.js +10 -26
  259. package/dist/trajectory/format-detect.js +5 -5
  260. package/dist/trajectory/frame-reader.d.ts +1 -1
  261. package/dist/trajectory/frame-reader.js +5 -12
  262. package/dist/trajectory/helpers.d.ts +0 -1
  263. package/dist/trajectory/helpers.js +2 -17
  264. package/dist/trajectory/index.js +14 -12
  265. package/dist/trajectory/parse/ase.js +5 -4
  266. package/dist/trajectory/parse/hdf5.js +26 -18
  267. package/dist/trajectory/parse/index.js +13 -18
  268. package/dist/trajectory/parse/lammps.js +17 -7
  269. package/dist/trajectory/parse/vasp.js +5 -2
  270. package/dist/trajectory/parse/xyz.js +8 -7
  271. package/dist/trajectory/plotting.js +13 -8
  272. package/dist/utils.d.ts +1 -0
  273. package/dist/utils.js +13 -0
  274. package/dist/xrd/XrdPlot.svelte +337 -247
  275. package/dist/xrd/broadening.js +14 -9
  276. package/dist/xrd/calc-xrd.js +12 -18
  277. package/dist/xrd/parse.d.ts +1 -1
  278. package/dist/xrd/parse.js +17 -17
  279. package/package.json +99 -103
  280. package/readme.md +1 -1
  281. /package/dist/theme/{themes.js → themes.mjs} +0 -0
@@ -1,127 +1,152 @@
1
- <script lang="ts">import { T, useThrelte } from '@threlte/core';
2
- import * as THREE from 'three';
3
- import { Line2 } from 'three/examples/jsm/lines/Line2.js';
4
- import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js';
5
- import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js';
6
- import { create_to_threejs, span_or } from './reference-line';
7
- let { ref_line, scene_size = [10, 10, 5], ranges } = $props();
8
- const { size } = useThrelte();
9
- let [scene_x, scene_y, scene_z] = $derived(scene_size);
10
- let { x: x_range, y: y_range, z: z_range } = $derived(ranges);
11
- // Transform data coords to Three.js coordinates
12
- let to_coords = $derived.by(() => {
1
+ <script lang="ts">
2
+ // ReferenceLine3D: 3D reference lines for axis-parallel, segments, and extended lines
3
+ // Uses Line2 for proper variable-width lines (WebGL ignores linewidth on basic lines)
4
+ import type { Vec3 } from '../math'
5
+ import { T, useThrelte } from '@threlte/core'
6
+ import * as THREE from 'three'
7
+ import { Line2 } from 'three/examples/jsm/lines/Line2.js'
8
+ import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js'
9
+ import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js'
10
+ import { create_to_threejs, span_or } from './reference-line'
11
+ import type { RefLine3D } from './types'
12
+
13
+ let { ref_line, scene_size = [10, 10, 5], ranges }: {
14
+ ref_line: RefLine3D
15
+ scene_size?: Vec3
16
+ ranges: { x: [number, number]; y: [number, number]; z: [number, number] }
17
+ } = $props()
18
+
19
+ const { size } = useThrelte()
20
+ let [scene_x, scene_y, scene_z] = $derived(scene_size)
21
+ let { x: x_range, y: y_range, z: z_range } = $derived(ranges)
22
+
23
+ // Transform data coords to Three.js coordinates
24
+ let to_coords = $derived.by(() => {
13
25
  const transform = create_to_threejs({
14
- scene_x,
15
- scene_y,
16
- scene_z,
17
- x_range,
18
- y_range,
19
- z_range,
20
- });
21
- return (ux, uy, uz) => transform(ux, uy, uz);
22
- });
23
- // Compute line endpoints based on type
24
- let endpoints = $derived.by(() => {
25
- if (ref_line.visible === false)
26
- return null;
27
- const [x_min, x_max] = span_or(ref_line.x_span, x_range);
28
- const [y_min, y_max] = span_or(ref_line.y_span, y_range);
29
- const [z_min, z_max] = span_or(ref_line.z_span, z_range);
30
- switch (ref_line.type) {
26
+ scene_x,
27
+ scene_y,
28
+ scene_z,
29
+ x_range,
30
+ y_range,
31
+ z_range,
32
+ })
33
+ return (ux: number, uy: number, uz: number) => transform(ux, uy, uz)
34
+ })
35
+
36
+ // Compute line endpoints based on type
37
+ let endpoints = $derived.by(
38
+ ():
39
+ | [{ x: number; y: number; z: number }, { x: number; y: number; z: number }]
40
+ | null => {
41
+ if (ref_line.visible === false) return null
42
+ const [x_min, x_max] = span_or(ref_line.x_span, x_range)
43
+ const [y_min, y_max] = span_or(ref_line.y_span, y_range)
44
+ const [z_min, z_max] = span_or(ref_line.z_span, z_range)
45
+
46
+ switch (ref_line.type) {
31
47
  case `x-axis`:
32
- return [
33
- to_coords(x_min, ref_line.y, ref_line.z),
34
- to_coords(x_max, ref_line.y, ref_line.z),
35
- ];
48
+ return [
49
+ to_coords(x_min, ref_line.y, ref_line.z),
50
+ to_coords(x_max, ref_line.y, ref_line.z),
51
+ ]
36
52
  case `y-axis`:
37
- return [
38
- to_coords(ref_line.x, y_min, ref_line.z),
39
- to_coords(ref_line.x, y_max, ref_line.z),
40
- ];
53
+ return [
54
+ to_coords(ref_line.x, y_min, ref_line.z),
55
+ to_coords(ref_line.x, y_max, ref_line.z),
56
+ ]
41
57
  case `z-axis`:
42
- return [
43
- to_coords(ref_line.x, ref_line.y, z_min),
44
- to_coords(ref_line.x, ref_line.y, z_max),
45
- ];
58
+ return [
59
+ to_coords(ref_line.x, ref_line.y, z_min),
60
+ to_coords(ref_line.x, ref_line.y, z_max),
61
+ ]
46
62
  case `segment`:
47
- return [to_coords(...ref_line.p1), to_coords(...ref_line.p2)];
63
+ return [to_coords(...ref_line.p1), to_coords(...ref_line.p2)]
48
64
  case `line`: {
49
- // Extend line through two points to bounding box
50
- const [p1x, p1y, p1z] = ref_line.p1;
51
- const [dx, dy, dz] = [
52
- ref_line.p2[0] - p1x,
53
- ref_line.p2[1] - p1y,
54
- ref_line.p2[2] - p1z,
55
- ];
56
- // Find t values at each boundary plane
57
- const t_values = [
58
- ...(dx !== 0 ? [(x_min - p1x) / dx, (x_max - p1x) / dx] : []),
59
- ...(dy !== 0 ? [(y_min - p1y) / dy, (y_max - p1y) / dy] : []),
60
- ...(dz !== 0 ? [(z_min - p1z) / dz, (z_max - p1z) / dz] : []),
61
- ];
62
- // Keep only t values where the resulting point is inside bounds
63
- const eps = 1e-6;
64
- const valid_t = t_values.filter((t) => {
65
- const [px, py, pz] = [p1x + t * dx, p1y + t * dy, p1z + t * dz];
66
- return px >= x_min - eps && px <= x_max + eps &&
67
- py >= y_min - eps && py <= y_max + eps && pz >= z_min - eps &&
68
- pz <= z_max + eps;
69
- });
70
- if (valid_t.length < 2)
71
- return null;
72
- const t_min = Math.min(...valid_t);
73
- const t_max = Math.max(...valid_t);
74
- return [
75
- to_coords(p1x + t_min * dx, p1y + t_min * dy, p1z + t_min * dz),
76
- to_coords(p1x + t_max * dx, p1y + t_max * dy, p1z + t_max * dz),
77
- ];
65
+ // Extend line through two points to bounding box
66
+ const [p1x, p1y, p1z] = ref_line.p1
67
+ const [dx, dy, dz] = [
68
+ ref_line.p2[0] - p1x,
69
+ ref_line.p2[1] - p1y,
70
+ ref_line.p2[2] - p1z,
71
+ ]
72
+ // Find t values at each boundary plane
73
+ const t_values = [
74
+ ...(dx !== 0 ? [(x_min - p1x) / dx, (x_max - p1x) / dx] : []),
75
+ ...(dy !== 0 ? [(y_min - p1y) / dy, (y_max - p1y) / dy] : []),
76
+ ...(dz !== 0 ? [(z_min - p1z) / dz, (z_max - p1z) / dz] : []),
77
+ ]
78
+ // Keep only t values where the resulting point is inside bounds
79
+ const eps = 1e-6
80
+ const valid_t = t_values.filter((t) => {
81
+ const [px, py, pz] = [p1x + t * dx, p1y + t * dy, p1z + t * dz]
82
+ return px >= x_min - eps && px <= x_max + eps &&
83
+ py >= y_min - eps && py <= y_max + eps && pz >= z_min - eps &&
84
+ pz <= z_max + eps
85
+ })
86
+ if (valid_t.length < 2) return null
87
+ const t_min = Math.min(...valid_t)
88
+ const t_max = Math.max(...valid_t)
89
+ return [
90
+ to_coords(p1x + t_min * dx, p1y + t_min * dy, p1z + t_min * dz),
91
+ to_coords(p1x + t_max * dx, p1y + t_max * dy, p1z + t_max * dz),
92
+ ]
78
93
  }
79
- }
80
- });
81
- // Line style (with defaults)
82
- let style = $derived({
94
+ }
95
+ },
96
+ )
97
+
98
+ // Line style (with defaults)
99
+ let style = $derived({
83
100
  color: ref_line.style?.color ?? `white`,
84
101
  opacity: ref_line.style?.opacity ?? 1,
85
102
  width: ref_line.style?.width ?? 2,
86
103
  dashed: !!ref_line.style?.dash,
87
- });
88
- // Create Line2 with LineGeometry and LineMaterial for proper variable-width lines
89
- let line2 = $state(null);
90
- let material = $state(null);
91
- $effect(() => {
104
+ })
105
+
106
+ // Create Line2 with LineGeometry and LineMaterial for proper variable-width lines
107
+ let line2: Line2 | null = $state(null)
108
+ let material: LineMaterial | null = $state(null)
109
+
110
+ $effect(() => {
92
111
  if (!endpoints) {
93
- line2 = null;
94
- material = null;
95
- return;
112
+ line2 = null
113
+ material = null
114
+ return
96
115
  }
97
- const [p1, p2] = endpoints;
98
- const geo = new LineGeometry();
99
- geo.setPositions([p1.x, p1.y, p1.z, p2.x, p2.y, p2.z]);
116
+ const [p1, p2] = endpoints
117
+
118
+ const geo = new LineGeometry()
119
+ geo.setPositions([p1.x, p1.y, p1.z, p2.x, p2.y, p2.z])
120
+
100
121
  const mat = new LineMaterial({
101
- color: new THREE.Color(style.color).getHex(),
102
- linewidth: style.width,
103
- transparent: style.opacity < 1,
104
- opacity: style.opacity,
105
- dashed: style.dashed,
106
- dashSize: 0.3,
107
- gapSize: 0.1,
108
- resolution: new THREE.Vector2($size.width || 1, $size.height || 1),
109
- });
110
- const line = new Line2(geo, mat);
111
- line.computeLineDistances(); // Required for dashed lines
112
- material = mat;
113
- line2 = line;
122
+ color: new THREE.Color(style.color).getHex(),
123
+ linewidth: style.width,
124
+ transparent: style.opacity < 1,
125
+ opacity: style.opacity,
126
+ dashed: style.dashed,
127
+ dashSize: 0.3,
128
+ gapSize: 0.1,
129
+ resolution: new THREE.Vector2($size.width || 1, $size.height || 1),
130
+ })
131
+
132
+ const line = new Line2(geo, mat)
133
+ line.computeLineDistances() // Required for dashed lines
134
+
135
+ material = mat
136
+ line2 = line
137
+
114
138
  return () => {
115
- geo.dispose();
116
- mat.dispose();
117
- };
118
- });
119
- // Update material resolution when canvas size changes
120
- $effect(() => {
139
+ geo.dispose()
140
+ mat.dispose()
141
+ }
142
+ })
143
+
144
+ // Update material resolution when canvas size changes
145
+ $effect(() => {
121
146
  if (material) {
122
- material.resolution.set($size.width || 1, $size.height || 1);
147
+ material.resolution.set($size.width || 1, $size.height || 1)
123
148
  }
124
- });
149
+ })
125
150
  </script>
126
151
 
127
152
  {#if line2}
@@ -1,137 +1,162 @@
1
- <script lang="ts">import { cross_3d, normalize_vec3 } from '../math';
2
- import { T } from '@threlte/core';
3
- import * as THREE from 'three';
4
- import { create_to_threejs, span_or } from './reference-line';
5
- let { ref_plane, scene_size = [10, 10, 5], ranges } = $props();
6
- let [scene_x, scene_y, scene_z] = $derived(scene_size);
7
- let { x: x_range, y: y_range, z: z_range } = $derived(ranges);
8
- // Transform data coords to Three.js Vector3
9
- let to_vec3 = $derived.by(() => {
1
+ <script lang="ts">
2
+ // ReferencePlane: 3D reference planes (axis-aligned, normal-defined, or point-defined)
3
+ import type { Vec3 } from '../math'
4
+ import { cross_3d, normalize_vec3 } from '../math'
5
+ import { T } from '@threlte/core'
6
+ import * as THREE from 'three'
7
+ import { create_to_threejs, span_or } from './reference-line'
8
+ import type { RefPlane } from './types'
9
+
10
+ let { ref_plane, scene_size = [10, 10, 5], ranges }: {
11
+ ref_plane: RefPlane
12
+ scene_size?: Vec3
13
+ ranges: { x: [number, number]; y: [number, number]; z: [number, number] }
14
+ } = $props()
15
+
16
+ let [scene_x, scene_y, scene_z] = $derived(scene_size)
17
+ let { x: x_range, y: y_range, z: z_range } = $derived(ranges)
18
+
19
+ // Transform data coords to Three.js Vector3
20
+ let to_vec3 = $derived.by(() => {
10
21
  const transform = create_to_threejs({
11
- scene_x,
12
- scene_y,
13
- scene_z,
14
- x_range,
15
- y_range,
16
- z_range,
17
- });
18
- return (ux, uy, uz) => {
19
- const { x, y, z } = transform(ux, uy, uz);
20
- return new THREE.Vector3(x, y, z);
21
- };
22
- });
23
- // Apply span constraints or use full range
24
- let [x_min, x_max] = $derived(span_or(ref_plane.x_span, x_range));
25
- let [y_min, y_max] = $derived(span_or(ref_plane.y_span, y_range));
26
- let [z_min, z_max] = $derived(span_or(ref_plane.z_span, z_range));
27
- // Helper to create quad from 4 corner coords
28
- const quad = (coords) => create_quad_geometry(coords.map(([ux, uy, uz]) => to_vec3(ux, uy, uz)));
29
- // Compute plane geometry based on type - returns result to use in $effect
30
- function compute_geometry() {
31
- if (ref_plane.visible === false)
32
- return null;
22
+ scene_x,
23
+ scene_y,
24
+ scene_z,
25
+ x_range,
26
+ y_range,
27
+ z_range,
28
+ })
29
+ return (ux: number, uy: number, uz: number) => {
30
+ const { x, y, z } = transform(ux, uy, uz)
31
+ return new THREE.Vector3(x, y, z)
32
+ }
33
+ })
34
+
35
+ // Apply span constraints or use full range
36
+ let [x_min, x_max] = $derived(span_or(ref_plane.x_span, x_range))
37
+ let [y_min, y_max] = $derived(span_or(ref_plane.y_span, y_range))
38
+ let [z_min, z_max] = $derived(span_or(ref_plane.z_span, z_range))
39
+
40
+ // Helper to create quad from 4 corner coords
41
+ const quad = (coords: Vec3[]) =>
42
+ create_quad_geometry(coords.map(([ux, uy, uz]) => to_vec3(ux, uy, uz)))
43
+
44
+ // Compute plane geometry based on type - returns result to use in $effect
45
+ function compute_geometry(): THREE.BufferGeometry | null {
46
+ if (ref_plane.visible === false) return null
47
+
33
48
  switch (ref_plane.type) {
34
- case `xy`: {
35
- const zval = ref_plane.z;
36
- return quad([
37
- [x_min, y_min, zval],
38
- [x_max, y_min, zval],
39
- [x_max, y_max, zval],
40
- [x_min, y_max, zval],
41
- ]);
42
- }
43
- case `xz`: {
44
- const yval = ref_plane.y;
45
- return quad([
46
- [x_min, yval, z_min],
47
- [x_max, yval, z_min],
48
- [x_max, yval, z_max],
49
- [x_min, yval, z_max],
50
- ]);
51
- }
52
- case `yz`: {
53
- const xval = ref_plane.x;
54
- return quad([
55
- [xval, y_min, z_min],
56
- [xval, y_max, z_min],
57
- [xval, y_max, z_max],
58
- [xval, y_min, z_max],
59
- ]);
60
- }
61
- case `normal`: {
62
- if (Math.hypot(...ref_plane.normal) < 1e-9)
63
- return null; // degenerate normal
64
- return create_plane_from_normal(ref_plane.normal, ref_plane.point);
65
- }
66
- case `points`: {
67
- const { p1, p2, p3 } = ref_plane;
68
- const v1 = [p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]];
69
- const v2 = [p3[0] - p1[0], p3[1] - p1[1], p3[2] - p1[2]];
70
- const cross = cross_3d(v1, v2);
71
- if (Math.hypot(...cross) < 1e-9)
72
- return null; // collinear points
73
- return create_plane_from_normal(normalize_vec3(cross), p1);
74
- }
75
- default:
76
- return null;
49
+ case `xy`: {
50
+ const zval = ref_plane.z
51
+ return quad([
52
+ [x_min, y_min, zval],
53
+ [x_max, y_min, zval],
54
+ [x_max, y_max, zval],
55
+ [x_min, y_max, zval],
56
+ ])
57
+ }
58
+ case `xz`: {
59
+ const yval = ref_plane.y
60
+ return quad([
61
+ [x_min, yval, z_min],
62
+ [x_max, yval, z_min],
63
+ [x_max, yval, z_max],
64
+ [x_min, yval, z_max],
65
+ ])
66
+ }
67
+ case `yz`: {
68
+ const xval = ref_plane.x
69
+ return quad([
70
+ [xval, y_min, z_min],
71
+ [xval, y_max, z_min],
72
+ [xval, y_max, z_max],
73
+ [xval, y_min, z_max],
74
+ ])
75
+ }
76
+ case `normal`: {
77
+ if (Math.hypot(...ref_plane.normal) < 1e-9) return null // degenerate normal
78
+ return create_plane_from_normal(ref_plane.normal, ref_plane.point)
79
+ }
80
+ case `points`: {
81
+ const { p1, p2, p3 } = ref_plane
82
+ const v1: Vec3 = [p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]]
83
+ const v2: Vec3 = [p3[0] - p1[0], p3[1] - p1[1], p3[2] - p1[2]]
84
+ const cross = cross_3d(v1, v2)
85
+ if (Math.hypot(...cross) < 1e-9) return null // collinear points
86
+ return create_plane_from_normal(normalize_vec3(cross), p1)
87
+ }
88
+ default:
89
+ return null
77
90
  }
78
- }
79
- // Create geometry with proper disposal on dependency change
80
- let geometry = $state(null);
81
- $effect(() => {
82
- const geo = compute_geometry();
83
- geometry = geo;
84
- return () => geo?.dispose();
85
- });
86
- // Create a quad geometry from 4 corners (two triangles: 0-1-2 and 0-2-3)
87
- function create_quad_geometry(corners) {
88
- const geo = new THREE.BufferGeometry();
89
- const [c0, c1, c2, c3] = corners;
90
- const verts = [c0, c1, c2, c0, c2, c3].flatMap((c) => [c.x, c.y, c.z]);
91
- geo.setAttribute(`position`, new THREE.BufferAttribute(new Float32Array(verts), 3));
92
- geo.computeVertexNormals();
93
- return geo;
94
- }
95
- // Create plane from normal and point, scaled to cover bounding box
96
- function create_plane_from_normal(normal, point) {
97
- const normalized = normalize_vec3(normal);
91
+ }
92
+
93
+ // Create geometry with proper disposal on dependency change
94
+ let geometry: THREE.BufferGeometry | null = $state(null)
95
+
96
+ $effect(() => {
97
+ const geo = compute_geometry()
98
+ geometry = geo
99
+ return () => geo?.dispose()
100
+ })
101
+
102
+ // Create a quad geometry from 4 corners (two triangles: 0-1-2 and 0-2-3)
103
+ function create_quad_geometry(corners: THREE.Vector3[]): THREE.BufferGeometry {
104
+ const geo = new THREE.BufferGeometry()
105
+ const [c0, c1, c2, c3] = corners
106
+ const verts = [c0, c1, c2, c0, c2, c3].flatMap((corner) => [corner.x, corner.y, corner.z])
107
+ geo.setAttribute(
108
+ `position`,
109
+ new THREE.BufferAttribute(new Float32Array(verts), 3),
110
+ )
111
+ geo.computeVertexNormals()
112
+ return geo
113
+ }
114
+
115
+ // Create plane from normal and point, scaled to cover bounding box
116
+ function create_plane_from_normal(normal: Vec3, point: Vec3): THREE.BufferGeometry {
117
+ const normalized = normalize_vec3(normal)
98
118
  // Pick u perpendicular to normal (use axis least aligned with normal)
99
- const u_dir = normalize_vec3(cross_3d(normalized, Math.abs(normalized[0]) < 0.9 ? [1, 0, 0] : [0, 1, 0]));
100
- const v_dir = cross_3d(normalized, u_dir);
119
+ const u_dir = normalize_vec3(
120
+ cross_3d(normalized, Math.abs(normalized[0]) < 0.9 ? [1, 0, 0] : [0, 1, 0]),
121
+ )
122
+ const v_dir = cross_3d(normalized, u_dir)
101
123
  // Scale to cover bounding box
102
- const scale = Math.max(x_max - x_min, y_max - y_min, z_max - z_min) * 2;
103
- const [px, py, pz] = point;
124
+ const scale = Math.max(x_max - x_min, y_max - y_min, z_max - z_min) * 2
125
+ const [px, py, pz] = point
104
126
  // Helper to offset point by u*su + v*sv
105
- const corner = (su, sv) => [
106
- px + u_dir[0] * su + v_dir[0] * sv,
107
- py + u_dir[1] * su + v_dir[1] * sv,
108
- pz + u_dir[2] * su + v_dir[2] * sv,
109
- ];
127
+ const corner = (su: number, sv: number): Vec3 => [
128
+ px + u_dir[0] * su + v_dir[0] * sv,
129
+ py + u_dir[1] * su + v_dir[1] * sv,
130
+ pz + u_dir[2] * su + v_dir[2] * sv,
131
+ ]
110
132
  const corners = [
111
- corner(-scale, -scale),
112
- corner(scale, -scale),
113
- corner(scale, scale),
114
- corner(-scale, scale),
115
- ];
116
- return create_quad_geometry(corners.map(([ux, uy, uz]) => to_vec3(ux, uy, uz)));
117
- }
118
- // Material properties (with defaults)
119
- let style = $derived({
133
+ corner(-scale, -scale),
134
+ corner(scale, -scale),
135
+ corner(scale, scale),
136
+ corner(-scale, scale),
137
+ ]
138
+ return create_quad_geometry(corners.map(([ux, uy, uz]) => to_vec3(ux, uy, uz)))
139
+ }
140
+
141
+ // Material properties (with defaults)
142
+ let style = $derived({
120
143
  color: ref_plane.style?.color ?? `#4488ff`,
121
144
  opacity: ref_plane.style?.opacity ?? 0.3,
122
145
  wireframe: ref_plane.style?.wireframe ?? false,
123
146
  wireframe_color: ref_plane.style?.wireframe_color ?? `white`,
124
147
  double_sided: ref_plane.style?.double_sided ?? true,
125
- });
126
- // Create wireframe geometry with automatic disposal when dependencies change
127
- let wireframe_geometry = $state(null);
128
- $effect(() => {
148
+ })
149
+
150
+ // Create wireframe geometry with automatic disposal when dependencies change
151
+ let wireframe_geometry: THREE.WireframeGeometry | null = $state(null)
152
+
153
+ $effect(() => {
129
154
  const wf_geo = geometry && style.wireframe
130
- ? new THREE.WireframeGeometry(geometry)
131
- : null;
132
- wireframe_geometry = wf_geo;
133
- return () => wf_geo?.dispose();
134
- });
155
+ ? new THREE.WireframeGeometry(geometry)
156
+ : null
157
+ wireframe_geometry = wf_geo
158
+ return () => wf_geo?.dispose()
159
+ })
135
160
  </script>
136
161
 
137
162
  {#if geometry}