build-dxf 0.0.18 → 0.0.19-10

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 (44) hide show
  1. package/README.md +30 -0
  2. package/package.json +1 -3
  3. package/src/build.d.ts +30 -1
  4. package/src/build.js +578 -472
  5. package/src/components/Editor.vue.d.ts +26 -0
  6. package/src/index.css +765 -1
  7. package/src/index.js +5 -2
  8. package/src/index2.js +185 -6898
  9. package/src/index3.js +2047 -0
  10. package/src/pages/Editor.vue.d.ts +2 -0
  11. package/src/pages/Editor02.vue.d.ts +4 -0
  12. package/src/selectLocalFile.js +4167 -0
  13. package/src/utils/CommandManager/CommandFlow.d.ts +23 -0
  14. package/src/utils/CommandManager/CommandManager.d.ts +59 -0
  15. package/src/utils/CommandManager/index.d.ts +2 -0
  16. package/src/utils/ComponentManager/ComponentManager.d.ts +1 -1
  17. package/src/utils/ComponentManager/EventDispatcher.d.ts +11 -1
  18. package/src/utils/DxfSystem/components/Dxf.d.ts +15 -12
  19. package/src/utils/DxfSystem/components/LineAnalysis.d.ts +1 -20
  20. package/src/utils/DxfSystem/components/Variable.d.ts +8 -0
  21. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/CommandFlowComponent.d.ts +36 -0
  22. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/Default.d.ts +57 -0
  23. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DrawDoorLine.d.ts +19 -0
  24. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DrawLine.d.ts +20 -0
  25. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DrawWindow.d.ts +25 -0
  26. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/PointDrag.d.ts +27 -0
  27. package/src/utils/DxfSystem/plugin/Editor/components/Editor.d.ts +22 -3
  28. package/src/utils/DxfSystem/plugin/Editor/components/RenderManager.d.ts +88 -0
  29. package/src/utils/DxfSystem/plugin/Editor/components/index.d.ts +6 -0
  30. package/src/utils/DxfSystem/plugin/Editor/pages/EditorTool.vue.d.ts +9 -0
  31. package/src/utils/DxfSystem/plugin/ModelDataPlugin/components/DxfLineModel.d.ts +7 -3
  32. package/src/utils/DxfSystem/plugin/ModelDataPlugin/index.d.ts +9 -1
  33. package/src/utils/DxfSystem/plugin/RenderPlugin/components/DomContainer.d.ts +1 -0
  34. package/src/utils/DxfSystem/plugin/RenderPlugin/components/DomEventRegister.d.ts +47 -6
  35. package/src/utils/DxfSystem/plugin/RenderPlugin/components/EventInput.d.ts +74 -0
  36. package/src/utils/DxfSystem/plugin/RenderPlugin/components/Renderer.d.ts +1 -12
  37. package/src/utils/DxfSystem/plugin/RenderPlugin/components/index.d.ts +1 -0
  38. package/src/utils/DxfSystem/plugin/RenderPlugin/index.d.ts +12 -1
  39. package/src/utils/PointVirtualGrid/index.d.ts +10 -4
  40. package/src/utils/Quadtree/Box2.d.ts +3 -2
  41. package/src/utils/Quadtree/LineSegment.d.ts +11 -9
  42. package/src/utils/Quadtree/Point.d.ts +11 -6
  43. package/src/utils/Quadtree/Quadtree.d.ts +5 -0
  44. package/src/utils/Quadtree/Rectangle.d.ts +5 -4
