feat: Entity 선택기능, Property Inspector 패널, Layer 관리 패널, 드래그/접기/크기조절 UI 구현

This commit is contained in:
minsung
2026-07-31 13:38:14 +09:00
parent f7564d4abf
commit 199317d575
7 changed files with 846 additions and 27 deletions
+3
View File
@@ -11,6 +11,9 @@ export class Viewer2D {
/** Resync renderer/camera to the container size (call after un-hiding). */
resize(): void;
onSelect(cb: (entity: unknown) => void): void;
getSelectedEntity(): unknown;
zoomToSelection(): void;
setAccent(hex: string): void;
setTheme(dark: boolean): void;
setGrid(visible: boolean): void;
getLayerInfo(): { name: string; colorHex: string; count: number; visible: boolean }[];
+46
View File
@@ -3535,6 +3535,52 @@ export class Viewer2D {
if (this._selMeta) { const m = this._selMeta; this._selMeta = null; this._highlight(m); }
}
/** Get currently selected CAD entity (or null). */
getSelectedEntity() {
return this._selMeta ? this._selMeta.entity : null;
}
/** Zoom extents to the currently selected CAD entity. */
zoomToSelection() {
if (!this._selMeta) return;
const idx = this._entityMeta.indexOf(this._selMeta);
if (idx < 0) return;
const box = new THREE.Box3();
const S = this._pickSegs, SM = this._pickSegMeta;
if (S && SM) {
for (let i = 0, j = 0; i < S.length; i += 4, j++) {
if (SM[j] === idx) {
box.expandByPoint(new THREE.Vector3(S[i], S[i + 1], 0));
box.expandByPoint(new THREE.Vector3(S[i + 2], S[i + 3], 0));
}
}
}
if (this._pickFills) {
for (const f of this._pickFills) {
if (f.metaIdx === idx) {
for (const loop of f.loops || []) {
for (const p of loop) {
box.expandByPoint(new THREE.Vector3(p.x, p.y, 0));
}
}
}
}
}
if (box.isEmpty() && this._selMeta.entity) {
const e = this._selMeta.entity;
const d = e.data || e;
const pt = d.start || d.center || d.pos || d.insertionPoint || d.insertionPt;
if (pt) {
const pad = 10;
box.expandByPoint(new THREE.Vector3(pt.x - pad, pt.y - pad, 0));
box.expandByPoint(new THREE.Vector3(pt.x + pad, pt.y + pad, 0));
}
}
if (!box.isEmpty()) {
this._fit(box);
}
}
_distToBounds(wx, wy, b) {
if (b.type === 'point') return Math.hypot(wx - b.cx, wy - b.cy);
if (b.type === 'circle') return Math.abs(Math.hypot(wx - b.cx, wy - b.cy) - b.r);