@maqiuyao/dxf-viewer 0.1.0 → 0.2.1

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.
@@ -0,0 +1,82 @@
1
+ import { Viewer2d } from '../viewers/Viewer2d';
2
+ import * as THREE from "three";
3
+ /**
4
+ * 一条文本搜索结果。
5
+ */
6
+ export interface TextSearchResult {
7
+ /** 实体句柄 */
8
+ handle: string;
9
+ /** 图层名 */
10
+ layer: string;
11
+ /** 所属布局名(Model / Layout1 ...) */
12
+ layoutName: string;
13
+ /** 文本内容(已去除 MTEXT 格式码) */
14
+ text: string;
15
+ /** 世界坐标包围盒 */
16
+ box: THREE.Box3;
17
+ }
18
+ /**
19
+ * 搜索模式:
20
+ * - exact:精准匹配,文本内容(去首尾空格后)与关键字完全相等才算命中(不区分大小写);
21
+ * - fuzzy:模糊匹配,关键字作为连续子串出现即命中,还支持跳字子序列(如"铁院"命中"铁一院")。
22
+ */
23
+ export type TextSearchMode = "exact" | "fuzzy";
24
+ /**
25
+ * 图纸文本搜索辅助类:在已加载的模型中检索文本实体(TEXT/MTEXT/ATTRIB),
26
+ * 支持定位(切换布局 + 缩放)与高亮(叠加层云线框)。
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * const helper = new TextSearchHelper(viewer);
31
+ * const results = helper.search("道岔");
32
+ * helper.focus(results[0]);
33
+ * helper.clearHighlight();
34
+ * ```
35
+ */
36
+ export declare class TextSearchHelper {
37
+ private viewer;
38
+ private overlayRender?;
39
+ private drawableList?;
40
+ private indexedModelObject?;
41
+ private index;
42
+ constructor(viewer: Viewer2d);
43
+ private getMasterModel;
44
+ /**
45
+ * 遍历主模型场景图,收集所有带 userData.textContent 的文本对象。
46
+ */
47
+ private buildIndex;
48
+ /** 向上查找布局层对象名 */
49
+ private findLayoutName;
50
+ /**
51
+ * 按关键字搜索文本(不区分大小写)。
52
+ * - mode = "exact"(精准):关键字作为连续子串出现即命中;
53
+ * - mode = "fuzzy"(模糊,默认):在精准基础上还支持跳字子序列,例如"铁院"匹配"铁一院"。
54
+ * 结果按匹配度从高到低排序(完全相等 > 靠前子串 > 短跳字 > 长跳字)。
55
+ * @param keyword 搜索关键字
56
+ * @param options.mode 匹配模式,默认 "fuzzy"
57
+ * @param options.layer 限定图层名(不区分大小写,可选)
58
+ * @param options.maxResults 最大返回条数,默认 200
59
+ */
60
+ search(keyword: string, options?: {
61
+ mode?: TextSearchMode;
62
+ layer?: string;
63
+ maxResults?: number;
64
+ }): TextSearchResult[];
65
+ /**
66
+ * 定位到一条搜索结果:切换到其所在布局、缩放至包围盒,并在叠加层高亮。
67
+ */
68
+ focus(result: TextSearchResult): void;
69
+ /**
70
+ * 在叠加层用云线框高亮指定结果(替换上一个高亮)。
71
+ */
72
+ highlight(result: TextSearchResult): void;
73
+ /**
74
+ * 清除当前高亮。
75
+ */
76
+ clearHighlight(): void;
77
+ /**
78
+ * 模型重新加载后调用,强制重建索引。
79
+ */
80
+ invalidate(): void;
81
+ destroy(): void;
82
+ }
@@ -8,4 +8,5 @@ export * from './OSnapHelper';
8
8
  export * from './PickMarkupHelper';
9
9
  export * from './BoxSelectHelper';
10
10
  export * from './ZoomToRectHelper';
11
+ export * from './TextSearchHelper';
11
12
  export * from './MobileTouchHelperDrawable';
