@realsee/dnalogel 4.0.0-webgpu.18 → 4.0.0-webgpu.20

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 (93) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/floorplan.js +1 -1
  3. package/dist/index.js +19 -19
  4. package/dist/internal/{BasePlugin-Cr_atQUC.js → BasePlugin-hxM1EHtV.js} +2 -2
  5. package/dist/internal/{BasePlugin-Cr_atQUC.js.map → BasePlugin-hxM1EHtV.js.map} +1 -1
  6. package/dist/internal/BasePluginWithData-BS2O9hNu.js +7 -0
  7. package/dist/internal/{BasePluginWithData-CIQpqYGe.js.map → BasePluginWithData-BS2O9hNu.js.map} +1 -1
  8. package/dist/internal/{Controller-Cq-mYkzT.js → Controller-CDLmWyXz.js} +3 -3
  9. package/dist/internal/{Controller-Cq-mYkzT.js.map → Controller-CDLmWyXz.js.map} +1 -1
  10. package/dist/internal/{Controller-BDT5_ZNe.js → Controller-CxAUW5kD.js} +2 -2
  11. package/dist/internal/{Controller-BDT5_ZNe.js.map → Controller-CxAUW5kD.js.map} +1 -1
  12. package/dist/internal/{Controller-5BvatEWD.js → Controller-DSKeCecj.js} +171 -154
  13. package/dist/internal/Controller-DSKeCecj.js.map +1 -0
  14. package/dist/internal/PointHelper-G9EgUMWo.js +1052 -0
  15. package/dist/internal/PointHelper-G9EgUMWo.js.map +1 -0
  16. package/dist/internal/{Rectangle-Z2T_h74M.js → Rectangle-HB8jF_bX.js} +3 -3
  17. package/dist/internal/{Rectangle-Z2T_h74M.js.map → Rectangle-HB8jF_bX.js.map} +1 -1
  18. package/dist/internal/{Work-PKaUMpXd.js → Work-6uuml2Ft.js} +4 -4
  19. package/dist/internal/{Work-PKaUMpXd.js.map → Work-6uuml2Ft.js.map} +1 -1
  20. package/dist/internal/{area-maker-BTGqxG6D.js → area-maker-D2ZIYsTG.js} +2 -2
  21. package/dist/internal/{area-maker-BTGqxG6D.js.map → area-maker-D2ZIYsTG.js.map} +1 -1
  22. package/dist/internal/{controller-B0hqJtoB.js → controller-DjCi781H.js} +4 -4
  23. package/dist/internal/{controller-B0hqJtoB.js.map → controller-DjCi781H.js.map} +1 -1
  24. package/dist/internal/{cruise-BkSbiLjd.js → cruise-DWxq9GTd.js} +2 -2
  25. package/dist/internal/{cruise-BkSbiLjd.js.map → cruise-DWxq9GTd.js.map} +1 -1
  26. package/dist/internal/{current-pano-image-DqyUFIP6.js → current-pano-image-DPLm0-o2.js} +2 -2
  27. package/dist/internal/{current-pano-image-DqyUFIP6.js.map → current-pano-image-DPLm0-o2.js.map} +1 -1
  28. package/dist/internal/{edgeSnap-8fdFCcXB.js → edgeSnap-CH0HidZm.js} +206 -83
  29. package/dist/internal/edgeSnap-CH0HidZm.js.map +1 -0
  30. package/dist/internal/{floorplan-Dkp7omYn.js → floorplan-B6Y-8xjB.js} +2 -2
  31. package/dist/internal/{floorplan-Dkp7omYn.js.map → floorplan-B6Y-8xjB.js.map} +1 -1
  32. package/dist/internal/{measure-KVSCjRnS.js → measure-DIstq55p.js} +2 -2
  33. package/dist/internal/{measure-KVSCjRnS.js.map → measure-DIstq55p.js.map} +1 -1
  34. package/dist/internal/measure-v2-Byp1mE5q.js +215 -0
  35. package/dist/internal/measure-v2-Byp1mE5q.js.map +1 -0
  36. package/dist/internal/{model-maker-L5eqUgkU.js → model-maker-Cea52AmN.js} +2 -2
  37. package/dist/internal/{model-maker-L5eqUgkU.js.map → model-maker-Cea52AmN.js.map} +1 -1
  38. package/dist/internal/{model-view-BWUU0-uq.js → model-view-DSRXOhPg.js} +12 -2
  39. package/dist/internal/model-view-DSRXOhPg.js.map +1 -0
  40. package/dist/internal/object3d-helper-JrdReT4Y.js +7 -0
  41. package/dist/internal/{object3d-helper-CUhRRdCQ.js.map → object3d-helper-JrdReT4Y.js.map} +1 -1
  42. package/dist/internal/{pano-compass-dmcsnFDQ.js → pano-compass-DENjS-F-.js} +2 -2
  43. package/dist/internal/{pano-compass-dmcsnFDQ.js.map → pano-compass-DENjS-F-.js.map} +1 -1
  44. package/dist/internal/{pano-door-label-C0sd66vf.js → pano-door-label-DFcBreFx.js} +2 -2
  45. package/dist/internal/{pano-door-label-C0sd66vf.js.map → pano-door-label-DFcBreFx.js.map} +1 -1
  46. package/dist/internal/{pano-measure-NbB7-uVE.js → pano-measure-bIqtdQ8N.js} +2 -2
  47. package/dist/internal/{pano-measure-NbB7-uVE.js.map → pano-measure-bIqtdQ8N.js.map} +1 -1
  48. package/dist/internal/{pano-measure-v2-CRPvPs0e.js → pano-measure-v2-BRr9Jses.js} +4 -4
  49. package/dist/internal/{pano-measure-v2-CRPvPs0e.js.map → pano-measure-v2-BRr9Jses.js.map} +1 -1
  50. package/dist/internal/{pano-tag-j8ZPJDDK.js → pano-tag-BI_eOX_D.js} +2 -2
  51. package/dist/internal/{pano-tag-j8ZPJDDK.js.map → pano-tag-BI_eOX_D.js.map} +1 -1
  52. package/dist/internal/{pano-video-Dcspq4j1.js → pano-video-D0dQTeX6.js} +2 -2
  53. package/dist/internal/{pano-video-Dcspq4j1.js.map → pano-video-D0dQTeX6.js.map} +1 -1
  54. package/dist/internal/{pipeline-CD2YkN5U.js → pipeline-CyleoezT.js} +2 -2
  55. package/dist/internal/{pipeline-CD2YkN5U.js.map → pipeline-CyleoezT.js.map} +1 -1
  56. package/dist/internal/{sculpt-CbEBEh9F.js → sculpt-BGx4Dudb.js} +3 -3
  57. package/dist/internal/{sculpt-CbEBEh9F.js.map → sculpt-BGx4Dudb.js.map} +1 -1
  58. package/dist/plugins/area-maker.js +1 -1
  59. package/dist/plugins/cruise.js +2 -2
  60. package/dist/plugins/current-pano-image.js +1 -1
  61. package/dist/plugins/guide-line.js +1 -1
  62. package/dist/plugins/measure-v2.js +2 -2
  63. package/dist/plugins/measure.js +2 -2
  64. package/dist/plugins/model-maker.js +1 -1
  65. package/dist/plugins/model-view.js +1 -1
  66. package/dist/plugins/object3d-helper.js +2 -2
  67. package/dist/plugins/pano-compass.js +1 -1
  68. package/dist/plugins/pano-door-label.js +1 -1
  69. package/dist/plugins/pano-measure-v2.js +1 -1
  70. package/dist/plugins/pano-measure.js +1 -1
  71. package/dist/plugins/pano-tag.js +2 -2
  72. package/dist/plugins/pano-video.js +1 -1
  73. package/dist/plugins/pipeline.js +1 -1
  74. package/dist/plugins/sculpt.js +2 -2
  75. package/dist/types/MeasurePlugin/Controller.d.ts +7 -0
  76. package/dist/types/MeasurePlugin/utils/MeasureMesh.d.ts +5 -0
  77. package/dist/types/MeasurePluginV2/Controller.d.ts +9 -0
  78. package/dist/types/MeasurePluginV2/Magnifier.d.ts +33 -0
  79. package/dist/types/MeasurePluginV2/PointOverlay.d.ts +5 -0
  80. package/dist/types/MeasurePluginV2/closeupView.d.ts +69 -0
  81. package/dist/types/MeasurePluginV2/normalMeasure.d.ts +116 -0
  82. package/dist/types/shared-utils/three/Magnifier.d.ts +55 -0
  83. package/dist/utils.js +1 -1
  84. package/package.json +1 -1
  85. package/dist/internal/BasePluginWithData-CIQpqYGe.js +0 -7
  86. package/dist/internal/Controller-5BvatEWD.js.map +0 -1
  87. package/dist/internal/PointHelper-grrf8vu1.js +0 -953
  88. package/dist/internal/PointHelper-grrf8vu1.js.map +0 -1
  89. package/dist/internal/edgeSnap-8fdFCcXB.js.map +0 -1
  90. package/dist/internal/measure-v2-DqjBlSeF.js +0 -83
  91. package/dist/internal/measure-v2-DqjBlSeF.js.map +0 -1
  92. package/dist/internal/model-view-BWUU0-uq.js.map +0 -1
  93. package/dist/internal/object3d-helper-CUhRRdCQ.js +0 -7
