@realsee/dnalogel
Version:
254 lines (253 loc) • 11.7 kB
JavaScript
var ct = Object.defineProperty, Pt = Object.defineProperties;
var yt = Object.getOwnPropertyDescriptors;
var it = Object.getOwnPropertySymbols;
var mt = Object.prototype.hasOwnProperty, xt = Object.prototype.propertyIsEnumerable;
var _ = Math.pow, T = (e, s, t) => s in e ? ct(e, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[s] = t, H = (e, s) => {
for (var t in s || (s = {}))
mt.call(s, t) && T(e, t, s[t]);
if (it)
for (var t of it(s))
xt.call(s, t) && T(e, t, s[t]);
return e;
}, R = (e, s) => Pt(e, yt(s));
var C = (e, s, t) => (T(e, typeof s != "symbol" ? s + "" : s, t), t);
var ot = (e, s, t) => new Promise((n, r) => {
var x = (c) => {
try {
w(t.next(c));
} catch (u) {
r(u);
}
}, a = (c) => {
try {
w(t.throw(c));
} catch (u) {
r(u);
}
}, w = (c) => c.done ? n(c.value) : Promise.resolve(c.value).then(x, a);
w((t = t.apply(e, s)).next());
});
import { BaseObject as ft } from "../Base/index.js";
import * as j from "three";
import { PolylineMesh as nt } from "../../Meshes/Polyline.js";
import { AreaMesh as rt } from "../../Meshes/Area.js";
import { PolygonEditor as bt } from "./Editor.js";
import { vector3ToArray as Ct } from "../../../shared-utils/three/vector3ToArray.js";
import { withResolvers as wt } from "../../../shared-utils/promise/withResolvers.js";
import { anyPositionToVector3 as Dt } from "../../../shared-utils/positionToVector3.js";
import { PointMesh as Ht } from "../../Meshes/Point.js";
class Wt extends ft {
constructor(t, n) {
var r;
super(t, n);
C(this, "type", "Polygon");
C(this, "areaMesh");
// 新增:Polygon 专属的历史记录
C(this, "historyStack", []);
C(this, "currentHistoryIndex", -1);
C(this, "maxHistorySize", 50);
C(this, "_editor");
C(this, "creatingObject");
t && (this.areaMesh = new rt(H(H({}, t.style), t)), this.areaMesh.userData = (r = this.areaMesh.userData) != null ? r : {}, typeof this.areaMesh.userData.dragSelectPixelDistance != "number" && (this.areaMesh.userData.dragSelectPixelDistance = 10), this.add(this.areaMesh));
}
get editor() {
return this._editor || (this._editor = new bt(this)), this._editor;
}
updateCreationPointMeshes() {
var n, r;
const t = (r = (n = this.areaMesh) == null ? void 0 : n.userData) == null ? void 0 : r.syncCreationPointMeshes;
typeof t == "function" && t(), this._editor && this._editor.updatePointMeshes();
}
get data() {
return this.updateMatrixWorld(), R(H({}, this.baseData), {
points: Ct(this.applyObjectMatrixWorld(this.areaMesh.points)),
style: {
color: this.areaMesh.color.getHex(),
lineColor: this.areaMesh.lineColor.getHex(),
lineWidth: this.areaMesh.lineWidth
}
});
}
setData(t) {
t.points && this.areaMesh.setPoints(this.applyObjectReversalMatrixWorld(t.points.map(Dt))), this.areaMesh.setStyle(t.style), this.updateCreationPointMeshes();
}
highlight() {
var t;
(t = this.areaMesh) == null || t.highlight();
}
unhighlight() {
var t;
(t = this.areaMesh) == null || t.unhighlight();
}
canUndo() {
var n, r, x;
return this.creatingObject ? (x = (r = (n = this.creatingObject) == null ? void 0 : n.canUndo) == null ? void 0 : r.call(n)) != null ? x : !1 : this.currentHistoryIndex > 0;
}
canRedo() {
var t, n, r;
return this.creatingObject ? (r = (n = (t = this.creatingObject) == null ? void 0 : t.canRedo) == null ? void 0 : n.call(t)) != null ? r : !1 : this.currentHistoryIndex < this.historyStack.length - 1;
}
undo() {
var t, n;
if (this.creatingObject)
return (n = (t = this.creatingObject) == null ? void 0 : t.undo) == null ? void 0 : n.call(t);
if (this.canUndo()) {
this.currentHistoryIndex--;
const r = this.historyStack[this.currentHistoryIndex];
this.restoreSnapshot(r);
} else
console.log("[Polygon] undo: 无法撤销", { uuid: this.uuid });
}
redo() {
var t, n;
if (this.creatingObject)
return (n = (t = this.creatingObject) == null ? void 0 : t.redo) == null ? void 0 : n.call(t);
if (this.canRedo()) {
this.currentHistoryIndex++;
const r = this.historyStack[this.currentHistoryIndex];
this.restoreSnapshot(r);
}
}
/**
* 记录当前状态到历史记录
*/
recordHistory() {
if (this.creatingObject)
return;
this.historyStack = this.historyStack.slice(0, this.currentHistoryIndex + 1);
const t = {
points: this.areaMesh.points.map((n) => n.clone())
};
this.historyStack.push(t), this.historyStack.length > this.maxHistorySize ? this.historyStack.shift() : this.currentHistoryIndex++;
}
/**
* 恢复快照
*/
restoreSnapshot(t) {
this.areaMesh.setPoints(t.points.map((n) => n.clone())), this.updateCreationPointMeshes(), this._editor && this._editor.updatePointMeshes();
}
create(t) {
return ot(this, null, function* () {
var r;
this.children.forEach((x) => {
x.parent === this && this.remove(x);
}), this.children.length = 0;
const n = new rt(t);
this.areaMesh = n, this.add(this.areaMesh), this.creatingObject = jt(this.areaMesh, this.pointSelector, t), yield (r = this.creatingObject) == null ? void 0 : r.finished, this.creatingObject = null, this.recordHistory(), this.updateCreationPointMeshes(), this.config.defaultAction && this.editor.enable();
});
}
}
function jt(e, s, t) {
var N, $, G, J, K, Q, X, Z, g;
const { promise: n, resolve: r, reject: x } = wt(), a = e.parent;
if (!a) {
x(new Error("No container"));
return;
}
const w = (N = t == null ? void 0 : t.limit) != null ? N : "none", c = t == null ? void 0 : t.simpleMode, u = (Q = (K = (G = e.five) != null ? G : ($ = e.get) == null ? void 0 : $.call(e, "five")) != null ? K : (J = window.globalModules) == null ? void 0 : J.five) != null ? Q : window.$five, V = (X = t == null ? void 0 : t.autoClosePixelDistance) != null ? X : 10;
e.userData = (Z = e.userData) != null ? Z : {}, e.userData.dragSelectPixelDistance = V;
let M = 0;
c && u && u.model && u.model.bounding && typeof ((g = u.model.bounding.max) == null ? void 0 : g.y) == "number" && (M = u.model.bounding.max.y + 1);
const P = new nt(e.style);
a == null || a.add(P);
const y = new nt(R(H({}, e.style), { dashed: !0, lengthEnable: !1 }));
a == null || a.add(y);
let v = [];
const lt = (i = o) => {
v.forEach((d, p) => {
const h = i[p];
h && d.position.copy(h);
});
};
function D() {
var d, p;
v.forEach((h) => {
var f;
return (f = h.parent) == null ? void 0 : f.remove(h);
});
const i = (p = (d = e.line) == null ? void 0 : d.style) != null ? p : e.style;
v = o.map((h, f) => {
var S, k;
const b = new Ht(R(H({}, i), {
color: (S = i.pointColor) != null ? S : i.lineColor,
tip: void 0,
point: h
}));
return b.name = `PolygonPointMesh_${f}`, b.userData = (k = b.userData) != null ? k : {}, b.userData.dragSelectPixelDistance = V, a == null || a.add(b), b;
}), lt();
}
function Y() {
v.forEach((i) => {
var d;
return (d = i.parent) == null ? void 0 : d.remove(i);
}), v = [], e.userData && (delete e.userData.creationPointMeshes, delete e.userData.syncCreationPointMeshes, delete e.userData.disposeCreationPointMeshes);
}
s.enable(), c && s.setAdherePoints([]);
const o = [];
let l, m, W = !1, U;
const E = [], z = () => o.length > 0, B = () => E.length > 0, at = () => {
var i;
z() && (E.push(o.pop()), O(U), D(), (i = t == null ? void 0 : t.onUndo) == null || i.call(t), s.pointSelectorHelper && s.pointSelectorHelper.magnifier && s.pointSelectorHelper.magnifier.render());
}, ht = () => {
var i;
B() && (o.push(E.pop()), O(U), D(), (i = t == null ? void 0 : t.onRedo) == null || i.call(t), s.pointSelectorHelper && s.pointSelectorHelper.magnifier && s.pointSelectorHelper.magnifier.render());
}, q = (i) => {
var p, h;
E.length = 0;
let d = o.length === 0 ? i.point : l.clone();
if (c && (d = d.clone().setY(M)), t.__onWillAddPoint(d, o), !((t == null ? void 0 : t.experimental_max_point_count) != null && o.length === t.experimental_max_point_count)) {
if (o.push(d), e.setPoints(o, { closed: !1 }), t != null && t.experimental_self_intersect_check && o.length > 2 && e.isBlank) {
const f = o.pop();
e.setPoints(o, { closed: !1 }), D(), console.warn("[Polygon] 检测到自相交,无法添加该点"), (p = t == null ? void 0 : t.__onSelfIntersect) == null || p.call(t, f);
return;
}
D(), (h = t == null ? void 0 : t.onPointPlaced) == null || h.call(t, o), W && (F(), r());
}
}, O = (i) => {
const d = () => {
P.setPoints([]), y.setPoints([]), e.setPoints(o), s.pointSelectorHelper && s.pointSelectorHelper.magnifier && s.pointSelectorHelper.magnifier.render();
};
if (!i) {
d(), D();
return;
}
if (U = i, !(o != null && o.length))
return d();
const p = o.at(-1).clone();
if (o.length < 3 && (c ? (l = i.point.clone().setY(M), P.setPoints([p, l]), y.setPoints([])) : w === "none" ? (l = i.point, P.setPoints([p, l]), y.setPoints([])) : w === "xoz" ? (m = m != null ? m : new j.Plane().setFromNormalAndCoplanarPoint(new j.Vector3(0, 1, 0), o[0]), s.plane = m, l = m.projectPoint(i.point, new j.Vector3()), P.setPoints([p, l]), y.setPoints([l, i.point])) : w === "y" && (o.length === 1 ? (l = i.point, P.setPoints([p, l]), y.setPoints([])) : (m = m != null ? m : new j.Plane().setFromCoplanarPoints(o[0], o[1], new j.Vector3(0, 1, 0).add(o[0])), s.plane = m, l = m.projectPoint(i.point, new j.Vector3()), P.setPoints([p, l]), y.setPoints([l, i.point])))), o.length >= 3) {
c ? l = i.point.clone().setY(M) : l = e.projectPoint(i.point);
const h = o[0];
let f = !1;
if (typeof (t == null ? void 0 : t.autoClosePixelDistance) == "number") {
if (u && u.camera && u.getElement) {
const b = u.getElement(), S = b.clientWidth, k = b.clientHeight, A = (pt) => {
const st = pt.clone().project(u.camera);
return {
x: (st.x * 0.5 + 0.5) * S,
y: (1 - (st.y * 0.5 + 0.5)) * k
};
}, I = A(h), tt = A(l), et = A(i.point), dt = Math.sqrt(_(I.x - tt.x, 2) + _(I.y - tt.y, 2)), ut = Math.sqrt(_(I.x - et.x, 2) + _(I.y - et.y, 2));
(dt < t.autoClosePixelDistance || ut < t.autoClosePixelDistance) && (f = !0);
}
} else
(h.distanceTo(l) < 0.2 || h.distanceTo(i.point) < 0.2) && (f = !0);
f ? (l = h, i.point.copy(h), s.pointSelectorHelper.updateWithIntersect(i, { emitEvent: !1 }), W = !0) : W = !1, P.setPoints([p, l]), y.setPoints([l, i.point]);
}
o.length >= 2 ? (e.setPoints([...o, l], { closed: !1 }), e.line.setPoints(e.points.slice(0, -1)), e.isBlank ? (s.cursorError = !0, P.setStyle({ lineColor: 16734553 }), y.setStyle({ lineColor: 16734553 })) : (s.cursorError = !1, P.setStyle({ lineColor: e.lineColor }), y.setStyle({ lineColor: e.lineColor }))) : e.setPoints([]), D();
}, F = () => {
s.off("select", q), s.off("intersectionUpdate", O), s.off("disable", L), s.plane = null, s.disable(), a == null || a.remove(P, y), Y();
}, L = () => {
F(), a == null || a.remove(e, y, P), Y(), x(new Error("Cancelled"));
};
return s.on("select", q), s.on("intersectionUpdate", O), s.on("disable", L), {
finished: n,
canUndo: z,
canRedo: B,
undo: at,
redo: ht
};
}
export {
Wt as Polygon,
jt as createPolygon
};