build-dxf 0.0.17 → 0.0.19

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 (41) hide show
  1. package/package.json +1 -1
  2. package/src/build.d.ts +10 -1
  3. package/src/build.js +556 -450
  4. package/src/components/Editor.vue.d.ts +26 -0
  5. package/src/index.js +3 -2
  6. package/src/index2.js +373 -3426
  7. package/src/index3.js +1937 -0
  8. package/src/pages/Editor.vue.d.ts +2 -0
  9. package/src/pages/Editor02.vue.d.ts +4 -0
  10. package/src/selectLocalFile.js +3745 -0
  11. package/src/utils/CommandManager/CommandFlow.d.ts +23 -0
  12. package/src/utils/CommandManager/CommandManager.d.ts +59 -0
  13. package/src/utils/CommandManager/index.d.ts +2 -0
  14. package/src/utils/ComponentManager/EventDispatcher.d.ts +11 -1
  15. package/src/utils/DxfSystem/components/Dxf.d.ts +15 -12
  16. package/src/utils/DxfSystem/components/LineAnalysis.d.ts +5 -21
  17. package/src/utils/DxfSystem/components/Variable.d.ts +8 -0
  18. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/CommandFlowComponent.d.ts +36 -0
  19. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/Default.d.ts +57 -0
  20. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DrawDoorLine.d.ts +19 -0
  21. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DrawLine.d.ts +20 -0
  22. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DrawWindow.d.ts +25 -0
  23. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/PointDrag.d.ts +27 -0
  24. package/src/utils/DxfSystem/plugin/Editor/components/Editor.d.ts +22 -3
  25. package/src/utils/DxfSystem/plugin/Editor/components/RenderManager.d.ts +88 -0
  26. package/src/utils/DxfSystem/plugin/Editor/components/index.d.ts +6 -0
  27. package/src/utils/DxfSystem/plugin/Editor/pages/EditorTool.vue.d.ts +6 -0
  28. package/src/utils/DxfSystem/plugin/ModelDataPlugin/components/DxfLineModel.d.ts +7 -3
  29. package/src/utils/DxfSystem/plugin/ModelDataPlugin/index.d.ts +9 -1
  30. package/src/utils/DxfSystem/plugin/RenderPlugin/components/DomContainer.d.ts +1 -0
  31. package/src/utils/DxfSystem/plugin/RenderPlugin/components/DomEventRegister.d.ts +20 -1
  32. package/src/utils/DxfSystem/plugin/RenderPlugin/components/EventInput.d.ts +74 -0
  33. package/src/utils/DxfSystem/plugin/RenderPlugin/components/Renderer.d.ts +0 -11
  34. package/src/utils/DxfSystem/plugin/RenderPlugin/components/index.d.ts +1 -0
  35. package/src/utils/DxfSystem/plugin/RenderPlugin/index.d.ts +11 -1
  36. package/src/utils/PointVirtualGrid/index.d.ts +10 -4
  37. package/src/utils/Quadtree/Box2.d.ts +3 -2
  38. package/src/utils/Quadtree/LineSegment.d.ts +11 -9
  39. package/src/utils/Quadtree/Point.d.ts +11 -6
  40. package/src/utils/Quadtree/Quadtree.d.ts +5 -0
  41. package/src/utils/Quadtree/Rectangle.d.ts +5 -4