package/src/index3.js ADDED
@@ -0,0 +1,2047 @@
1
+ import * as THREE from "three";
2
+ import { i as isString, n as noop, r as resolveUnref, t as tryOnScopeDispose, c as isClient, d as tryOnMounted, e as identity, f as buildProps, g as definePropType, _ as _export_sfc, u as useNamespace, h as isNumber, j as addUnit, w as withInstall, k as useEmptyValuesProps, l as useSizeProp, p as provideGlobalConfig, m as iconPropType, o as useGlobalComponentSettings, T as TypeComponentsMap, q as ElIcon, s as TypeComponents, v as useTimeoutFn, x as isString$1, y as isFunction, z as isBoolean, A as isElement, B as withInstallFunction, L as Lines, D as DomEventRegister, b as ElCheckbox, E as ElButton, S as SelectLocalFile } from "./selectLocalFile.js";
3
+ import { C as Component, L as LineSegment, P as Point, B as Box2, E as EventDispatcher, b as PointVirtualGrid, Q as Quadtree } from "./build.js";
4
+ import { watch, ref, defineComponent, computed, createElementBlock, openBlock, normalizeClass, unref, renderSlot, createVNode, Transition, withCtx, withDirectives, createElementVNode, normalizeStyle, createTextVNode, toDisplayString, vShow, shallowReactive, onMounted, createBlock, createCommentVNode, resolveDynamicComponent, Fragment, withModifiers, nextTick, isVNode, render, toRaw, watchEffect, onUnmounted, renderList, createApp } from "vue";
5
+ import "clipper-lib";
6
+ import "dxf-writer";
7
+ import "three/addons/controls/OrbitControls.js";
8
+ function unrefElement(elRef) {
9
+ var _a;
10
+ const plain = resolveUnref(elRef);
11
+ return (_a = plain == null ? void 0 : plain.$el) != null ? _a : plain;
12
+ }
13
+ const defaultWindow = isClient ? window : void 0;
14
+ function useEventListener(...args) {
15
+ let target;
16
+ let events;
17
+ let listeners;
18
+ let options;
19
+ if (isString(args[0]) || Array.isArray(args[0])) {
20
+ [events, listeners, options] = args;
21
+ target = defaultWindow;
22
+ } else {
23
+ [target, events, listeners, options] = args;
24
+ }
25
+ if (!target)
26
+ return noop;
27
+ if (!Array.isArray(events))
28
+ events = [events];
29
+ if (!Array.isArray(listeners))
30
+ listeners = [listeners];
31
+ const cleanups = [];
32
+ const cleanup = () => {
33
+ cleanups.forEach((fn) => fn());
34
+ cleanups.length = 0;
35
+ };
36
+ const register = (el, event, listener, options2) => {
37
+ el.addEventListener(event, listener, options2);
38
+ return () => el.removeEventListener(event, listener, options2);
39
+ };
40
+ const stopWatch = watch(() => [unrefElement(target), resolveUnref(options)], ([el, options2]) => {
41
+ cleanup();
42
+ if (!el)
43
+ return;
44
+ cleanups.push(...events.flatMap((event) => {
45
+ return listeners.map((listener) => register(el, event, listener, options2));
46
+ }));
47
+ }, { immediate: true, flush: "post" });
48
+ const stop = () => {
49
+ stopWatch();
50
+ cleanup();
51
+ };
52
+ tryOnScopeDispose(stop);
53
+ return stop;
54
+ }
55
+ function useSupported(callback, sync = false) {
56
+ const isSupported = ref();
57
+ const update = () => isSupported.value = Boolean(callback());
58
+ update();
59
+ tryOnMounted(update, sync);
60
+ return isSupported;
61
+ }
62
+ const _global = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
63
+ const globalKey = "__vueuse_ssr_handlers__";
64
+ _global[globalKey] = _global[globalKey] || {};
65
+ var __getOwnPropSymbols$g = Object.getOwnPropertySymbols;
66
+ var __hasOwnProp$g = Object.prototype.hasOwnProperty;
67
+ var __propIsEnum$g = Object.prototype.propertyIsEnumerable;
68
+ var __objRest$2 = (source, exclude) => {
69
+ var target = {};
70
+ for (var prop in source)
71
+ if (__hasOwnProp$g.call(source, prop) && exclude.indexOf(prop) < 0)
72
+ target[prop] = source[prop];
73
+ if (source != null && __getOwnPropSymbols$g)
74
+ for (var prop of __getOwnPropSymbols$g(source)) {
75
+ if (exclude.indexOf(prop) < 0 && __propIsEnum$g.call(source, prop))
76
+ target[prop] = source[prop];
77
+ }
78
+ return target;
79
+ };
80
+ function useResizeObserver(target, callback, options = {}) {
81
+ const _a = options, { window: window2 = defaultWindow } = _a, observerOptions = __objRest$2(_a, ["window"]);
82
+ let observer;
83
+ const isSupported = useSupported(() => window2 && "ResizeObserver" in window2);
84
+ const cleanup = () => {
85
+ if (observer) {
86
+ observer.disconnect();
87
+ observer = void 0;
88
+ }
89
+ };
90
+ const stopWatch = watch(() => unrefElement(target), (el) => {
91
+ cleanup();
92
+ if (isSupported.value && window2 && el) {
93
+ observer = new ResizeObserver(callback);
94
+ observer.observe(el, observerOptions);
95
+ }
96
+ }, { immediate: true, flush: "post" });
97
+ const stop = () => {
98
+ cleanup();
99
+ stopWatch();
100
+ };
101
+ tryOnScopeDispose(stop);
102
+ return {
103
+ isSupported,
104
+ stop
105
+ };
106
+ }
107
+ var SwipeDirection;
108
+ (function(SwipeDirection2) {
109
+ SwipeDirection2["UP"] = "UP";
110
+ SwipeDirection2["RIGHT"] = "RIGHT";
111
+ SwipeDirection2["DOWN"] = "DOWN";
112
+ SwipeDirection2["LEFT"] = "LEFT";
113
+ SwipeDirection2["NONE"] = "NONE";
114
+ })(SwipeDirection || (SwipeDirection = {}));
115
+ var __defProp = Object.defineProperty;
116
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
117
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
118
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
119
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
120
+ var __spreadValues = (a, b) => {
121
+ for (var prop in b || (b = {}))
122
+ if (__hasOwnProp.call(b, prop))
123
+ __defNormalProp(a, prop, b[prop]);
124
+ if (__getOwnPropSymbols)
125
+ for (var prop of __getOwnPropSymbols(b)) {
126
+ if (__propIsEnum.call(b, prop))
127
+ __defNormalProp(a, prop, b[prop]);
128
+ }
129
+ return a;
130
+ };
131
+ const _TransitionPresets = {
132
+ easeInSine: [0.12, 0, 0.39, 0],
133
+ easeOutSine: [0.61, 1, 0.88, 1],
134
+ easeInOutSine: [0.37, 0, 0.63, 1],
135
+ easeInQuad: [0.11, 0, 0.5, 0],
136
+ easeOutQuad: [0.5, 1, 0.89, 1],
137
+ easeInOutQuad: [0.45, 0, 0.55, 1],
138
+ easeInCubic: [0.32, 0, 0.67, 0],
139
+ easeOutCubic: [0.33, 1, 0.68, 1],
140
+ easeInOutCubic: [0.65, 0, 0.35, 1],
141
+ easeInQuart: [0.5, 0, 0.75, 0],
142
+ easeOutQuart: [0.25, 1, 0.5, 1],
143
+ easeInOutQuart: [0.76, 0, 0.24, 1],
144
+ easeInQuint: [0.64, 0, 0.78, 0],
145
+ easeOutQuint: [0.22, 1, 0.36, 1],
146
+ easeInOutQuint: [0.83, 0, 0.17, 1],
147
+ easeInExpo: [0.7, 0, 0.84, 0],
148
+ easeOutExpo: [0.16, 1, 0.3, 1],
149
+ easeInOutExpo: [0.87, 0, 0.13, 1],
150
+ easeInCirc: [0.55, 0, 1, 0.45],
151
+ easeOutCirc: [0, 0.55, 0.45, 1],
152
+ easeInOutCirc: [0.85, 0, 0.15, 1],
153
+ easeInBack: [0.36, 0, 0.66, -0.56],
154
+ easeOutBack: [0.34, 1.56, 0.64, 1],
155
+ easeInOutBack: [0.68, -0.6, 0.32, 1.6]
156
+ };
157
+ __spreadValues({
158
+ linear: identity
159
+ }, _TransitionPresets);
160
+ const mutable = (val) => val;
161
+ const EVENT_CODE = {
162
+ esc: "Escape"
163
+ };
164
+ const badgeProps = buildProps({
165
+ value: {
166
+ type: [String, Number],
167
+ default: ""
168
+ },
169
+ max: {
170
+ type: Number,
171
+ default: 99
172
+ },
173
+ isDot: Boolean,
174
+ hidden: Boolean,
175
+ type: {
176
+ type: String,
177
+ values: ["primary", "success", "warning", "info", "danger"],
178
+ default: "danger"
179
+ },
180
+ showZero: {
181
+ type: Boolean,
182
+ default: true
183
+ },
184
+ color: String,
185
+ badgeStyle: {
186
+ type: definePropType([String, Object, Array])
187
+ },
188
+ offset: {
189
+ type: definePropType(Array),
190
+ default: [0, 0]
191
+ },
192
+ badgeClass: {
193
+ type: String
194
+ }
195
+ });
196
+ const __default__$1 = defineComponent({
197
+ name: "ElBadge"
198
+ });
199
+ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
200
+ ...__default__$1,
201
+ props: badgeProps,
202
+ setup(__props, { expose }) {
203
+ const props = __props;
204
+ const ns = useNamespace("badge");
205
+ const content = computed(() => {
206
+ if (props.isDot)
207
+ return "";
208
+ if (isNumber(props.value) && isNumber(props.max)) {
209
+ return props.max < props.value ? `${props.max}+` : `${props.value}`;
210
+ }
211
+ return `${props.value}`;
212
+ });
213
+ const style = computed(() => {
214
+ var _a, _b, _c, _d, _e;
215
+ return [
216
+ {
217
+ backgroundColor: props.color,
218
+ marginRight: addUnit(-((_b = (_a = props.offset) == null ? void 0 : _a[0]) != null ? _b : 0)),
219
+ marginTop: addUnit((_d = (_c = props.offset) == null ? void 0 : _c[1]) != null ? _d : 0)
220
+ },
221
+ (_e = props.badgeStyle) != null ? _e : {}
222
+ ];
223
+ });
224
+ expose({
225
+ content
226
+ });
227
+ return (_ctx, _cache) => {
228
+ return openBlock(), createElementBlock("div", {
229
+ class: normalizeClass(unref(ns).b())
230
+ }, [
231
+ renderSlot(_ctx.$slots, "default"),
232
+ createVNode(Transition, {
233
+ name: `${unref(ns).namespace.value}-zoom-in-center`,
234
+ persisted: ""
235
+ }, {
236
+ default: withCtx(() => [
237
+ withDirectives(createElementVNode("sup", {
238
+ class: normalizeClass([
239
+ unref(ns).e("content"),
240
+ unref(ns).em("content", _ctx.type),
241
+ unref(ns).is("fixed", !!_ctx.$slots.default),
242
+ unref(ns).is("dot", _ctx.isDot),
243
+ unref(ns).is("hide-zero", !_ctx.showZero && props.value === 0),
244
+ _ctx.badgeClass
245
+ ]),
246
+ style: normalizeStyle(unref(style))
247
+ }, [
248
+ renderSlot(_ctx.$slots, "content", { value: unref(content) }, () => [
249
+ createTextVNode(toDisplayString(unref(content)), 1)
250
+ ])
251
+ ], 6), [
252
+ [vShow, !_ctx.hidden && (unref(content) || _ctx.isDot || _ctx.$slots.content)]
253
+ ])
254
+ ]),
255
+ _: 3
256
+ }, 8, ["name"])
257
+ ], 2);
258
+ };
259
+ }
260
+ });
261
+ var Badge = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__file", "badge.vue"]]);
262
+ const ElBadge = withInstall(Badge);
263
+ const configProviderProps = buildProps({
264
+ a11y: {
265
+ type: Boolean,
266
+ default: true
267
+ },
268
+ locale: {
269
+ type: definePropType(Object)
270
+ },
271
+ size: useSizeProp,
272
+ button: {
273
+ type: definePropType(Object)
274
+ },
275
+ card: {
276
+ type: definePropType(Object)
277
+ },
278
+ dialog: {
279
+ type: definePropType(Object)
280
+ },
281
+ link: {
282
+ type: definePropType(Object)
283
+ },
284
+ experimentalFeatures: {
285
+ type: definePropType(Object)
286
+ },
287
+ keyboardNavigation: {
288
+ type: Boolean,
289
+ default: true
290
+ },
291
+ message: {
292
+ type: definePropType(Object)
293
+ },
294
+ zIndex: Number,
295
+ namespace: {
296
+ type: String,
297
+ default: "el"
298
+ },
299
+ ...useEmptyValuesProps
300
+ });
301
+ const messageConfig = {};
302
+ defineComponent({
303
+ name: "ElConfigProvider",
304
+ props: configProviderProps,
305
+ setup(props, { slots }) {
306
+ const config = provideGlobalConfig(props);
307
+ watch(() => props.message, (val) => {
308
+ var _a, _b;
309
+ Object.assign(messageConfig, (_b = (_a = config == null ? void 0 : config.value) == null ? void 0 : _a.message) != null ? _b : {}, val != null ? val : {});
310
+ }, { immediate: true, deep: true });
311
+ return () => renderSlot(slots, "default", { config: config == null ? void 0 : config.value });
312
+ }
313
+ });
314
+ const messageTypes = [
315
+ "primary",
316
+ "success",
317
+ "info",
318
+ "warning",
319
+ "error"
320
+ ];
321
+ const messageDefaults = mutable({
322
+ customClass: "",
323
+ dangerouslyUseHTMLString: false,
324
+ duration: 3e3,
325
+ icon: void 0,
326
+ id: "",
327
+ message: "",
328
+ onClose: void 0,
329
+ showClose: false,
330
+ type: "info",
331
+ plain: false,
332
+ offset: 16,
333
+ zIndex: 0,
334
+ grouping: false,
335
+ repeatNum: 1,
336
+ appendTo: isClient ? document.body : void 0
337
+ });
338
+ const messageProps = buildProps({
339
+ customClass: {
340
+ type: String,
341
+ default: messageDefaults.customClass
342
+ },
343
+ dangerouslyUseHTMLString: {
344
+ type: Boolean,
345
+ default: messageDefaults.dangerouslyUseHTMLString
346
+ },
347
+ duration: {
348
+ type: Number,
349
+ default: messageDefaults.duration
350
+ },
351
+ icon: {
352
+ type: iconPropType,
353
+ default: messageDefaults.icon
354
+ },
355
+ id: {
356
+ type: String,
357
+ default: messageDefaults.id
358
+ },
359
+ message: {
360
+ type: definePropType([
361
+ String,
362
+ Object,
363
+ Function
364
+ ]),
365
+ default: messageDefaults.message
366
+ },
367
+ onClose: {
368
+ type: definePropType(Function),
369
+ default: messageDefaults.onClose
370
+ },
371
+ showClose: {
372
+ type: Boolean,
373
+ default: messageDefaults.showClose
374
+ },
375
+ type: {
376
+ type: String,
377
+ values: messageTypes,
378
+ default: messageDefaults.type
379
+ },
380
+ plain: {
381
+ type: Boolean,
382
+ default: messageDefaults.plain
383
+ },
384
+ offset: {
385
+ type: Number,
386
+ default: messageDefaults.offset
387
+ },
388
+ zIndex: {
389
+ type: Number,
390
+ default: messageDefaults.zIndex
391
+ },
392
+ grouping: {
393
+ type: Boolean,
394
+ default: messageDefaults.grouping
395
+ },
396
+ repeatNum: {
397
+ type: Number,
398
+ default: messageDefaults.repeatNum
399
+ }
400
+ });
401
+ const messageEmits = {
402
+ destroy: () => true
403
+ };
404
+ const instances = shallowReactive([]);
405
+ const getInstance = (id) => {
406
+ const idx = instances.findIndex((instance) => instance.id === id);
407
+ const current = instances[idx];
408
+ let prev;
409
+ if (idx > 0) {
410
+ prev = instances[idx - 1];
411
+ }
412
+ return { current, prev };
413
+ };
414
+ const getLastOffset = (id) => {
415
+ const { prev } = getInstance(id);
416
+ if (!prev)
417
+ return 0;
418
+ return prev.vm.exposed.bottom.value;
419
+ };
420
+ const getOffsetOrSpace = (id, offset) => {
421
+ const idx = instances.findIndex((instance) => instance.id === id);
422
+ return idx > 0 ? 16 : offset;
423
+ };
424
+ const __default__ = defineComponent({
425
+ name: "ElMessage"
426
+ });
427
+ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
428
+ ...__default__,
429
+ props: messageProps,
430
+ emits: messageEmits,
431
+ setup(__props, { expose, emit }) {
432
+ const props = __props;
433
+ const { Close } = TypeComponents;
434
+ const isStartTransition = ref(false);
435
+ const { ns, zIndex } = useGlobalComponentSettings("message");
436
+ const { currentZIndex, nextZIndex } = zIndex;
437
+ const messageRef = ref();
438
+ const visible = ref(false);
439
+ const height = ref(0);
440
+ let stopTimer = void 0;
441
+ const badgeType = computed(() => props.type ? props.type === "error" ? "danger" : props.type : "info");
442
+ const typeClass = computed(() => {
443
+ const type = props.type;
444
+ return { [ns.bm("icon", type)]: type && TypeComponentsMap[type] };
445
+ });
446
+ const iconComponent = computed(() => props.icon || TypeComponentsMap[props.type] || "");
447
+ const lastOffset = computed(() => getLastOffset(props.id));
448
+ const offset = computed(() => getOffsetOrSpace(props.id, props.offset) + lastOffset.value);
449
+ const bottom = computed(() => height.value + offset.value);
450
+ const customStyle = computed(() => ({
451
+ top: `${offset.value}px`,
452
+ zIndex: currentZIndex.value
453
+ }));
454
+ function startTimer() {
455
+ if (props.duration === 0)
456
+ return;
457
+ ({ stop: stopTimer } = useTimeoutFn(() => {
458
+ close();
459
+ }, props.duration));
460
+ }
461
+ function clearTimer() {
462
+ stopTimer == null ? void 0 : stopTimer();
463
+ }
464
+ function close() {
465
+ visible.value = false;
466
+ nextTick(() => {
467
+ var _a;
468
+ if (!isStartTransition.value) {
469
+ (_a = props.onClose) == null ? void 0 : _a.call(props);
470
+ emit("destroy");
471
+ }
472
+ });
473
+ }
474
+ function keydown({ code }) {
475
+ if (code === EVENT_CODE.esc) {
476
+ close();
477
+ }
478
+ }
479
+ onMounted(() => {
480
+ startTimer();
481
+ nextZIndex();
482
+ visible.value = true;
483
+ });
484
+ watch(() => props.repeatNum, () => {
485
+ clearTimer();
486
+ startTimer();
487
+ });
488
+ useEventListener(document, "keydown", keydown);
489
+ useResizeObserver(messageRef, () => {
490
+ height.value = messageRef.value.getBoundingClientRect().height;
491
+ });
492
+ expose({
493
+ visible,
494
+ bottom,
495
+ close
496
+ });
497
+ return (_ctx, _cache) => {
498
+ return openBlock(), createBlock(Transition, {
499
+ name: unref(ns).b("fade"),
500
+ onBeforeEnter: ($event) => isStartTransition.value = true,
501
+ onBeforeLeave: _ctx.onClose,
502
+ onAfterLeave: ($event) => _ctx.$emit("destroy"),
503
+ persisted: ""
504
+ }, {
505
+ default: withCtx(() => [
506
+ withDirectives(createElementVNode("div", {
507
+ id: _ctx.id,
508
+ ref_key: "messageRef",
509
+ ref: messageRef,
510
+ class: normalizeClass([
511
+ unref(ns).b(),
512
+ { [unref(ns).m(_ctx.type)]: _ctx.type },
513
+ unref(ns).is("closable", _ctx.showClose),
514
+ unref(ns).is("plain", _ctx.plain),
515
+ _ctx.customClass
516
+ ]),
517
+ style: normalizeStyle(unref(customStyle)),
518
+ role: "alert",
519
+ onMouseenter: clearTimer,
520
+ onMouseleave: startTimer
521
+ }, [
522
+ _ctx.repeatNum > 1 ? (openBlock(), createBlock(unref(ElBadge), {
523
+ key: 0,
524
+ value: _ctx.repeatNum,
525
+ type: unref(badgeType),
526
+ class: normalizeClass(unref(ns).e("badge"))
527
+ }, null, 8, ["value", "type", "class"])) : createCommentVNode("v-if", true),
528
+ unref(iconComponent) ? (openBlock(), createBlock(unref(ElIcon), {
529
+ key: 1,
530
+ class: normalizeClass([unref(ns).e("icon"), unref(typeClass)])
531
+ }, {
532
+ default: withCtx(() => [
533
+ (openBlock(), createBlock(resolveDynamicComponent(unref(iconComponent))))
534
+ ]),
535
+ _: 1
536
+ }, 8, ["class"])) : createCommentVNode("v-if", true),
537
+ renderSlot(_ctx.$slots, "default", {}, () => [
538
+ !_ctx.dangerouslyUseHTMLString ? (openBlock(), createElementBlock("p", {
539
+ key: 0,
540
+ class: normalizeClass(unref(ns).e("content"))
541
+ }, toDisplayString(_ctx.message), 3)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
542
+ createCommentVNode(" Caution here, message could've been compromised, never use user's input as message "),
543
+ createElementVNode("p", {
544
+ class: normalizeClass(unref(ns).e("content")),
545
+ innerHTML: _ctx.message
546
+ }, null, 10, ["innerHTML"])
547
+ ], 2112))
548
+ ]),
549
+ _ctx.showClose ? (openBlock(), createBlock(unref(ElIcon), {
550
+ key: 2,
551
+ class: normalizeClass(unref(ns).e("closeBtn")),
552
+ onClick: withModifiers(close, ["stop"])
553
+ }, {
554
+ default: withCtx(() => [
555
+ createVNode(unref(Close))
556
+ ]),
557
+ _: 1
558
+ }, 8, ["class", "onClick"])) : createCommentVNode("v-if", true)
559
+ ], 46, ["id"]), [
560
+ [vShow, visible.value]
561
+ ])
562
+ ]),
563
+ _: 3
564
+ }, 8, ["name", "onBeforeEnter", "onBeforeLeave", "onAfterLeave"]);
565
+ };
566
+ }
567
+ });
568
+ var MessageConstructor = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__file", "message.vue"]]);
569
+ let seed = 1;
570
+ const normalizeOptions = (params) => {
571
+ const options = !params || isString$1(params) || isVNode(params) || isFunction(params) ? { message: params } : params;
572
+ const normalized = {
573
+ ...messageDefaults,
574
+ ...options
575
+ };
576
+ if (!normalized.appendTo) {
577
+ normalized.appendTo = document.body;
578
+ } else if (isString$1(normalized.appendTo)) {
579
+ let appendTo = document.querySelector(normalized.appendTo);
580
+ if (!isElement(appendTo)) {
581
+ appendTo = document.body;
582
+ }
583
+ normalized.appendTo = appendTo;
584
+ }
585
+ if (isBoolean(messageConfig.grouping) && !normalized.grouping) {
586
+ normalized.grouping = messageConfig.grouping;
587
+ }
588
+ if (isNumber(messageConfig.duration) && normalized.duration === 3e3) {
589
+ normalized.duration = messageConfig.duration;
590
+ }
591
+ if (isNumber(messageConfig.offset) && normalized.offset === 16) {
592
+ normalized.offset = messageConfig.offset;
593
+ }
594
+ if (isBoolean(messageConfig.showClose) && !normalized.showClose) {
595
+ normalized.showClose = messageConfig.showClose;
596
+ }
597
+ if (isBoolean(messageConfig.plain) && !normalized.plain) {
598
+ normalized.plain = messageConfig.plain;
599
+ }
600
+ return normalized;
601
+ };
602
+ const closeMessage = (instance) => {
603
+ const idx = instances.indexOf(instance);
604
+ if (idx === -1)
605
+ return;
606
+ instances.splice(idx, 1);
607
+ const { handler } = instance;
608
+ handler.close();
609
+ };
610
+ const createMessage = ({ appendTo, ...options }, context) => {
611
+ const id = `message_${seed++}`;
612
+ const userOnClose = options.onClose;
613
+ const container = document.createElement("div");
614
+ const props = {
615
+ ...options,
616
+ id,
617
+ onClose: () => {
618
+ userOnClose == null ? void 0 : userOnClose();
619
+ closeMessage(instance);
620
+ },
621
+ onDestroy: () => {
622
+ render(null, container);
623
+ }
624
+ };
625
+ const vnode = createVNode(MessageConstructor, props, isFunction(props.message) || isVNode(props.message) ? {
626
+ default: isFunction(props.message) ? props.message : () => props.message
627
+ } : null);
628
+ vnode.appContext = context || message._context;
629
+ render(vnode, container);
630
+ appendTo.appendChild(container.firstElementChild);
631
+ const vm = vnode.component;
632
+ const handler = {
633
+ close: () => {
634
+ vm.exposed.close();
635
+ }
636
+ };
637
+ const instance = {
638
+ id,
639
+ vnode,
640
+ vm,
641
+ handler,
642
+ props: vnode.component.props
643
+ };
644
+ return instance;
645
+ };
646
+ const message = (options = {}, context) => {
647
+ if (!isClient)
648
+ return { close: () => void 0 };
649
+ const normalized = normalizeOptions(options);
650
+ if (normalized.grouping && instances.length) {
651
+ const instance2 = instances.find(({ vnode: vm }) => {
652
+ var _a;
653
+ return ((_a = vm.props) == null ? void 0 : _a.message) === normalized.message;
654
+ });
655
+ if (instance2) {
656
+ instance2.props.repeatNum += 1;
657
+ instance2.props.type = normalized.type;
658
+ return instance2.handler;
659
+ }
660
+ }
661
+ if (isNumber(messageConfig.max) && instances.length >= messageConfig.max) {
662
+ return { close: () => void 0 };
663
+ }
664
+ const instance = createMessage(normalized, context);
665
+ instances.push(instance);
666
+ return instance.handler;
667
+ };
668
+ messageTypes.forEach((type) => {
669
+ message[type] = (options = {}, appContext) => {
670
+ const normalized = normalizeOptions(options);
671
+ return message({ ...normalized, type }, appContext);
672
+ };
673
+ });
674
+ function closeAll(type) {
675
+ const instancesToClose = [...instances];
676
+ for (const instance of instancesToClose) {
677
+ if (!type || type === instance.props.type) {
678
+ instance.handler.close();
679
+ }
680
+ }
681
+ }
682
+ message.closeAll = closeAll;
683
+ message._context = null;
684
+ const ElMessage = withInstallFunction(message, "$message");
685
+ class CommandFlowComponent extends Component {
686
+ _renderer;
687
+ get renderer() {
688
+ if (!this._renderer) this._renderer = this.parent?.findComponentByName("Renderer");
689
+ return this._renderer;
690
+ }
691
+ _domElement;
692
+ get domElement() {
693
+ if (!this._domElement) this._domElement = this.editor?.domContainer?.domElement;
694
+ return this._domElement;
695
+ }
696
+ _editor;
697
+ get editor() {
698
+ if (!this._editor) this._editor = this.parent?.findComponentByName("Editor");
699
+ return this._editor;
700
+ }
701
+ _eventInput;
702
+ get eventInput() {
703
+ if (!this._eventInput) this._eventInput = this.parent?.findComponentByName("EventInput");
704
+ return this._eventInput;
705
+ }
706
+ _renderManager;
707
+ get renderManager() {
708
+ if (!this._renderManager) this._renderManager = this.parent?.findComponentByName("RenderManager");
709
+ return this._renderManager;
710
+ }
711
+ _commandManager;
712
+ get commandManager() {
713
+ if (!this._commandManager) this._commandManager = this.editor?.commandManager;
714
+ return this._commandManager;
715
+ }
716
+ interruptKeys = ["escape"];
717
+ /**
718
+ * 创建中断
719
+ * @returns
720
+ */
721
+ createInterrupt() {
722
+ return (next, data) => {
723
+ this.addEventRecord(
724
+ "clear",
725
+ this.editor?.eventInput.addEventListener("codeChange", async () => {
726
+ if (this.editor.eventInput.isKeyDowns(this.interruptKeys)) {
727
+ this.editor.commandManager.cancel();
728
+ }
729
+ })
730
+ );
731
+ next(data);
732
+ };
733
+ }
734
+ /**
735
+ * 创建鼠标图标变化
736
+ * @param cursor
737
+ * @returns
738
+ */
739
+ createCursor(cursor) {
740
+ return (next, data) => {
741
+ const defaultCursor = this.domElement.style.cursor;
742
+ this.domElement.style.cursor = cursor;
743
+ this.addEventRecord("clear", () => {
744
+ this.domElement.style.cursor = defaultCursor ?? "default";
745
+ });
746
+ next(data);
747
+ };
748
+ }
749
+ /**
750
+ * 创建清理
751
+ * @returns
752
+ */
753
+ createFinally() {
754
+ return () => {
755
+ this.canceEventRecord("clear");
756
+ };
757
+ }
758
+ }
759
+ class DrawLine extends CommandFlowComponent {
760
+ static name = "DrawLine";
761
+ container = new THREE.Group();
762
+ interruptKeys = ["escape"];
763
+ withdrawalKeys = ["control", "z"];
764
+ shortcutKeys = ["control", "l"];
765
+ confirmKeys = ["enter"];
766
+ commandName = "draw-line";
767
+ onAddFromParent() {
768
+ this.editor.container.add(this.container);
769
+ const commandFlow = this.commandManager.addCommandFlow(this.commandName).add(this.createInterrupt()).add(this.createCursor("crosshair")).add(this.selectPoint.bind(this));
770
+ commandFlow.addEventListener("finally", this.createFinally());
771
+ commandFlow.addEventListener("completed", (e) => this.completed(e.data));
772
+ this.eventInput.addKeyCombination(this.commandName, this.shortcutKeys);
773
+ this.eventInput.addEventListener("codeChange", async () => this.eventInput.isKeyCombination(this.commandName) && await this.commandManager.start(this.commandName));
774
+ this.eventInput.addCancelDefaultBehavior(() => this.eventInput.isOnlyKeyDowns(this.shortcutKeys));
775
+ }
776
+ /** 选择点
777
+ * @param next
778
+ */
779
+ selectPoint(next) {
780
+ let editor = this.parent?.findComponentByName("Editor"), start = null, end = null, points = [], circle = new THREE.Mesh(new THREE.SphereGeometry(0.05), new THREE.MeshBasicMaterial({ color: 65280 })), dom = editor.domContainer.domElement, line = new Lines([], 16711935), auxiliaryLine = new Lines([
781
+ new THREE.Vector3(-1e4, 0, 0),
782
+ new THREE.Vector3(1e4, 0, 0),
783
+ new THREE.Vector3(0, -1e4, 0),
784
+ new THREE.Vector3(0, 1e4, 0)
785
+ ], 16711935);
786
+ auxiliaryLine.material = new THREE.LineDashedMaterial({
787
+ color: 4235007,
788
+ dashSize: 0.1,
789
+ gapSize: 0.1,
790
+ linewidth: 0.1
791
+ });
792
+ this.container.add(line);
793
+ const updateLine = () => {
794
+ line.setPoint(...points, start, end);
795
+ auxiliaryLine.position.copy(end);
796
+ this.container.add(auxiliaryLine);
797
+ auxiliaryLine.computeLineDistances();
798
+ };
799
+ const currentPoint = new THREE.Vector3();
800
+ this.addEventRecord(
801
+ "clear",
802
+ editor.addEventListener("pointerPositionChange", () => {
803
+ const { point, find } = editor.renderManager.adsorption();
804
+ if (find) {
805
+ circle.position.set(point.x, point.y, 0);
806
+ this.container.add(circle);
807
+ dom.style.cursor = "none";
808
+ } else {
809
+ circle.removeFromParent();
810
+ dom.style.cursor = "crosshair";
811
+ }
812
+ currentPoint.copy(point);
813
+ if (!(start && end)) return;
814
+ if (editor.eventInput.isKeyDown("shift")) {
815
+ const x = Math.abs(editor.pointerPosition.x - start.x), y = Math.abs(editor.pointerPosition.y - start.y);
816
+ if (x > y) end.set(editor.pointerPosition.x, start.y, 0);
817
+ else end.set(start.x, editor.pointerPosition.y, 0);
818
+ updateLine();
819
+ currentPoint.copy(end);
820
+ return;
821
+ }
822
+ end.set(editor.pointerPosition.x, editor.pointerPosition.y, 0);
823
+ updateLine();
824
+ }),
825
+ editor.eventInput.addEventListener("codeChange", async () => {
826
+ if (editor.eventInput.isKeyDown("mouse_0")) {
827
+ if (!start) {
828
+ start = currentPoint.clone();
829
+ end = currentPoint.clone();
830
+ updateLine();
831
+ return;
832
+ }
833
+ end = currentPoint.clone();
834
+ points.push(start.clone(), end.clone());
835
+ start.copy(end);
836
+ updateLine();
837
+ } else if (editor.eventInput.isOnlyKeyDowns(this.withdrawalKeys)) {
838
+ if (points.length) {
839
+ const { point } = editor.renderManager.adsorption();
840
+ points.pop();
841
+ end?.copy(point);
842
+ start?.copy(points.pop());
843
+ updateLine();
844
+ }
845
+ } else if (editor.eventInput.isKeyDowns(this.confirmKeys)) next(points);
846
+ }),
847
+ function() {
848
+ line.removeFromParent();
849
+ circle.removeFromParent();
850
+ auxiliaryLine.removeFromParent();
851
+ }
852
+ );
853
+ }
854
+ /** 执行完成
855
+ */
856
+ completed(points) {
857
+ const editor = this.editor, lines = [];
858
+ for (let i = 0; i < points.length; i += 2) {
859
+ lines.push(new LineSegment(Point.from(points[i]), Point.from(points[i + 1])));
860
+ }
861
+ editor.renderManager.addLines(lines);
862
+ editor.renderManager.draw();
863
+ }
864
+ }
865
+ class Default extends Component {
866
+ static name = "Default";
867
+ get editor() {
868
+ return this.parent?.findComponentByName("Editor");
869
+ }
870
+ renderer;
871
+ container = new THREE.Group();
872
+ onAddFromParent() {
873
+ const editor = this.editor, commandManager = editor.commandManager;
874
+ this.renderer = this.parent?.findComponentByName("Renderer");
875
+ editor.container.add(this.container);
876
+ commandManager.addCommandFlow("default").add(this.start.bind(this)).addEventListener("finally", this.finally.bind(this));
877
+ commandManager.addEventListener("startedBefore", (e) => {
878
+ if (e.currentName === "default" && e.name !== "default") commandManager.cancel();
879
+ });
880
+ commandManager.addEventListener("finally", (e) => e.name !== "default" && commandManager.start("default"));
881
+ editor.eventInput.addCancelDefaultBehavior(() => editor.eventInput.isOnlyKeyDowns(["control", "g"]));
882
+ }
883
+ selectLines = [];
884
+ selectLineObject3D = new THREE.Mesh();
885
+ /** 添加选择的线段
886
+ * @param lineSegment
887
+ */
888
+ addSelectLine(lineSegment) {
889
+ if (this.selectLines.indexOf(lineSegment) > -1) return;
890
+ this.selectLines.push(lineSegment);
891
+ this.updateSelectLinesGeometry();
892
+ }
893
+ /** 移除选择的线段
894
+ * @param lineSegment
895
+ */
896
+ removeSelectLine(lineSegment) {
897
+ const i = this.selectLines.indexOf(lineSegment);
898
+ if (i > -1) {
899
+ this.selectLines.splice(i, 1);
900
+ this.updateSelectLinesGeometry();
901
+ }
902
+ }
903
+ /**
904
+ * 删除选择的线段
905
+ */
906
+ deleteSelectLine() {
907
+ const editor = this.editor;
908
+ this.selectLines.forEach((line) => editor.renderManager.removeLine(line));
909
+ this.selectLines.length = 0;
910
+ this.updateSelectLinesGeometry();
911
+ ElMessage({ message: "删除成功", type: "success" });
912
+ }
913
+ /**
914
+ * 删除选择线段上的窗户
915
+ */
916
+ deleteSelectWindow() {
917
+ let is = false;
918
+ this.selectLines.forEach((line) => {
919
+ if (!line.userData.isWindow) return;
920
+ line.userData = {};
921
+ is = true;
922
+ });
923
+ this.editor.renderManager.draw();
924
+ is && ElMessage({ message: "删除窗户成功", type: "success" });
925
+ }
926
+ /**
927
+ * 如果只选择两个线段,可为两个未链接的点创建连接
928
+ */
929
+ connection() {
930
+ if (this.selectLines.length !== 2) {
931
+ ElMessage({ message: "连接失败,请选择两个线段", type: "warning" });
932
+ return;
933
+ }
934
+ const editor = this.editor;
935
+ let start, end, diatance = Infinity;
936
+ for (let i = 0; i < 2; i++)
937
+ for (let j = 0; j < 2; j++) {
938
+ const point1 = this.selectLines[0].points[i];
939
+ const point2 = this.selectLines[1].points[j];
940
+ const d = point1.distance(point2);
941
+ if (d < diatance) {
942
+ start = point1;
943
+ end = point2;
944
+ diatance = d;
945
+ }
946
+ }
947
+ if (start && end) {
948
+ const line = new LineSegment(start.clone(), end.clone());
949
+ editor.renderManager.addLine(line);
950
+ editor.renderManager.draw();
951
+ ElMessage({ message: "连接成功", type: "success" });
952
+ }
953
+ }
954
+ /**
955
+ * 如果只选择两个线段,可为两个未链接的点创建连接, 通过计算交点,线段延长到交点
956
+ */
957
+ intersectionConnection() {
958
+ if (this.selectLines.length !== 2) {
959
+ ElMessage({ message: "连接失败,请选择两个线段", type: "warning" });
960
+ return;
961
+ }
962
+ const editor = this.editor, line1 = this.selectLines[0], line2 = this.selectLines[1], point = this.selectLines[0].getIntersection(this.selectLines[1]);
963
+ if (!point) return;
964
+ editor.renderManager.removeLine(line1);
965
+ editor.renderManager.removeLine(line2);
966
+ if (line1.start.distance(point) < line1.end.distance(point)) {
967
+ line1.start.copy(point);
968
+ } else {
969
+ line1.end.copy(point);
970
+ }
971
+ if (line2.start.distance(point) < line2.end.distance(point)) {
972
+ line2.start.copy(point);
973
+ } else {
974
+ line2.end.copy(point);
975
+ }
976
+ editor.renderManager.addLines([line1, line2]);
977
+ editor.renderManager.draw();
978
+ ElMessage({ message: "连接成功", type: "success" });
979
+ }
980
+ /**
981
+ * 如果只选择两个线段, 且两个线段在一条路径上,合并线段
982
+ */
983
+ mergeLine() {
984
+ if (this.selectLines.length !== 2) {
985
+ ElMessage({ message: "未执行线段合并,请选择两条线段", type: "warning" });
986
+ return;
987
+ }
988
+ const editor = this.editor, line1 = this.selectLines[0], line2 = this.selectLines[1];
989
+ for (let i = 0; i < line1.points.length; i++) {
990
+ const p1 = line1.points[i];
991
+ for (let j = 0; j < line2.points.length; j++) {
992
+ const p2 = line2.points[j];
993
+ if (p1.equal(p2)) {
994
+ const p1Next = line1.points[(i + 1) % 2];
995
+ const p2Next = line2.points[(j + 1) % 2];
996
+ editor.renderManager.removeLine(line1);
997
+ editor.renderManager.removeLine(line2);
998
+ const line = new LineSegment(p1Next, p2Next);
999
+ editor.renderManager.addLine(line);
1000
+ editor.renderManager.draw();
1001
+ ElMessage({ message: "已合并", type: "success" });
1002
+ return;
1003
+ }
1004
+ }
1005
+ }
1006
+ ElMessage({ message: "合并失败,两条线未找到共用点", type: "warning" });
1007
+ }
1008
+ _timer = null;
1009
+ /**
1010
+ * 更新选择的线段
1011
+ */
1012
+ updateSelectLinesGeometry() {
1013
+ if (this._timer) clearTimeout(this._timer);
1014
+ this._timer = setTimeout(() => {
1015
+ if (this.selectLines.length) this.container.add(this.selectLineObject3D);
1016
+ else this.selectLineObject3D.removeFromParent();
1017
+ const editor = this.editor;
1018
+ const position = this.selectLines.flatMap((line) => line.expandToRectangle(0.04, "bothSides").createGeometry());
1019
+ this.selectLineObject3D.geometry = editor.renderManager.createGeometry({ position }, position.length / 3);
1020
+ }, 10);
1021
+ }
1022
+ /**
1023
+ * 开始执行
1024
+ * @param next
1025
+ */
1026
+ start() {
1027
+ const editor = this.editor, eventInput = editor.eventInput, object3D = new THREE.Mesh(), dom = editor.domContainer.domElement;
1028
+ let currentSelectLine = null;
1029
+ object3D.position.z = 0.01;
1030
+ this.selectLineObject3D.position.z = object3D.position.z + 0.01;
1031
+ object3D.material = new THREE.MeshBasicMaterial({ color: 55561 });
1032
+ eventInput.addKeyCombination("intersectionConnection", ["control", "shift", "l"]);
1033
+ eventInput.addKeyCombination("connection", ["shift", "l"]);
1034
+ eventInput.addKeyCombination("mergeLine", ["control", "g"]);
1035
+ this.addEventRecord("clear", () => {
1036
+ eventInput.removeKeyCombination("intersectionConnection");
1037
+ eventInput.removeKeyCombination("connection");
1038
+ eventInput.removeKeyCombination("mergeLine");
1039
+ });
1040
+ const showSelectBox = () => {
1041
+ const startPoint = editor.pointerPosition.clone(), endPoint = editor.pointerPosition.clone(), mesh = new THREE.Mesh();
1042
+ this.container.add(mesh);
1043
+ mesh.position.z = 0.05;
1044
+ mesh.material = new THREE.MeshBasicMaterial({
1045
+ color: 16777215,
1046
+ transparent: true,
1047
+ opacity: 0.5
1048
+ });
1049
+ const update = () => {
1050
+ const minX = Math.min(startPoint.x, endPoint.x), maxX = Math.max(startPoint.x, endPoint.x), minY = Math.min(startPoint.y, endPoint.y), maxY = Math.max(startPoint.y, endPoint.y);
1051
+ const position = [
1052
+ minX,
1053
+ maxY,
1054
+ 0,
1055
+ maxX,
1056
+ minY,
1057
+ 0,
1058
+ maxX,
1059
+ maxY,
1060
+ 0,
1061
+ minX,
1062
+ maxY,
1063
+ 0,
1064
+ minX,
1065
+ minY,
1066
+ 0,
1067
+ maxX,
1068
+ minY,
1069
+ 0
1070
+ ];
1071
+ mesh.geometry = editor.renderManager.createGeometry({ position }, position.length / 3);
1072
+ };
1073
+ const move = () => {
1074
+ endPoint.copy(editor.pointerPosition);
1075
+ update();
1076
+ };
1077
+ const end = () => {
1078
+ document.removeEventListener("mousemove", move);
1079
+ document.removeEventListener("mouseup", end);
1080
+ mesh.removeFromParent();
1081
+ const minX = Math.min(startPoint.x, endPoint.x), maxX = Math.max(startPoint.x, endPoint.x), minY = Math.min(startPoint.y, endPoint.y), maxY = Math.max(startPoint.y, endPoint.y);
1082
+ const box = new Box2(minX, maxX, minY, maxY);
1083
+ const resultList = editor.renderManager.quadtree.queryBox(box);
1084
+ this.selectLines.length = 0;
1085
+ resultList.forEach((result) => this.addSelectLine(result.line));
1086
+ this.updateSelectLinesGeometry();
1087
+ };
1088
+ document.addEventListener("mousemove", move);
1089
+ document.addEventListener("mouseup", end);
1090
+ };
1091
+ this.addEventRecord(
1092
+ "clear",
1093
+ // 注册鼠标指针位置变化事件
1094
+ editor.addEventListener("pointerPositionChange", () => {
1095
+ const { line } = editor.renderManager.adsorption(0.05);
1096
+ if (line) {
1097
+ const rectangle = line.expandToRectangle(0.02, "bothSides");
1098
+ object3D.geometry = editor.renderManager.createGeometry({ position: rectangle.createGeometry() }, 6);
1099
+ this.container.add(object3D);
1100
+ dom.style.cursor = "pointer";
1101
+ currentSelectLine = line;
1102
+ } else {
1103
+ object3D.removeFromParent();
1104
+ dom.style.cursor = "default";
1105
+ currentSelectLine = null;
1106
+ }
1107
+ }),
1108
+ eventInput.addEventListener("codeChange", () => {
1109
+ if (eventInput.isKeyDown("mouse_0")) {
1110
+ if (!currentSelectLine) return showSelectBox();
1111
+ if (eventInput.isKeyDown("alt")) {
1112
+ return this.removeSelectLine(currentSelectLine);
1113
+ }
1114
+ if (!eventInput.isKeyDown("control")) this.selectLines.length = 0;
1115
+ this.addSelectLine(currentSelectLine);
1116
+ } else if (eventInput.isOnlyKeyDown("delete")) {
1117
+ this.deleteSelectLine();
1118
+ } else if (eventInput.isKeyDowns(["q", "delete"])) {
1119
+ this.deleteSelectWindow();
1120
+ } else if (eventInput.isKeyCombination("connection")) {
1121
+ this.connection();
1122
+ } else if (eventInput.isKeyCombination("intersectionConnection")) {
1123
+ this.intersectionConnection();
1124
+ } else if (eventInput.isKeyCombination("mergeLine")) {
1125
+ this.mergeLine();
1126
+ }
1127
+ }),
1128
+ function() {
1129
+ object3D.removeFromParent();
1130
+ }
1131
+ );
1132
+ }
1133
+ /**
1134
+ * 清理
1135
+ */
1136
+ finally() {
1137
+ this.canceEventRecord("clear");
1138
+ this.selectLines.length = 0;
1139
+ this.updateSelectLinesGeometry();
1140
+ }
1141
+ }
1142
+ class CommandFlow extends EventDispatcher {
1143
+ list = [];
1144
+ add(operation) {
1145
+ this.list.push(operation);
1146
+ return this;
1147
+ }
1148
+ }
1149
+ class CommandManager extends EventDispatcher {
1150
+ commandFlowMap = /* @__PURE__ */ new Map();
1151
+ lock = false;
1152
+ abortController = null;
1153
+ resolve = null;
1154
+ currentName = null;
1155
+ _disabled = false;
1156
+ set disabled(disabled) {
1157
+ this._disabled = disabled;
1158
+ if (this._disabled) this.cancel();
1159
+ }
1160
+ get disabled() {
1161
+ return this._disabled;
1162
+ }
1163
+ constructor() {
1164
+ super();
1165
+ }
1166
+ /** 添加命令流
1167
+ * @param name
1168
+ * @returns
1169
+ */
1170
+ addCommandFlow(name) {
1171
+ if (this.commandFlowMap.has(name)) throw new Error(`${name} 命令已经存在`);
1172
+ const commandFlow = new CommandFlow();
1173
+ this.commandFlowMap.set(name, commandFlow);
1174
+ return commandFlow;
1175
+ }
1176
+ executionPromise = null;
1177
+ executionResolve = null;
1178
+ /** 执行控制流
1179
+ * @param name
1180
+ * @returns
1181
+ */
1182
+ async start(name, data = null, step = 0) {
1183
+ if (this.disabled) throw new Error("命令管理器已禁用,无法启动新的命令流");
1184
+ this.dispatchEvent({
1185
+ type: "startedBefore",
1186
+ name,
1187
+ currentName: this.currentName
1188
+ });
1189
+ this.executionPromise && await this.executionPromise;
1190
+ this.executionPromise = null;
1191
+ if (this.lock) {
1192
+ throw new Error("命令管理器已被锁定,无法启动新的命令流");
1193
+ }
1194
+ const commandFlow = this.commandFlowMap.get(name);
1195
+ if (!commandFlow) {
1196
+ throw new Error(`命令流 ${name} 不存在`);
1197
+ }
1198
+ this.lock = true;
1199
+ this.abortController = new AbortController();
1200
+ this.currentName = name;
1201
+ commandFlow.dispatchEvent({ type: "started" });
1202
+ this.dispatchEvent({ type: "started", name });
1203
+ try {
1204
+ for (let i = step; i < commandFlow.list.length; i++) {
1205
+ const operation = commandFlow.list[i];
1206
+ commandFlow.dispatchEvent({ type: "executing", index: i });
1207
+ this.dispatchEvent({ type: "executing", name, index: i });
1208
+ data = await new Promise((resolve) => {
1209
+ this.resolve = resolve;
1210
+ operation(resolve, data);
1211
+ });
1212
+ if (this.abortController.signal.aborted) {
1213
+ commandFlow.dispatchEvent({ type: "executionInterrupt", index: i });
1214
+ this.dispatchEvent({ type: "executionInterrupt", name, index: i });
1215
+ this.dispatchEvent({ type: "cancel", name });
1216
+ break;
1217
+ } else {
1218
+ commandFlow.dispatchEvent({ type: "executionCompleted", index: i, data });
1219
+ this.dispatchEvent({ type: "executionCompleted", name, index: i, data });
1220
+ }
1221
+ }
1222
+ } catch (error) {
1223
+ console.error(error);
1224
+ } finally {
1225
+ if (this.abortController && !this.abortController.signal.aborted) {
1226
+ commandFlow.dispatchEvent({ type: "completed", data });
1227
+ this.dispatchEvent({ type: "completed", name, data });
1228
+ }
1229
+ this.lock = false;
1230
+ this.abortController = null;
1231
+ this.currentName = null;
1232
+ commandFlow.dispatchEvent({ type: "finally" });
1233
+ this.dispatchEvent({ type: "finally", name });
1234
+ if (this.executionResolve) {
1235
+ this.executionResolve(null);
1236
+ this.executionResolve = null;
1237
+ }
1238
+ }
1239
+ return data;
1240
+ }
1241
+ /** 取消当前命令
1242
+ */
1243
+ cancel() {
1244
+ if (this.abortController) {
1245
+ this.abortController.abort();
1246
+ if (this.resolve) this.resolve();
1247
+ this.executionPromise = new Promise((resolve) => this.executionResolve = resolve);
1248
+ }
1249
+ }
1250
+ }
1251
+ const _imports_0 = "data:image/svg+xml,%3c?xml%20version='1.0'%20standalone='no'?%3e%3c!DOCTYPE%20svg%20PUBLIC%20'-//W3C//DTD%20SVG%201.1//EN'%20'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3e%3csvg%20t='1757902422799'%20class='icon'%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='1735'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20width='200'%20height='200'%3e%3cpath%20d='M843.2%20726.4c-20.2%200-39.2%205.2-55.8%2014.3L283.8%20237.2c9-16.5%2014.1-35.4%2014.1-55.5%200-64.2-52.3-116.5-116.5-116.5S65%20117.4%2065%20181.6s52.3%20116.5%20116.5%20116.5c20.2%200%2039.2-5.2%2055.8-14.2l503.5%20503.5c-9%2016.5-14.1%2035.4-14.1%2055.5%200%2064.2%2052.3%20116.5%20116.5%20116.5s116.5-52.3%20116.5-116.5-52.3-116.5-116.5-116.5zM181.4%20232.1c-27.8%200-50.5-22.6-50.5-50.5s22.6-50.5%2050.5-50.5%2050.5%2022.6%2050.5%2050.5-22.6%2050.5-50.5%2050.5z%20m661.8%20661.3c-27.8%200-50.5-22.6-50.5-50.5%200-27.8%2022.6-50.5%2050.5-50.5s50.5%2022.6%2050.5%2050.5c0%2027.8-22.7%2050.5-50.5%2050.5z'%20fill='%23231815'%20p-id='1736'%3e%3c/path%3e%3c/svg%3e";
1252
+ const _hoisted_1 = { class: "mt-[5px] text-[#888] text-[10px] absolute left-[10px] bottom-[10px] rounded-[8px] min-w-[150px] bg-black/15 p-[10px]" };
1253
+ const _hoisted_2 = { class: "inline-block ml-[10px]" };
1254
+ const _hoisted_3 = { class: "flex p-[5px_0px] flex-row header text-[14px] font-bold p-[10px 0px] border-b-1 border-b-[#eee]" };
1255
+ const _hoisted_4 = { class: "p-[5px]" };
1256
+ const _hoisted_5 = { class: "mt-[10px] text-[14px] flex flex-col" };
1257
+ const _hoisted_6 = { class: "flex flex-row items-center gap-[10px] mt-[10px]" };
1258
+ const _sfc_main = /* @__PURE__ */ defineComponent({
1259
+ __name: "EditorTool",
1260
+ props: {
1261
+ dxfSystem: {}
1262
+ },
1263
+ setup(__props) {
1264
+ const props = __props;
1265
+ const originalLineVisible = ref(true), dxfVisible = ref(true), whiteModelVisible = ref(true), isLook = ref(false), elRef = ref(), toolBarRef = ref(), dxfSystem = toRaw(props.dxfSystem), domEventRegister = dxfSystem.findComponentByType(DomEventRegister), toolBarPosition = ref({ left: 10, top: 10 }), shortcutKeys = [
1266
+ { "name": "绘制连续线段", "shortcut": "Ctrl + L" },
1267
+ { "name": "绘制线段确认", "shortcut": "Enter" },
1268
+ { "name": "绘制门线", "shortcut": "Ctrl + M" },
1269
+ { "name": "绘制窗户线", "shortcut": "Ctrl + Q" },
1270
+ { "name": "移动线段点", "shortcut": "Ctrl + P" },
1271
+ { "name": "删除线段", "shortcut": "选中 + Delete" },
1272
+ { "name": "删除窗户线", "shortcut": "选中 + Q + Delete" },
1273
+ { "name": "选中", "shortcut": "鼠标左键" },
1274
+ { "name": "多选", "shortcut": "鼠标左键 + Ctrl" },
1275
+ { "name": "取消选中", "shortcut": "鼠标左键 + Alt" },
1276
+ { "name": "框选", "shortcut": "鼠标左键 + 移动" },
1277
+ { "name": "线段同方向合并", "shortcut": "Ctrl + G" },
1278
+ { "name": "线段连接", "shortcut": "选中 + Shift + L" },
1279
+ { "name": "线段交点连接", "shortcut": "选中 + Ctrl + Shift + L" },
1280
+ { "name": "取消命令", "shortcut": "Esc" }
1281
+ ];
1282
+ watchEffect(() => localStorage.setItem("EditorToolPosition", JSON.stringify(toolBarPosition.value)));
1283
+ function setEditorToolPosition(left, top) {
1284
+ const dom = elRef.value, toolBarDom = elRef.value, rect = dom.getBoundingClientRect(), toolBarRect = toolBarDom.getBoundingClientRect(), minX = 0, maxX = toolBarRect.width - rect.width, minY = 0, maxY = toolBarRect.height - rect.height;
1285
+ left = Math.max(minX, Math.min(left, maxX));
1286
+ top = Math.max(minY, Math.min(top, maxY));
1287
+ toolBarPosition.value = { left, top };
1288
+ console.log(left, top);
1289
+ }
1290
+ function setLines(lines) {
1291
+ if (lines) {
1292
+ localStorage.setItem("lines", JSON.stringify(lines));
1293
+ try {
1294
+ dxfSystem.Dxf.set(lines);
1295
+ dxfSystem.Dxf.lineOffset();
1296
+ } catch (error) {
1297
+ console.log(error);
1298
+ }
1299
+ }
1300
+ }
1301
+ async function selectLocalFile() {
1302
+ const data = await SelectLocalFile.json();
1303
+ if (Array.isArray(data)) {
1304
+ localStorage.removeItem("orbitControls");
1305
+ setLines(data);
1306
+ }
1307
+ }
1308
+ function dragMoveHelper(e) {
1309
+ domEventRegister.mouseMoveEventProxylock = true;
1310
+ const cusor = document.body.style.cursor;
1311
+ document.body.style.cursor = "move";
1312
+ const move = (e2) => {
1313
+ setEditorToolPosition(
1314
+ toolBarPosition.value.left + e2.movementX,
1315
+ toolBarPosition.value.top + e2.movementY
1316
+ );
1317
+ e2.stopPropagation();
1318
+ document.body.style.cursor = "move";
1319
+ };
1320
+ const end = () => {
1321
+ document.body.removeEventListener("mousemove", move);
1322
+ document.body.removeEventListener("mouseup", end);
1323
+ document.body.style.cursor = cusor;
1324
+ domEventRegister.mouseMoveEventProxylock = false;
1325
+ };
1326
+ document.body.addEventListener("mousemove", move);
1327
+ document.body.addEventListener("mouseup", end);
1328
+ }
1329
+ watch(originalLineVisible, () => dxfSystem.Variable.set("originalLineVisible", originalLineVisible.value));
1330
+ watch(dxfVisible, () => dxfSystem.Variable.set("dxfVisible", dxfVisible.value));
1331
+ watch(whiteModelVisible, () => dxfSystem.Variable.set("whiteModelVisible", whiteModelVisible.value));
1332
+ dxfSystem.Variable.addEventListener("isLook", (e) => isLook.value = e.value);
1333
+ dxfSystem.Variable.addEventListener("originalLineVisible", (e) => originalLineVisible.value = e.value);
1334
+ dxfSystem.Variable.addEventListener("dxfVisible", (e) => dxfVisible.value = e.value);
1335
+ dxfSystem.Variable.addEventListener("whiteModelVisible", (e) => whiteModelVisible.value = e.value);
1336
+ onMounted(() => {
1337
+ if (localStorage.getItem("EditorToolPosition")) {
1338
+ const { left, top } = JSON.parse(localStorage.getItem("EditorToolPosition") ?? "{}");
1339
+ setEditorToolPosition(left, top);
1340
+ }
1341
+ });
1342
+ onUnmounted(() => {
1343
+ domEventRegister.mouseMoveEventProxylock = false;
1344
+ });
1345
+ return (_ctx, _cache) => {
1346
+ return openBlock(), createElementBlock("div", {
1347
+ ref_key: "elRef",
1348
+ ref: elRef,
1349
+ class: "pointer-events-none overflow-hidden absolute left-0 top-0 w-full h-full z-[10000] flex flex-row justify-between p-[5px] box-border select-none pointer-events-[all]"
1350
+ }, [
1351
+ createElementVNode("div", _hoisted_1, [
1352
+ (openBlock(), createElementBlock(Fragment, null, renderList(shortcutKeys, (item) => {
1353
+ return createElementVNode("p", {
1354
+ class: "p-[2px_0px] flex justify-between text-right border-b-1 border-b-[rgba(255,255,255,0.1)] last-of-type:border-b-0",
1355
+ key: item.name
1356
+ }, [
1357
+ createTextVNode(toDisplayString(item.name) + ": ", 1),
1358
+ createElementVNode("span", _hoisted_2, toDisplayString(item.shortcut), 1)
1359
+ ]);
1360
+ }), 64))
1361
+ ]),
1362
+ createElementVNode("div", {
1363
+ ref_key: "toolBarRef",
1364
+ ref: toolBarRef,
1365
+ style: normalizeStyle({ left: toolBarPosition.value.left + "px", top: toolBarPosition.value.top + "px" }),
1366
+ class: "pointer-events-auto text-[#333] absolute rounded-[8px] min-w-[140px] z-[1000] bg-white select-none"
1367
+ }, [
1368
+ createElementVNode("div", _hoisted_3, [
1369
+ (openBlock(), createElementBlock("svg", {
1370
+ onMousedown: dragMoveHelper,
1371
+ class: "m-[0px_5px]",
1372
+ fill: "#aaa",
1373
+ width: "20",
1374
+ height: "20",
1375
+ viewBox: "0 0 1024 1024",
1376
+ version: "1.1",
1377
+ xmlns: "http://www.w3.org/2000/svg"
1378
+ }, _cache[2] || (_cache[2] = [
1379
+ createElementVNode("path", { d: "M341.333333 298.666667a85.333333 85.333333 0 1 0 0-170.666667 85.333333 85.333333 0 0 0 0 170.666667z m0 298.666666a85.333333 85.333333 0 1 0 0-170.666666 85.333333 85.333333 0 0 0 0 170.666666z m85.333334 213.333334a85.333333 85.333333 0 1 1-170.666667 0 85.333333 85.333333 0 0 1 170.666667 0z m256-512a85.333333 85.333333 0 1 0 0-170.666667 85.333333 85.333333 0 0 0 0 170.666667z m85.333333 213.333333a85.333333 85.333333 0 1 1-170.666667 0 85.333333 85.333333 0 0 1 170.666667 0z m-85.333333 384a85.333333 85.333333 0 1 0 0-170.666667 85.333333 85.333333 0 0 0 0 170.666667z" }, null, -1)
1380
+ ]), 32)),
1381
+ _cache[3] || (_cache[3] = createElementVNode("span", null, "小工具", -1))
1382
+ ]),
1383
+ createElementVNode("div", _hoisted_4, [
1384
+ createElementVNode("ul", _hoisted_5, [
1385
+ (openBlock(), createElementBlock(Fragment, null, renderList(4, (i) => {
1386
+ return createElementVNode("li", {
1387
+ key: i,
1388
+ class: "hover:bg-[#ddd] transition-all rounded-[6px] p-[5px] flex flex-row items-center cursor-pointer"
1389
+ }, _cache[4] || (_cache[4] = [
1390
+ createElementVNode("div", { class: "p-[5px] bg-[#f0f0f0] rounded-[6px] mr-[10px]" }, [
1391
+ createElementVNode("img", {
1392
+ class: "w-[20px] h-[20px]",
1393
+ src: _imports_0,
1394
+ alt: "",
1395
+ srcset: ""
1396
+ })
1397
+ ], -1),
1398
+ createElementVNode("span", null, "直线", -1)
1399
+ ]));
1400
+ }), 64))
1401
+ ]),
1402
+ createElementVNode("div", _hoisted_6, [
1403
+ createVNode(unref(ElCheckbox), {
1404
+ modelValue: dxfVisible.value,
1405
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => dxfVisible.value = $event),
1406
+ label: "dxf"
1407
+ }, null, 8, ["modelValue"]),
1408
+ createVNode(unref(ElButton), {
1409
+ size: "small",
1410
+ type: "success",
1411
+ onClick: selectLocalFile
1412
+ }, {
1413
+ default: withCtx(() => _cache[5] || (_cache[5] = [
1414
+ createTextVNode(" 选择文件 ", -1)
1415
+ ])),
1416
+ _: 1,
1417
+ __: [5]
1418
+ }),
1419
+ createVNode(unref(ElButton), {
1420
+ size: "small",
1421
+ type: "primary",
1422
+ onClick: _cache[1] || (_cache[1] = ($event) => unref(dxfSystem).Dxf.download("test.dxf"))
1423
+ }, {
1424
+ default: withCtx(() => _cache[6] || (_cache[6] = [
1425
+ createTextVNode(" 下载 DXF ", -1)
1426
+ ])),
1427
+ _: 1,
1428
+ __: [6]
1429
+ })
1430
+ ])
1431
+ ])
1432
+ ], 4)
1433
+ ], 512);
1434
+ };
1435
+ }
1436
+ });
1437
+ let Editor$1 = class Editor extends Component {
1438
+ static name = "Editor";
1439
+ container = new THREE.Group();
1440
+ get renderer() {
1441
+ return this.parent?.findComponentByName("Renderer");
1442
+ }
1443
+ get dxf() {
1444
+ return this.parent?.findComponentByName("Dxf");
1445
+ }
1446
+ get variable() {
1447
+ return this.parent?.findComponentByName("Variable");
1448
+ }
1449
+ get eventInput() {
1450
+ return this.parent?.findComponentByName("EventInput");
1451
+ }
1452
+ get renderManager() {
1453
+ return this.parent?.findComponentByName("RenderManager");
1454
+ }
1455
+ get domEventRegister() {
1456
+ return this.parent?.findComponentByName("DomEventRegister");
1457
+ }
1458
+ get domContainer() {
1459
+ return this.parent?.findComponentByName("DomContainer");
1460
+ }
1461
+ commandManager = new CommandManager();
1462
+ plane = new THREE.Mesh(new THREE.PlaneGeometry(2e3, 2e3, 2, 2));
1463
+ app;
1464
+ domElement = document.createElement("div");
1465
+ onAddFromParent() {
1466
+ setTimeout(() => this.openEdit(), 10);
1467
+ const grid = new THREE.GridHelper(200, 100, 6710886, 4473924);
1468
+ grid.rotation.x = Math.PI * 0.5;
1469
+ grid.position.z = -0.01;
1470
+ this.container.add(grid);
1471
+ this.container.add(this.plane);
1472
+ this.plane.visible = false;
1473
+ this.app = createApp(_sfc_main, { dxfSystem: this.parent });
1474
+ this.app.mount(this.domElement);
1475
+ const cancelEvent = this.addEventListener("update", () => {
1476
+ if (this.domContainer.domElement.parentElement) {
1477
+ this.domContainer.domElement.parentElement.appendChild(this.domElement);
1478
+ cancelEvent();
1479
+ }
1480
+ });
1481
+ }
1482
+ coords = new THREE.Vector2();
1483
+ pointerPosition = new THREE.Vector2();
1484
+ _exitEditCallBack;
1485
+ /**
1486
+ * 打开编辑器
1487
+ */
1488
+ openEdit() {
1489
+ const renderer = this.renderer, domEventRegister = this.domEventRegister, dxf = this.dxf, orbitControls = renderer.orbitControls, camera = renderer.camera, center = dxf.box.center, cameraPosition = renderer.camera.position.clone(), target = orbitControls?.target?.clone(), size = new THREE.Vector2(), raycaster = new THREE.Raycaster(), coords = this.coords, pointerPosition = this.pointerPosition;
1490
+ this.container.position.z = dxf.originalZAverage;
1491
+ renderer.scene.add(this.container);
1492
+ camera.position.set(center.x, center.y, 14);
1493
+ if (orbitControls) {
1494
+ orbitControls.target.set(center.x, center.y, 0);
1495
+ orbitControls.enableRotate = false;
1496
+ }
1497
+ const mousemoveFun = () => {
1498
+ renderer.renderer.getSize(size);
1499
+ const x = domEventRegister.pointer.x / size.x * 2 - 1;
1500
+ const y = -(domEventRegister.pointer.y / size.y * 2 - 1);
1501
+ coords.set(x, y);
1502
+ raycaster.setFromCamera(coords, renderer.camera);
1503
+ const intersections = raycaster.intersectObject(this.plane);
1504
+ if (intersections.length) {
1505
+ pointerPosition.copy(intersections[0].point);
1506
+ this.dispatchEvent({
1507
+ type: "pointerPositionChange",
1508
+ position: pointerPosition
1509
+ });
1510
+ }
1511
+ };
1512
+ domEventRegister.addEventListener("mousemove", mousemoveFun);
1513
+ this.commandManager.disabled = false;
1514
+ this.commandManager.start("default");
1515
+ this._exitEditCallBack = () => {
1516
+ domEventRegister.removeEventListener("mousemove", mousemoveFun);
1517
+ camera.position.copy(cameraPosition);
1518
+ orbitControls.enableRotate = true;
1519
+ orbitControls.target.copy(target);
1520
+ };
1521
+ }
1522
+ /**
1523
+ * 退出编辑
1524
+ */
1525
+ exitEdit() {
1526
+ if (typeof this._exitEditCallBack === "function") {
1527
+ this._exitEditCallBack();
1528
+ this._exitEditCallBack = void 0;
1529
+ this.commandManager.disabled = true;
1530
+ }
1531
+ }
1532
+ destroy() {
1533
+ this.exitEdit();
1534
+ this.renderer.scene.remove(this.container);
1535
+ this.domElement.remove();
1536
+ this.app?.unmount();
1537
+ }
1538
+ };
1539
+ class RenderManager extends Component {
1540
+ static name = "RenderManager";
1541
+ container = new THREE.Group();
1542
+ lines = [];
1543
+ pointVirtualGrid = new PointVirtualGrid();
1544
+ quadtree = new Quadtree(new Box2());
1545
+ actionHistory = /* @__PURE__ */ new Set();
1546
+ onAddFromParent() {
1547
+ const dxfLineModel = this.dxfLineModel;
1548
+ this.editor.container.add(this.container);
1549
+ this.editor.container.add(dxfLineModel.dxfModelGroup);
1550
+ dxfLineModel.dxfLineModel.material = new THREE.LineBasicMaterial({
1551
+ transparent: true,
1552
+ opacity: 0.5,
1553
+ color: 16777215
1554
+ });
1555
+ dxfLineModel.addEventListener("modelUpdate", (e) => {
1556
+ e.model.position.z = 0;
1557
+ dxfLineModel.dxfDoorsLineModel.visible = false;
1558
+ });
1559
+ this.variable.addEventListener("dxfVisible", (e) => dxfLineModel.dxfModelGroup.visible = e.value);
1560
+ this.dxf.addEventListener("createGroup", () => this.reset());
1561
+ this.reset();
1562
+ }
1563
+ updatedMode = null;
1564
+ /** 重新设置数据
1565
+ */
1566
+ reset() {
1567
+ if (this.updatedMode === "self") {
1568
+ this.updatedMode = null;
1569
+ return;
1570
+ } else {
1571
+ this.updatedMode = "dxf";
1572
+ }
1573
+ this.pointVirtualGrid = new PointVirtualGrid();
1574
+ const box = this.dxf.box.clone().expansion(Math.max(this.dxf.box.width, this.dxf.box.height) * 2);
1575
+ if (box.width === 0 || box.height === 0) box.set(-200, -200, 200, 200);
1576
+ this.quadtree = new Quadtree(box);
1577
+ this.lines.length = 0;
1578
+ this.dxf.lineSegments.forEach((line) => {
1579
+ if (line.userData.isDoor && !line.userData.doorDirectConnection) return;
1580
+ this.addLine(line.clone());
1581
+ });
1582
+ this.dxf.doorLineSegment.forEach((line) => {
1583
+ const door = line.clone();
1584
+ door.userData = {
1585
+ isDoor: true,
1586
+ doorDirectConnection: true
1587
+ };
1588
+ this.addLine(door);
1589
+ });
1590
+ this.draw();
1591
+ }
1592
+ /** 添加线段
1593
+ * @param line
1594
+ */
1595
+ addLine(line) {
1596
+ if (!line.userData) line.userData = {};
1597
+ this.lines.push(line);
1598
+ this.pointVirtualGrid.insert(line.start, line);
1599
+ this.pointVirtualGrid.insert(line.end, line);
1600
+ const quadtreeNode = {
1601
+ line,
1602
+ userData: void 0
1603
+ };
1604
+ line.userData.quadtreeNode = quadtreeNode;
1605
+ this.quadtree.insert(quadtreeNode);
1606
+ this.actionHistory.add({
1607
+ type: "addLine",
1608
+ data: [line]
1609
+ });
1610
+ }
1611
+ /**
1612
+ * 批量添加
1613
+ * @param lines
1614
+ */
1615
+ addLines(lines) {
1616
+ for (let i = 0; i < lines.length; i++) {
1617
+ const line = lines[i];
1618
+ this.lines.push(line);
1619
+ this.pointVirtualGrid.insert(line.start, line);
1620
+ this.pointVirtualGrid.insert(line.end, line);
1621
+ const quadtreeNode = {
1622
+ line,
1623
+ userData: void 0
1624
+ };
1625
+ line.userData.quadtreeNode = quadtreeNode;
1626
+ this.quadtree.insert(quadtreeNode);
1627
+ }
1628
+ this.actionHistory.add({
1629
+ type: "addLine",
1630
+ data: [...lines]
1631
+ });
1632
+ }
1633
+ /** 移除线段
1634
+ * @param line
1635
+ */
1636
+ removeLine(line) {
1637
+ line.userData.quadtreeNode && this.quadtree.remove(line.userData.quadtreeNode);
1638
+ this.pointVirtualGrid.remove(line.start);
1639
+ this.pointVirtualGrid.remove(line.end);
1640
+ const index = this.lines.indexOf(line);
1641
+ this.lines.splice(index, 1);
1642
+ this.draw();
1643
+ this.actionHistory.add({
1644
+ type: "removeLine",
1645
+ data: [line]
1646
+ });
1647
+ }
1648
+ /**
1649
+ * 绘制
1650
+ */
1651
+ draw(synchronize = true) {
1652
+ this.container.clear();
1653
+ const position = [], doorPosition = [], windowPosition = [];
1654
+ this.lines.forEach((line) => {
1655
+ line.points.forEach((p) => {
1656
+ if (line.userData.isDoor) doorPosition.push(p.x, p.y, 0);
1657
+ else position.push(p.x, p.y, 0);
1658
+ });
1659
+ if (line.userData.isWindow && line.userData.drawDoorData) {
1660
+ line.userData.drawDoorData.forEach(({ width, p }) => {
1661
+ const center = Point.from(p), direction = line.direction(), start = center.clone().add(direction.clone().multiplyScalar(width * 0.5)), end = center.clone().add(direction.clone().multiplyScalar(-width * 0.5));
1662
+ windowPosition.push(start.x, start.y, 1e-3);
1663
+ windowPosition.push(end.x, end.y, 1e-3);
1664
+ });
1665
+ }
1666
+ });
1667
+ position.length && this.renderer.createLineSegments({
1668
+ position
1669
+ }, position.length / 3, {
1670
+ color: 5745151
1671
+ }, this.container);
1672
+ doorPosition.length && this.renderer.createLineSegments({
1673
+ position: doorPosition
1674
+ }, doorPosition.length / 3, {
1675
+ color: 16776960
1676
+ }, this.container);
1677
+ windowPosition.length && this.renderer.createLineSegments({
1678
+ position: windowPosition
1679
+ }, windowPosition.length / 3, {
1680
+ color: 16711935
1681
+ }, this.container);
1682
+ synchronize && this.synchronizeDxf();
1683
+ }
1684
+ /** 获取鼠标当前点, 吸附后的点
1685
+ * @param point
1686
+ * @returns
1687
+ */
1688
+ adsorption(radius = 0.1, pointVirtualGrid = this.pointVirtualGrid, quadtree = this.quadtree) {
1689
+ const editor = this.parent?.findComponentByName("Editor"), point = Point.from(editor.pointerPosition);
1690
+ const p = pointVirtualGrid.queryCircle(point, radius).sort((a, b) => a.point.distance(point) - b.point.distance(point));
1691
+ if (p.length) return {
1692
+ point: new THREE.Vector3(p[0].point.x, p[0].point.y, 0),
1693
+ find: true,
1694
+ mode: "point",
1695
+ line: p[0].userData
1696
+ };
1697
+ let result = quadtree.queryCircle(point, radius);
1698
+ if (result.length) {
1699
+ let projectPoints = result.map((res) => res.line.projectPoint(point));
1700
+ projectPoints.sort((a, b) => {
1701
+ if (a && b) return a.distance(point) - b.distance(point);
1702
+ return 0;
1703
+ });
1704
+ result = result.filter((_, i) => !!projectPoints[i]);
1705
+ projectPoints = projectPoints.filter((_, i) => !!projectPoints[i]);
1706
+ return {
1707
+ point: new THREE.Vector3(projectPoints[0].x, projectPoints[0].y, 0),
1708
+ find: true,
1709
+ mode: "line",
1710
+ line: result[0].line
1711
+ };
1712
+ }
1713
+ return {
1714
+ point: new THREE.Vector3(editor.pointerPosition.x, editor.pointerPosition.y, 0),
1715
+ find: false
1716
+ };
1717
+ }
1718
+ /** 创建几何体
1719
+ * @param rectangle
1720
+ */
1721
+ createGeometry(map, count) {
1722
+ const geometry = new THREE.BufferGeometry();
1723
+ Object.keys(map).forEach((k) => {
1724
+ geometry.setAttribute("position", new THREE.BufferAttribute(new Float32Array(map[k]), map[k].length / count));
1725
+ });
1726
+ return geometry;
1727
+ }
1728
+ /**
1729
+ * 转为json
1730
+ */
1731
+ toJson() {
1732
+ return this.lines.map((line) => {
1733
+ const userData = line.userData;
1734
+ const drawDoorData = userData.drawDoorData;
1735
+ return {
1736
+ start: line.start.toJson(),
1737
+ end: line.end.toJson(),
1738
+ insetionArr: [],
1739
+ isDoor: userData.isDoor,
1740
+ doorDirectConnection: userData.isDoor,
1741
+ isWindow: userData.isWindow,
1742
+ drawDoorData: drawDoorData && drawDoorData.map((w) => ({
1743
+ p: { x: w.p.x, y: w.p.y, z: w.p.z },
1744
+ width: w.width,
1745
+ full: w.full
1746
+ }))
1747
+ };
1748
+ });
1749
+ }
1750
+ _timer = null;
1751
+ /**
1752
+ * 同步到dxf
1753
+ */
1754
+ synchronizeDxf() {
1755
+ if (this.updatedMode === "dxf") {
1756
+ this.updatedMode = null;
1757
+ return;
1758
+ }
1759
+ if (this._timer) clearTimeout(this._timer);
1760
+ setTimeout(() => {
1761
+ this.updatedMode = "self";
1762
+ const dxf = this.dxf;
1763
+ const json = this.toJson();
1764
+ dxf.set(json).then(() => {
1765
+ dxf.lineOffset();
1766
+ });
1767
+ }, 10);
1768
+ }
1769
+ get renderer() {
1770
+ return this.parent?.findComponentByName("Renderer");
1771
+ }
1772
+ get dxf() {
1773
+ return this.parent?.findComponentByName("Dxf");
1774
+ }
1775
+ get variable() {
1776
+ return this.parent?.findComponentByName("Variable");
1777
+ }
1778
+ get eventInput() {
1779
+ return this.parent?.findComponentByName("EventInput");
1780
+ }
1781
+ get editor() {
1782
+ return this.parent?.findComponentByName("Editor");
1783
+ }
1784
+ get dxfLineModel() {
1785
+ return this.parent?.findComponentByName("DxfLineModel");
1786
+ }
1787
+ }
1788
+ class DrawDoorLine extends CommandFlowComponent {
1789
+ static name = "DrawDoorLine";
1790
+ container = new THREE.Group();
1791
+ interruptKeys = ["escape"];
1792
+ shortcutKeys = ["control", "m"];
1793
+ commandName = "draw-door-line";
1794
+ onAddFromParent(parent) {
1795
+ const editor = parent.findComponentByName("Editor"), eventInput = editor.eventInput, commandManager = editor.commandManager;
1796
+ this.editor.container.add(this.container);
1797
+ const commandFlow = this.commandManager.addCommandFlow("draw-door-line").add(this.createInterrupt()).add(this.createCursor("no-drop")).add(this.selectPoint.bind(this));
1798
+ eventInput.addKeyCombination(this.commandName, this.shortcutKeys);
1799
+ commandFlow.addEventListener("finally", this.createFinally());
1800
+ commandFlow.addEventListener("completed", (e) => this.completed(e.data));
1801
+ eventInput.addCancelDefaultBehavior(() => eventInput.isOnlyKeyDowns(this.shortcutKeys));
1802
+ eventInput.addEventListener("codeChange", async () => {
1803
+ eventInput.isKeyCombination(this.commandName) && await commandManager.start(this.commandName);
1804
+ });
1805
+ }
1806
+ /** 选择点
1807
+ * @param next
1808
+ */
1809
+ selectPoint(next) {
1810
+ let editor = this.parent?.findComponentByName("Editor"), start = null, circle = new THREE.Mesh(new THREE.SphereGeometry(0.05), new THREE.MeshBasicMaterial({ color: 65280 })), line = new Lines([], 16711935), auxiliaryLine = new Lines([
1811
+ new THREE.Vector3(-1e4, 0, 0),
1812
+ new THREE.Vector3(1e4, 0, 0),
1813
+ new THREE.Vector3(0, -1e4, 0),
1814
+ new THREE.Vector3(0, 1e4, 0)
1815
+ ], 16711935);
1816
+ auxiliaryLine.material = new THREE.LineDashedMaterial({
1817
+ color: 4235007,
1818
+ dashSize: 0.1,
1819
+ gapSize: 0.1,
1820
+ linewidth: 0.1
1821
+ });
1822
+ this.container.add(line);
1823
+ let currentPoint = null;
1824
+ this.addEventRecord(
1825
+ "clear",
1826
+ editor.addEventListener("pointerPositionChange", () => {
1827
+ const { point, find } = editor.renderManager.adsorption(0.05);
1828
+ start && line.setPoint(start, point);
1829
+ if (find) {
1830
+ circle.position.set(point.x, point.y, 0);
1831
+ this.container.add(circle);
1832
+ this.domElement.style.cursor = "none";
1833
+ currentPoint = point.clone();
1834
+ } else {
1835
+ currentPoint = null;
1836
+ circle.removeFromParent();
1837
+ this.domElement.style.cursor = "no-drop";
1838
+ }
1839
+ }),
1840
+ editor.eventInput.addEventListener("codeChange", async () => {
1841
+ if (editor.eventInput.isKeyDown("mouse_0") && currentPoint) {
1842
+ if (!start) {
1843
+ start = currentPoint.clone();
1844
+ return;
1845
+ }
1846
+ next([start.clone(), currentPoint.clone()]);
1847
+ }
1848
+ }),
1849
+ function() {
1850
+ line.removeFromParent();
1851
+ circle.removeFromParent();
1852
+ auxiliaryLine.removeFromParent();
1853
+ }
1854
+ );
1855
+ }
1856
+ /** 执行完成
1857
+ */
1858
+ completed(points) {
1859
+ const editor = this.editor, lines = [];
1860
+ for (let i = 0; i < points.length; i += 2) {
1861
+ const line = new LineSegment(Point.from(points[i]), Point.from(points[i + 1]));
1862
+ line.userData.isDoor = true;
1863
+ line.userData.doorDirectConnection = true;
1864
+ lines.push(line);
1865
+ }
1866
+ editor.renderManager.addLines(lines);
1867
+ editor.renderManager.draw();
1868
+ }
1869
+ }
1870
+ class DrawWindow extends CommandFlowComponent {
1871
+ static name = "DrawWindow";
1872
+ container = new THREE.Group();
1873
+ interruptKeys = ["escape"];
1874
+ shortcutKeys = ["control", "q"];
1875
+ commandName = "draw-window-line";
1876
+ onAddFromParent() {
1877
+ this.editor.container.add(this.container);
1878
+ const commandFlow = this.commandManager.addCommandFlow(this.commandName).add(this.createInterrupt()).add(this.createCursor("no-drop")).add(this.selectPointStart.bind(this)).add(this.selectPointEnd.bind(this));
1879
+ commandFlow.addEventListener("finally", this.createFinally());
1880
+ commandFlow.addEventListener("completed", (e) => this.completed(e.data));
1881
+ this.eventInput.addKeyCombination(this.commandName, this.shortcutKeys);
1882
+ this.eventInput.addEventListener("codeChange", async () => this.eventInput.isKeyCombination(this.commandName) && await this.commandManager.start(this.commandName));
1883
+ this.eventInput.addCancelDefaultBehavior(() => this.eventInput.isOnlyKeyDowns(this.shortcutKeys));
1884
+ }
1885
+ /** 选择开始点
1886
+ * @param next
1887
+ */
1888
+ selectPointStart(next) {
1889
+ let currentPoint = null, circle = new THREE.Mesh(new THREE.SphereGeometry(0.05), new THREE.MeshBasicMaterial({ color: 16711935 })), currentLine = null;
1890
+ this.addEventRecord("selectPointStart").add(this.editor.addEventListener("pointerPositionChange", () => {
1891
+ const { point, line, find } = this.editor.renderManager.adsorption();
1892
+ if (find) {
1893
+ this.domElement.style.cursor = "none";
1894
+ circle.position.copy(point);
1895
+ currentLine = line;
1896
+ currentPoint = point.clone();
1897
+ this.container.add(circle);
1898
+ } else {
1899
+ this.domElement.style.cursor = "no-drop";
1900
+ currentPoint = null;
1901
+ circle.removeFromParent();
1902
+ }
1903
+ })).add(this.eventInput.addEventListener("codeChange", () => {
1904
+ if (this.eventInput.isKeyDown("mouse_0") && currentPoint) {
1905
+ this.canceEventRecord("selectPointStart");
1906
+ next({ point: currentPoint, line: currentLine });
1907
+ }
1908
+ }));
1909
+ this.addEventRecord("clear").add(() => circle.removeFromParent());
1910
+ }
1911
+ /** 选择结束点
1912
+ * @param next
1913
+ */
1914
+ selectPointEnd(next, { point, line }) {
1915
+ let currentPoint = null, circle = new THREE.Mesh(new THREE.SphereGeometry(0.05), new THREE.MeshBasicMaterial({ color: 16711935 }));
1916
+ this.addEventRecord("clear").add(() => circle.removeFromParent()).add(this.editor.addEventListener("pointerPositionChange", () => {
1917
+ const { point: point2, find, line: l } = this.editor.renderManager.adsorption();
1918
+ if (find && l === line) {
1919
+ this.domElement.style.cursor = "none";
1920
+ circle.position.copy(point2);
1921
+ currentPoint = point2.clone();
1922
+ this.container.add(circle);
1923
+ } else {
1924
+ this.domElement.style.cursor = "no-drop";
1925
+ currentPoint = null;
1926
+ circle.removeFromParent();
1927
+ }
1928
+ })).add(this.eventInput.addEventListener("codeChange", () => {
1929
+ if (this.eventInput.isKeyDown("mouse_0") && currentPoint) next({ line, start: point, end: currentPoint });
1930
+ }));
1931
+ }
1932
+ /** 执行完成
1933
+ */
1934
+ completed(data) {
1935
+ const start = data.start, end = data.end, line = data.line, win = new LineSegment(Point.from(start), Point.from(end)), center = win.center, len = win.length();
1936
+ line.userData.isWindow = true;
1937
+ if (!line.userData.drawDoorData) line.userData.drawDoorData = [];
1938
+ line.userData.drawDoorData.push({
1939
+ p: new THREE.Vector3(center.x, center.y, 0),
1940
+ width: len,
1941
+ full: Math.abs(len - line.length()) < 0.01
1942
+ });
1943
+ this.renderManager.draw();
1944
+ }
1945
+ }
1946
+ class PointDrag extends CommandFlowComponent {
1947
+ static name = "PointDrag";
1948
+ container = new THREE.Group();
1949
+ interruptKeys = ["escape"];
1950
+ shortcutKeys = ["control", "p"];
1951
+ commandName = "point";
1952
+ onAddFromParent() {
1953
+ this.editor.container.add(this.container);
1954
+ this.container.position.z = 1e-3;
1955
+ const commandFlow = this.commandManager.addCommandFlow(this.commandName).add(this.createInterrupt()).add(this.createCursor("crosshair")).add(this.selectPoint.bind(this)).add(this.drag.bind(this));
1956
+ commandFlow.addEventListener("finally", this.createFinally());
1957
+ commandFlow.addEventListener("completed", (e) => this.completed(e.data));
1958
+ this.eventInput.addKeyCombination(this.commandName, this.shortcutKeys);
1959
+ this.eventInput.addEventListener("codeChange", async () => this.eventInput.isKeyCombination(this.commandName) && await this.commandManager.start(this.commandName));
1960
+ this.eventInput.addCancelDefaultBehavior(() => this.eventInput.isOnlyKeyDowns(this.shortcutKeys));
1961
+ }
1962
+ /** 选择开始点
1963
+ * @param next
1964
+ */
1965
+ selectPoint(next) {
1966
+ let currentPoint = null, circle = new THREE.Mesh(new THREE.SphereGeometry(0.05), new THREE.MeshBasicMaterial({ color: 16711935 })), currentLine = null;
1967
+ this.addEventRecord("selectPointStart").add(this.editor.addEventListener("pointerPositionChange", () => {
1968
+ const { point, line, find, mode } = this.editor.renderManager.adsorption();
1969
+ if (find && mode === "point") {
1970
+ this.domElement.style.cursor = "none";
1971
+ circle.position.copy(point);
1972
+ currentLine = line;
1973
+ currentPoint = point.clone();
1974
+ this.container.add(circle);
1975
+ } else {
1976
+ this.domElement.style.cursor = "no-drop";
1977
+ currentPoint = null;
1978
+ circle.removeFromParent();
1979
+ }
1980
+ })).add(this.eventInput.addEventListener("codeChange", () => {
1981
+ if (this.eventInput.isKeyDown("mouse_0") && currentPoint) {
1982
+ this.canceEventRecord("selectPointStart");
1983
+ circle.material.color.set(65280);
1984
+ next({ point: currentPoint, line: currentLine });
1985
+ }
1986
+ }));
1987
+ this.addEventRecord("clear").add(() => circle.removeFromParent());
1988
+ }
1989
+ /** 拖拽点
1990
+ * @description 拖拽点到指定位置
1991
+ * @param next
1992
+ * @param param1
1993
+ */
1994
+ drag(next, { point, line }) {
1995
+ this.domElement.style.cursor = "crosshair";
1996
+ const mode = line.start.equal(Point.from(point)) ? "start" : "end", start = mode == "start" ? new THREE.Vector3(line.end.x, line.end.y, 0) : new THREE.Vector3(line.start.x, line.start.y, 0), end = point.clone(), lines = new Lines([start, end], 16711935), circle = new THREE.Mesh(new THREE.SphereGeometry(0.03), new THREE.MeshBasicMaterial({ color: 16711935 }));
1997
+ this.container.add(lines);
1998
+ this.addEventRecord("clear").add(this.editor.addEventListener("pointerPositionChange", () => {
1999
+ let { point: point2, find } = this.editor.renderManager.adsorption(), cursor = "none";
2000
+ if (point2) {
2001
+ if (this.eventInput.isKeyDown("shift")) {
2002
+ const p = line.projectPoint(Point.from(point2), false);
2003
+ point2.set(p?.x ?? point2.x, p?.y ?? point2.y, 0);
2004
+ find = true;
2005
+ cursor = "crosshair";
2006
+ }
2007
+ if (find) {
2008
+ circle.position.copy(point2);
2009
+ this.container.add(circle);
2010
+ } else {
2011
+ circle.removeFromParent();
2012
+ cursor = "crosshair";
2013
+ }
2014
+ end.copy(point2);
2015
+ lines.setPoint(start, end);
2016
+ this.domElement.style.cursor = cursor;
2017
+ }
2018
+ })).add(this.eventInput.addEventListener("codeChange", () => {
2019
+ if (this.eventInput.isKeyDown("mouse_0")) {
2020
+ this.canceEventRecord("selectPointStart");
2021
+ next({ point: end, line, mode });
2022
+ }
2023
+ })).add(() => circle.removeFromParent()).add(() => lines.removeFromParent());
2024
+ }
2025
+ /** 执行完成
2026
+ */
2027
+ completed(data) {
2028
+ const { line, point, mode } = data;
2029
+ this.renderManager.removeLine(line);
2030
+ if (mode === "end") line.end.set(point.x, point.y);
2031
+ else if (mode === "start") line.start.set(point.x, point.y);
2032
+ this.renderManager.addLine(line);
2033
+ this.renderManager.draw();
2034
+ }
2035
+ }
2036
+ function Editor2(dxfSystem) {
2037
+ dxfSystem.addComponent(new Editor$1());
2038
+ dxfSystem.addComponent(new RenderManager());
2039
+ dxfSystem.addComponent(new Default());
2040
+ dxfSystem.addComponent(new DrawLine());
2041
+ dxfSystem.addComponent(new DrawDoorLine());
2042
+ dxfSystem.addComponent(new DrawWindow());
2043
+ dxfSystem.addComponent(new PointDrag());
2044
+ }
2045
+ export {
2046
+ Editor2 as Editor
2047
+ };