@@ -2,7 +2,7 @@ import { CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer.js';
2
2
  import { ProgressBar, Spinner } from '../components';
3
3
  import { ViewerName } from './Constants';
4
4
  import { Plugin } from './Plugin';
5
- import { ViewerEvent } from './ViewerEvent';
5
+ import { ViewerEvent, MouseClickInfo } from './ViewerEvent';
6
6
  import { BaseViewerConfig, CameraConfig, CameraProjection, ModelConfig, Viewpoint } from '../../core/Configs';
7
7
  import { CameraManager } from '../../core/camera';
8
8
  import { CanvasRender } from '../../core/canvas';
@@ -18,7 +18,7 @@ import { UndoManager } from '../../core/undo';
18
18
  import { Event } from '../../core/utils';
19
19
  import * as THREE from "three";
20
20
  type ViewerEvents = {
21
- [K in ViewerEvent]: any;
21
+ [K in ViewerEvent]: K extends ViewerEvent.MouseClick ? MouseClickInfo : any;
22
22
  };
23
23
  /**
24
24
  * Abstract base class for Viewer2d, Viewer3d, etc.
@@ -5,6 +5,7 @@ import { Drawable } from '../../core/canvas';
5
5
  import { DxfLayer } from '../../core/dxf';
6
6
  import { EventInfo } from '../../core/input-manager/InputManager';
7
7
  import { Model2d } from '../../core/model';
8
+ import { TextSearchMode, TextSearchResult } from '../../core/helpers/TextSearchHelper';
8
9
  import * as THREE from "three";
9
10
  export interface EntityData {
10
11
  modelId: string;
@@ -169,9 +170,41 @@ export declare class Viewer2d extends BaseViewer {
169
170
  * Used to indicate how many dxf is loading
170
171
  */
171
172
  private loadingDxfCount;
173
+ private textSearchHelper?;
174
+ /** 实体点击高亮的云线框叠加层 */
175
+ private clickHighlightList?;
176
+ /** 是否启用点击实体高亮,默认关闭 */
177
+ private _enableClickHighlight;
172
178
  constructor(viewerCfg: Viewer2dConfig);
173
179
  get camera(): THREE.OrthographicCamera;
174
180
  private setupDefaultEvents;
181
+ /**
182
+ * 从拾取命中结果反查所属 DXF 实体的 userData 与对应 batch。
183
+ * 合并(deepMerge)后一个几何对象含多个 batch,每个 batch.userData 保存原实体元数据;
184
+ * 依据命中的索引/面游标定位 batch。返回的 batch 用于计算该实体的世界包围盒以高亮。
185
+ */
186
+ private resolveEntityFromPick;
187
+ /**
188
+ * 计算命中实体(batch 或整个对象)的世界包围盒。
189
+ */
190
+ private getEntityBoundingBox;
191
+ /**
192
+ * 用云线框高亮指定实体包围盒(替换上一个高亮)。
193
+ */
194
+ private highlightEntityBox;
195
+ /**
196
+ * Gets if click-to-highlight entity is enabled. Default is false.
197
+ */
198
+ get enableClickHighlight(): boolean;
199
+ /**
200
+ * Sets if click-to-highlight entity is enabled.
201
+ * When turned off, the current highlight (if any) is cleared.
202
+ */
203
+ set enableClickHighlight(enable: boolean);
204
+ /**
205
+ * 清除实体点击高亮。
206
+ */
207
+ clearClickHighlight(): void;
175
208
  protected handleMouseClick(e: EventInfo): void;
176
209
  private setDefaultBackground;
177
210
  /**
@@ -325,6 +358,34 @@ export declare class Viewer2d extends BaseViewer {
325
358
  * ```
326
359
  */
327
360
  getActiveLayoutName(): string | undefined;
361
+ /**
362
+ * @description {en} Searches text entities (TEXT/MTEXT/ATTRIB) in the loaded drawing.
363
+ * @description {zh} 在已加载的图纸中搜索文本实体(TEXT/MTEXT/ATTRIB)。
364
+ * @param keyword 搜索关键字(不区分大小写、子串匹配)
365
+ * @param options.layer 限定图层名(可选)
366
+ * @param options.maxResults 最大返回条数,默认 200
367
+ * @returns 匹配的文本结果列表
368
+ * @example
369
+ * ```typescript
370
+ * const results = viewer.searchText("道岔");
371
+ * results.length > 0 && viewer.focusText(results[0]);
372
+ * ```
373
+ */
374
+ searchText(keyword: string, options?: {
375
+ mode?: TextSearchMode;
376
+ layer?: string;
377
+ maxResults?: number;
378
+ }): TextSearchResult[];
379
+ /**
380
+ * @description {en} Zooms to a text search result and highlights it with a cloud border.
381
+ * @description {zh} 定位到一条文本搜索结果并高亮(云线框)。
382
+ */
383
+ focusText(result: TextSearchResult): void;
384
+ /**
385
+ * @description {en} Clears the highlight of text search results.
386
+ * @description {zh} 清除文本搜索结果的高亮。
387
+ */
388
+ clearTextHighlight(): void;
328
389
  zoomIn(step?: number): void;
329
390
  zoomOut(step?: number): void;
330
391
  /**
@@ -1,3 +1,29 @@
1
+ import { Object3D, Vector2, Vector3 } from 'three';
2
+ import { EventInfo } from '../input-manager/InputManager';
3
+ /**
4
+ * 实体点击事件({@link ViewerEvent.MouseClick})的载荷。
5
+ * 点击图纸实体时携带命中信息;点击空白处时 entity/object/point/userData/handle 为 undefined。
6
+ */
7
+ export interface MouseClickInfo {
8
+ /** 原始输入事件信息 */
9
+ event: EventInfo;
10
+ /** 点击位置(查看器容器内像素坐标) */
11
+ position: Vector2;
12
+ /** 点击位置对应的世界坐标 */
13
+ worldPosition: Vector3;
14
+ /** @deprecated 兼容旧字段,等价于 worldPosition */
15
+ pooo: Vector3;
16
+ /** 命中的实体对象;点击空白处为 undefined */
17
+ entity?: Object3D;
18
+ /** 命中对象(与 entity 一致,仅当解析出实体时非空) */
19
+ object?: Object3D;
20
+ /** 命中点(世界坐标) */
21
+ point?: Vector3;
22
+ /** 命中实体的元数据(handle / dxfType / layerName / textContent 等) */
23
+ userData?: Record<string, any>;
24
+ /** 命中实体的 DXF handle */
25
+ handle?: string;
26
+ }
1
27
  /**
2
28
  * Viewer events
3
29
  * TODO: dxf event and bim event
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maqiuyao/dxf-viewer",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "基于 three.js 的 DXF 图纸 2D/3D 查看与对比库(Viewer2d / DxfCompareHelper)",
5
5
  "type": "module",
6
6
  "main": "./dist/dxf-viewer.cjs",