package/src/index3.js ADDED
@@ -0,0 +1,1937 @@
1
+ import * as THREE from "three";
2
+ import { i as isString, n as noop, r as resolveUnref, t as tryOnScopeDispose, b as isClient, c as tryOnMounted, d as identity, e as buildProps, f as definePropType, _ as _export_sfc, u as useNamespace, g as isNumber, h as addUnit, w as withInstall, j as useEmptyValuesProps, k as useSizeProp, p as provideGlobalConfig, l as iconPropType, m as useGlobalComponentSettings, T as TypeComponentsMap, o as ElIcon, q as TypeComponents, s as useTimeoutFn, v as isString$1, x as isFunction, y as isBoolean, z as isElement, A as withInstallFunction, L as Lines, E as ElButton, a as ElCheckbox, 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, createStaticVNode, 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"), renderer = editor.renderer, start = null, end = null, points = [], circle = new THREE.Mesh(new THREE.SphereGeometry(0.05), new THREE.MeshBasicMaterial({ color: 65280 })), dom = renderer.html2DRenderer?.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.parentElement.style.cursor = "none";
808
+ } else {
809
+ circle.removeFromParent();
810
+ dom.parentElement.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.parentElement.style.cursor = "pointer";
1101
+ currentSelectLine = line;
1102
+ } else {
1103
+ object3D.removeFromParent();
1104
+ dom.parentElement.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 _hoisted_1 = { class: "pointer-events-none absolute left-0 top-0 w-full h-fit z-[10000] flex flex-row justify-between p-[5px] box-border select-none pointer-events-[all]" };
1252
+ const _hoisted_2 = { class: "pointer-events-auto" };
1253
+ const _hoisted_3 = { class: "pointer-events-auto" };
1254
+ const _hoisted_4 = { class: "text-[14px] bg-[rgba(255,255,255,1)] rounded-[6px] p-[0px_10px]" };
1255
+ const _sfc_main = /* @__PURE__ */ defineComponent({
1256
+ __name: "EditorTool",
1257
+ props: {
1258
+ dxfSystem: {}
1259
+ },
1260
+ setup(__props) {
1261
+ const props = __props;
1262
+ const originalLineVisible = ref(true), dxfVisible = ref(true), whiteModelVisible = ref(true), isLook = ref(false), dxfSystem = toRaw(props.dxfSystem);
1263
+ function setLines(lines) {
1264
+ if (lines) {
1265
+ localStorage.setItem("lines", JSON.stringify(lines));
1266
+ try {
1267
+ dxfSystem.Dxf.set(lines);
1268
+ dxfSystem.Dxf.lineOffset();
1269
+ } catch (error) {
1270
+ console.log(error);
1271
+ }
1272
+ }
1273
+ }
1274
+ async function selectLocalFile() {
1275
+ const data = await SelectLocalFile.json();
1276
+ if (Array.isArray(data)) {
1277
+ localStorage.removeItem("orbitControls");
1278
+ setLines(data);
1279
+ }
1280
+ }
1281
+ watch(originalLineVisible, () => dxfSystem.Variable.set("originalLineVisible", originalLineVisible.value));
1282
+ watch(dxfVisible, () => dxfSystem.Variable.set("dxfVisible", dxfVisible.value));
1283
+ watch(whiteModelVisible, () => dxfSystem.Variable.set("whiteModelVisible", whiteModelVisible.value));
1284
+ dxfSystem.Variable.addEventListener("isLook", (e) => isLook.value = e.value);
1285
+ dxfSystem.Variable.addEventListener("originalLineVisible", (e) => originalLineVisible.value = e.value);
1286
+ dxfSystem.Variable.addEventListener("dxfVisible", (e) => dxfVisible.value = e.value);
1287
+ dxfSystem.Variable.addEventListener("whiteModelVisible", (e) => whiteModelVisible.value = e.value);
1288
+ return (_ctx, _cache) => {
1289
+ return openBlock(), createElementBlock("div", _hoisted_1, [
1290
+ createElementVNode("div", _hoisted_2, [
1291
+ createVNode(unref(ElButton), {
1292
+ size: "small",
1293
+ type: "success",
1294
+ onClick: selectLocalFile
1295
+ }, {
1296
+ default: withCtx(() => _cache[2] || (_cache[2] = [
1297
+ createTextVNode(" 选择文件 ", -1)
1298
+ ])),
1299
+ _: 1,
1300
+ __: [2]
1301
+ }),
1302
+ createVNode(unref(ElButton), {
1303
+ size: "small",
1304
+ type: "primary",
1305
+ onClick: _cache[0] || (_cache[0] = ($event) => unref(dxfSystem).Dxf.download("test.dxf"))
1306
+ }, {
1307
+ default: withCtx(() => _cache[3] || (_cache[3] = [
1308
+ createTextVNode(" 下载 DXF ", -1)
1309
+ ])),
1310
+ _: 1,
1311
+ __: [3]
1312
+ })
1313
+ ]),
1314
+ createElementVNode("div", _hoisted_3, [
1315
+ createElementVNode("div", _hoisted_4, [
1316
+ createVNode(unref(ElCheckbox), {
1317
+ modelValue: dxfVisible.value,
1318
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => dxfVisible.value = $event),
1319
+ label: "dxf"
1320
+ }, null, 8, ["modelValue"])
1321
+ ]),
1322
+ _cache[4] || (_cache[4] = createStaticVNode('<div class="mt-[5px] text-[#c9c9c9] text-[10px]"><p class="text-right"> 绘制连续线段:<span class="w-[110px] inline-block">Ctrl + L</span></p><p class="text-right"> 绘制线段确认:<span class="w-[110px] inline-block">Enter</span></p><p class="text-right"> 绘制门线:<span class="w-[110px] inline-block">Ctrl + M</span></p><p class="text-right"> 绘制窗户线:<span class="w-[110px] inline-block">Ctrl + Q</span></p><p class="text-right"> 移动线段点:<span class="w-[110px] inline-block">Ctrl + P</span></p><p class="text-right"> 删除线段:<span class="w-[110px] inline-block">选中 + Delete</span></p><p class="text-right"> 删除窗户线:<span class="w-[110px] inline-block">选中 + Q + Delete</span></p><p class="text-right"> 选中:<span class="w-[110px] inline-block">鼠标左键</span></p><p class="text-right"> 多选:<span class="w-[110px] inline-block">鼠标左键 + Ctrl</span></p><p class="text-right"> 取消选中:<span class="w-[110px] inline-block">鼠标左键 + Alt</span></p><p class="text-right"> 框选:<span class="w-[110px] inline-block">鼠标左键 + 移动</span></p><p class="text-right"> 线段同方向合并:<span class="w-[110px] inline-block">Ctrl + G</span></p><p class="text-right"> 线段连接:<span class="w-[110px] inline-block">选中 + Shift + L</span></p><p class="text-right"> 线段交点连接:<span class="w-[110px] inline-block">选中 + Ctrl + Shift + L</span></p><p class="text-right"> 取消命令:<span class="w-[110px] inline-block">Esc</span></p></div>', 1))
1323
+ ])
1324
+ ]);
1325
+ };
1326
+ }
1327
+ });
1328
+ let Editor$1 = class Editor extends Component {
1329
+ static name = "Editor";
1330
+ container = new THREE.Group();
1331
+ get renderer() {
1332
+ return this.parent?.findComponentByName("Renderer");
1333
+ }
1334
+ get dxf() {
1335
+ return this.parent?.findComponentByName("Dxf");
1336
+ }
1337
+ get variable() {
1338
+ return this.parent?.findComponentByName("Variable");
1339
+ }
1340
+ get eventInput() {
1341
+ return this.parent?.findComponentByName("EventInput");
1342
+ }
1343
+ get renderManager() {
1344
+ return this.parent?.findComponentByName("RenderManager");
1345
+ }
1346
+ get domEventRegister() {
1347
+ return this.parent?.findComponentByName("DomEventRegister");
1348
+ }
1349
+ get domContainer() {
1350
+ return this.parent?.findComponentByName("DomContainer");
1351
+ }
1352
+ commandManager = new CommandManager();
1353
+ plane = new THREE.Mesh(new THREE.PlaneGeometry(2e3, 2e3, 2, 2));
1354
+ app;
1355
+ domElement = document.createElement("div");
1356
+ onAddFromParent() {
1357
+ setTimeout(() => this.openEdit(), 10);
1358
+ const grid = new THREE.GridHelper(200, 100, 6710886, 4473924);
1359
+ grid.rotation.x = Math.PI * 0.5;
1360
+ grid.position.z = -0.01;
1361
+ this.container.add(grid);
1362
+ this.container.add(this.plane);
1363
+ this.plane.visible = false;
1364
+ this.app = createApp(_sfc_main, { dxfSystem: this.parent });
1365
+ this.app.mount(this.domElement);
1366
+ const cancelEvent = this.addEventListener("update", () => {
1367
+ if (this.domContainer.domElement.parentElement) {
1368
+ this.domContainer.domElement.parentElement.appendChild(this.domElement);
1369
+ cancelEvent();
1370
+ }
1371
+ });
1372
+ }
1373
+ coords = new THREE.Vector2();
1374
+ pointerPosition = new THREE.Vector2();
1375
+ _exitEditCallBack;
1376
+ /**
1377
+ * 打开编辑器
1378
+ */
1379
+ openEdit() {
1380
+ 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;
1381
+ this.container.position.z = dxf.originalZAverage;
1382
+ renderer.scene.add(this.container);
1383
+ camera.position.set(center.x, center.y, 14);
1384
+ if (orbitControls) {
1385
+ orbitControls.target.set(center.x, center.y, 0);
1386
+ orbitControls.enableRotate = false;
1387
+ }
1388
+ const mousemoveFun = () => {
1389
+ renderer.renderer.getSize(size);
1390
+ const x = domEventRegister.pointer.x / size.x * 2 - 1;
1391
+ const y = -(domEventRegister.pointer.y / size.y * 2 - 1);
1392
+ coords.set(x, y);
1393
+ raycaster.setFromCamera(coords, renderer.camera);
1394
+ const intersections = raycaster.intersectObject(this.plane);
1395
+ if (intersections.length) {
1396
+ pointerPosition.copy(intersections[0].point);
1397
+ this.dispatchEvent({
1398
+ type: "pointerPositionChange",
1399
+ position: pointerPosition
1400
+ });
1401
+ }
1402
+ };
1403
+ domEventRegister.addEventListener("mousemove", mousemoveFun);
1404
+ this.commandManager.disabled = false;
1405
+ this.commandManager.start("default");
1406
+ this._exitEditCallBack = () => {
1407
+ domEventRegister.removeEventListener("mousemove", mousemoveFun);
1408
+ camera.position.copy(cameraPosition);
1409
+ orbitControls.enableRotate = true;
1410
+ orbitControls.target.copy(target);
1411
+ };
1412
+ }
1413
+ /**
1414
+ * 退出编辑
1415
+ */
1416
+ exitEdit() {
1417
+ if (typeof this._exitEditCallBack === "function") {
1418
+ this._exitEditCallBack();
1419
+ this._exitEditCallBack = void 0;
1420
+ this.commandManager.disabled = true;
1421
+ }
1422
+ }
1423
+ destroy() {
1424
+ this.exitEdit();
1425
+ this.renderer.scene.remove(this.container);
1426
+ this.domElement.remove();
1427
+ this.app?.unmount();
1428
+ }
1429
+ };
1430
+ class RenderManager extends Component {
1431
+ static name = "RenderManager";
1432
+ container = new THREE.Group();
1433
+ lines = [];
1434
+ pointVirtualGrid = new PointVirtualGrid();
1435
+ quadtree = new Quadtree(new Box2());
1436
+ actionHistory = /* @__PURE__ */ new Set();
1437
+ onAddFromParent() {
1438
+ const dxfLineModel = this.dxfLineModel;
1439
+ this.reset();
1440
+ this.editor.container.add(this.container);
1441
+ this.editor.container.add(dxfLineModel.dxfModelGroup);
1442
+ dxfLineModel.dxfLineModel.material = new THREE.LineBasicMaterial({
1443
+ transparent: true,
1444
+ opacity: 0.5,
1445
+ color: 16777215
1446
+ });
1447
+ dxfLineModel.addEventListener("modelUpdate", (e) => {
1448
+ e.model.position.z = 0;
1449
+ dxfLineModel.dxfDoorsLineModel.visible = false;
1450
+ });
1451
+ this.variable.addEventListener("dxfVisible", (e) => dxfLineModel.dxfModelGroup.visible = e.value);
1452
+ this.dxf.addEventListener("createGroup", () => this.reset());
1453
+ }
1454
+ updatedMode = null;
1455
+ /** 重新设置数据
1456
+ */
1457
+ reset() {
1458
+ if (this.updatedMode === "self") {
1459
+ this.updatedMode = null;
1460
+ return;
1461
+ } else {
1462
+ this.updatedMode = "dxf";
1463
+ }
1464
+ this.pointVirtualGrid = new PointVirtualGrid();
1465
+ const box = this.dxf.box.clone().expansion(Math.max(this.dxf.box.width, this.dxf.box.height) * 2);
1466
+ this.quadtree = new Quadtree(box);
1467
+ this.lines.length = 0;
1468
+ this.dxf.lineSegments.forEach((line) => {
1469
+ if (line.userData.isDoor && !line.userData.doorDirectConnection) return;
1470
+ this.addLine(line.clone());
1471
+ });
1472
+ this.dxf.doorLineSegment.forEach((line) => {
1473
+ const door = line.clone();
1474
+ door.userData = {
1475
+ isDoor: true,
1476
+ doorDirectConnection: true
1477
+ };
1478
+ this.addLine(door);
1479
+ });
1480
+ this.draw();
1481
+ }
1482
+ /** 添加线段
1483
+ * @param line
1484
+ */
1485
+ addLine(line) {
1486
+ if (!line.userData) line.userData = {};
1487
+ this.lines.push(line);
1488
+ this.pointVirtualGrid.insert(line.start, line);
1489
+ this.pointVirtualGrid.insert(line.end, line);
1490
+ const quadtreeNode = {
1491
+ line,
1492
+ userData: void 0
1493
+ };
1494
+ line.userData.quadtreeNode = quadtreeNode;
1495
+ this.quadtree.insert(quadtreeNode);
1496
+ this.actionHistory.add({
1497
+ type: "addLine",
1498
+ data: [line]
1499
+ });
1500
+ }
1501
+ /**
1502
+ * 批量添加
1503
+ * @param lines
1504
+ */
1505
+ addLines(lines) {
1506
+ for (let i = 0; i < lines.length; i++) {
1507
+ const line = lines[i];
1508
+ this.lines.push(line);
1509
+ this.pointVirtualGrid.insert(line.start, line);
1510
+ this.pointVirtualGrid.insert(line.end, line);
1511
+ const quadtreeNode = {
1512
+ line,
1513
+ userData: void 0
1514
+ };
1515
+ line.userData.quadtreeNode = quadtreeNode;
1516
+ this.quadtree.insert(quadtreeNode);
1517
+ }
1518
+ this.actionHistory.add({
1519
+ type: "addLine",
1520
+ data: [...lines]
1521
+ });
1522
+ }
1523
+ /** 移除线段
1524
+ * @param line
1525
+ */
1526
+ removeLine(line) {
1527
+ line.userData.quadtreeNode && this.quadtree.remove(line.userData.quadtreeNode);
1528
+ this.pointVirtualGrid.remove(line.start);
1529
+ this.pointVirtualGrid.remove(line.end);
1530
+ const index = this.lines.indexOf(line);
1531
+ this.lines.splice(index, 1);
1532
+ this.draw();
1533
+ this.actionHistory.add({
1534
+ type: "removeLine",
1535
+ data: [line]
1536
+ });
1537
+ }
1538
+ /**
1539
+ * 绘制
1540
+ */
1541
+ draw(synchronize = true) {
1542
+ this.container.clear();
1543
+ const position = [], doorPosition = [], windowPosition = [];
1544
+ this.lines.forEach((line) => {
1545
+ line.points.forEach((p) => {
1546
+ if (line.userData.isDoor) doorPosition.push(p.x, p.y, 0);
1547
+ else position.push(p.x, p.y, 0);
1548
+ });
1549
+ if (line.userData.isWindow && line.userData.drawDoorData) {
1550
+ line.userData.drawDoorData.forEach(({ width, p }) => {
1551
+ 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));
1552
+ windowPosition.push(start.x, start.y, 1e-3);
1553
+ windowPosition.push(end.x, end.y, 1e-3);
1554
+ });
1555
+ }
1556
+ });
1557
+ position.length && this.renderer.createLineSegments({
1558
+ position
1559
+ }, position.length / 3, {
1560
+ color: 5745151
1561
+ }, this.container);
1562
+ doorPosition.length && this.renderer.createLineSegments({
1563
+ position: doorPosition
1564
+ }, doorPosition.length / 3, {
1565
+ color: 16776960
1566
+ }, this.container);
1567
+ windowPosition.length && this.renderer.createLineSegments({
1568
+ position: windowPosition
1569
+ }, windowPosition.length / 3, {
1570
+ color: 16711935
1571
+ }, this.container);
1572
+ synchronize && this.synchronizeDxf();
1573
+ }
1574
+ /** 获取鼠标当前点, 吸附后的点
1575
+ * @param point
1576
+ * @returns
1577
+ */
1578
+ adsorption(radius = 0.1, pointVirtualGrid = this.pointVirtualGrid, quadtree = this.quadtree) {
1579
+ const editor = this.parent?.findComponentByName("Editor"), point = Point.from(editor.pointerPosition);
1580
+ const p = pointVirtualGrid.queryCircle(point, radius).sort((a, b) => a.point.distance(point) - b.point.distance(point));
1581
+ if (p.length) return {
1582
+ point: new THREE.Vector3(p[0].point.x, p[0].point.y, 0),
1583
+ find: true,
1584
+ mode: "point",
1585
+ line: p[0].userData
1586
+ };
1587
+ let result = quadtree.queryCircle(point, radius);
1588
+ if (result.length) {
1589
+ let projectPoints = result.map((res) => res.line.projectPoint(point));
1590
+ projectPoints.sort((a, b) => {
1591
+ if (a && b) return a.distance(point) - b.distance(point);
1592
+ return 0;
1593
+ });
1594
+ result = result.filter((_, i) => !!projectPoints[i]);
1595
+ projectPoints = projectPoints.filter((_, i) => !!projectPoints[i]);
1596
+ return {
1597
+ point: new THREE.Vector3(projectPoints[0].x, projectPoints[0].y, 0),
1598
+ find: true,
1599
+ mode: "line",
1600
+ line: result[0].line
1601
+ };
1602
+ }
1603
+ return {
1604
+ point: new THREE.Vector3(editor.pointerPosition.x, editor.pointerPosition.y, 0),
1605
+ find: false
1606
+ };
1607
+ }
1608
+ /** 创建几何体
1609
+ * @param rectangle
1610
+ */
1611
+ createGeometry(map, count) {
1612
+ const geometry = new THREE.BufferGeometry();
1613
+ Object.keys(map).forEach((k) => {
1614
+ geometry.setAttribute("position", new THREE.BufferAttribute(new Float32Array(map[k]), map[k].length / count));
1615
+ });
1616
+ return geometry;
1617
+ }
1618
+ /**
1619
+ * 转为json
1620
+ */
1621
+ toJson() {
1622
+ return this.lines.map((line) => {
1623
+ const userData = line.userData;
1624
+ const drawDoorData = userData.drawDoorData;
1625
+ return {
1626
+ start: line.start.toJson(),
1627
+ end: line.end.toJson(),
1628
+ insetionArr: [],
1629
+ isDoor: userData.isDoor,
1630
+ doorDirectConnection: userData.isDoor,
1631
+ isWindow: userData.isWindow,
1632
+ drawDoorData: drawDoorData && drawDoorData.map((w) => ({
1633
+ p: { x: w.p.x, y: w.p.y, z: w.p.z },
1634
+ width: w.width,
1635
+ full: w.full
1636
+ }))
1637
+ };
1638
+ });
1639
+ }
1640
+ _timer = null;
1641
+ /**
1642
+ * 同步到dxf
1643
+ */
1644
+ synchronizeDxf() {
1645
+ if (this.updatedMode === "dxf") {
1646
+ this.updatedMode = null;
1647
+ return;
1648
+ }
1649
+ if (this._timer) clearTimeout(this._timer);
1650
+ setTimeout(() => {
1651
+ this.updatedMode = "self";
1652
+ const dxf = this.dxf;
1653
+ const json = this.toJson();
1654
+ dxf.set(json).then(() => {
1655
+ dxf.lineOffset();
1656
+ });
1657
+ }, 10);
1658
+ }
1659
+ get renderer() {
1660
+ return this.parent?.findComponentByName("Renderer");
1661
+ }
1662
+ get dxf() {
1663
+ return this.parent?.findComponentByName("Dxf");
1664
+ }
1665
+ get variable() {
1666
+ return this.parent?.findComponentByName("Variable");
1667
+ }
1668
+ get eventInput() {
1669
+ return this.parent?.findComponentByName("EventInput");
1670
+ }
1671
+ get editor() {
1672
+ return this.parent?.findComponentByName("Editor");
1673
+ }
1674
+ get dxfLineModel() {
1675
+ return this.parent?.findComponentByName("DxfLineModel");
1676
+ }
1677
+ }
1678
+ class DrawDoorLine extends CommandFlowComponent {
1679
+ static name = "DrawDoorLine";
1680
+ container = new THREE.Group();
1681
+ interruptKeys = ["escape"];
1682
+ shortcutKeys = ["control", "m"];
1683
+ commandName = "draw-door-line";
1684
+ onAddFromParent(parent) {
1685
+ const editor = parent.findComponentByName("Editor"), eventInput = editor.eventInput, commandManager = editor.commandManager;
1686
+ this.editor.container.add(this.container);
1687
+ const commandFlow = this.commandManager.addCommandFlow("draw-door-line").add(this.createInterrupt()).add(this.createCursor("no-drop")).add(this.selectPoint.bind(this));
1688
+ eventInput.addKeyCombination(this.commandName, this.shortcutKeys);
1689
+ commandFlow.addEventListener("finally", this.createFinally());
1690
+ commandFlow.addEventListener("completed", (e) => this.completed(e.data));
1691
+ eventInput.addCancelDefaultBehavior(() => eventInput.isOnlyKeyDowns(this.shortcutKeys));
1692
+ eventInput.addEventListener("codeChange", async () => {
1693
+ eventInput.isKeyCombination(this.commandName) && await commandManager.start(this.commandName);
1694
+ });
1695
+ }
1696
+ /** 选择点
1697
+ * @param next
1698
+ */
1699
+ selectPoint(next) {
1700
+ 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([
1701
+ new THREE.Vector3(-1e4, 0, 0),
1702
+ new THREE.Vector3(1e4, 0, 0),
1703
+ new THREE.Vector3(0, -1e4, 0),
1704
+ new THREE.Vector3(0, 1e4, 0)
1705
+ ], 16711935);
1706
+ auxiliaryLine.material = new THREE.LineDashedMaterial({
1707
+ color: 4235007,
1708
+ dashSize: 0.1,
1709
+ gapSize: 0.1,
1710
+ linewidth: 0.1
1711
+ });
1712
+ this.container.add(line);
1713
+ let currentPoint = null;
1714
+ this.addEventRecord(
1715
+ "clear",
1716
+ editor.addEventListener("pointerPositionChange", () => {
1717
+ const { point, find } = editor.renderManager.adsorption(0.05);
1718
+ start && line.setPoint(start, point);
1719
+ if (find) {
1720
+ circle.position.set(point.x, point.y, 0);
1721
+ this.container.add(circle);
1722
+ this.domElement.style.cursor = "none";
1723
+ currentPoint = point.clone();
1724
+ } else {
1725
+ currentPoint = null;
1726
+ circle.removeFromParent();
1727
+ this.domElement.style.cursor = "no-drop";
1728
+ }
1729
+ }),
1730
+ editor.eventInput.addEventListener("codeChange", async () => {
1731
+ if (editor.eventInput.isKeyDown("mouse_0") && currentPoint) {
1732
+ if (!start) {
1733
+ start = currentPoint.clone();
1734
+ return;
1735
+ }
1736
+ next([start.clone(), currentPoint.clone()]);
1737
+ }
1738
+ }),
1739
+ function() {
1740
+ line.removeFromParent();
1741
+ circle.removeFromParent();
1742
+ auxiliaryLine.removeFromParent();
1743
+ }
1744
+ );
1745
+ }
1746
+ /** 执行完成
1747
+ */
1748
+ completed(points) {
1749
+ const editor = this.editor, lines = [];
1750
+ for (let i = 0; i < points.length; i += 2) {
1751
+ const line = new LineSegment(Point.from(points[i]), Point.from(points[i + 1]));
1752
+ line.userData.isDoor = true;
1753
+ line.userData.doorDirectConnection = true;
1754
+ lines.push(line);
1755
+ }
1756
+ editor.renderManager.addLines(lines);
1757
+ editor.renderManager.draw();
1758
+ }
1759
+ }
1760
+ class DrawWindow extends CommandFlowComponent {
1761
+ static name = "DrawWindow";
1762
+ container = new THREE.Group();
1763
+ interruptKeys = ["escape"];
1764
+ shortcutKeys = ["control", "q"];
1765
+ commandName = "draw-window-line";
1766
+ onAddFromParent() {
1767
+ this.editor.container.add(this.container);
1768
+ 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));
1769
+ commandFlow.addEventListener("finally", this.createFinally());
1770
+ commandFlow.addEventListener("completed", (e) => this.completed(e.data));
1771
+ this.eventInput.addKeyCombination(this.commandName, this.shortcutKeys);
1772
+ this.eventInput.addEventListener("codeChange", async () => this.eventInput.isKeyCombination(this.commandName) && await this.commandManager.start(this.commandName));
1773
+ this.eventInput.addCancelDefaultBehavior(() => this.eventInput.isOnlyKeyDowns(this.shortcutKeys));
1774
+ }
1775
+ /** 选择开始点
1776
+ * @param next
1777
+ */
1778
+ selectPointStart(next) {
1779
+ let currentPoint = null, circle = new THREE.Mesh(new THREE.SphereGeometry(0.05), new THREE.MeshBasicMaterial({ color: 16711935 })), currentLine = null;
1780
+ this.addEventRecord("selectPointStart").add(this.editor.addEventListener("pointerPositionChange", () => {
1781
+ const { point, line, find } = this.editor.renderManager.adsorption();
1782
+ if (find) {
1783
+ this.domElement.style.cursor = "none";
1784
+ circle.position.copy(point);
1785
+ currentLine = line;
1786
+ currentPoint = point.clone();
1787
+ this.container.add(circle);
1788
+ } else {
1789
+ this.domElement.style.cursor = "no-drop";
1790
+ currentPoint = null;
1791
+ circle.removeFromParent();
1792
+ }
1793
+ })).add(this.eventInput.addEventListener("codeChange", () => {
1794
+ if (this.eventInput.isKeyDown("mouse_0") && currentPoint) {
1795
+ this.canceEventRecord("selectPointStart");
1796
+ next({ point: currentPoint, line: currentLine });
1797
+ }
1798
+ }));
1799
+ this.addEventRecord("clear").add(() => circle.removeFromParent());
1800
+ }
1801
+ /** 选择结束点
1802
+ * @param next
1803
+ */
1804
+ selectPointEnd(next, { point, line }) {
1805
+ let currentPoint = null, circle = new THREE.Mesh(new THREE.SphereGeometry(0.05), new THREE.MeshBasicMaterial({ color: 16711935 }));
1806
+ this.addEventRecord("clear").add(() => circle.removeFromParent()).add(this.editor.addEventListener("pointerPositionChange", () => {
1807
+ const { point: point2, find, line: l } = this.editor.renderManager.adsorption();
1808
+ if (find && l === line) {
1809
+ this.domElement.style.cursor = "none";
1810
+ circle.position.copy(point2);
1811
+ currentPoint = point2.clone();
1812
+ this.container.add(circle);
1813
+ } else {
1814
+ this.domElement.style.cursor = "no-drop";
1815
+ currentPoint = null;
1816
+ circle.removeFromParent();
1817
+ }
1818
+ })).add(this.eventInput.addEventListener("codeChange", () => {
1819
+ if (this.eventInput.isKeyDown("mouse_0") && currentPoint) next({ line, start: point, end: currentPoint });
1820
+ }));
1821
+ }
1822
+ /** 执行完成
1823
+ */
1824
+ completed(data) {
1825
+ 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();
1826
+ line.userData.isWindow = true;
1827
+ if (!line.userData.drawDoorData) line.userData.drawDoorData = [];
1828
+ line.userData.drawDoorData.push({
1829
+ p: new THREE.Vector3(center.x, center.y, 0),
1830
+ width: len,
1831
+ full: Math.abs(len - line.length()) < 0.01
1832
+ });
1833
+ this.renderManager.draw();
1834
+ }
1835
+ }
1836
+ class PointDrag extends CommandFlowComponent {
1837
+ static name = "PointDrag";
1838
+ container = new THREE.Group();
1839
+ interruptKeys = ["escape"];
1840
+ shortcutKeys = ["control", "p"];
1841
+ commandName = "point";
1842
+ onAddFromParent() {
1843
+ this.editor.container.add(this.container);
1844
+ this.container.position.z = 1e-3;
1845
+ const commandFlow = this.commandManager.addCommandFlow(this.commandName).add(this.createInterrupt()).add(this.createCursor("crosshair")).add(this.selectPoint.bind(this)).add(this.drag.bind(this));
1846
+ commandFlow.addEventListener("finally", this.createFinally());
1847
+ commandFlow.addEventListener("completed", (e) => this.completed(e.data));
1848
+ this.eventInput.addKeyCombination(this.commandName, this.shortcutKeys);
1849
+ this.eventInput.addEventListener("codeChange", async () => this.eventInput.isKeyCombination(this.commandName) && await this.commandManager.start(this.commandName));
1850
+ this.eventInput.addCancelDefaultBehavior(() => this.eventInput.isOnlyKeyDowns(this.shortcutKeys));
1851
+ }
1852
+ /** 选择开始点
1853
+ * @param next
1854
+ */
1855
+ selectPoint(next) {
1856
+ let currentPoint = null, circle = new THREE.Mesh(new THREE.SphereGeometry(0.05), new THREE.MeshBasicMaterial({ color: 16711935 })), currentLine = null;
1857
+ this.addEventRecord("selectPointStart").add(this.editor.addEventListener("pointerPositionChange", () => {
1858
+ const { point, line, find, mode } = this.editor.renderManager.adsorption();
1859
+ if (find && mode === "point") {
1860
+ this.domElement.style.cursor = "none";
1861
+ circle.position.copy(point);
1862
+ currentLine = line;
1863
+ currentPoint = point.clone();
1864
+ this.container.add(circle);
1865
+ } else {
1866
+ this.domElement.style.cursor = "no-drop";
1867
+ currentPoint = null;
1868
+ circle.removeFromParent();
1869
+ }
1870
+ })).add(this.eventInput.addEventListener("codeChange", () => {
1871
+ if (this.eventInput.isKeyDown("mouse_0") && currentPoint) {
1872
+ this.canceEventRecord("selectPointStart");
1873
+ circle.material.color.set(65280);
1874
+ next({ point: currentPoint, line: currentLine });
1875
+ }
1876
+ }));
1877
+ this.addEventRecord("clear").add(() => circle.removeFromParent());
1878
+ }
1879
+ /** 拖拽点
1880
+ * @description 拖拽点到指定位置
1881
+ * @param next
1882
+ * @param param1
1883
+ */
1884
+ drag(next, { point, line }) {
1885
+ this.domElement.style.cursor = "crosshair";
1886
+ 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 }));
1887
+ this.container.add(lines);
1888
+ this.addEventRecord("clear").add(this.editor.addEventListener("pointerPositionChange", () => {
1889
+ let { point: point2, find } = this.editor.renderManager.adsorption(), cursor = "none";
1890
+ if (point2) {
1891
+ if (this.eventInput.isKeyDown("shift")) {
1892
+ const p = line.projectPoint(Point.from(point2), false);
1893
+ point2.set(p?.x ?? point2.x, p?.y ?? point2.y, 0);
1894
+ find = true;
1895
+ cursor = "crosshair";
1896
+ }
1897
+ if (find) {
1898
+ circle.position.copy(point2);
1899
+ this.container.add(circle);
1900
+ } else {
1901
+ circle.removeFromParent();
1902
+ cursor = "crosshair";
1903
+ }
1904
+ end.copy(point2);
1905
+ lines.setPoint(start, end);
1906
+ this.domElement.style.cursor = cursor;
1907
+ }
1908
+ })).add(this.eventInput.addEventListener("codeChange", () => {
1909
+ if (this.eventInput.isKeyDown("mouse_0")) {
1910
+ this.canceEventRecord("selectPointStart");
1911
+ next({ point: end, line, mode });
1912
+ }
1913
+ })).add(() => circle.removeFromParent()).add(() => lines.removeFromParent());
1914
+ }
1915
+ /** 执行完成
1916
+ */
1917
+ completed(data) {
1918
+ const { line, point, mode } = data;
1919
+ this.renderManager.removeLine(line);
1920
+ if (mode === "end") line.end.set(point.x, point.y);
1921
+ else if (mode === "start") line.start.set(point.x, point.y);
1922
+ this.renderManager.addLine(line);
1923
+ this.renderManager.draw();
1924
+ }
1925
+ }
1926
+ function Editor2(dxfSystem) {
1927
+ dxfSystem.addComponent(new Editor$1());
1928
+ dxfSystem.addComponent(new RenderManager());
1929
+ dxfSystem.addComponent(new Default());
1930
+ dxfSystem.addComponent(new DrawLine());
1931
+ dxfSystem.addComponent(new DrawDoorLine());
1932
+ dxfSystem.addComponent(new DrawWindow());
1933
+ dxfSystem.addComponent(new PointDrag());
1934
+ }
1935
+ export {
1936
+ Editor2 as Editor
1937
+ };