@@ -1,7 +1,7 @@
1
- import { t as e } from "./Controller-5BvatEWD.js";
1
+ import { t as e } from "./Controller-DSKeCecj.js";
2
2
  //#region src/MeasurePlugin/index.ts
3
3
  var t = (t, n) => new e(t, n);
4
4
  //#endregion
5
5
  export { t };
6
6
 
7
- //# sourceMappingURL=measure-KVSCjRnS.js.map
7
+ //# sourceMappingURL=measure-DIstq55p.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"measure-KVSCjRnS.js","names":["MeasureController","MeasurePlugin","five","config"],"sources":["../../src/MeasurePlugin/index.ts"],"sourcesContent":["import type { Five } from '@realsee/five-webgpu'\nimport { MeasureController } from './Controller'\n\nexport type MeasurePluginConfig = {\n unit: 'm' | 'ft' | 'mm'\n lengthEnable?: boolean\n /**\n * @description Length label precision.\n * - When unit is `m`: number of decimal places.\n * - When unit is `ft`: inch fraction denominator (`1` | `4` | `8` | `16` for 1\" / 1/4\" / 1/8\" / 1/16\").\n * Area measurements remain at fixed 2 decimal places.\n * @default 2\n */\n precision?: number\n}\n\n// 导出测量相关类型\nexport type { MeasureEndReason, MeasurePluginEventMap, MeasureInteractionState } from './Controller'\n\n// 导出多边形验证工具函数\nexport { validatePolygon } from './utils/validatePolygon'\n\nexport const MeasurePlugin = (five: Five, config?: MeasurePluginConfig) => new MeasureController(five, config)\n"],"mappings":";;AAsBA,IAAaC,KAAiB,GAAY,MAAiC,IAAID,EAAkBE,GAAMC,CAAM"}
1
+ {"version":3,"file":"measure-DIstq55p.js","names":["MeasureController","MeasurePlugin","five","config"],"sources":["../../src/MeasurePlugin/index.ts"],"sourcesContent":["import type { Five } from '@realsee/five-webgpu'\nimport { MeasureController } from './Controller'\n\nexport type MeasurePluginConfig = {\n unit: 'm' | 'ft' | 'mm'\n lengthEnable?: boolean\n /**\n * @description Length label precision.\n * - When unit is `m`: number of decimal places.\n * - When unit is `ft`: inch fraction denominator (`1` | `4` | `8` | `16` for 1\" / 1/4\" / 1/8\" / 1/16\").\n * Area measurements remain at fixed 2 decimal places.\n * @default 2\n */\n precision?: number\n}\n\n// 导出测量相关类型\nexport type { MeasureEndReason, MeasurePluginEventMap, MeasureInteractionState } from './Controller'\n\n// 导出多边形验证工具函数\nexport { validatePolygon } from './utils/validatePolygon'\n\nexport const MeasurePlugin = (five: Five, config?: MeasurePluginConfig) => new MeasureController(five, config)\n"],"mappings":";;AAsBA,IAAaC,KAAiB,GAAY,MAAiC,IAAID,EAAkBE,GAAMC,CAAM"}
@@ -0,0 +1,215 @@
1
+ import { c as e } from "./PointHelper-G9EgUMWo.js";
2
+ import { t } from "./Controller-DSKeCecj.js";
3
+ import { a as n, i as r, n as i, o as a, s as o } from "./edgeSnap-CH0HidZm.js";
4
+ import * as s from "three/webgpu";
5
+ //#region src/MeasurePluginV2/normalMeasure.ts
6
+ var c = .01;
7
+ function l(e, t, n) {
8
+ if (![
9
+ e.x,
10
+ e.y,
11
+ e.z,
12
+ t.x,
13
+ t.y,
14
+ t.z
15
+ ].every(Number.isFinite) || t.lengthSq() < 1e-12) return null;
16
+ let r = t.clone().normalize(), i = e.clone().addScaledVector(r, c), a = new s.Raycaster(i, r, 0, 100);
17
+ for (let t of n(a)) {
18
+ if (!t?.point || !Number.isFinite(t.distance)) continue;
19
+ if (t.distance > 100) break;
20
+ let n = t.point.clone();
21
+ if (n.distanceTo(e) < .02) continue;
22
+ let r = t.face?.normal;
23
+ return {
24
+ point: n,
25
+ normal: r && r.lengthSq() > 1e-12 ? r.clone().normalize() : null
26
+ };
27
+ }
28
+ return null;
29
+ }
30
+ var u = class {
31
+ interval;
32
+ maxMove;
33
+ last = null;
34
+ constructor(e = 350, t = 6) {
35
+ this.interval = e, this.maxMove = t;
36
+ }
37
+ hit(e, t, n) {
38
+ let r = this.last;
39
+ return r && n - r.time <= this.interval && Math.hypot(e - r.x, t - r.y) <= this.maxMove ? (this.last = null, !0) : (this.last = {
40
+ time: n,
41
+ x: e,
42
+ y: t
43
+ }, !1);
44
+ }
45
+ reset() {
46
+ this.last = null;
47
+ }
48
+ }, d = 100, f = class {
49
+ options;
50
+ detector = new u();
51
+ lastMouseUp = null;
52
+ startNormal = null;
53
+ attached = !1;
54
+ constructor(e) {
55
+ this.options = e;
56
+ }
57
+ attach(e) {
58
+ this.attached || (this.attached = !0, document.addEventListener("mouseup", this.onMouseUp, !0), e.on("wantsSelect", this.onWantsSelect));
59
+ }
60
+ detach(e) {
61
+ this.attached && (this.attached = !1, document.removeEventListener("mouseup", this.onMouseUp, !0), e.off("wantsSelect", this.onWantsSelect), this.reset());
62
+ }
63
+ reset() {
64
+ this.detector.reset(), this.lastMouseUp = null, this.startNormal = null;
65
+ }
66
+ onMouseUp = (e) => {
67
+ e.button === 0 && (this.lastMouseUp = {
68
+ x: e.clientX,
69
+ y: e.clientY,
70
+ time: performance.now()
71
+ });
72
+ };
73
+ onWantsSelect = (e) => {
74
+ let t = this.options.getMeasuringPoints();
75
+ if (!t) return;
76
+ let n = this.consumeMouseUp(), r = n ? this.detector.hit(n.x, n.y, n.time) : !1;
77
+ if (t.length === 0) {
78
+ this.startNormal = p(e);
79
+ return;
80
+ }
81
+ if (t.length !== 1 || !n) return;
82
+ let i = t[0];
83
+ if (!this.isOnStartPoint(i, n)) return;
84
+ if (!r) return !1;
85
+ let a = this.startNormal ? this.orientTowardCamera(this.startNormal, i) : null, o = a ? l(i, a, this.options.raycast) : null;
86
+ return this.startNormal = null, o ? (this.options.finish(i, o.point) === !0 && o.normal && (this.startNormal = this.orientTowardCamera(o.normal, o.point)), !1) : (this.options.cancelStart(), !1);
87
+ };
88
+ consumeMouseUp() {
89
+ let e = this.lastMouseUp;
90
+ return this.lastMouseUp = null, !e || performance.now() - e.time > d ? null : e;
91
+ }
92
+ isOnStartPoint(e, t) {
93
+ let n = this.options.getElement();
94
+ if (!n) return !1;
95
+ let r = n.getBoundingClientRect(), i = e.clone().project(this.options.getCamera());
96
+ if (!Number.isFinite(i.x) || !Number.isFinite(i.y) || i.z > 1) return !1;
97
+ let a = r.left + (i.x + 1) / 2 * r.width, o = r.top + (1 - i.y) / 2 * r.height;
98
+ return Math.hypot(a - t.x, o - t.y) <= 16;
99
+ }
100
+ orientTowardCamera(e, t) {
101
+ let n = this.options.getCamera().position.clone().sub(t);
102
+ return e.dot(n) < 0 ? e.clone().negate() : e.clone();
103
+ }
104
+ };
105
+ function p(e) {
106
+ let t = e?.face?.normal;
107
+ return !t || t.lengthSq() < 1e-12 ? null : t.clone().normalize();
108
+ }
109
+ //#endregion
110
+ //#region src/MeasurePluginV2/Controller.ts
111
+ function m() {
112
+ return typeof window > "u" ? 1 : Math.min(2, Math.max(1, Math.ceil(window.devicePixelRatio || 1)));
113
+ }
114
+ var h = class extends t {
115
+ lastEdgeSnapEdgeCount = 0;
116
+ v2Five;
117
+ v2Magnifier;
118
+ v2Attached = !1;
119
+ edgeSnapOptions;
120
+ edgeSnapCache = new i();
121
+ quickMeasureEnabled;
122
+ quickMeasure;
123
+ constructor(e, t) {
124
+ super(e, t), this.v2Five = e, this.edgeSnapOptions = r(t?.edgeSnap), this.quickMeasureEnabled = t?.quickMeasure !== !1;
125
+ let n = this.measure;
126
+ this.measure = () => {
127
+ this.edgeSnapCache.clear(), this.lastEdgeSnapEdgeCount = 0, this.pointSelector.clearDynamicAdhereLine(), this.quickMeasure?.reset(), n();
128
+ };
129
+ let i = this.dispose;
130
+ this.dispose = () => {
131
+ this.v2Attached && this.quickMeasure?.detach(this.pointSelector), this.quickMeasure = void 0, i();
132
+ };
133
+ }
134
+ get edgeSnapEnabled() {
135
+ return this.edgeSnapOptions.enabled;
136
+ }
137
+ setEdgeSnapEnabled(e) {
138
+ this.edgeSnapOptions.enabled = e, this.edgeSnapCache.clear(), this.lastEdgeSnapEdgeCount = 0, this.pointSelector.clearDynamicAdhereLine(), this.pointSelector.refresh(), this.v2Five.needsRender = !0;
139
+ }
140
+ get magnifier() {
141
+ return this.v2Magnifier;
142
+ }
143
+ createPointSelector() {
144
+ return new o(this.v2Five, {
145
+ mode: "cursor",
146
+ helper: {
147
+ pointHelper: "highlight",
148
+ ...e ? { magnifierParams: {
149
+ width: 150,
150
+ height: 150,
151
+ dragEnabled: !1,
152
+ autoFixPCPosition: !1,
153
+ initialPosition: {
154
+ left: "12px",
155
+ top: "12px"
156
+ }
157
+ } } : {}
158
+ },
159
+ skipPanorama: !1
160
+ });
161
+ }
162
+ get pointSelector() {
163
+ let e = super.pointSelector;
164
+ return this.v2Attached || (this.v2Attached = !0, this.attachOverlayRenderers(e)), e;
165
+ }
166
+ attachOverlayRenderers(e) {
167
+ let t = e.pointSelectorHelper;
168
+ this.attachMagnifier(t), this.attachPointHelper(t), this.attachEdgeSnap(e), this.attachQuickMeasure(e), e.on("intersectionUpdate", (e) => {
169
+ this.v2Magnifier?.setIntersection(e ?? null);
170
+ });
171
+ }
172
+ attachMagnifier(e) {
173
+ let t = e.magnifier;
174
+ if (!t) return;
175
+ let n = new a(this.v2Five, {
176
+ ...t.config,
177
+ width: t.width,
178
+ height: t.height,
179
+ scale: t.scale,
180
+ overlayEnabled: !0,
181
+ readPixelsPixelRatio: m(),
182
+ closeupMode: "rotate",
183
+ adaptiveReadWindow: !0
184
+ });
185
+ t.containerDom && n.appendTo(t.containerDom), t.state.enabled && n.enable(), e.magnifier = n, t.dispose(), this.v2Magnifier = n;
186
+ }
187
+ attachPointHelper(e) {
188
+ let t = e.pointHelper;
189
+ e.pointHelper = new n(this.v2Five), t?.dispose(), t?.parent && t.parent.remove(t);
190
+ }
191
+ attachQuickMeasure(e) {
192
+ this.quickMeasureEnabled && (this.quickMeasure = new f({
193
+ getCamera: () => this.v2Five.camera,
194
+ getElement: () => this.v2Five.getElement(),
195
+ raycast: (e) => this.v2Five.model.intersectRaycaster(e),
196
+ getMeasuringPoints: () => this.currentMeasureMesh?.points ?? null,
197
+ finish: (e, t) => {
198
+ let n = this.currentMeasureMesh;
199
+ return n ? (n.setPoints([e, t]), this.continueMeasureFrom ? (this.continueMeasureFrom(t), !0) : (this.endMeasure(), !1)) : !1;
200
+ },
201
+ cancelStart: () => this.undo()
202
+ }), this.quickMeasure.attach(e));
203
+ }
204
+ attachEdgeSnap(e) {
205
+ e.adhereLineProvider = ({ intersection: e }) => {
206
+ if (!e?.point) return [];
207
+ let t = this.edgeSnapCache.query(this.v2Five.model, e.point, this.edgeSnapOptions);
208
+ return this.lastEdgeSnapEdgeCount = t.length, t;
209
+ };
210
+ }
211
+ }, g = (e, t) => new h(e, t);
212
+ //#endregion
213
+ export { h as n, g as t };
214
+
215
+ //# sourceMappingURL=measure-v2-Byp1mE5q.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"measure-v2-Byp1mE5q.js","names":["isTouchDevice","MeasurePointHelperV2","resolveEdgeSnapOptions","EdgeSnapCache","MeasureMagnifier","MeasurePointSelector","THREE","NORMAL_RAY_START_OFFSET","findNormalMeasureHit","point","normal","direction","origin","raycaster","hit","raycast","end","hitNormal","DoubleClickDetector","interval","maxMove","last","time","x","y","MOUSE_UP_FRESHNESS","QuickNormalMeasure","options","pointSelector","event","points","click","isDoubleClick","getIntersectionNormal","intersection","start","element","rect","ndc","screenX","screenY","toCamera","getMagnifierReadPixelsPixelRatio","MeasureControllerV2","MeasureController","five","config","measure","dispose","enabled","helper","original","magnifier","mesh","edges","MeasurePluginV2"],"sources":["../../src/MeasurePluginV2/normalMeasure.ts","../../src/MeasurePluginV2/Controller.ts","../../src/MeasurePluginV2/index.ts"],"sourcesContent":["import * as THREE from 'three/webgpu'\n\n/**\n * 双击快速测量:从落点沿所在平面的法线发一条射线,取第一个打到的模型表面作为终点。\n * 典型场景是双击墙面直接得到墙到对面墙的垂直距离。\n */\n\n/** 射线起点离开表面的距离(米),避免射线一出发就打中落点所在的面 */\nexport const NORMAL_RAY_START_OFFSET = 0.01\n/** 终点离起点太近(米)视为无效,例如打中了落点旁边的小凸起 */\nexport const NORMAL_RAY_MIN_DISTANCE = 0.02\n/** 射线最远距离(米),超过视为没打到 */\nexport const NORMAL_RAY_MAX_DISTANCE = 100\n\n/** 双击判定:两次抬起的最大间隔(毫秒) */\nexport const DOUBLE_CLICK_INTERVAL = 350\n/** 双击判定:两次抬起的最大屏幕距离(像素) */\nexport const DOUBLE_CLICK_MAX_MOVE = 6\n\nexport interface RaycastHit {\n point: THREE.Vector3\n distance: number\n /** 命中面;THREE.Intersection 的 face.normal 已经是世界坐标系法线 */\n face?: { normal?: THREE.Vector3 | null } | null\n}\n\n/** 法线快速测量的命中结果 */\nexport interface NormalMeasureHit {\n /** 终点 */\n point: THREE.Vector3\n /** 终点所在表面的世界坐标系法线;拿不到时为 null */\n normal: THREE.Vector3 | null\n}\n\n/** 对模型做射线检测,返回按距离排序的命中结果 */\nexport type ModelRaycast = (raycaster: THREE.Raycaster) => RaycastHit[]\n\n/**\n * 沿法线求快速测量的命中点。\n * @param point - 起点(双击的落点)\n * @param normal - 起点所在平面的法线(世界坐标,朝向表面外侧,即朝向相机这一侧)\n * @returns 命中点及其表面法线;法线无效或没打到模型时返回 null\n */\nexport function findNormalMeasureHit(point: THREE.Vector3, normal: THREE.Vector3, raycast: ModelRaycast): NormalMeasureHit | null {\n if (![point.x, point.y, point.z, normal.x, normal.y, normal.z].every(Number.isFinite)) return null\n if (normal.lengthSq() < 1e-12) return null\n\n const direction = normal.clone().normalize()\n const origin = point.clone().addScaledVector(direction, NORMAL_RAY_START_OFFSET)\n const raycaster = new THREE.Raycaster(origin, direction, 0, NORMAL_RAY_MAX_DISTANCE)\n\n for (const hit of raycast(raycaster)) {\n if (!hit?.point || !Number.isFinite(hit.distance)) continue\n if (hit.distance > NORMAL_RAY_MAX_DISTANCE) break\n const end = hit.point.clone()\n if (end.distanceTo(point) < NORMAL_RAY_MIN_DISTANCE) continue\n const hitNormal = hit.face?.normal\n return {\n point: end,\n normal: hitNormal && hitNormal.lengthSq() > 1e-12 ? hitNormal.clone().normalize() : null,\n }\n }\n return null\n}\n\n/** 只要终点时用这个 */\nexport function findNormalMeasureEnd(point: THREE.Vector3, normal: THREE.Vector3, raycast: ModelRaycast): THREE.Vector3 | null {\n return findNormalMeasureHit(point, normal, raycast)?.point ?? null\n}\n\n/**\n * 识别「第二下点在刚打下的点上」的双击。\n * 只记录上一次抬起的时间和屏幕位置;时间和位置都足够近才算双击,命中后清空,三连击不会触发两次。\n */\nexport class DoubleClickDetector {\n private last: { time: number; x: number; y: number } | null = null\n\n public constructor(\n private readonly interval = DOUBLE_CLICK_INTERVAL,\n private readonly maxMove = DOUBLE_CLICK_MAX_MOVE,\n ) {}\n\n /** 每次单击抬起时调用;返回 true 表示与上一次构成双击 */\n public hit(x: number, y: number, time: number): boolean {\n const last = this.last\n if (last && time - last.time <= this.interval && Math.hypot(x - last.x, y - last.y) <= this.maxMove) {\n this.last = null\n return true\n }\n this.last = { time, x, y }\n return false\n }\n\n public reset() {\n this.last = null\n }\n}\n\n/** 双击时第二下离起点的最大屏幕距离(像素)。起点可能被吸附偏离光标几像素,所以比双击判定宽一些 */\nexport const START_POINT_HIT_RADIUS = 16\n/** mouseup 与随后的选点必须在这个时间内(毫秒),否则视为不是鼠标触发(例如触屏长按松手) */\nconst MOUSE_UP_FRESHNESS = 100\n\ninterface QuickMeasureCamera {\n position: THREE.Vector3\n}\n\nexport interface QuickNormalMeasureOptions {\n /** 当前相机;朝向判断和屏幕投影都用它 */\n getCamera: () => THREE.Camera & QuickMeasureCamera\n /** five 画布,用来把世界坐标换算成屏幕坐标 */\n getElement: () => HTMLElement | null | undefined\n /** 对模型做射线检测 */\n raycast: ModelRaycast\n /** 正在测量的点;不在测量中返回 null */\n getMeasuringPoints: () => THREE.Vector3[] | null\n /**\n * 打到对面:用起点和终点生成测量。\n * 返回 true 表示测量会话继续(控制器以终点作为下一段的起点),此时命中面的法线会留作下一段的起始法线。\n */\n finish: (start: THREE.Vector3, end: THREE.Vector3) => boolean | void\n /** 没打到:撤掉起点,回到未打点状态 */\n cancelStart: () => void\n}\n\n/** 由 PointSelector 的 wantsSelect 事件驱动,返回 false 表示取消这次选点 */\ntype WantsSelectHandler = (intersection?: { point?: THREE.Vector3; face?: { normal?: THREE.Vector3 | null } | null } | null) => boolean | void\n\n/**\n * 双击快速测量(只处理鼠标,触屏不触发)。\n *\n * 规则与 MP 一致:\n * - 第一下单击照常打下起点 A,不延迟;第二下在双击时间内又点在 A 上,就从 A 沿法线测到对面,直接完成这条测量;\n * - A 已经打下一段时间后,再双击 A 也会快速测量:落在 A 上的单击不会再打一个重合的点;\n * - 已经开始连线(两个点及以上)时双击按普通单击处理;法线没打到模型时撤掉 A,不生成测量;\n * - 快速测量完成后不退出选点:控制器以命中点为新一段的起点(finish 返回 true),继续选择下一个点位。\n */\nexport class QuickNormalMeasure {\n private readonly detector = new DoubleClickDetector()\n private lastMouseUp: { x: number; y: number; time: number } | null = null\n /** 起点 A 所在平面的法线,在打下 A 的那次选点里记下 */\n private startNormal: THREE.Vector3 | null = null\n private attached = false\n\n public constructor(private readonly options: QuickNormalMeasureOptions) {}\n\n public attach(pointSelector: { on: (name: 'wantsSelect', callback: WantsSelectHandler) => unknown }) {\n if (this.attached) return\n this.attached = true\n // 捕获阶段注册在 document 上,保证先于 PointSelector 在画布上的 mouseup 回调执行\n document.addEventListener('mouseup', this.onMouseUp, true)\n pointSelector.on('wantsSelect', this.onWantsSelect)\n }\n\n public detach(pointSelector: { off: (name: 'wantsSelect', callback: WantsSelectHandler) => unknown }) {\n if (!this.attached) return\n this.attached = false\n document.removeEventListener('mouseup', this.onMouseUp, true)\n pointSelector.off('wantsSelect', this.onWantsSelect)\n this.reset()\n }\n\n public reset() {\n this.detector.reset()\n this.lastMouseUp = null\n this.startNormal = null\n }\n\n private onMouseUp = (event: MouseEvent) => {\n if (event.button !== 0) return\n this.lastMouseUp = { x: event.clientX, y: event.clientY, time: performance.now() }\n }\n\n private onWantsSelect: WantsSelectHandler = (intersection) => {\n const points = this.options.getMeasuringPoints()\n if (!points) return\n\n const click = this.consumeMouseUp()\n const isDoubleClick = click ? this.detector.hit(click.x, click.y, click.time) : false\n\n if (points.length === 0) {\n // 这一下会打下起点 A,记下它所在平面的法线\n this.startNormal = getIntersectionNormal(intersection)\n return\n }\n if (points.length !== 1 || !click) return\n\n const start = points[0]\n if (!this.isOnStartPoint(start, click)) return\n\n // 点在 A 上:不打重合的第二个点;构成双击时快速测量\n if (!isDoubleClick) return false\n\n const normal = this.startNormal ? this.orientTowardCamera(this.startNormal, start) : null\n const hit = normal ? findNormalMeasureHit(start, normal, this.options.raycast) : null\n this.startNormal = null\n if (!hit) {\n this.options.cancelStart()\n return false\n }\n\n const continued = this.options.finish(start, hit.point) === true\n // 继续测量时命中点就是新一段的起点;记下命中面的法线,双击新起点还能接着快速测量\n if (continued && hit.normal) this.startNormal = this.orientTowardCamera(hit.normal, hit.point)\n return false\n }\n\n /** 只认刚刚发生的鼠标抬起,用完即清,避免触屏选点误用上一次鼠标的位置 */\n private consumeMouseUp() {\n const click = this.lastMouseUp\n this.lastMouseUp = null\n if (!click || performance.now() - click.time > MOUSE_UP_FRESHNESS) return null\n return click\n }\n\n private isOnStartPoint(start: THREE.Vector3, click: { x: number; y: number }) {\n const element = this.options.getElement()\n if (!element) return false\n const rect = element.getBoundingClientRect()\n const ndc = start.clone().project(this.options.getCamera())\n if (!Number.isFinite(ndc.x) || !Number.isFinite(ndc.y) || ndc.z > 1) return false\n const screenX = rect.left + ((ndc.x + 1) / 2) * rect.width\n const screenY = rect.top + ((1 - ndc.y) / 2) * rect.height\n return Math.hypot(screenX - click.x, screenY - click.y) <= START_POINT_HIT_RADIUS\n }\n\n /** 面法线可能朝向表面内侧;射线要往相机这一侧(空的一侧)发 */\n private orientTowardCamera(normal: THREE.Vector3, point: THREE.Vector3) {\n const toCamera = this.options.getCamera().position.clone().sub(point)\n return normal.dot(toCamera) < 0 ? normal.clone().negate() : normal.clone()\n }\n}\n\nfunction getIntersectionNormal(intersection: Parameters<WantsSelectHandler>[0]): THREE.Vector3 | null {\n const normal = intersection?.face?.normal\n if (!normal || normal.lengthSq() < 1e-12) return null\n return normal.clone().normalize()\n}\n","import type { Five } from '@realsee/five-webgpu'\nimport { MeasurePointSelector } from './PointSelector'\nimport { MeasureController } from '../MeasurePlugin/Controller'\nimport { isTouchDevice } from '../shared-utils/isTouchDevice'\nimport type { MeasurePluginConfig } from '../MeasurePlugin'\nimport { MeasureMagnifier } from './Magnifier'\nimport { MeasurePointHelperV2 } from './PointHelper'\nimport { EdgeSnapCache, resolveEdgeSnapOptions, type EdgeSnapOptions, type ResolvedEdgeSnapOptions } from './edgeSnap'\nimport { QuickNormalMeasure, type RaycastHit } from './normalMeasure'\n\n/** 放大镜按设备像素读回(上限 2x);读回失败时 Magnifier 内部会自动降级 */\nfunction getMagnifierReadPixelsPixelRatio() {\n if (typeof window === 'undefined') return 1\n return Math.min(2, Math.max(1, Math.ceil(window.devicePixelRatio || 1)))\n}\n\n/**\n * 量尺插件 V2:把放大镜和场景里的小光标换成带「红 / 绿 / 蓝坐标轴 + 红色截面框」的版本。\n *\n * 复用 MeasureController 的测量流程,通过工厂创建独立的 V2 选点器,并替换两个渲染组件:\n * - pointSelectorHelper.magnifier → MeasureMagnifier(多画一层叠加层)\n * - pointSelectorHelper.pointHelper → MeasurePointHelperV2(同样的红 / 绿 / 蓝 + 截面框)\n *\n * 两个替换件都沿用原实例的全部参数(宽高、缩放、autoFixPCPosition、dragEnabled、挂载容器),\n * 所以放大镜出现的位置、跟随方式、是否吃鼠标事件都和原插件一致,不会挡住在原本能选中的点位。\n */\n/** V2 配置:在原 MeasurePlugin 配置上增加模型边缘吸附 */\nexport type MeasurePluginV2Config = MeasurePluginConfig & {\n /**\n * @description 模型边缘吸附(试验能力):落点靠近模型边线时自动吸到边上。\n * 传 `false` 可关闭;不传默认开启。\n */\n edgeSnap?: boolean | EdgeSnapOptions\n /**\n * @description 双击快速测量(仅鼠标):双击起点时沿所在平面的法线测到对面,例如墙到对面墙。\n * 传 `false` 可关闭;不传默认开启。\n */\n quickMeasure?: boolean\n}\n\nexport class MeasureControllerV2 extends MeasureController {\n /** 最近一次查询到的候选边数量,示例页 / 调试用 */\n public lastEdgeSnapEdgeCount = 0\n\n private v2Five: Five\n private v2Magnifier?: MeasureMagnifier\n private v2Attached = false\n private readonly edgeSnapOptions: ResolvedEdgeSnapOptions\n private readonly edgeSnapCache = new EdgeSnapCache()\n private readonly quickMeasureEnabled: boolean\n private quickMeasure?: QuickNormalMeasure\n\n public constructor(five: Five, config?: MeasurePluginV2Config) {\n super(five, config)\n this.v2Five = five\n this.edgeSnapOptions = resolveEdgeSnapOptions(config?.edgeSnap)\n this.quickMeasureEnabled = config?.quickMeasure !== false\n\n // MeasureController.measure 是实例上的箭头函数,不能用 prototype 方法覆盖,\n // 这里在包装后的入口里清一次缓存,避免上一次测量 / 上一楼层的边残留。\n const measure = this.measure\n this.measure = () => {\n this.edgeSnapCache.clear()\n this.lastEdgeSnapEdgeCount = 0\n this.pointSelector.clearDynamicAdhereLine()\n this.quickMeasure?.reset()\n measure()\n }\n\n // dispose 同理是箭头函数:先摘掉双击监听,再走原有释放流程\n const dispose = this.dispose\n this.dispose = () => {\n if (this.v2Attached) this.quickMeasure?.detach(this.pointSelector)\n this.quickMeasure = undefined\n dispose()\n }\n }\n\n public get edgeSnapEnabled() {\n return this.edgeSnapOptions.enabled\n }\n\n /** 运行时开关模型边缘吸附(不需要重开测量) */\n public setEdgeSnapEnabled(enabled: boolean) {\n this.edgeSnapOptions.enabled = enabled\n this.edgeSnapCache.clear()\n this.lastEdgeSnapEdgeCount = 0\n this.pointSelector.clearDynamicAdhereLine()\n this.pointSelector.refresh()\n this.v2Five.needsRender = true\n }\n\n /** V2 的放大镜实例;需要临时关掉叠加层做对比时,可以 magnifier.setOverlayEnabled(false) */\n public get magnifier() {\n return this.v2Magnifier\n }\n\n protected override createPointSelector() {\n // skipPanorama=false:全景模式下放大镜显示主视图的全景照片,而不是低分辨率网格贴图\n return new MeasurePointSelector(this.v2Five, { mode: 'cursor', helper: { pointHelper: 'highlight', ...(isTouchDevice ? { magnifierParams: { width: 150, height: 150, dragEnabled: false, autoFixPCPosition: false, initialPosition: { left: '12px', top: '12px' } } } : {}) }, skipPanorama: false })\n }\n\n public override get pointSelector(): MeasurePointSelector {\n const pointSelector = super.pointSelector as MeasurePointSelector\n if (!this.v2Attached) {\n this.v2Attached = true\n this.attachOverlayRenderers(pointSelector)\n }\n return pointSelector\n }\n\n private attachOverlayRenderers(pointSelector: MeasurePointSelector) {\n const helper = pointSelector.pointSelectorHelper\n this.attachMagnifier(helper)\n this.attachPointHelper(helper)\n this.attachEdgeSnap(pointSelector)\n this.attachQuickMeasure(pointSelector)\n\n // 放大镜是在 renderFrame 里渲染的,而这次事件是同步抛出的,\n // 所以放大镜真正渲染时一定已经拿到了当次的落点与法线\n pointSelector.on('intersectionUpdate', (intersection) => {\n this.v2Magnifier?.setIntersection(intersection ?? null)\n })\n }\n\n private attachMagnifier(helper: MeasurePointSelector['pointSelectorHelper']) {\n const original = helper.magnifier\n if (!original) return\n\n // 宽 / 高 / 缩放 / dragEnabled / autoFixPCPosition / skipPanorama 全部照抄原实例,\n // 只把 render 换成「读像素之后再多画一层坐标轴 + 截面框」\n const magnifier = new MeasureMagnifier(this.v2Five, {\n ...original.config,\n width: original.width,\n height: original.height,\n scale: (original as any).scale,\n overlayEnabled: true,\n // 按设备像素读回 + 只旋转的近景视角,远景自动提高光学倍率\n readPixelsPixelRatio: getMagnifierReadPixelsPixelRatio(),\n closeupMode: 'rotate',\n adaptiveReadWindow: true,\n })\n\n if (original.containerDom) magnifier.appendTo(original.containerDom)\n if (original.state.enabled) magnifier.enable()\n\n helper.magnifier = magnifier\n // 原放大镜自己的 canvas 和 hammer 手势一并释放,避免两个 canvas 叠在一起\n original.dispose()\n this.v2Magnifier = magnifier\n }\n\n private attachPointHelper(helper: MeasurePointSelector['pointSelectorHelper']) {\n const original = helper.pointHelper\n const pointHelper = new MeasurePointHelperV2(this.v2Five)\n helper.pointHelper = pointHelper\n\n original?.dispose()\n if (original?.parent) original.parent.remove(original)\n }\n\n /** 双击快速测量:只在测量过程中生效,选点链路仍由原 MeasureController 负责 */\n private attachQuickMeasure(pointSelector: MeasurePointSelector) {\n if (!this.quickMeasureEnabled) return\n this.quickMeasure = new QuickNormalMeasure({\n getCamera: () => this.v2Five.camera,\n getElement: () => this.v2Five.getElement(),\n raycast: (raycaster) => this.v2Five.model.intersectRaycaster(raycaster) as unknown as RaycastHit[],\n getMeasuringPoints: () => this.currentMeasureMesh?.points ?? null,\n finish: (start, end) => {\n const mesh = this.currentMeasureMesh\n if (!mesh) return false\n mesh.setPoints([start, end])\n if (!this.continueMeasureFrom) {\n this.endMeasure()\n return false\n }\n // 不退出选点:以上一段的终点作为新一段的起点,继续测量\n this.continueMeasureFrom(end)\n return true\n },\n cancelStart: () => this.undo(),\n })\n this.quickMeasure.attach(pointSelector)\n }\n\n /**\n * 模型边缘吸附:每次选点器计算吸附前,按当前落点取附近的模型边界线。\n * 真正的吸附判断(3D 距离 / 屏幕距离)仍在 PointSelector 里,这里只负责供线。\n */\n private attachEdgeSnap(pointSelector: MeasurePointSelector) {\n pointSelector.adhereLineProvider = ({ intersection }) => {\n if (!intersection?.point) return []\n const edges = this.edgeSnapCache.query(this.v2Five.model, intersection.point, this.edgeSnapOptions)\n this.lastEdgeSnapEdgeCount = edges.length\n return edges\n }\n }\n}\n","import type { Five } from '@realsee/five-webgpu'\nimport { MeasureControllerV2 } from './Controller'\n\n/**\n * 量尺插件 V2 —— 点位选择可视化(对应 PRD《量尺点位选择器优化》)\n *\n * 与 MeasurePlugin 的关系:V2 是试点 fork,完全继承 MeasurePlugin 的控制器,\n * 新吸附算法、放大镜叠加层和场景光标仅在 V2 中生效,原插件继续使用原选点器。\n *\n * 使用方式(Console / 编辑器等接入方):\n * ```ts\n * import { MeasurePluginV2 } from '@realsee/dnalogel/plugins/measure-v2'\n * const measure = MeasurePluginV2(five, { unit: 'm' })\n * ```\n */\nexport { MeasureControllerV2 } from './Controller'\nexport type { MeasurePluginV2Config } from './Controller'\nexport { MeasureMagnifier } from './Magnifier'\nexport type { MeasureMagnifierOptions } from './Magnifier'\nexport { drawMeasureOverlay, getWorldNormal, OVERLAY_STYLE } from './PointOverlay'\nexport type { MagnifierViewport } from './PointOverlay'\nexport { collectNearbyEdges, EdgeSnapCache, DEFAULT_EDGE_SNAP_OPTIONS } from './edgeSnap'\nexport type { EdgeSnapOptions, ResolvedEdgeSnapOptions } from './edgeSnap'\n\n// 与 MeasurePlugin 完全一致的类型与工具,方便接入方整体替换 import 来源\nexport { validatePolygon } from '../MeasurePlugin'\nexport type { MeasureEndReason, MeasurePluginConfig, MeasurePluginEventMap, MeasureInteractionState } from '../MeasurePlugin'\n\nexport type MeasureControllerV2Interface = InstanceType<typeof MeasureControllerV2>\nexport type MeasurePluginV2ParamsInterface = ConstructorParameters<typeof MeasureControllerV2>[1]\n\nexport const MeasurePluginV2 = (five: Five, config?: MeasurePluginV2ParamsInterface) => {\n return new MeasureControllerV2(five, config)\n}\n\nexport default MeasurePluginV2\n"],"mappings":"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"}
@@ -6,7 +6,7 @@ import { n as o, t as s } from "./isNil-CQNA0Sbe.js";
6
6
  import { t as c } from "./FiveDomEvents-DFG9hd51.js";
7
7
  import { n as l } from "./Line2-CDxLMjGj.js";
8
8
  import { i as u, n as d } from "./boundingBox-CIqXgNXW.js";
9
- import { t as f } from "./BasePluginWithData-CIQpqYGe.js";
9
+ import { t as f } from "./BasePluginWithData-BS2O9hNu.js";
10
10
  import { C as p, G as m, J as h, M as g, N as _, P as ee, j as te, n as v, q as y, t as b } from "./component.svelte-D5LYqt50.js";
11
11
  import { t as x } from "./LabelItem-Cnys51gZ.js";
12
12
  import { n as S, r as ne } from "./fontSize-DMhRSrtx.js";
@@ -894,4 +894,4 @@ var pe = class extends f {
894
894
  //#endregion
895
895
  export { G as n, me as t };
896
896
 
897
- //# sourceMappingURL=model-maker-L5eqUgkU.js.map
897
+ //# sourceMappingURL=model-maker-Cea52AmN.js.map