build-dxf 0.0.19 → 0.0.20-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 (39) hide show
  1. package/README.md +30 -0
  2. package/package.json +1 -3
  3. package/src/build.d.ts +23 -1
  4. package/src/build.js +70 -16
  5. package/src/index.css +661 -1
  6. package/src/index.js +4 -2
  7. package/src/index2.js +9 -3681
  8. package/src/index3.js +1546 -410
  9. package/src/pages/Editor.vue.d.ts +3 -1
  10. package/src/selectLocalFile.js +444 -21
  11. package/src/utils/CommandManager/CommandFlow.d.ts +16 -0
  12. package/src/utils/CommandManager/CommandManager.d.ts +23 -0
  13. package/src/utils/ComponentManager/Component.d.ts +1 -0
  14. package/src/utils/ComponentManager/ComponentManager.d.ts +1 -1
  15. package/src/utils/DxfSystem/components/Dxf.d.ts +1 -0
  16. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/CommandFlowComponent.d.ts +13 -3
  17. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/ConnectionLine.d.ts +33 -0
  18. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/Default.d.ts +5 -19
  19. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DeleteSelectLine.d.ts +28 -0
  20. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DeleteSelectWindow.d.ts +33 -0
  21. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DrawDoorLine.d.ts +19 -3
  22. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DrawLine.d.ts +22 -5
  23. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DrawWindow.d.ts +22 -2
  24. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/IntersectionConnectionLine.d.ts +33 -0
  25. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/MergeLine.d.ts +32 -0
  26. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/PointDrag.d.ts +16 -2
  27. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/SelectAll.d.ts +30 -0
  28. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/VerticalCorrection.d.ts +63 -0
  29. package/src/utils/DxfSystem/plugin/Editor/components/Editor.d.ts +7 -0
  30. package/src/utils/DxfSystem/plugin/Editor/components/index.d.ts +1 -0
  31. package/src/utils/DxfSystem/plugin/Editor/index.d.ts +8 -1
  32. package/src/utils/DxfSystem/plugin/Editor/pages/EditorTool.vue.d.ts +5 -1
  33. package/src/utils/DxfSystem/plugin/RenderPlugin/components/DomEventRegister.d.ts +28 -6
  34. package/src/utils/DxfSystem/plugin/RenderPlugin/components/Renderer.d.ts +1 -1
  35. package/src/utils/DxfSystem/plugin/RenderPlugin/index.d.ts +2 -1
  36. package/src/utils/Quadtree/LineSegment.d.ts +2 -1
  37. package/src/utils/Quadtree/Point.d.ts +2 -1
  38. package/src/components/Editor.vue.d.ts +0 -26
  39. package/src/pages/Editor02.vue.d.ts +0 -4
package/src/index3.js CHANGED
@@ -1,10 +1,10 @@
1
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";
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$1, 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, W as WhiteModel } from "./build.js";
5
4
  import "clipper-lib";
6
5
  import "dxf-writer";
7
6
  import "three/addons/controls/OrbitControls.js";
7
+ 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, onUnmounted, renderList, createStaticVNode, TransitionGroup, createApp } from "vue";
8
8
  function unrefElement(elRef) {
9
9
  var _a;
10
10
  const plain = resolveUnref(elRef);
@@ -258,7 +258,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
258
258
  };
259
259
  }
260
260
  });
261
- var Badge = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__file", "badge.vue"]]);
261
+ var Badge = /* @__PURE__ */ _export_sfc$1(_sfc_main$2, [["__file", "badge.vue"]]);
262
262
  const ElBadge = withInstall(Badge);
263
263
  const configProviderProps = buildProps({
264
264
  a11y: {
@@ -565,7 +565,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
565
565
  };
566
566
  }
567
567
  });
568
- var MessageConstructor = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__file", "message.vue"]]);
568
+ var MessageConstructor = /* @__PURE__ */ _export_sfc$1(_sfc_main$1, [["__file", "message.vue"]]);
569
569
  let seed = 1;
570
570
  const normalizeOptions = (params) => {
571
571
  const options = !params || isString$1(params) || isVNode(params) || isFunction(params) ? { message: params } : params;
@@ -713,19 +713,39 @@ class CommandFlowComponent extends Component {
713
713
  if (!this._commandManager) this._commandManager = this.editor?.commandManager;
714
714
  return this._commandManager;
715
715
  }
716
+ _default;
717
+ get default() {
718
+ if (!this._default) this._default = this.parent?.findComponentByName("Default");
719
+ return this._default;
720
+ }
716
721
  interruptKeys = ["escape"];
722
+ commandName = "";
723
+ constructor() {
724
+ super();
725
+ }
726
+ onAddFromParent(parent) {
727
+ this.editor.addEventListener("cancelCommand", () => {
728
+ this.cancel();
729
+ });
730
+ }
731
+ /**
732
+ * 取消
733
+ */
734
+ cancel() {
735
+ const commandName = this.commandName || this.constructor.commandName;
736
+ if (this.commandManager.currentName !== commandName) return;
737
+ this.commandManager.cancel();
738
+ }
717
739
  /**
718
- * 创建中断
740
+ * 创建中断处理命令节点
719
741
  * @returns
720
742
  */
721
743
  createInterrupt() {
722
744
  return (next, data) => {
723
745
  this.addEventRecord(
724
746
  "clear",
725
- this.editor?.eventInput.addEventListener("codeChange", async () => {
726
- if (this.editor.eventInput.isKeyDowns(this.interruptKeys)) {
727
- this.editor.commandManager.cancel();
728
- }
747
+ this.eventInput.addEventListener("codeChange", async () => {
748
+ if (this.eventInput.isKeyDowns(this.interruptKeys)) this.cancel();
729
749
  })
730
750
  );
731
751
  next(data);
@@ -750,9 +770,10 @@ class CommandFlowComponent extends Component {
750
770
  * 创建清理
751
771
  * @returns
752
772
  */
753
- createFinally() {
773
+ createFinally(keys = []) {
754
774
  return () => {
755
775
  this.canceEventRecord("clear");
776
+ keys.forEach((k) => this.canceEventRecord(k));
756
777
  };
757
778
  }
758
779
  }
@@ -764,9 +785,10 @@ class DrawLine extends CommandFlowComponent {
764
785
  shortcutKeys = ["control", "l"];
765
786
  confirmKeys = ["enter"];
766
787
  commandName = "draw-line";
767
- onAddFromParent() {
788
+ onAddFromParent(parent) {
789
+ super.onAddFromParent(parent);
768
790
  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));
791
+ const commandFlow = this.commandManager.addCommandFlow(this.commandName).add(this.createInterrupt()).add(this.createCursor("crosshair")).add(this.selectPoint.bind(this)).add(this.end.bind(this)).addRollback(this.rollback.bind(this)).addRevokeRollback(this.revokeRollback.bind(this));
770
792
  commandFlow.addEventListener("finally", this.createFinally());
771
793
  commandFlow.addEventListener("completed", (e) => this.completed(e.data));
772
794
  this.eventInput.addKeyCombination(this.commandName, this.shortcutKeys);
@@ -777,7 +799,7 @@ class DrawLine extends CommandFlowComponent {
777
799
  * @param next
778
800
  */
779
801
  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([
802
+ 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, line2 = new Lines([], 16711935), auxiliaryLine = new Lines([
781
803
  new THREE.Vector3(-1e4, 0, 0),
782
804
  new THREE.Vector3(1e4, 0, 0),
783
805
  new THREE.Vector3(0, -1e4, 0),
@@ -789,9 +811,9 @@ class DrawLine extends CommandFlowComponent {
789
811
  gapSize: 0.1,
790
812
  linewidth: 0.1
791
813
  });
792
- this.container.add(line);
814
+ this.container.add(line2);
793
815
  const updateLine = () => {
794
- line.setPoint(...points, start, end);
816
+ line2.setPoint(...points, start, end);
795
817
  auxiliaryLine.position.copy(end);
796
818
  this.container.add(auxiliaryLine);
797
819
  auxiliaryLine.computeLineDistances();
@@ -801,13 +823,14 @@ class DrawLine extends CommandFlowComponent {
801
823
  "clear",
802
824
  editor.addEventListener("pointerPositionChange", () => {
803
825
  const { point, find } = editor.renderManager.adsorption();
826
+ this.dispatchEvent({ type: "pointerMove", point });
804
827
  if (find) {
805
828
  circle.position.set(point.x, point.y, 0);
806
829
  this.container.add(circle);
807
- dom.parentElement.style.cursor = "none";
830
+ dom.style.cursor = "none";
808
831
  } else {
809
832
  circle.removeFromParent();
810
- dom.parentElement.style.cursor = "crosshair";
833
+ dom.style.cursor = "crosshair";
811
834
  }
812
835
  currentPoint.copy(point);
813
836
  if (!(start && end)) return;
@@ -845,21 +868,43 @@ class DrawLine extends CommandFlowComponent {
845
868
  } else if (editor.eventInput.isKeyDowns(this.confirmKeys)) next(points);
846
869
  }),
847
870
  function() {
848
- line.removeFromParent();
871
+ line2.removeFromParent();
849
872
  circle.removeFromParent();
850
873
  auxiliaryLine.removeFromParent();
851
874
  }
852
875
  );
853
876
  }
854
- /** 执行完成
877
+ /** 结束, 汇总结果
878
+ * @param points
855
879
  */
856
- completed(points) {
857
- const editor = this.editor, lines = [];
880
+ end(next, points) {
881
+ const lines = [];
858
882
  for (let i = 0; i < points.length; i += 2) {
859
883
  lines.push(new LineSegment(Point.from(points[i]), Point.from(points[i + 1])));
860
884
  }
861
- editor.renderManager.addLines(lines);
862
- editor.renderManager.draw();
885
+ next(lines);
886
+ }
887
+ /** 执行完成
888
+ */
889
+ completed(lines) {
890
+ this.renderManager.addLines(lines);
891
+ this.renderManager.draw();
892
+ }
893
+ /** 回滚操作
894
+ * @param data
895
+ */
896
+ rollback(lines) {
897
+ lines.forEach((line2) => this.renderManager.removeLine(line2));
898
+ this.renderManager.draw();
899
+ return lines;
900
+ }
901
+ /** 撤回回滚
902
+ * @param lines
903
+ * @returns
904
+ */
905
+ revokeRollback(lines) {
906
+ this.completed(lines);
907
+ return lines;
863
908
  }
864
909
  }
865
910
  class Default extends Component {
@@ -889,6 +934,9 @@ class Default extends Component {
889
934
  if (this.selectLines.indexOf(lineSegment) > -1) return;
890
935
  this.selectLines.push(lineSegment);
891
936
  this.updateSelectLinesGeometry();
937
+ this.dispatchEvent({
938
+ type: "selectLineChange"
939
+ });
892
940
  }
893
941
  /** 移除选择的线段
894
942
  * @param lineSegment
@@ -898,112 +946,19 @@ class Default extends Component {
898
946
  if (i > -1) {
899
947
  this.selectLines.splice(i, 1);
900
948
  this.updateSelectLinesGeometry();
949
+ this.dispatchEvent({
950
+ type: "selectLineChange"
951
+ });
901
952
  }
902
953
  }
903
954
  /**
904
- * 删除选择的线段
955
+ * 移除所有选中线段
905
956
  */
906
- deleteSelectLine() {
907
- const editor = this.editor;
908
- this.selectLines.forEach((line) => editor.renderManager.removeLine(line));
957
+ removeSelectLineAll() {
909
958
  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;
959
+ this.dispatchEvent({
960
+ type: "selectLineChange"
922
961
  });
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
962
  }
1008
963
  _timer = null;
1009
964
  /**
@@ -1012,10 +967,11 @@ class Default extends Component {
1012
967
  updateSelectLinesGeometry() {
1013
968
  if (this._timer) clearTimeout(this._timer);
1014
969
  this._timer = setTimeout(() => {
970
+ if (this.destroyed) return;
1015
971
  if (this.selectLines.length) this.container.add(this.selectLineObject3D);
1016
972
  else this.selectLineObject3D.removeFromParent();
1017
973
  const editor = this.editor;
1018
- const position = this.selectLines.flatMap((line) => line.expandToRectangle(0.04, "bothSides").createGeometry());
974
+ const position = this.selectLines.flatMap((line2) => line2.expandToRectangle(0.04, "bothSides").createGeometry());
1019
975
  this.selectLineObject3D.geometry = editor.renderManager.createGeometry({ position }, position.length / 3);
1020
976
  }, 10);
1021
977
  }
@@ -1029,14 +985,6 @@ class Default extends Component {
1029
985
  object3D.position.z = 0.01;
1030
986
  this.selectLineObject3D.position.z = object3D.position.z + 0.01;
1031
987
  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
988
  const showSelectBox = () => {
1041
989
  const startPoint = editor.pointerPosition.clone(), endPoint = editor.pointerPosition.clone(), mesh = new THREE.Mesh();
1042
990
  this.container.add(mesh);
@@ -1081,7 +1029,7 @@ class Default extends Component {
1081
1029
  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
1030
  const box = new Box2(minX, maxX, minY, maxY);
1083
1031
  const resultList = editor.renderManager.quadtree.queryBox(box);
1084
- this.selectLines.length = 0;
1032
+ this.removeSelectLineAll();
1085
1033
  resultList.forEach((result) => this.addSelectLine(result.line));
1086
1034
  this.updateSelectLinesGeometry();
1087
1035
  };
@@ -1092,16 +1040,16 @@ class Default extends Component {
1092
1040
  "clear",
1093
1041
  // 注册鼠标指针位置变化事件
1094
1042
  editor.addEventListener("pointerPositionChange", () => {
1095
- const { line } = editor.renderManager.adsorption(0.05);
1096
- if (line) {
1097
- const rectangle = line.expandToRectangle(0.02, "bothSides");
1043
+ const { line: line2 } = editor.renderManager.adsorption(0.05);
1044
+ if (line2) {
1045
+ const rectangle = line2.expandToRectangle(0.02, "bothSides");
1098
1046
  object3D.geometry = editor.renderManager.createGeometry({ position: rectangle.createGeometry() }, 6);
1099
1047
  this.container.add(object3D);
1100
- dom.parentElement.style.cursor = "pointer";
1101
- currentSelectLine = line;
1048
+ dom.style.cursor = "pointer";
1049
+ currentSelectLine = line2;
1102
1050
  } else {
1103
1051
  object3D.removeFromParent();
1104
- dom.parentElement.style.cursor = "default";
1052
+ dom.style.cursor = "default";
1105
1053
  currentSelectLine = null;
1106
1054
  }
1107
1055
  }),
@@ -1111,18 +1059,12 @@ class Default extends Component {
1111
1059
  if (eventInput.isKeyDown("alt")) {
1112
1060
  return this.removeSelectLine(currentSelectLine);
1113
1061
  }
1114
- if (!eventInput.isKeyDown("control")) this.selectLines.length = 0;
1062
+ if (!eventInput.isKeyDown("control")) this.removeSelectLineAll();
1115
1063
  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();
1064
+ } else if (eventInput.isKeyDowns(["control", "z"])) {
1065
+ editor.commandManager.rollback();
1066
+ } else if (eventInput.isKeyDowns(["control", "y"])) {
1067
+ editor.commandManager.revokeRollback();
1126
1068
  }
1127
1069
  }),
1128
1070
  function() {
@@ -1135,16 +1077,38 @@ class Default extends Component {
1135
1077
  */
1136
1078
  finally() {
1137
1079
  this.canceEventRecord("clear");
1138
- this.selectLines.length = 0;
1080
+ this.removeSelectLineAll();
1139
1081
  this.updateSelectLinesGeometry();
1140
1082
  }
1141
1083
  }
1142
1084
  class CommandFlow extends EventDispatcher {
1143
1085
  list = [];
1086
+ rollbacklist = [];
1087
+ revokeRollbacklist = [];
1088
+ /**
1089
+ *
1090
+ * @param operation
1091
+ * @returns
1092
+ */
1144
1093
  add(operation) {
1145
1094
  this.list.push(operation);
1146
1095
  return this;
1147
1096
  }
1097
+ /** 添加回滚回调列表
1098
+ * @param callBack
1099
+ */
1100
+ addRollback(callBack) {
1101
+ this.rollbacklist.push(callBack);
1102
+ return this;
1103
+ }
1104
+ /** 添加撤回回滚回调列表
1105
+ * @param callBack
1106
+ * @returns
1107
+ */
1108
+ addRevokeRollback(callBack) {
1109
+ this.revokeRollbacklist.push(callBack);
1110
+ return this;
1111
+ }
1148
1112
  }
1149
1113
  class CommandManager extends EventDispatcher {
1150
1114
  commandFlowMap = /* @__PURE__ */ new Map();
@@ -1160,6 +1124,11 @@ class CommandManager extends EventDispatcher {
1160
1124
  get disabled() {
1161
1125
  return this._disabled;
1162
1126
  }
1127
+ /**
1128
+ * 操作记录
1129
+ */
1130
+ operationList = [];
1131
+ rollbackList = [];
1163
1132
  constructor() {
1164
1133
  super();
1165
1134
  }
@@ -1189,7 +1158,7 @@ class CommandManager extends EventDispatcher {
1189
1158
  this.executionPromise && await this.executionPromise;
1190
1159
  this.executionPromise = null;
1191
1160
  if (this.lock) {
1192
- throw new Error("命令管理器已被锁定,无法启动新的命令流");
1161
+ throw new Error("命令管理器已被 " + this.currentName + " 命令锁定,无法启动新的命令流,请退出或等待命令执行结束");
1193
1162
  }
1194
1163
  const commandFlow = this.commandFlowMap.get(name);
1195
1164
  if (!commandFlow) {
@@ -1225,6 +1194,8 @@ class CommandManager extends EventDispatcher {
1225
1194
  if (this.abortController && !this.abortController.signal.aborted) {
1226
1195
  commandFlow.dispatchEvent({ type: "completed", data });
1227
1196
  this.dispatchEvent({ type: "completed", name, data });
1197
+ this.operationList.push({ name, data });
1198
+ this.rollbackList.length = 0;
1228
1199
  }
1229
1200
  this.lock = false;
1230
1201
  this.abortController = null;
@@ -1247,186 +1218,109 @@ class CommandManager extends EventDispatcher {
1247
1218
  this.executionPromise = new Promise((resolve) => this.executionResolve = resolve);
1248
1219
  }
1249
1220
  }
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
1221
  /**
1377
- * 打开编辑器
1222
+ * 回滚
1378
1223
  */
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;
1224
+ rollback() {
1225
+ try {
1226
+ const operation = this.operationList.pop();
1227
+ if (!operation) return false;
1228
+ const commandFlow = this.commandFlowMap.get(operation.name);
1229
+ if (!commandFlow) return false;
1230
+ const data = commandFlow.rollbacklist.reduce((data2, callBack) => callBack(data2), operation.data);
1231
+ this.dispatchEvent({ type: "rollback", name: operation.name });
1232
+ this.rollbackList.push({
1233
+ data,
1234
+ name: operation.name
1235
+ });
1236
+ return true;
1237
+ } catch (error) {
1238
+ throw new Error(`回滚失败:${error}`);
1387
1239
  }
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
1240
  }
1413
1241
  /**
1414
- * 退出编辑
1242
+ * 撤销回滚
1415
1243
  */
1416
- exitEdit() {
1417
- if (typeof this._exitEditCallBack === "function") {
1418
- this._exitEditCallBack();
1419
- this._exitEditCallBack = void 0;
1420
- this.commandManager.disabled = true;
1244
+ revokeRollback() {
1245
+ try {
1246
+ const operation = this.rollbackList.pop();
1247
+ if (!operation) return false;
1248
+ const commandFlow = this.commandFlowMap.get(operation.name);
1249
+ if (!commandFlow) return false;
1250
+ const data = commandFlow.revokeRollbacklist.reduce((data2, callBack) => callBack(data2), operation.data);
1251
+ this.dispatchEvent({ type: "revokeRollback", name: operation.name });
1252
+ this.operationList.push({ name: operation.name, data });
1253
+ return true;
1254
+ } catch (error) {
1255
+ throw new Error(`撤回回滚失败:${error}`);
1421
1256
  }
1422
1257
  }
1423
- destroy() {
1424
- this.exitEdit();
1425
- this.renderer.scene.remove(this.container);
1426
- this.domElement.remove();
1427
- this.app?.unmount();
1428
- }
1429
- };
1258
+ }
1259
+ const connection = "data:image/svg+xml,%3csvg%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20fill='%23555'%20width='16'%20height='16'%3e%3cpath%20d='M639.999191%20893.597594c-0.999994-54.699654-36.39977-101.099361-85.39946-118.399252-6.39996-2.199986-10.599933-8.299948-10.599933-14.999905V263.801573c0-6.699958%204.199973-12.799919%2010.599933-14.999905%2049.09969-17.299891%2084.399467-63.599598%2085.39946-118.399252C641.299183%2059.902862%20583.399549%200.503237%20512.899994%200.00324%20441.800444-0.496757%20384.000809%2057.00288%20384.000809%20128.002431c0%2055.699648%2035.599775%20103.099349%2085.299461%20120.699238%206.39996%202.299985%2010.699932%208.299948%2010.699932%2015.099904v496.396864c0%206.799957-4.299973%2012.799919-10.699932%2015.099904-49.699686%2017.599889-85.299461%2064.999589-85.299461%20120.699238%200%2070.999551%2057.799635%20128.499188%20128.899185%20127.999191%2070.499555-0.499997%20128.399189-59.899622%20127.099197-130.399176zM448.000404%20128.002431c0-35.299777%2028.699819-63.999596%2063.999596-63.999595s63.999596%2028.699819%2063.999596%2063.999595-28.699819%2063.999596-63.999596%2063.999596-63.999596-28.699819-63.999596-63.999596z%20m0%20767.995148c0-35.299777%2028.699819-63.999596%2063.999596-63.999596s63.999596%2028.699819%2063.999596%2063.999596-28.699819%2063.999596-63.999596%2063.999595-63.999596-28.699819-63.999596-63.999595z'%3e%3c/path%3e%3c/svg%3e";
1260
+ const __vite_glob_0_0 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1261
+ __proto__: null,
1262
+ default: connection
1263
+ }, Symbol.toStringTag, { value: "Module" }));
1264
+ const deleteSelectLine = "data:image/svg+xml,%3csvg%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20fill='%23555'%20width='16'%20height='16'%3e%3cpath%20d='M909.050991%20169.476903l-217.554898%200%200-31.346939c0-39.5866-32.205493-71.792093-71.793116-71.792093L408.15591%2066.337871c-39.5866%200-71.792093%2032.205493-71.792093%2071.792093l0%2031.346939L113.349581%20169.476903c-11.013845%200-19.942191%208.940626-19.942191%2019.954471s8.928347%2019.954471%2019.942191%2019.954471l84.264149%200%200%20640.687918c0%2060.479443%2049.203632%20109.683075%20109.683075%20109.683075l416.474366%200c60.479443%200%20109.683075-49.203632%20109.683075-109.683075L833.454246%20209.385844l75.595722%200c11.012821%200%2019.942191-8.940626%2019.942191-19.954471S920.063813%20169.476903%20909.050991%20169.476903zM376.2482%20138.130987c0-17.593703%2014.314007-31.907711%2031.907711-31.907711l211.547067%200c17.593703%200%2031.907711%2014.314007%2031.907711%2031.907711l0%2031.346939L376.2482%20169.477926%20376.2482%20138.130987zM793.569864%20850.074785c0%2038.486546-31.312146%2069.798692-69.798692%2069.798692L307.297828%20919.873478c-38.486546%200-69.798692-31.312146-69.798692-69.798692L237.499136%20211.042577l556.070728%200L793.569864%20850.074785zM510.662539%20861.276918c11.012821%200%2019.954471-8.92937%2019.954471-19.942191L530.61701%20294.912753c0-11.013845-8.94165-19.942191-19.954471-19.942191s-19.954471%208.928347-19.954471%2019.942191L490.708068%20841.334727C490.708068%20852.347548%20499.649717%20861.276918%20510.662539%20861.276918zM374.562814%20801.449321c11.012821%200%2019.954471-8.92937%2019.954471-19.942191L394.517285%20354.74035c0-11.013845-8.94165-19.942191-19.954471-19.942191s-19.954471%208.928347-19.954471%2019.942191l0%20426.76678C354.608344%20792.519951%20363.549993%20801.449321%20374.562814%20801.449321zM649.832182%20801.449321c11.012821%200%2019.954471-8.92937%2019.954471-19.942191L669.786653%20354.74035c0-11.013845-8.94165-19.942191-19.954471-19.942191s-19.954471%208.928347-19.954471%2019.942191l0%20426.76678C629.877711%20792.519951%20638.81936%20801.449321%20649.832182%20801.449321z'%20%3e%3c/path%3e%3c/svg%3e";
1265
+ const __vite_glob_0_1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1266
+ __proto__: null,
1267
+ default: deleteSelectLine
1268
+ }, Symbol.toStringTag, { value: "Module" }));
1269
+ const deleteSelectWindow = "data:image/svg+xml,%3csvg%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20fill='%23555'%20width='16'%20height='16'%3e%3cpath%20d='M220.451548%20913.518482V318.145854c0-27.62038%2022.505495-50.125874%2050.125875-50.125874H865.95005c27.62038%200%2050.125874%2022.505495%2050.125874%2050.125874v218.917083h59.332667V318.145854c0-60.355644-49.102897-109.458541-109.458541-109.458541h-39.896104v-99.228772C826.053946%2049.102897%20776.951049%200%20716.595405%200H121.222777C60.867133%200%2011.764236%2049.102897%2011.764236%20109.458541V705.854146c0%2060.355644%2049.102897%20109.458541%20109.458541%20109.458541h39.896104v99.228772c0%2060.355644%2049.102897%20109.458541%20109.458542%20109.458541h257.790209v-59.332667H269.554446c-26.597403-1.022977-49.102897-23.528472-49.102898-51.148851z%20m-59.332667-595.372628v436.811189h-39.896104c-27.62038%200-50.125874-22.505495-50.125874-50.125874V109.458541c0-27.62038%2022.505495-50.125874%2050.125874-50.125874H716.595405c27.62038%200%2050.125874%2022.505495%2050.125874%2050.125874v99.228772H269.554446c-59.332667%200-108.435564%2049.102897-108.435565%20109.458541z'%20%3e%3c/path%3e%3cpath%20d='M902.777223%20854.185814l98.205794-98.205794c15.344655-15.344655%2015.344655-40.919081%200-56.263736s-40.919081-15.344655-56.263736%200L846.513487%20797.922078%20747.284715%20699.716284c-15.344655-15.344655-40.919081-15.344655-56.263736%200s-15.344655%2040.919081%200%2056.263736l98.205794%2098.205794-98.205794%2098.205794c-15.344655%2015.344655-15.344655%2040.919081%200%2056.263737s40.919081%2015.344655%2056.263736%200l98.205794-98.205795%2098.205795%2098.205795c15.344655%2015.344655%2040.919081%2015.344655%2056.263736%200s15.344655-40.919081%200-56.263737l-97.182817-98.205794z'%20%3e%3c/path%3e%3c/svg%3e";
1270
+ const __vite_glob_0_2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1271
+ __proto__: null,
1272
+ default: deleteSelectWindow
1273
+ }, Symbol.toStringTag, { value: "Module" }));
1274
+ const door = "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='1757902601497'%20class='icon'%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='9801'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20width='200'%20height='200'%3e%3cpath%20d='M761.344%20119.296H226.816c-18.944%200-39.424%2011.776-39.424%2030.72V921.6h614.4V148.48c0.512-18.944-22.016-29.184-40.448-29.184z%20m-537.6%20768c-2.048%200-2.048%200%200%200L221.696%20163.84c0-5.12%205.12-10.24%2010.24-10.24h522.24c8.704%200%2013.824%205.12%2013.824%2013.824v720.384s0%201.536-1.536%201.536h-15.36V194.56c0-16.896-8.704-24.064-29.184-24.064H266.24c-18.944%200-27.136%208.704-27.136%2024.064v692.736h-15.36z%20m49.152%200V204.8H716.8v682.496H272.896z'%20p-id='9802'%3e%3c/path%3e%3cpath%20d='M648.704%20508.416c-16.896%200-32.256%2013.824-32.256%2032.256%200%2016.896%2013.824%2032.256%2032.256%2032.256s32.256-13.824%2032.256-32.256c0-16.896-13.824-32.256-32.256-32.256z'%20p-id='9803'%3e%3c/path%3e%3c/svg%3e";
1275
+ const __vite_glob_0_3 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1276
+ __proto__: null,
1277
+ default: door
1278
+ }, Symbol.toStringTag, { value: "Module" }));
1279
+ const intersectionConnection = "data:image/svg+xml,%3csvg%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20fill='%23555'%20width='16'%20height='16'%3e%3cpath%20d='M491.80027198%20557.44938977c-10.0998647-15.14979706-20.19972802-25.24966037-35.34952507-35.34952507-15.14979706-10.0998647-30.29959271-15.14979706-50.49932211-15.14979704-55.54925309%200-100.99864286%2045.44938977-100.99864287%20100.99864285%200%2015.14979706%205.04993234%2035.34952507%2015.14979568%2050.49932212%2010.0998647%2015.14979706%2020.19972802%2030.29959271%2035.34952506%2035.34952508%2015.14979706%2010.0998647%2035.34952507%2015.14979706%2050.49932213%2015.14979567%2055.54925309%200%20100.99864286-45.44938977%20100.99864286-100.99864287%200-15.14979706-5.04993234-35.34952507-15.14979568-50.49932074z%20m-85.84884718%20100.99864286h-15.14979706c-20.19972802-5.04993234-30.29959271-20.19972802-35.34952507-35.34952507V612.99864286c0-30.29959271%2025.24966037-50.49932212%2050.49932213-50.49932074h10.09986469c15.14979706%205.04993234%2030.29959271%2015.14979706%2035.34952507%2035.34952507v15.14979567c5.04993234%2025.24966037-20.19972802%2045.44938977-45.44938976%2045.44938977z'%3e%3c/path%3e%3cpath%20d='M390.80162774%20658.44803263l-40.39945604%2040.39945743-227.24694747%20222.19701373-35.34952506-35.34952508%20227.24694745-227.24694608%2040.39945605-40.39945743c5.04993234%2020.19972802%2020.19972802%2035.34952507%2035.34952507%2040.39945743zM648.34816793%20405.9514248l-40.39945742%2040.3994574-116.14843853%20116.14843992-40.39945742%2035.34952507c-5.04993234-20.19972802-20.19972802-30.29959271-35.34952507-35.34952507l40.39945742-40.39945742%20116.14843853-111.09850756%2035.34952507-35.34952507c10.0998647%2015.14979706%2020.19972802%2025.24966037%2040.39945742%2030.29959273zM926.09443614%20133.25508894L749.34681078%20310.00271428l-40.3994574%2040.39945742c-5.04993234-20.19972802-15.14979706-35.34952507-30.29959272-40.39945742l35.34952506-40.39945742%20176.74762534-176.74762535%2035.34952508%2040.39945743z'%20%3e%3c/path%3e%3cpath%20d='M749.34681078%20310.00271428c-10.0998647-15.14979706-20.19972802-30.29959271-35.34952506-35.34952506-15.14979706-10.0998647-35.34952507-15.14979706-55.54925309-15.14979706-55.54925309%200-100.99864286%2045.44938977-100.99864286%20100.99864286%200%2020.19972802%205.04993234%2040.39945743%2015.14979567%2055.54925447%2010.0998647%2015.14979706%2020.19972802%2025.24966037%2035.34952507%2035.34952507%2015.14979706%2010.0998647%2030.29959271%2015.14979706%2050.49932212%2015.14979567%2055.54925309%200%20100.99864286-45.44938977%20100.99864286-100.99864286%200-25.24966037-5.04993234-40.39945743-10.09986471-55.54925309z%20m-90.89877815%2095.94871052h-10.0998647c-20.19972802-5.04993234-35.34952507-15.14979706-40.39945742-35.34952509%200-5.04993234-5.04993234-10.0998647-5.04993234-15.14979704%200-30.29959271%2025.24966037-50.49932212%2050.49932212-50.49932074%205.04993234%200%2010.0998647%200%2015.14979704%205.04993235%2015.14979706%205.04993234%2030.29959271%2020.19972802%2030.29959273%2040.39945742v10.09986332c10.0998647%2025.24966037-15.14979706%2045.44938977-40.39945743%2045.44938978z'%20%3e%3c/path%3e%3c/svg%3e";
1280
+ const __vite_glob_0_4 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1281
+ __proto__: null,
1282
+ default: intersectionConnection
1283
+ }, Symbol.toStringTag, { value: "Module" }));
1284
+ const line = "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";
1285
+ const __vite_glob_0_5 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1286
+ __proto__: null,
1287
+ default: line
1288
+ }, Symbol.toStringTag, { value: "Module" }));
1289
+ const mergeLine = "data:image/svg+xml,%3csvg%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20fill='%23555'%20width='16'%20height='16'%3e%3cpath%20d='M114.176%2046.528h618.496c37.312%200.064%2067.584%2030.336%2067.648%2067.648v618.56c0%2037.248-30.336%2067.584-67.648%2067.584H114.176A67.776%2067.776%200%200%201%2046.528%20732.8V114.176c0-37.312%2030.336-67.648%2067.648-67.648z%20m2.176%20686.208l616.32-2.24-2.176-616.32-614.144%202.176v616.32zM907.648%20291.2l2.176%20616.32H291.264a34.88%2034.88%200%201%200%200%2069.888h618.56c37.312%200%2067.648-30.336%2067.648-67.648V291.264a34.88%2034.88%200%201%200-69.824%200z'%20%3e%3c/path%3e%3c/svg%3e";
1290
+ const __vite_glob_0_6 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1291
+ __proto__: null,
1292
+ default: mergeLine
1293
+ }, Symbol.toStringTag, { value: "Module" }));
1294
+ const revokeRollback = "data:image/svg+xml,%3csvg%20viewBox='0%200%201029%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20fill='%23555'%20width='16'%20height='16'%3e%3cpath%20d='M788.17984%2016l-55.424%2060.672%20116.48%20106.56H418.13184a410.816%20410.816%200%201%200%200%20821.632h547.712v-82.176H418.13184a328.64%20328.64%200%200%201%200-657.28l441.792-0.128-124.8%2098.368%2050.752%2064.512%20243.328-191.488L788.17984%2016z'%3e%3c/path%3e%3c/svg%3e";
1295
+ const __vite_glob_0_7 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1296
+ __proto__: null,
1297
+ default: revokeRollback
1298
+ }, Symbol.toStringTag, { value: "Module" }));
1299
+ const rollback = "data:image/svg+xml,%3csvg%20viewBox='0%200%201048%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20fill='%23555'%20width='16'%20height='16'%3e%3cpath%20d='M310.04722%20451.334244A49.95122%2049.95122%200%200%201%20239.416195%20521.990244L27.473171%20310.04722a49.95122%2049.95122%200%200%201%200-70.631025L239.416195%2027.473171a49.95122%2049.95122%200%200%201%2070.631025%2070.631024l-126.651318%20126.626342L649.365854%20224.780488c220.709463%200%20399.609756%20178.900293%20399.609756%20399.609756s-178.900293%20399.609756-399.609756%20399.609756H124.878049a49.95122%2049.95122%200%201%201%200-99.902439h524.487805c165.513366%200%20299.707317-134.193951%20299.707317-299.707317s-134.193951-299.707317-299.707317-299.707317H183.395902l126.651318%20126.651317z'%3e%3c/path%3e%3c/svg%3e";
1300
+ const __vite_glob_0_8 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1301
+ __proto__: null,
1302
+ default: rollback
1303
+ }, Symbol.toStringTag, { value: "Module" }));
1304
+ const selectAll = "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%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='11576'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20fill='%23555'%20width='16'%20height='16'%3e%3cpath%20d='M102.4%20302.08c5.12%205.12%2015.36%2010.24%2025.6%2010.24s15.36-5.12%2025.6-10.24l174.08-174.08c5.12-5.12%2010.24-15.36%2010.24-25.6s-5.12-15.36-10.24-25.6c-20.48-5.12-40.96-5.12-51.2%2010.24l-148.48%20153.6-71.68-76.8C51.2%20158.72%2040.96%20158.72%2035.84%20158.72c-10.24%200-15.36%205.12-25.6%2010.24-5.12%205.12-10.24%2010.24-10.24%2020.48s5.12%2015.36%2010.24%2025.6L102.4%20302.08zM276.48%20409.6l-148.48%20153.6-71.68-71.68C51.2%20486.4%2040.96%20481.28%2035.84%20481.28c-10.24%200-15.36%205.12-25.6%2010.24-5.12%2010.24-10.24%2015.36-10.24%2025.6s5.12%2015.36%2010.24%2025.6L102.4%20629.76c5.12%205.12%2015.36%2010.24%2025.6%2010.24s15.36-5.12%2025.6-10.24L322.56%20460.8c5.12-5.12%2010.24-15.36%2010.24-25.6s-5.12-15.36-10.24-25.6c-10.24-10.24-30.72-10.24-46.08%200z%20m0%20327.68l-148.48%20153.6L56.32%20819.2c-5.12-5.12-15.36-10.24-25.6-10.24s-15.36%205.12-25.6%2010.24c0%205.12-5.12%2015.36-5.12%2025.6s5.12%2015.36%2010.24%2025.6L102.4%20957.44c5.12%205.12%2015.36%2010.24%2025.6%2010.24h5.12c10.24%200%2015.36-5.12%2025.6-10.24l174.08-174.08c5.12-5.12%2010.24-15.36%2010.24-25.6s-5.12-15.36-10.24-25.6c-25.6-5.12-40.96-5.12-56.32%205.12zM1024%20153.6c0%2030.72-25.6%2056.32-56.32%2056.32h-460.8c-30.72%200-61.44-25.6-61.44-56.32%200-30.72%2025.6-56.32%2056.32-56.32h455.68c35.84-5.12%2066.56%2020.48%2066.56%2056.32z%20m0%20358.4c0%2030.72-25.6%2056.32-56.32%2056.32h-460.8c-30.72%200-56.32-25.6-56.32-56.32s25.6-56.32%2056.32-56.32h455.68c35.84%200%2061.44%2025.6%2061.44%2056.32z%20m-5.12%20358.4c0%2030.72-25.6%2056.32-56.32%2056.32h-460.8c-30.72%200-56.32-25.6-56.32-56.32%200-30.72%2025.6-56.32%2056.32-56.32h455.68c35.84%200%2061.44%2025.6%2061.44%2056.32z%20m0%200'%20%3e%3c/path%3e%3c/svg%3e";
1305
+ const __vite_glob_0_9 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1306
+ __proto__: null,
1307
+ default: selectAll
1308
+ }, Symbol.toStringTag, { value: "Module" }));
1309
+ const selectPoint = "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='1757902488735'%20class='icon'%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='3957'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20width='200'%20height='200'%3e%3cpath%20d='M520.416%20179.392c-12.384%200-22.4%204.672-22.4%2010.432l-0.032%20139.136c0%205.76%2010.016%2010.432%2022.368%2010.432%2012.352%200%2022.368-4.672%2022.368-10.432l0.064-139.136c0-5.76-10.016-10.432-22.4-10.432M520.32%20623.04c-12.352%200-22.368%204.64-22.368%2010.4l-0.032%20139.168c0%205.76%2010.016%2010.432%2022.368%2010.432%2012.352%200%2022.368-4.672%2022.368-10.432l0.064-139.168c0-5.76-10.016-10.4-22.4-10.4M800.256%20458.72l-139.168-0.064c-5.76%200-10.432%2010.016-10.432%2022.4%200%2012.352%204.672%2022.368%2010.432%2022.368l139.168%200.032c5.76%200%2010.4-10.016%2010.4-22.368%200-12.352-4.64-22.368-10.4-22.4zM352.256%20458.72l-139.168-0.064c-5.76%200-10.432%2010.016-10.432%2022.4%200%2012.352%204.672%2022.368%2010.432%2022.368l139.168%200.032c5.76%200%2010.4-10.016%2010.4-22.368%200-12.352-4.64-22.368-10.4-22.4M801.568%20748.672l-72.544-72.544%2073.792-23.2a4.416%204.416%200%200%200%200.096-8.384l-183.136-62.4a4.416%204.416%200%200%200-5.6%205.568l62.464%20183.168a4.416%204.416%200%200%200%208.352-0.064l23.36-73.6%2072.32%2072.32a14.752%2014.752%200%200%200%2020.896-20.864M510.688%20382.112c49.952%200%2092.8%2040.832%2092.8%2092.8%200%2051.968-42.848%2092.8-92.8%2092.8-49.984%200-92.8-40.832-92.8-92.8%200-51.968%2042.816-92.8%2092.8-92.8z'%20p-id='3958'%3e%3c/path%3e%3c/svg%3e";
1310
+ const __vite_glob_0_10 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1311
+ __proto__: null,
1312
+ default: selectPoint
1313
+ }, Symbol.toStringTag, { value: "Module" }));
1314
+ const verticalCorrection = "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%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='10587'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20fill='%23555'%20width='16'%20height='16'%3e%3cpath%20d='M64.21%20703.88h888.34M64.21%20667.88h888.34v72H64.21z'%3e%3c/path%3e%3cpath%20d='M509.58%20102.72v566.13M473.58%20102.72h72v566.14h-72z'%3e%3c/path%3e%3c/svg%3e";
1315
+ const __vite_glob_0_11 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1316
+ __proto__: null,
1317
+ default: verticalCorrection
1318
+ }, Symbol.toStringTag, { value: "Module" }));
1319
+ const window$1 = "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='1757902547951'%20class='icon'%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns='http://www.w3.org/2000/svg'%20p-id='5129'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20width='200'%20height='200'%3e%3cpath%20d='M59.355%2091.776v867.881h867.881V91.776H59.356zM897.31%20929.73H89.282V121.703h808.027V929.73z'%20fill=''%20p-id='5130'%3e%3c/path%3e%3cpath%20d='M833.964%20185.048H152.627v681.337h681.337V185.048z%20m-355.632%20651.41H182.554V532.2h295.778v304.257z%20m0-334.184H182.554V214.975h295.778v287.299z%20m325.705%20334.184H508.259V532.2h295.778v304.257z%20m0-334.184H508.259V214.975h295.778v287.299z'%20fill=''%20p-id='5131'%3e%3c/path%3e%3c/svg%3e";
1320
+ const __vite_glob_0_12 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1321
+ __proto__: null,
1322
+ default: window$1
1323
+ }, Symbol.toStringTag, { value: "Module" }));
1430
1324
  class RenderManager extends Component {
1431
1325
  static name = "RenderManager";
1432
1326
  container = new THREE.Group();
@@ -1436,7 +1330,6 @@ class RenderManager extends Component {
1436
1330
  actionHistory = /* @__PURE__ */ new Set();
1437
1331
  onAddFromParent() {
1438
1332
  const dxfLineModel = this.dxfLineModel;
1439
- this.reset();
1440
1333
  this.editor.container.add(this.container);
1441
1334
  this.editor.container.add(dxfLineModel.dxfModelGroup);
1442
1335
  dxfLineModel.dxfLineModel.material = new THREE.LineBasicMaterial({
@@ -1450,6 +1343,7 @@ class RenderManager extends Component {
1450
1343
  });
1451
1344
  this.variable.addEventListener("dxfVisible", (e) => dxfLineModel.dxfModelGroup.visible = e.value);
1452
1345
  this.dxf.addEventListener("createGroup", () => this.reset());
1346
+ this.reset();
1453
1347
  }
1454
1348
  updatedMode = null;
1455
1349
  /** 重新设置数据
@@ -1463,39 +1357,40 @@ class RenderManager extends Component {
1463
1357
  }
1464
1358
  this.pointVirtualGrid = new PointVirtualGrid();
1465
1359
  const box = this.dxf.box.clone().expansion(Math.max(this.dxf.box.width, this.dxf.box.height) * 2);
1360
+ if (box.width === 0 || box.height === 0) box.set(-200, -200, 200, 200);
1466
1361
  this.quadtree = new Quadtree(box);
1467
1362
  this.lines.length = 0;
1468
- this.dxf.lineSegments.forEach((line) => {
1469
- if (line.userData.isDoor && !line.userData.doorDirectConnection) return;
1470
- this.addLine(line.clone());
1363
+ this.dxf.lineSegments.forEach((line2) => {
1364
+ if (line2.userData.isDoor && !line2.userData.doorDirectConnection) return;
1365
+ this.addLine(line2.clone());
1471
1366
  });
1472
- this.dxf.doorLineSegment.forEach((line) => {
1473
- const door = line.clone();
1474
- door.userData = {
1367
+ this.dxf.doorLineSegment.forEach((line2) => {
1368
+ const door2 = line2.clone();
1369
+ door2.userData = {
1475
1370
  isDoor: true,
1476
1371
  doorDirectConnection: true
1477
1372
  };
1478
- this.addLine(door);
1373
+ this.addLine(door2);
1479
1374
  });
1480
1375
  this.draw();
1481
1376
  }
1482
1377
  /** 添加线段
1483
1378
  * @param line
1484
1379
  */
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);
1380
+ addLine(line2) {
1381
+ if (!line2.userData) line2.userData = {};
1382
+ this.lines.push(line2);
1383
+ this.pointVirtualGrid.insert(line2.start, line2);
1384
+ this.pointVirtualGrid.insert(line2.end, line2);
1490
1385
  const quadtreeNode = {
1491
- line,
1386
+ line: line2,
1492
1387
  userData: void 0
1493
1388
  };
1494
- line.userData.quadtreeNode = quadtreeNode;
1389
+ line2.userData.quadtreeNode = quadtreeNode;
1495
1390
  this.quadtree.insert(quadtreeNode);
1496
1391
  this.actionHistory.add({
1497
1392
  type: "addLine",
1498
- data: [line]
1393
+ data: [line2]
1499
1394
  });
1500
1395
  }
1501
1396
  /**
@@ -1504,15 +1399,15 @@ class RenderManager extends Component {
1504
1399
  */
1505
1400
  addLines(lines) {
1506
1401
  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);
1402
+ const line2 = lines[i];
1403
+ this.lines.push(line2);
1404
+ this.pointVirtualGrid.insert(line2.start, line2);
1405
+ this.pointVirtualGrid.insert(line2.end, line2);
1511
1406
  const quadtreeNode = {
1512
- line,
1407
+ line: line2,
1513
1408
  userData: void 0
1514
1409
  };
1515
- line.userData.quadtreeNode = quadtreeNode;
1410
+ line2.userData.quadtreeNode = quadtreeNode;
1516
1411
  this.quadtree.insert(quadtreeNode);
1517
1412
  }
1518
1413
  this.actionHistory.add({
@@ -1523,16 +1418,16 @@ class RenderManager extends Component {
1523
1418
  /** 移除线段
1524
1419
  * @param line
1525
1420
  */
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);
1421
+ removeLine(line2) {
1422
+ line2.userData.quadtreeNode && this.quadtree.remove(line2.userData.quadtreeNode);
1423
+ this.pointVirtualGrid.remove(line2.start);
1424
+ this.pointVirtualGrid.remove(line2.end);
1425
+ const index = this.lines.indexOf(line2);
1531
1426
  this.lines.splice(index, 1);
1532
1427
  this.draw();
1533
1428
  this.actionHistory.add({
1534
1429
  type: "removeLine",
1535
- data: [line]
1430
+ data: [line2]
1536
1431
  });
1537
1432
  }
1538
1433
  /**
@@ -1541,14 +1436,14 @@ class RenderManager extends Component {
1541
1436
  draw(synchronize = true) {
1542
1437
  this.container.clear();
1543
1438
  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);
1439
+ this.lines.forEach((line2) => {
1440
+ line2.points.forEach((p) => {
1441
+ if (line2.userData.isDoor) doorPosition.push(p.x, p.y, 0);
1547
1442
  else position.push(p.x, p.y, 0);
1548
1443
  });
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));
1444
+ if (line2.userData.isWindow && line2.userData.drawDoorData) {
1445
+ line2.userData.drawDoorData.forEach(({ width, p }) => {
1446
+ const center = Point.from(p), direction = line2.direction(), start = center.clone().add(direction.clone().multiplyScalar(width * 0.5)), end = center.clone().add(direction.clone().multiplyScalar(-width * 0.5));
1552
1447
  windowPosition.push(start.x, start.y, 1e-3);
1553
1448
  windowPosition.push(end.x, end.y, 1e-3);
1554
1449
  });
@@ -1619,15 +1514,17 @@ class RenderManager extends Component {
1619
1514
  * 转为json
1620
1515
  */
1621
1516
  toJson() {
1622
- return this.lines.map((line) => {
1623
- const userData = line.userData;
1517
+ return this.lines.map((line2) => {
1518
+ const userData = line2.userData;
1624
1519
  const drawDoorData = userData.drawDoorData;
1520
+ const insetionArr = this.quadtree.queryLineSegment(line2).filter((r) => r.line !== line2 && !r.userData?.isDoor).map((r) => ({ index: this.lines.indexOf(r.line) }));
1625
1521
  return {
1626
- start: line.start.toJson(),
1627
- end: line.end.toJson(),
1628
- insetionArr: [],
1522
+ start: line2.start.toJson(this.dxf.originalZAverage),
1523
+ end: line2.end.toJson(this.dxf.originalZAverage),
1524
+ insetionArr,
1629
1525
  isDoor: userData.isDoor,
1630
1526
  doorDirectConnection: userData.isDoor,
1527
+ length: line2.length(),
1631
1528
  isWindow: userData.isWindow,
1632
1529
  drawDoorData: drawDoorData && drawDoorData.map((w) => ({
1633
1530
  p: { x: w.p.x, y: w.p.y, z: w.p.z },
@@ -1647,7 +1544,7 @@ class RenderManager extends Component {
1647
1544
  return;
1648
1545
  }
1649
1546
  if (this._timer) clearTimeout(this._timer);
1650
- setTimeout(() => {
1547
+ this._timer = setTimeout(() => {
1651
1548
  this.updatedMode = "self";
1652
1549
  const dxf = this.dxf;
1653
1550
  const json = this.toJson();
@@ -1682,9 +1579,10 @@ class DrawDoorLine extends CommandFlowComponent {
1682
1579
  shortcutKeys = ["control", "m"];
1683
1580
  commandName = "draw-door-line";
1684
1581
  onAddFromParent(parent) {
1582
+ super.onAddFromParent(parent);
1685
1583
  const editor = parent.findComponentByName("Editor"), eventInput = editor.eventInput, commandManager = editor.commandManager;
1686
1584
  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));
1585
+ const commandFlow = this.commandManager.addCommandFlow("draw-door-line").add(this.createInterrupt()).add(this.createCursor("no-drop")).add(this.selectPoint.bind(this)).add(this.end.bind(this)).addRollback(this.rollback.bind(this)).addRevokeRollback(this.revokeRollback.bind(this));
1688
1586
  eventInput.addKeyCombination(this.commandName, this.shortcutKeys);
1689
1587
  commandFlow.addEventListener("finally", this.createFinally());
1690
1588
  commandFlow.addEventListener("completed", (e) => this.completed(e.data));
@@ -1697,7 +1595,7 @@ class DrawDoorLine extends CommandFlowComponent {
1697
1595
  * @param next
1698
1596
  */
1699
1597
  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([
1598
+ let editor = this.parent?.findComponentByName("Editor"), start = null, circle = new THREE.Mesh(new THREE.SphereGeometry(0.05), new THREE.MeshBasicMaterial({ color: 65280 })), line2 = new Lines([], 16711935), auxiliaryLine = new Lines([
1701
1599
  new THREE.Vector3(-1e4, 0, 0),
1702
1600
  new THREE.Vector3(1e4, 0, 0),
1703
1601
  new THREE.Vector3(0, -1e4, 0),
@@ -1709,13 +1607,13 @@ class DrawDoorLine extends CommandFlowComponent {
1709
1607
  gapSize: 0.1,
1710
1608
  linewidth: 0.1
1711
1609
  });
1712
- this.container.add(line);
1610
+ this.container.add(line2);
1713
1611
  let currentPoint = null;
1714
1612
  this.addEventRecord(
1715
1613
  "clear",
1716
1614
  editor.addEventListener("pointerPositionChange", () => {
1717
1615
  const { point, find } = editor.renderManager.adsorption(0.05);
1718
- start && line.setPoint(start, point);
1616
+ start && line2.setPoint(start, point);
1719
1617
  if (find) {
1720
1618
  circle.position.set(point.x, point.y, 0);
1721
1619
  this.container.add(circle);
@@ -1737,24 +1635,48 @@ class DrawDoorLine extends CommandFlowComponent {
1737
1635
  }
1738
1636
  }),
1739
1637
  function() {
1740
- line.removeFromParent();
1638
+ line2.removeFromParent();
1741
1639
  circle.removeFromParent();
1742
1640
  auxiliaryLine.removeFromParent();
1743
1641
  }
1744
1642
  );
1745
1643
  }
1746
- /** 执行完成
1644
+ /**
1645
+ * 结束处理
1646
+ * @param next
1647
+ * @param points
1747
1648
  */
1748
- completed(points) {
1749
- const editor = this.editor, lines = [];
1649
+ end(next, points) {
1650
+ const lines = [];
1750
1651
  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);
1652
+ const line2 = new LineSegment(Point.from(points[i]), Point.from(points[i + 1]));
1653
+ line2.userData.isDoor = true;
1654
+ line2.userData.doorDirectConnection = true;
1655
+ lines.push(line2);
1755
1656
  }
1756
- editor.renderManager.addLines(lines);
1757
- editor.renderManager.draw();
1657
+ next(lines);
1658
+ }
1659
+ /** 执行完成
1660
+ */
1661
+ completed(lines) {
1662
+ this.renderManager.addLines(lines);
1663
+ this.renderManager.draw();
1664
+ }
1665
+ /** 回滚操作
1666
+ * @param data
1667
+ */
1668
+ rollback(lines) {
1669
+ lines.forEach((line2) => this.renderManager.removeLine(line2));
1670
+ this.renderManager.draw();
1671
+ return lines;
1672
+ }
1673
+ /** 撤回回滚
1674
+ * @param lines
1675
+ * @returns
1676
+ */
1677
+ revokeRollback(lines) {
1678
+ this.completed(lines);
1679
+ return lines;
1758
1680
  }
1759
1681
  }
1760
1682
  class DrawWindow extends CommandFlowComponent {
@@ -1763,10 +1685,11 @@ class DrawWindow extends CommandFlowComponent {
1763
1685
  interruptKeys = ["escape"];
1764
1686
  shortcutKeys = ["control", "q"];
1765
1687
  commandName = "draw-window-line";
1766
- onAddFromParent() {
1688
+ onAddFromParent(parent) {
1689
+ super.onAddFromParent(parent);
1767
1690
  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());
1691
+ 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)).add(this.end.bind(this)).addRollback(this.rollback.bind(this)).addRevokeRollback(this.revokeRollback.bind(this));
1692
+ commandFlow.addEventListener("finally", this.createFinally(["selectPointStart"]));
1770
1693
  commandFlow.addEventListener("completed", (e) => this.completed(e.data));
1771
1694
  this.eventInput.addKeyCombination(this.commandName, this.shortcutKeys);
1772
1695
  this.eventInput.addEventListener("codeChange", async () => this.eventInput.isKeyCombination(this.commandName) && await this.commandManager.start(this.commandName));
@@ -1778,11 +1701,11 @@ class DrawWindow extends CommandFlowComponent {
1778
1701
  selectPointStart(next) {
1779
1702
  let currentPoint = null, circle = new THREE.Mesh(new THREE.SphereGeometry(0.05), new THREE.MeshBasicMaterial({ color: 16711935 })), currentLine = null;
1780
1703
  this.addEventRecord("selectPointStart").add(this.editor.addEventListener("pointerPositionChange", () => {
1781
- const { point, line, find } = this.editor.renderManager.adsorption();
1704
+ const { point, line: line2, find } = this.editor.renderManager.adsorption();
1782
1705
  if (find) {
1783
1706
  this.domElement.style.cursor = "none";
1784
1707
  circle.position.copy(point);
1785
- currentLine = line;
1708
+ currentLine = line2;
1786
1709
  currentPoint = point.clone();
1787
1710
  this.container.add(circle);
1788
1711
  } else {
@@ -1801,11 +1724,11 @@ class DrawWindow extends CommandFlowComponent {
1801
1724
  /** 选择结束点
1802
1725
  * @param next
1803
1726
  */
1804
- selectPointEnd(next, { point, line }) {
1727
+ selectPointEnd(next, { point, line: line2 }) {
1805
1728
  let currentPoint = null, circle = new THREE.Mesh(new THREE.SphereGeometry(0.05), new THREE.MeshBasicMaterial({ color: 16711935 }));
1806
1729
  this.addEventRecord("clear").add(() => circle.removeFromParent()).add(this.editor.addEventListener("pointerPositionChange", () => {
1807
1730
  const { point: point2, find, line: l } = this.editor.renderManager.adsorption();
1808
- if (find && l === line) {
1731
+ if (find && l === line2) {
1809
1732
  this.domElement.style.cursor = "none";
1810
1733
  circle.position.copy(point2);
1811
1734
  currentPoint = point2.clone();
@@ -1816,33 +1739,1213 @@ class DrawWindow extends CommandFlowComponent {
1816
1739
  circle.removeFromParent();
1817
1740
  }
1818
1741
  })).add(this.eventInput.addEventListener("codeChange", () => {
1819
- if (this.eventInput.isKeyDown("mouse_0") && currentPoint) next({ line, start: point, end: currentPoint });
1742
+ if (this.eventInput.isKeyDown("mouse_0") && currentPoint) next({ line: line2, start: point, end: currentPoint });
1820
1743
  }));
1821
1744
  }
1822
- /** 执行完成
1745
+ /**
1746
+ * 结束处理
1747
+ * @param next
1748
+ * @param points
1823
1749
  */
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({
1750
+ end(next, { start, end, line: line2 }) {
1751
+ const win = new LineSegment(Point.from(start), Point.from(end)), center = win.center, len = win.length();
1752
+ const doorDataItem = {
1829
1753
  p: new THREE.Vector3(center.x, center.y, 0),
1830
1754
  width: len,
1831
- full: Math.abs(len - line.length()) < 0.01
1755
+ full: Math.abs(len - line2.length()) < 0.01
1756
+ };
1757
+ next({ line: line2, doorDataItem });
1758
+ }
1759
+ /** 执行完成
1760
+ */
1761
+ completed({ doorDataItem, line: line2 }) {
1762
+ line2.userData.isWindow = true;
1763
+ if (!line2.userData.drawDoorData) line2.userData.drawDoorData = [];
1764
+ line2.userData.drawDoorData.push(doorDataItem);
1765
+ this.renderManager.draw();
1766
+ }
1767
+ /** 回滚操作
1768
+ * @param data
1769
+ */
1770
+ rollback(data) {
1771
+ const { doorDataItem, line: line2 } = data;
1772
+ if (line2.userData.drawDoorData) {
1773
+ const index = line2.userData.drawDoorData.indexOf(doorDataItem);
1774
+ if (index !== -1) {
1775
+ line2.userData.drawDoorData.splice(index, 1);
1776
+ if (line2.userData.drawDoorData.length === 0) {
1777
+ delete line2.userData.drawDoorData;
1778
+ delete line2.userData.isWindow;
1779
+ }
1780
+ this.renderManager.draw();
1781
+ }
1782
+ }
1783
+ return data;
1784
+ }
1785
+ /** 撤回回滚
1786
+ * @param data
1787
+ * @returns
1788
+ */
1789
+ revokeRollback(data) {
1790
+ this.completed(data);
1791
+ return data;
1792
+ }
1793
+ }
1794
+ class VerticalCorrection extends CommandFlowComponent {
1795
+ static name = "VerticalCorrection";
1796
+ container = new THREE.Group();
1797
+ shortcutKeys = ["control", "c"];
1798
+ static commandName = "verticalCorrection";
1799
+ onAddFromParent(parent) {
1800
+ super.onAddFromParent(parent);
1801
+ this.editor.container.add(this.container);
1802
+ this.container.position.z = 1e-3;
1803
+ const commandFlow = this.commandManager.addCommandFlow(VerticalCorrection.commandName).add(this.createInterrupt()).add(this.constraint.bind(this)).add(this.verticalCorrection.bind(this)).addRollback(this.rollback.bind(this)).addRevokeRollback(this.revokeRollback.bind(this));
1804
+ commandFlow.addEventListener("finally", this.createFinally());
1805
+ commandFlow.addEventListener("completed", (e) => this.completed(e.data));
1806
+ this.eventInput.addKeyCombination(VerticalCorrection.commandName, this.shortcutKeys);
1807
+ this.eventInput.addEventListener("codeChange", async () => {
1808
+ this.eventInput.isKeyCombination(VerticalCorrection.commandName) && await this.commandManager.start(VerticalCorrection.commandName, [...this.default.selectLines]);
1832
1809
  });
1810
+ this.eventInput.addCancelDefaultBehavior(() => this.eventInput.isOnlyKeyDowns(this.shortcutKeys));
1811
+ }
1812
+ /**
1813
+ * 进入命令约束
1814
+ */
1815
+ constraint(next, selectLines) {
1816
+ if (!Array.isArray(selectLines)) {
1817
+ ElMessage({ message: "进入命令失败", type: "warning" });
1818
+ this.cancel();
1819
+ } else if (selectLines.length !== 1) {
1820
+ ElMessage({ message: "请选择一条线段", type: "warning" });
1821
+ this.cancel();
1822
+ } else next(selectLines);
1823
+ }
1824
+ /**
1825
+ * 线段是否为结尾线段
1826
+ * @param line
1827
+ */
1828
+ lineIsPathEnd(line2) {
1829
+ for (let i = 0; i < line2.points.length; i++) {
1830
+ const point = line2.points[i];
1831
+ const length = this.renderManager.pointVirtualGrid.queryPoint(point).filter((p) => !p.point.equal(point)).length;
1832
+ if (length === 0) return true;
1833
+ }
1834
+ return false;
1835
+ }
1836
+ /**
1837
+ *
1838
+ * @param line0
1839
+ * @param line1
1840
+ */
1841
+ isTowLineSegmentConnect(line0, line1) {
1842
+ if (line0.start.equal(line1.start) || line0.start.equal(line1.end) || line0.end.equal(line1.start) || line0.end.equal(line1.end)) {
1843
+ return true;
1844
+ }
1845
+ return false;
1846
+ }
1847
+ /**
1848
+ * 获取所有相同点的位置信息
1849
+ * @param point
1850
+ * @param point2
1851
+ */
1852
+ getSamePointAll(point, point2) {
1853
+ const resultList = this.renderManager.pointVirtualGrid.queryPoint(point);
1854
+ return resultList.map((result) => ({
1855
+ point: result.point,
1856
+ oldPoint: result.point.clone(),
1857
+ newPoint: point2,
1858
+ line: result.userData
1859
+ }));
1860
+ }
1861
+ /** 修正
1862
+ * @param targettLine
1863
+ * @param vistedList
1864
+ */
1865
+ correction(targettLine, resultList = [], vistedList = /* @__PURE__ */ new Set()) {
1866
+ if (vistedList.has(targettLine)) return;
1867
+ vistedList.add(targettLine);
1868
+ const lines = this.renderManager.quadtree.queryLineSegment(targettLine).filter(({ line: line2 }) => {
1869
+ if (line2 === targettLine || line2.userData.isDoor) return false;
1870
+ return true;
1871
+ }).map((result) => result.line), targettLineDirection = targettLine.direction();
1872
+ lines.forEach((line2) => {
1873
+ if (vistedList.has(line2)) return false;
1874
+ const direction = line2.direction(), angle = targettLineDirection.angleBetween(direction, "angle"), gap = Math.abs(90 - angle);
1875
+ if (gap > 10 || gap < 1) return;
1876
+ if (this.isTowLineSegmentConnect(targettLine, line2)) {
1877
+ const point0 = targettLine.start.equal(line2.start) || targettLine.start.equal(line2.end) ? targettLine.start : targettLine.end, point1 = line2.start.equal(targettLine.start) || line2.start.equal(targettLine.end) ? line2.end : line2.start, projectLine = new LineSegment(
1878
+ point1.clone().add(targettLineDirection.clone().multiplyScalar(1)),
1879
+ point1.clone().add(targettLineDirection.clone().multiplyScalar(-1))
1880
+ ), projectPoint = projectLine.projectPoint(point0, false);
1881
+ if (projectPoint) {
1882
+ resultList.push(this.getSamePointAll(point1, projectPoint));
1883
+ }
1884
+ } else {
1885
+ console.log("交点");
1886
+ }
1887
+ });
1888
+ lines.forEach((line2) => this.correction(line2, resultList, vistedList));
1889
+ return resultList;
1890
+ }
1891
+ /** 开始
1892
+ * @param next
1893
+ */
1894
+ verticalCorrection(next, selectLines) {
1895
+ next(this.correction(selectLines[0]));
1896
+ }
1897
+ /** 执行完成
1898
+ * @param data
1899
+ */
1900
+ completed(data) {
1901
+ data.forEach((items) => {
1902
+ items.forEach((item) => {
1903
+ const { line: line2, newPoint, point } = item;
1904
+ point.copy(newPoint);
1905
+ this.renderManager.removeLine(line2);
1906
+ this.renderManager.addLine(line2);
1907
+ });
1908
+ });
1909
+ this.renderManager.draw();
1910
+ }
1911
+ /** 回滚操作
1912
+ * @param data
1913
+ */
1914
+ rollback(data) {
1915
+ data.forEach((items) => {
1916
+ items.forEach((item) => {
1917
+ const { line: line2, oldPoint, point } = item;
1918
+ point.copy(oldPoint);
1919
+ this.renderManager.removeLine(line2);
1920
+ this.renderManager.addLine(line2);
1921
+ });
1922
+ });
1923
+ this.renderManager.draw();
1924
+ return data;
1925
+ }
1926
+ /** 撤回回滚
1927
+ * @param lines
1928
+ * @returns
1929
+ */
1930
+ revokeRollback(data) {
1931
+ this.completed(data);
1932
+ return data;
1933
+ }
1934
+ }
1935
+ class MergeLine extends CommandFlowComponent {
1936
+ static name = "MergeLine";
1937
+ shortcutKeys = ["control", "g"];
1938
+ static commandName = "merge-line";
1939
+ onAddFromParent(parent) {
1940
+ super.onAddFromParent(parent);
1941
+ const defaultComponent = parent.findComponentByType(Default);
1942
+ const commandFlow = this.commandManager.addCommandFlow(MergeLine.commandName).add(this.createInterrupt()).add(this.constraint.bind(this)).add(this.mergeLine.bind(this)).addRollback(this.rollback.bind(this)).addRevokeRollback(this.revokeRollback.bind(this));
1943
+ commandFlow.addEventListener("finally", this.createFinally());
1944
+ commandFlow.addEventListener("completed", (e) => this.completed(e.data));
1945
+ this.eventInput.addKeyCombination(MergeLine.commandName, this.shortcutKeys);
1946
+ this.eventInput.addEventListener("codeChange", async () => {
1947
+ defaultComponent?.selectLines.length === 2 && this.eventInput.isKeyCombination(MergeLine.commandName) && await this.commandManager.start(MergeLine.commandName, [...this.default.selectLines]);
1948
+ });
1949
+ this.eventInput.addCancelDefaultBehavior(() => this.eventInput.isOnlyKeyDowns(this.shortcutKeys));
1950
+ }
1951
+ /**
1952
+ * 进入命令约束
1953
+ */
1954
+ constraint(next, selectLines) {
1955
+ if (!Array.isArray(selectLines)) {
1956
+ ElMessage({ message: "进入命令失败", type: "warning" });
1957
+ this.cancel();
1958
+ } else if (selectLines.length !== 2) {
1959
+ ElMessage({ message: "未执行线段合并,请选择两条线段", type: "warning" });
1960
+ this.cancel();
1961
+ } else {
1962
+ next(selectLines);
1963
+ }
1964
+ }
1965
+ /** 开始
1966
+ * @param next
1967
+ */
1968
+ mergeLine(next, selectLines) {
1969
+ const line1 = selectLines[0], line2 = selectLines[1];
1970
+ for (let i = 0; i < line1.points.length; i++) {
1971
+ const p1 = line1.points[i];
1972
+ for (let j = 0; j < line2.points.length; j++) {
1973
+ const p2 = line2.points[j];
1974
+ if (p1.equal(p2)) {
1975
+ const p1Next = line1.points[(i + 1) % 2];
1976
+ const p2Next = line2.points[(j + 1) % 2];
1977
+ const line3 = new LineSegment(p1Next, p2Next);
1978
+ next({ line1, line2, newLine: line3 });
1979
+ return ElMessage({ message: "已合并", type: "success" });
1980
+ }
1981
+ }
1982
+ }
1983
+ ElMessage({ message: "合并失败,两条线未找到共用点", type: "warning" });
1984
+ next();
1985
+ }
1986
+ /** 执行完成
1987
+ * @param data
1988
+ */
1989
+ completed(data) {
1990
+ this.renderManager.removeLine(data.line1);
1991
+ this.renderManager.removeLine(data.line2);
1992
+ this.renderManager.addLine(data.newLine);
1833
1993
  this.renderManager.draw();
1834
1994
  }
1995
+ /** 回滚操作
1996
+ * @param data
1997
+ */
1998
+ rollback(data) {
1999
+ this.renderManager.addLines([data.line1, data.line2]);
2000
+ this.renderManager.removeLine(data.newLine);
2001
+ this.renderManager.draw();
2002
+ return data;
2003
+ }
2004
+ /** 撤回回滚
2005
+ * @param lines
2006
+ * @returns
2007
+ */
2008
+ revokeRollback(data) {
2009
+ this.completed(data);
2010
+ return data;
2011
+ }
1835
2012
  }
2013
+ class DeleteSelectLine extends CommandFlowComponent {
2014
+ static name = "DeleteSelectLine";
2015
+ shortcutKeys = ["Delete"];
2016
+ static commandName = "deleteSelectLine";
2017
+ onAddFromParent(parent) {
2018
+ super.onAddFromParent(parent);
2019
+ const commandFlow = this.commandManager.addCommandFlow(DeleteSelectLine.commandName).add(this.createInterrupt()).add(this.constraint.bind(this)).add(this.delete.bind(this)).addRollback(this.rollback.bind(this)).addRevokeRollback(this.revokeRollback.bind(this));
2020
+ commandFlow.addEventListener("finally", this.createFinally());
2021
+ this.eventInput.addKeyCombination(DeleteSelectLine.commandName, this.shortcutKeys);
2022
+ this.eventInput.addEventListener("codeChange", async () => {
2023
+ this.eventInput.isKeyCombination(DeleteSelectLine.commandName) && await this.commandManager.start(DeleteSelectLine.commandName, [...this.default.selectLines]);
2024
+ });
2025
+ this.eventInput.addCancelDefaultBehavior(() => this.eventInput.isOnlyKeyDowns(this.shortcutKeys));
2026
+ }
2027
+ /**
2028
+ * 进入命令约束
2029
+ */
2030
+ constraint(next, selectLines) {
2031
+ if (!Array.isArray(selectLines)) {
2032
+ ElMessage({ message: "请选择线段", type: "warning" });
2033
+ this.cancel();
2034
+ } else {
2035
+ next(selectLines);
2036
+ }
2037
+ }
2038
+ /** 开始
2039
+ * @param next
2040
+ */
2041
+ delete(next, selectLines) {
2042
+ selectLines.forEach((line2) => this.renderManager.removeLine(line2));
2043
+ ElMessage({ message: "删除成功", type: "success" });
2044
+ next(selectLines);
2045
+ }
2046
+ /** 回滚操作
2047
+ * @param data
2048
+ */
2049
+ rollback(lines) {
2050
+ this.renderManager.addLines(lines);
2051
+ this.renderManager.draw();
2052
+ return lines;
2053
+ }
2054
+ /** 撤回回滚
2055
+ * @param lines
2056
+ * @returns
2057
+ */
2058
+ revokeRollback(lines) {
2059
+ lines.forEach((line2) => this.renderManager.removeLine(line2));
2060
+ return lines;
2061
+ }
2062
+ }
2063
+ class ConnectionLine extends CommandFlowComponent {
2064
+ static name = "ConnectionLine";
2065
+ shortcutKeys = ["Shift", "L"];
2066
+ static commandName = "connectionLine";
2067
+ onAddFromParent(parent) {
2068
+ super.onAddFromParent(parent);
2069
+ const commandFlow = this.commandManager.addCommandFlow(ConnectionLine.commandName).add(this.createInterrupt()).add(this.constraint.bind(this)).add(this.connection.bind(this)).addRollback(this.rollback.bind(this)).addRevokeRollback(this.revokeRollback.bind(this));
2070
+ commandFlow.addEventListener("finally", this.createFinally());
2071
+ commandFlow.addEventListener("completed", (e) => this.completed(e.data));
2072
+ this.eventInput.addKeyCombination(ConnectionLine.commandName, this.shortcutKeys);
2073
+ this.eventInput.addEventListener("codeChange", async () => {
2074
+ this.eventInput.isKeyCombination(ConnectionLine.commandName) && await this.commandManager.start(ConnectionLine.commandName, [...this.default.selectLines]);
2075
+ });
2076
+ this.eventInput.addCancelDefaultBehavior(() => this.eventInput.isOnlyKeyDowns(this.shortcutKeys));
2077
+ }
2078
+ /**
2079
+ * 进入命令约束
2080
+ */
2081
+ constraint(next, selectLines) {
2082
+ if (!Array.isArray(selectLines)) {
2083
+ ElMessage({ message: "进入命令失败", type: "warning" });
2084
+ this.cancel();
2085
+ } else if (selectLines.length !== 2) {
2086
+ ElMessage({ message: "请选择2条线段", type: "warning" });
2087
+ this.cancel();
2088
+ } else {
2089
+ next(selectLines);
2090
+ }
2091
+ }
2092
+ /** 连接
2093
+ * @param next
2094
+ */
2095
+ connection(next, selectLines) {
2096
+ let start, end, diatance = Infinity;
2097
+ for (let i = 0; i < 2; i++)
2098
+ for (let j = 0; j < 2; j++) {
2099
+ const point1 = selectLines[0].points[i];
2100
+ const point2 = selectLines[1].points[j];
2101
+ const d = point1.distance(point2);
2102
+ if (d < diatance) {
2103
+ start = point1;
2104
+ end = point2;
2105
+ diatance = d;
2106
+ }
2107
+ }
2108
+ if (start && end) {
2109
+ const line2 = new LineSegment(start.clone(), end.clone());
2110
+ next(line2);
2111
+ ElMessage({ message: "连接成功", type: "success" });
2112
+ } else this.cancel();
2113
+ }
2114
+ /** 成功
2115
+ * @param next
2116
+ * @param selectLines
2117
+ */
2118
+ completed(line2) {
2119
+ this.renderManager.addLine(line2);
2120
+ this.renderManager.draw();
2121
+ }
2122
+ /** 回滚操作
2123
+ * @param data
2124
+ */
2125
+ rollback(line2) {
2126
+ this.renderManager.removeLine(line2);
2127
+ return line2;
2128
+ }
2129
+ /** 撤回回滚
2130
+ * @param lines
2131
+ * @returns
2132
+ */
2133
+ revokeRollback(line2) {
2134
+ this.completed(line2);
2135
+ return line2;
2136
+ }
2137
+ }
2138
+ class IntersectionConnectionLine extends CommandFlowComponent {
2139
+ static name = "IntersectionConnectionLine";
2140
+ shortcutKeys = ["control", "Shift", "L"];
2141
+ static commandName = "intersectionConnectionLine";
2142
+ onAddFromParent(parent) {
2143
+ super.onAddFromParent(parent);
2144
+ const commandFlow = this.commandManager.addCommandFlow(IntersectionConnectionLine.commandName).add(this.createInterrupt()).add(this.constraint.bind(this)).add(this.connection.bind(this)).addRollback(this.rollback.bind(this)).addRevokeRollback(this.revokeRollback.bind(this));
2145
+ commandFlow.addEventListener("finally", this.createFinally());
2146
+ commandFlow.addEventListener("completed", (e) => this.completed(e.data));
2147
+ this.eventInput.addKeyCombination(IntersectionConnectionLine.commandName, this.shortcutKeys);
2148
+ this.eventInput.addEventListener("codeChange", async () => {
2149
+ this.eventInput.isKeyCombination(IntersectionConnectionLine.commandName) && await this.commandManager.start(IntersectionConnectionLine.commandName, [...this.default.selectLines]);
2150
+ });
2151
+ this.eventInput.addCancelDefaultBehavior(() => this.eventInput.isOnlyKeyDowns(this.shortcutKeys));
2152
+ }
2153
+ /**
2154
+ * 进入命令约束
2155
+ */
2156
+ constraint(next, selectLines) {
2157
+ if (!Array.isArray(selectLines)) {
2158
+ ElMessage({ message: "进入命令失败", type: "warning" });
2159
+ this.cancel();
2160
+ } else if (selectLines.length !== 2) {
2161
+ ElMessage({ message: "请选择2条线段", type: "warning" });
2162
+ this.cancel();
2163
+ } else {
2164
+ next(selectLines);
2165
+ }
2166
+ }
2167
+ /** 开始
2168
+ * @param next
2169
+ */
2170
+ connection(next, selectLines) {
2171
+ const line1 = selectLines[0], line2 = selectLines[1], point = selectLines[0].getIntersection(selectLines[1]);
2172
+ if (!point) return;
2173
+ const oldLine1 = line1.points.map((p) => p.clone()), oldLine2 = line2.points.map((p) => p.clone());
2174
+ if (line1.start.distance(point) < line1.end.distance(point)) {
2175
+ line1.start.copy(point);
2176
+ } else {
2177
+ line1.end.copy(point);
2178
+ }
2179
+ if (line2.start.distance(point) < line2.end.distance(point)) {
2180
+ line2.start.copy(point);
2181
+ } else {
2182
+ line2.end.copy(point);
2183
+ }
2184
+ const newLine1 = line1.points.map((p) => p.clone()), newLine2 = line2.points.map((p) => p.clone());
2185
+ next({ line1, line2, oldLine1, oldLine2, newLine1, newLine2 });
2186
+ ElMessage({ message: "连接成功", type: "success" });
2187
+ }
2188
+ /** 执行完成
2189
+ * @param next
2190
+ * @param selectLines
2191
+ */
2192
+ completed({ line1, line2, newLine1, newLine2 }) {
2193
+ this.renderManager.removeLine(line1);
2194
+ this.renderManager.removeLine(line2);
2195
+ line1.set(...newLine1);
2196
+ line2.set(...newLine2);
2197
+ this.renderManager.addLines([line1, line2]);
2198
+ this.renderManager.draw();
2199
+ }
2200
+ /** 回滚操作
2201
+ * @param data
2202
+ */
2203
+ rollback(data) {
2204
+ const { line1, line2, oldLine1, oldLine2 } = data;
2205
+ this.renderManager.removeLine(line1);
2206
+ this.renderManager.removeLine(line2);
2207
+ line1.set(...oldLine1);
2208
+ line2.set(...oldLine2);
2209
+ this.renderManager.addLines([line1, line2]);
2210
+ this.renderManager.draw();
2211
+ return data;
2212
+ }
2213
+ /** 撤回回滚
2214
+ * @param lines
2215
+ * @returns
2216
+ */
2217
+ revokeRollback(data) {
2218
+ this.completed(data);
2219
+ return data;
2220
+ }
2221
+ }
2222
+ class DeleteSelectWindow extends CommandFlowComponent {
2223
+ static name = "DeleteSelectWindow";
2224
+ shortcutKeys = ["Q", "Delete"];
2225
+ static commandName = "deleteSelectWindow";
2226
+ onAddFromParent(parent) {
2227
+ super.onAddFromParent(parent);
2228
+ const commandFlow = this.commandManager.addCommandFlow(DeleteSelectWindow.commandName).add(this.createInterrupt()).add(this.constraint.bind(this)).add(this.end.bind(this)).addRollback(this.rollback.bind(this)).addRevokeRollback(this.revokeRollback.bind(this));
2229
+ commandFlow.addEventListener("finally", this.createFinally());
2230
+ commandFlow.addEventListener("completed", (e) => this.completed(e.data));
2231
+ this.eventInput.addKeyCombination(DeleteSelectWindow.commandName, this.shortcutKeys);
2232
+ this.eventInput.addEventListener("codeChange", async () => {
2233
+ this.eventInput.isKeyCombination(DeleteSelectWindow.commandName) && await this.commandManager.start(DeleteSelectWindow.commandName, [...this.default.selectLines]);
2234
+ });
2235
+ this.eventInput.addCancelDefaultBehavior(() => this.eventInput.isOnlyKeyDowns(this.shortcutKeys));
2236
+ }
2237
+ /**
2238
+ * 进入命令约束
2239
+ */
2240
+ constraint(next, selectLines) {
2241
+ if (!Array.isArray(selectLines)) {
2242
+ ElMessage({ message: "进入命令失败", type: "warning" });
2243
+ this.cancel();
2244
+ } else if (!selectLines.some((l) => l.userData.isWindow)) {
2245
+ ElMessage({ message: "请选择有窗户线段", type: "warning" });
2246
+ this.cancel();
2247
+ } else {
2248
+ next(selectLines);
2249
+ }
2250
+ }
2251
+ /** 开始
2252
+ * @param next
2253
+ */
2254
+ end(next, selectLines) {
2255
+ let is = false, list = [];
2256
+ selectLines.forEach((line2) => {
2257
+ if (!line2.userData.isWindow) return;
2258
+ list.push({
2259
+ line: line2,
2260
+ drawDoorData: line2.userData.drawDoorData
2261
+ });
2262
+ is = true;
2263
+ });
2264
+ is && ElMessage({ message: "删除窗户成功", type: "success" });
2265
+ next(list);
2266
+ }
2267
+ /**
2268
+ * 完成
2269
+ * @param list
2270
+ */
2271
+ completed(list) {
2272
+ list.forEach((item) => {
2273
+ const userData = item.line.userData;
2274
+ if (userData) {
2275
+ delete userData.isWindow;
2276
+ delete userData.drawDoorData;
2277
+ }
2278
+ });
2279
+ this.renderManager.draw();
2280
+ }
2281
+ /** 回滚操作
2282
+ * @param data
2283
+ */
2284
+ rollback(list) {
2285
+ list.forEach((item) => {
2286
+ if (!item.line.userData) item.line.userData = {};
2287
+ const userData = item.line.userData;
2288
+ userData.isWindow = true;
2289
+ userData.drawDoorData = item.drawDoorData;
2290
+ });
2291
+ this.renderManager.draw();
2292
+ return list;
2293
+ }
2294
+ /** 撤回回滚
2295
+ * @param lines
2296
+ * @returns
2297
+ */
2298
+ revokeRollback(list) {
2299
+ this.completed(list);
2300
+ return list;
2301
+ }
2302
+ }
2303
+ class SelectAll extends CommandFlowComponent {
2304
+ static name = "SelectAll";
2305
+ container = new THREE.Group();
2306
+ shortcutKeys = ["control", "a"];
2307
+ static commandName = "selectAll";
2308
+ onAddFromParent(parent) {
2309
+ super.onAddFromParent(parent);
2310
+ this.editor.container.add(this.container);
2311
+ this.container.position.z = 1e-3;
2312
+ const commandFlow = this.commandManager.addCommandFlow(SelectAll.commandName).add(this.createInterrupt()).add(this.selectAll.bind(this)).addRollback(this.rollback.bind(this)).addRevokeRollback(this.revokeRollback.bind(this));
2313
+ commandFlow.addEventListener("finally", this.createFinally());
2314
+ commandFlow.addEventListener("completed", (e) => this.completed(e.data));
2315
+ this.eventInput.addKeyCombination(SelectAll.commandName, this.shortcutKeys);
2316
+ this.eventInput.addEventListener("codeChange", async () => {
2317
+ this.eventInput.isKeyCombination(SelectAll.commandName) && await this.commandManager.start(SelectAll.commandName);
2318
+ });
2319
+ this.eventInput.addCancelDefaultBehavior(() => this.eventInput.isOnlyKeyDowns(this.shortcutKeys));
2320
+ }
2321
+ /** 开始
2322
+ * @param next
2323
+ */
2324
+ selectAll(next) {
2325
+ next([...this.renderManager.lines]);
2326
+ }
2327
+ /** 执行完成
2328
+ */
2329
+ completed(lines) {
2330
+ lines.map((line2) => this.default.addSelectLine(line2));
2331
+ }
2332
+ /** 回滚操作
2333
+ * @param lines
2334
+ */
2335
+ rollback(lines) {
2336
+ lines.map((line2) => this.default.removeSelectLine(line2));
2337
+ return lines;
2338
+ }
2339
+ /** 撤回回滚
2340
+ * @param lines
2341
+ * @returns
2342
+ */
2343
+ revokeRollback(lines) {
2344
+ this.completed(lines);
2345
+ return lines;
2346
+ }
2347
+ }
2348
+ const _hoisted_1 = {
2349
+ key: 0,
2350
+ class: "mt-[5px] text-[#ccc] text-[11px] absolute left-[10px] bottom-[10px] rounded-[8px] min-w-[150px] bg-black/15 p-[10px]"
2351
+ };
2352
+ const _hoisted_2 = { class: "text-start max-w-[150px]" };
2353
+ const _hoisted_3 = { class: "inline-block ml-[10px] text-[var(--color-primary)]" };
2354
+ const _hoisted_4 = {
2355
+ key: 0,
2356
+ class: "p-[5px] max-w-[200px]"
2357
+ };
2358
+ const _hoisted_5 = { class: "text-[14px] flex flex-col" };
2359
+ const _hoisted_6 = ["onClick"];
2360
+ const _hoisted_7 = { class: "flex flex-row items-center" };
2361
+ const _hoisted_8 = { class: "flex justify-center items-center size-[20px] bg-[#f0f0f0] rounded-[2px] mr-[10px]" };
2362
+ const _hoisted_9 = ["src"];
2363
+ const _hoisted_10 = { class: "text-wrap" };
2364
+ const _hoisted_11 = {
2365
+ key: 1,
2366
+ class: "text-[#999]"
2367
+ };
2368
+ const _hoisted_12 = {
2369
+ style: { "--el-color-primary": "var(--primary-color)" },
2370
+ class: "flex flex-row items-center justify-between gap-[10px] mt-[10px] text-[10px]"
2371
+ };
2372
+ const _hoisted_13 = {
2373
+ key: 0,
2374
+ class: "flex flex-row items-center flex-wrap justify-between gap-[10px] mt-[10px] text-[10px]"
2375
+ };
2376
+ const _hoisted_14 = { class: "flex-wrap border-t-1 border-t-[#eee] mt-[5px] pt-[5px] flex items-center gap-[10px]" };
2377
+ const _hoisted_15 = ["onClick", "title"];
2378
+ const _hoisted_16 = ["src"];
2379
+ const _sfc_main = /* @__PURE__ */ defineComponent({
2380
+ __name: "EditorTool",
2381
+ props: {
2382
+ dxfSystem: {},
2383
+ permission: {}
2384
+ },
2385
+ setup(__props) {
2386
+ function setEditorToolPosition(left, top, rect = elRef.value.getBoundingClientRect(), toolBarRect = toolBarRef.value.getBoundingClientRect()) {
2387
+ const minX = 0, maxX = rect.width - toolBarRect.width, minY = 0, maxY = rect.height - toolBarRect.height;
2388
+ left = Math.max(minX, Math.min(left, maxX));
2389
+ top = Math.max(minY, Math.min(top, maxY));
2390
+ toolBarPosition.value = { left, top };
2391
+ }
2392
+ function startCurrentCommandItem(item) {
2393
+ if (currentCommand.value === item.command) return;
2394
+ editor.commandManager.start(item.command);
2395
+ }
2396
+ function setLines(lines) {
2397
+ if (lines) {
2398
+ localStorage.setItem("lines", JSON.stringify(lines));
2399
+ try {
2400
+ dxfSystem.Dxf.set(lines);
2401
+ dxfSystem.Dxf.lineOffset();
2402
+ } catch (error) {
2403
+ console.log(error);
2404
+ }
2405
+ }
2406
+ }
2407
+ async function selectLocalFile() {
2408
+ const data = await SelectLocalFile.json();
2409
+ if (Array.isArray(data)) {
2410
+ localStorage.removeItem("orbitControls");
2411
+ setLines(data);
2412
+ }
2413
+ }
2414
+ function dragMoveHelper({ offsetX, offsetY }) {
2415
+ domEventRegister.mouseMoveEventProxylock = true;
2416
+ const cusor = document.body.style.cursor;
2417
+ document.body.style.cursor = "move";
2418
+ const move = (e) => {
2419
+ const rect = elRef.value.getBoundingClientRect(), toolBarRect = toolBarRef.value.getBoundingClientRect();
2420
+ setEditorToolPosition(
2421
+ e.pageX - rect.left - offsetX,
2422
+ e.pageY - rect.top - offsetY,
2423
+ rect,
2424
+ toolBarRect
2425
+ );
2426
+ e.stopPropagation();
2427
+ document.body.style.cursor = "move";
2428
+ };
2429
+ const end = () => {
2430
+ document.body.removeEventListener("mousemove", move);
2431
+ document.removeEventListener("mouseup", end);
2432
+ document.body.style.cursor = cusor;
2433
+ domEventRegister.mouseMoveEventProxylock = false;
2434
+ };
2435
+ document.body.addEventListener("mousemove", move);
2436
+ document.addEventListener("mouseup", end);
2437
+ }
2438
+ const props = __props;
2439
+ const originalLineVisible = ref(true), dxfVisible = ref(true), whiteModelVisible = ref(true), isLook = ref(false), elRef = ref(), toolBarRef = ref(), toolBarExpand = ref(true), currentCommand = ref(""), dxfSystem = toRaw(props.dxfSystem), domEventRegister = dxfSystem.findComponentByType(DomEventRegister), editor = dxfSystem.findComponentByType(Editor$1), defaultComponent = dxfSystem.findComponentByType(Default), whiteModel = dxfSystem.findComponentByType(WhiteModel), rollbackCount = ref(0), revokeRollbackCount = ref(0), toolBarPosition = ref({ left: 10, top: 10 }), images = /* @__PURE__ */ Object.assign({ "./assets/images/connection.svg": __vite_glob_0_0, "./assets/images/deleteSelectLine.svg": __vite_glob_0_1, "./assets/images/deleteSelectWindow.svg": __vite_glob_0_2, "./assets/images/door.svg": __vite_glob_0_3, "./assets/images/intersectionConnection.svg": __vite_glob_0_4, "./assets/images/line.svg": __vite_glob_0_5, "./assets/images/mergeLine.svg": __vite_glob_0_6, "./assets/images/revokeRollback.svg": __vite_glob_0_7, "./assets/images/rollback.svg": __vite_glob_0_8, "./assets/images/selectAll.svg": __vite_glob_0_9, "./assets/images/selectPoint.svg": __vite_glob_0_10, "./assets/images/verticalCorrection.svg": __vite_glob_0_11, "./assets/images/window.svg": __vite_glob_0_12 }), showShortcutKey = ref(false), selectLineCount = ref(0), hasWindowLine = ref(false), resizeObserver = new ResizeObserver(() => setEditorToolPosition(toolBarPosition.value.left, toolBarPosition.value.top)), shortcutKeys = [
2440
+ { "name": "开启绘制线段命令", "shortcut": "Ctrl + L" },
2441
+ { "name": "开启绘制门线命令", "shortcut": "Ctrl + M" },
2442
+ { "name": "开启绘制窗户线命令", "shortcut": "Ctrl + Q" },
2443
+ { "name": "开启点修改命令", "shortcut": "Ctrl + P" },
2444
+ { "name": "线段方向移动线段点(点修改命令下)", "shortcut": "Shift + 移动" },
2445
+ { "name": "删除线段", "shortcut": "选中 + Delete" },
2446
+ { "name": "删除窗户线", "shortcut": "选中 + Q + Delete" },
2447
+ { "name": "选中", "shortcut": "鼠标左键" },
2448
+ { "name": "多选", "shortcut": "鼠标左键 + Ctrl" },
2449
+ { "name": "取消选中", "shortcut": "鼠标左键 + Alt" },
2450
+ { "name": "框选", "shortcut": "鼠标左键 + 移动" },
2451
+ { "name": "线段同方向合并", "shortcut": "Ctrl + G" },
2452
+ { "name": "线段连接", "shortcut": "选中 + Shift + L" },
2453
+ { "name": "线段交点连接", "shortcut": "选中 + Ctrl + Shift + L" },
2454
+ { "name": "命令确认", "shortcut": "Enter" },
2455
+ { "name": "取消命令", "shortcut": "Esc" },
2456
+ { "name": "回滚操作", "shortcut": "Ctrl + Z" },
2457
+ { "name": "取消回滚操作", "shortcut": "Ctrl + Y" }
2458
+ ], commandList = [
2459
+ {
2460
+ command: "default",
2461
+ name: "默认",
2462
+ show: false,
2463
+ shortcut: ""
2464
+ },
2465
+ {
2466
+ command: "draw-line",
2467
+ name: "绘制线段",
2468
+ src: images["./assets/images/line.svg"].default,
2469
+ show: true,
2470
+ shortcut: "Ctrl + L"
2471
+ },
2472
+ {
2473
+ command: "draw-door-line",
2474
+ name: "绘制门线",
2475
+ show: true,
2476
+ src: images["./assets/images/door.svg"].default,
2477
+ shortcut: "Ctrl + M"
2478
+ },
2479
+ {
2480
+ command: "draw-window-line",
2481
+ name: "绘制窗户线",
2482
+ show: true,
2483
+ src: images["./assets/images/window.svg"].default,
2484
+ shortcut: "Ctrl + Q"
2485
+ },
2486
+ {
2487
+ command: "point",
2488
+ name: "点修改",
2489
+ show: true,
2490
+ src: images["./assets/images/selectPoint.svg"].default,
2491
+ shortcut: "Ctrl + P"
2492
+ }
2493
+ ], otherCommandList = [
2494
+ {
2495
+ command: "",
2496
+ name: "操作回滚",
2497
+ src: images["./assets/images/rollback.svg"].default,
2498
+ show: computed(() => rollbackCount.value !== 0),
2499
+ shortcut: "Ctrl + Z",
2500
+ action() {
2501
+ editor.commandManager.rollback();
2502
+ }
2503
+ },
2504
+ {
2505
+ command: "",
2506
+ name: "撤销操作回滚",
2507
+ src: images["./assets/images/revokeRollback.svg"].default,
2508
+ show: computed(() => revokeRollbackCount.value !== 0),
2509
+ shortcut: "Ctrl + Y",
2510
+ class: "rotateY-[180deg]",
2511
+ action() {
2512
+ editor.commandManager.revokeRollback();
2513
+ }
2514
+ },
2515
+ {
2516
+ command: MergeLine.commandName,
2517
+ name: "合并",
2518
+ src: images["./assets/images/mergeLine.svg"].default,
2519
+ show: computed(() => selectLineCount.value === 2),
2520
+ shortcut: "Ctrl + G"
2521
+ },
2522
+ {
2523
+ command: ConnectionLine.commandName,
2524
+ name: "两点连接",
2525
+ show: computed(() => selectLineCount.value === 2),
2526
+ src: images["./assets/images/connection.svg"].default,
2527
+ shortcut: "Shift + L"
2528
+ },
2529
+ {
2530
+ command: IntersectionConnectionLine.commandName,
2531
+ name: "延长线交点连接",
2532
+ show: computed(() => selectLineCount.value === 2),
2533
+ src: images["./assets/images/intersectionConnection.svg"].default,
2534
+ shortcut: "Ctrl + Shift + L"
2535
+ },
2536
+ {
2537
+ command: VerticalCorrection.commandName,
2538
+ name: "线段垂直纠正",
2539
+ show: computed(() => selectLineCount.value === 1),
2540
+ src: images["./assets/images/verticalCorrection.svg"].default,
2541
+ shortcut: "Ctrl + C"
2542
+ },
2543
+ {
2544
+ command: SelectAll.commandName,
2545
+ name: "全选",
2546
+ show: computed(() => selectLineCount.value !== editor.renderManager.lines.length),
2547
+ src: images["./assets/images/selectAll.svg"].default,
2548
+ shortcut: "Ctrl + A"
2549
+ },
2550
+ {
2551
+ command: DeleteSelectWindow.commandName,
2552
+ name: "清除窗户",
2553
+ show: computed(() => hasWindowLine.value),
2554
+ src: images["./assets/images/deleteSelectWindow.svg"].default,
2555
+ shortcut: "Q + Delete"
2556
+ },
2557
+ {
2558
+ command: DeleteSelectLine.commandName,
2559
+ name: "删除",
2560
+ show: computed(() => selectLineCount.value > 0),
2561
+ src: images["./assets/images/deleteSelectLine.svg"].default,
2562
+ shortcut: "Delete"
2563
+ }
2564
+ ];
2565
+ watch(toolBarPosition, () => localStorage.setItem("editorToolPosition", JSON.stringify(toolBarPosition.value)));
2566
+ watch(showShortcutKey, () => localStorage.setItem("showShortcutKey", showShortcutKey.value + ""));
2567
+ watch(toolBarExpand, () => {
2568
+ localStorage.setItem("toolBarExpand", toolBarExpand.value + "");
2569
+ if (toolBarExpand.value) {
2570
+ nextTick(() => setEditorToolPosition(toolBarPosition.value.left, toolBarPosition.value.top));
2571
+ }
2572
+ });
2573
+ watch(originalLineVisible, () => dxfSystem.Variable.set("originalLineVisible", originalLineVisible.value));
2574
+ watch(dxfVisible, () => dxfSystem.Variable.set("dxfVisible", dxfVisible.value));
2575
+ watch(whiteModelVisible, () => dxfSystem.Variable.set("whiteModelVisible", whiteModelVisible.value));
2576
+ dxfSystem.Variable.addEventListener("isLook", (e) => isLook.value = e.value);
2577
+ dxfSystem.Variable.addEventListener("originalLineVisible", (e) => originalLineVisible.value = e.value);
2578
+ dxfSystem.Variable.addEventListener("dxfVisible", (e) => dxfVisible.value = e.value);
2579
+ dxfSystem.Variable.addEventListener("whiteModelVisible", (e) => whiteModelVisible.value = e.value);
2580
+ const startedEventCancel = editor.commandManager.addEventListener("started", (e) => {
2581
+ currentCommand.value = e.name;
2582
+ });
2583
+ if (localStorage.getItem("showShortcutKey")) {
2584
+ showShortcutKey.value = localStorage.getItem("showShortcutKey") === "true";
2585
+ }
2586
+ if (localStorage.getItem("toolBarExpand")) {
2587
+ toolBarExpand.value = localStorage.getItem("toolBarExpand") === "true";
2588
+ }
2589
+ onMounted(() => {
2590
+ toolBarRef.value.style.display = "none";
2591
+ setTimeout(() => {
2592
+ toolBarRef.value.style.display = "block";
2593
+ if (localStorage.getItem("editorToolPosition")) {
2594
+ const { left, top } = JSON.parse(localStorage.getItem("editorToolPosition") ?? "{}");
2595
+ setEditorToolPosition(left, top);
2596
+ nextTick(() => resizeObserver.observe(elRef.value));
2597
+ } else {
2598
+ nextTick(() => resizeObserver.observe(elRef.value));
2599
+ }
2600
+ }, 100);
2601
+ defaultComponent.addEventListener("selectLineChange", () => {
2602
+ selectLineCount.value = defaultComponent.selectLines.length;
2603
+ hasWindowLine.value = defaultComponent.selectLines.some((l) => l.userData.isWindow);
2604
+ });
2605
+ ["rollback", "completed", "revokeRollback"].forEach((key) => {
2606
+ editor.commandManager.addEventListener(key, () => {
2607
+ setTimeout(() => {
2608
+ rollbackCount.value = editor.commandManager.operationList.length;
2609
+ revokeRollbackCount.value = editor.commandManager.rollbackList.length;
2610
+ });
2611
+ });
2612
+ });
2613
+ });
2614
+ onUnmounted(() => {
2615
+ domEventRegister.mouseMoveEventProxylock = false;
2616
+ startedEventCancel();
2617
+ resizeObserver.disconnect();
2618
+ });
2619
+ return (_ctx, _cache) => {
2620
+ return openBlock(), createElementBlock("div", {
2621
+ ref_key: "elRef",
2622
+ ref: elRef,
2623
+ class: "editorTool pointer-events-none overflow-hidden absolute left-0 top-0 w-full h-full z-[20] flex flex-row justify-between p-[5px] box-border select-none pointer-events-[all]"
2624
+ }, [
2625
+ createVNode(Transition, null, {
2626
+ default: withCtx(() => [
2627
+ showShortcutKey.value ? (openBlock(), createElementBlock("div", _hoisted_1, [
2628
+ (openBlock(), createElementBlock(Fragment, null, renderList(shortcutKeys, (item) => {
2629
+ return createElementVNode("div", {
2630
+ class: "p-[4px_0px] flex justify-between text-right border-b-1 border-b-[rgba(255,255,255,0.1)] last-of-type:border-b-0",
2631
+ key: item.name
2632
+ }, [
2633
+ createElementVNode("p", _hoisted_2, toDisplayString(item.name), 1),
2634
+ createElementVNode("span", _hoisted_3, toDisplayString(item.shortcut), 1)
2635
+ ]);
2636
+ }), 64))
2637
+ ])) : createCommentVNode("", true)
2638
+ ]),
2639
+ _: 1
2640
+ }),
2641
+ createElementVNode("div", {
2642
+ ref_key: "toolBarRef",
2643
+ ref: toolBarRef,
2644
+ style: normalizeStyle({ left: toolBarPosition.value.left + "px", top: toolBarPosition.value.top + "px" }),
2645
+ class: normalizeClass(["overflow-hidden pointer-events-auto w-fit max-w-[260px] transition-[border-radius] text-[#333] absolute z-[11] bg-white select-none", { "rounded-[8px] ": toolBarExpand.value }]),
2646
+ onMousedown: _cache[8] || (_cache[8] = (e) => e.stopPropagation())
2647
+ }, [
2648
+ createElementVNode("div", {
2649
+ onMousedown: dragMoveHelper,
2650
+ class: normalizeClass([{ "border-b-[#eee] border-b-1": toolBarExpand.value }, "flex flex-row justify-between header text-[14px] font-bold p-[10px 0px]"])
2651
+ }, [
2652
+ _cache[10] || (_cache[10] = createStaticVNode('<div class="flex flex-row" data-v-953dfd98><div class="p-[2px_5px] flex items-center pointer-events-none" data-v-953dfd98><svg fill="#aaa" width="20" height="20" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" data-v-953dfd98><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" data-v-953dfd98></path></svg></div><h5 class="flex text-nowrap text-[12px] items-center pointer-events-none" data-v-953dfd98>绘制工具</h5></div>', 1)),
2653
+ createElementVNode("div", {
2654
+ onMousedown: _cache[0] || (_cache[0] = (e) => e.stopPropagation()),
2655
+ onClick: _cache[1] || (_cache[1] = ($event) => toolBarExpand.value = !toolBarExpand.value),
2656
+ class: "cursor-pointer flex items-center p-[0px_5px]"
2657
+ }, [
2658
+ (openBlock(), createElementBlock("svg", {
2659
+ fill: "#666",
2660
+ class: normalizeClass([{ "rotate-90": toolBarExpand.value }, "transition-all"]),
2661
+ viewBox: "0 0 1024 1024",
2662
+ version: "1.1",
2663
+ xmlns: "http://www.w3.org/2000/svg",
2664
+ width: "12",
2665
+ height: "12"
2666
+ }, _cache[9] || (_cache[9] = [
2667
+ createElementVNode("path", { d: "M315.050667 938.666667a60.757333 60.757333 0 0 0 41.813333-16.298667L750.933333 551.338667a53.418667 53.418667 0 0 0 0-78.677334L356.864 101.632a61.696 61.696 0 0 0-83.541333 0 53.418667 53.418667 0 0 0-0.256 78.677333L625.408 512 273.066667 843.690667a53.418667 53.418667 0 0 0 0 78.677333 60.757333 60.757333 0 0 0 41.984 16.298667z" }, null, -1)
2668
+ ]), 2))
2669
+ ], 32)
2670
+ ], 34),
2671
+ toolBarExpand.value ? (openBlock(), createElementBlock("div", _hoisted_4, [
2672
+ createElementVNode("ul", _hoisted_5, [
2673
+ (openBlock(), createElementBlock(Fragment, null, renderList(commandList, (item) => {
2674
+ return openBlock(), createElementBlock(Fragment, {
2675
+ key: item.command
2676
+ }, [
2677
+ item.show ? (openBlock(), createElementBlock("li", {
2678
+ key: 0,
2679
+ onClick: ($event) => startCurrentCommandItem(item),
2680
+ class: normalizeClass([{ "!bg-[var(--primary-color)] text-[#fff]": currentCommand.value === item.command }, "gap-[10px] text-[12px] hover:bg-[#ddd] transition-all rounded-[6px] p-[5px] flex flex-row items-center justify-between cursor-pointer"])
2681
+ }, [
2682
+ createElementVNode("div", _hoisted_7, [
2683
+ createElementVNode("div", _hoisted_8, [
2684
+ createElementVNode("img", {
2685
+ class: "size-[14px]",
2686
+ src: item.src,
2687
+ alt: "",
2688
+ srcset: ""
2689
+ }, null, 8, _hoisted_9)
2690
+ ]),
2691
+ createElementVNode("span", _hoisted_10, toDisplayString(item.name), 1)
2692
+ ]),
2693
+ currentCommand.value === item.command ? (openBlock(), createElementBlock("div", {
2694
+ key: 0,
2695
+ title: "取消命令(Esc)",
2696
+ class: "active:scale-[0.7] transition-all",
2697
+ onClick: _cache[2] || (_cache[2] = (e) => (unref(editor).cancelCommand(), e.stopPropagation()))
2698
+ }, _cache[11] || (_cache[11] = [
2699
+ createElementVNode("svg", {
2700
+ fill: "#fff",
2701
+ width: "16",
2702
+ height: "16",
2703
+ viewBox: "0 0 1024 1024",
2704
+ version: "1.1",
2705
+ xmlns: "http://www.w3.org/2000/svg"
2706
+ }, [
2707
+ createElementVNode("path", { d: "M511.104 0C228.821333 0 0 228.821333 0 511.104c0 282.282667 228.821333 511.104 511.104 511.104 282.282667 0 511.104-228.842667 511.104-511.104C1022.208 228.821333 793.386667 0 511.104 0zM511.104 898.496c-213.973333 0-387.434667-173.44-387.434667-387.413333 0-213.952 173.44-387.413333 387.434667-387.413333 213.952 0 387.392 173.44 387.392 387.413333C898.496 725.056 725.056 898.496 511.104 898.496z" }),
2708
+ createElementVNode("path", { d: "M236.437333 463.914667l549.333333 0 0 96.874667-549.333333 0 0-96.874667Z" })
2709
+ ], -1)
2710
+ ]))) : item.shortcut ? (openBlock(), createElementBlock("div", _hoisted_11, toDisplayString(item.shortcut), 1)) : createCommentVNode("", true)
2711
+ ], 10, _hoisted_6)) : createCommentVNode("", true)
2712
+ ], 64);
2713
+ }), 64))
2714
+ ]),
2715
+ createElementVNode("div", _hoisted_12, [
2716
+ createVNode(unref(ElCheckbox), {
2717
+ size: "small",
2718
+ modelValue: showShortcutKey.value,
2719
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => showShortcutKey.value = $event),
2720
+ label: "快捷键提示"
2721
+ }, null, 8, ["modelValue"]),
2722
+ createVNode(unref(ElCheckbox), {
2723
+ size: "small",
2724
+ modelValue: dxfVisible.value,
2725
+ "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => dxfVisible.value = $event),
2726
+ label: "dxf"
2727
+ }, null, 8, ["modelValue"])
2728
+ ]),
2729
+ _ctx.permission === "admin" ? (openBlock(), createElementBlock("div", _hoisted_13, [
2730
+ createVNode(unref(ElButton), {
2731
+ style: { "padding": "5px", "font-size": "10px" },
2732
+ size: "small",
2733
+ type: "success",
2734
+ onClick: selectLocalFile
2735
+ }, {
2736
+ default: withCtx(() => _cache[12] || (_cache[12] = [
2737
+ createTextVNode(" 选择文件 ", -1)
2738
+ ])),
2739
+ _: 1,
2740
+ __: [12]
2741
+ }),
2742
+ createVNode(unref(ElButton), {
2743
+ style: { "padding": "5px", "font-size": "10px" },
2744
+ size: "small",
2745
+ type: "primary",
2746
+ onClick: _cache[5] || (_cache[5] = ($event) => console.log(unref(dxfSystem).Dxf.originalData))
2747
+ }, {
2748
+ default: withCtx(() => _cache[13] || (_cache[13] = [
2749
+ createTextVNode(" 打印Json ", -1)
2750
+ ])),
2751
+ _: 1,
2752
+ __: [13]
2753
+ }),
2754
+ createVNode(unref(ElButton), {
2755
+ style: { "padding": "5px", "font-size": "10px" },
2756
+ size: "small",
2757
+ type: "primary",
2758
+ onClick: _cache[6] || (_cache[6] = ($event) => unref(dxfSystem).Dxf.download("test.dxf"))
2759
+ }, {
2760
+ default: withCtx(() => _cache[14] || (_cache[14] = [
2761
+ createTextVNode(" 下载DXF ", -1)
2762
+ ])),
2763
+ _: 1,
2764
+ __: [14]
2765
+ }),
2766
+ createVNode(unref(ElButton), {
2767
+ style: { "padding": "5px", "font-size": "10px" },
2768
+ size: "small",
2769
+ type: "primary",
2770
+ onClick: _cache[7] || (_cache[7] = ($event) => unref(whiteModel).downloadGltf("test.glb", true))
2771
+ }, {
2772
+ default: withCtx(() => _cache[15] || (_cache[15] = [
2773
+ createTextVNode(" 下载白膜 ", -1)
2774
+ ])),
2775
+ _: 1,
2776
+ __: [15]
2777
+ })
2778
+ ])) : createCommentVNode("", true),
2779
+ createVNode(Transition, null, {
2780
+ default: withCtx(() => [
2781
+ createElementVNode("div", _hoisted_14, [
2782
+ createVNode(TransitionGroup, null, {
2783
+ default: withCtx(() => [
2784
+ (openBlock(), createElementBlock(Fragment, null, renderList(otherCommandList, (item) => {
2785
+ return createElementVNode("div", {
2786
+ onClick: ($event) => item.show.value && (item.action ? item.action() : unref(editor).commandManager.start(item.command, [...unref(defaultComponent).selectLines])),
2787
+ title: `${item.name}(${item.shortcut})`,
2788
+ class: normalizeClass(["size-[20px] flex justify-center items-center relative overflow-hidden active:scale-[0.8] border-1 border-[#ccc] rounded-[4px] transition-all cursor-pointer", { "opacity-30 bg-[#ccc] !cursor-no-drop active:!scale-[1]": !item.show.value, [item.class ?? ""]: true }]),
2789
+ key: item.command
2790
+ }, [
2791
+ createElementVNode("img", {
2792
+ class: "size-[14px]",
2793
+ src: item.src
2794
+ }, null, 8, _hoisted_16)
2795
+ ], 10, _hoisted_15);
2796
+ }), 64))
2797
+ ]),
2798
+ _: 1
2799
+ })
2800
+ ])
2801
+ ]),
2802
+ _: 1
2803
+ })
2804
+ ])) : createCommentVNode("", true)
2805
+ ], 38)
2806
+ ], 512);
2807
+ };
2808
+ }
2809
+ });
2810
+ const _export_sfc = (sfc, props) => {
2811
+ const target = sfc.__vccOpts || sfc;
2812
+ for (const [key, val] of props) {
2813
+ target[key] = val;
2814
+ }
2815
+ return target;
2816
+ };
2817
+ const EditorTool = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-953dfd98"]]);
2818
+ let Editor$1 = class Editor extends Component {
2819
+ static name = "Editor";
2820
+ container = new THREE.Group();
2821
+ get renderer() {
2822
+ return this.parent?.findComponentByName("Renderer");
2823
+ }
2824
+ get dxf() {
2825
+ return this.parent?.findComponentByName("Dxf");
2826
+ }
2827
+ get variable() {
2828
+ return this.parent?.findComponentByName("Variable");
2829
+ }
2830
+ get eventInput() {
2831
+ return this.parent?.findComponentByName("EventInput");
2832
+ }
2833
+ get renderManager() {
2834
+ return this.parent?.findComponentByName("RenderManager");
2835
+ }
2836
+ get domEventRegister() {
2837
+ return this.parent?.findComponentByName("DomEventRegister");
2838
+ }
2839
+ get domContainer() {
2840
+ return this.parent?.findComponentByName("DomContainer");
2841
+ }
2842
+ commandManager = new CommandManager();
2843
+ plane = new THREE.Mesh(new THREE.PlaneGeometry(2e3, 2e3, 2, 2));
2844
+ app;
2845
+ domElement = document.createElement("div");
2846
+ viewPermission;
2847
+ constructor(viewPermission) {
2848
+ super();
2849
+ this.viewPermission = viewPermission;
2850
+ }
2851
+ onAddFromParent() {
2852
+ setTimeout(() => this.openEdit(), 10);
2853
+ const grid = new THREE.GridHelper(200, 100, 6710886, 4473924);
2854
+ grid.rotation.x = Math.PI * 0.5;
2855
+ grid.position.z = -0.01;
2856
+ this.container.add(grid);
2857
+ this.container.add(this.plane);
2858
+ this.plane.visible = false;
2859
+ const cancelEvent = this.addEventListener("update", () => {
2860
+ if (this.domContainer.domElement.parentElement) {
2861
+ this.domContainer.domElement.parentElement.appendChild(this.domElement);
2862
+ cancelEvent();
2863
+ }
2864
+ });
2865
+ setTimeout(() => {
2866
+ this.app = createApp(EditorTool, { dxfSystem: this.parent, permission: this.viewPermission });
2867
+ this.app.mount(this.domElement);
2868
+ });
2869
+ }
2870
+ /**
2871
+ * 取消命令,由其他命令组件监听事件后注册事件监听实现
2872
+ */
2873
+ cancelCommand() {
2874
+ this.dispatchEvent({
2875
+ type: "cancelCommand"
2876
+ });
2877
+ }
2878
+ coords = new THREE.Vector2();
2879
+ pointerPosition = new THREE.Vector2();
2880
+ _exitEditCallBack;
2881
+ /**
2882
+ * 打开编辑器
2883
+ */
2884
+ openEdit() {
2885
+ 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;
2886
+ this.container.position.z = dxf.originalZAverage;
2887
+ renderer.scene.add(this.container);
2888
+ if (orbitControls) {
2889
+ camera.position.set(center.x, center.y, 15);
2890
+ orbitControls.target.set(center.x, center.y, 0);
2891
+ orbitControls.enableRotate = false;
2892
+ }
2893
+ const mousemoveFun = () => {
2894
+ renderer.renderer.getSize(size);
2895
+ const x = domEventRegister.pointer.x / size.x * 2 - 1;
2896
+ const y = -(domEventRegister.pointer.y / size.y * 2 - 1);
2897
+ coords.set(x, y);
2898
+ raycaster.setFromCamera(coords, renderer.camera.children.length ? renderer.camera.children[0] : renderer.camera);
2899
+ const intersections = raycaster.intersectObject(this.plane);
2900
+ if (intersections.length) {
2901
+ pointerPosition.copy(intersections[0].point);
2902
+ this.dispatchEvent({
2903
+ type: "pointerPositionChange",
2904
+ position: pointerPosition
2905
+ });
2906
+ }
2907
+ };
2908
+ domEventRegister.addEventListener("mousemove", mousemoveFun);
2909
+ this.commandManager.disabled = false;
2910
+ this.commandManager.start("default");
2911
+ this._exitEditCallBack = () => {
2912
+ domEventRegister.removeEventListener("mousemove", mousemoveFun);
2913
+ if (orbitControls) {
2914
+ camera.position.copy(cameraPosition);
2915
+ orbitControls.enableRotate = true;
2916
+ orbitControls.target.copy(target);
2917
+ }
2918
+ };
2919
+ }
2920
+ /**
2921
+ * 退出编辑
2922
+ */
2923
+ exitEdit() {
2924
+ if (typeof this._exitEditCallBack === "function") {
2925
+ this._exitEditCallBack();
2926
+ this._exitEditCallBack = void 0;
2927
+ this.commandManager.disabled = true;
2928
+ }
2929
+ }
2930
+ destroy() {
2931
+ super.destroy();
2932
+ this.exitEdit();
2933
+ this.renderer.scene.remove(this.container);
2934
+ this.domElement.remove();
2935
+ this.app?.unmount();
2936
+ }
2937
+ };
1836
2938
  class PointDrag extends CommandFlowComponent {
1837
2939
  static name = "PointDrag";
1838
2940
  container = new THREE.Group();
1839
2941
  interruptKeys = ["escape"];
1840
2942
  shortcutKeys = ["control", "p"];
1841
2943
  commandName = "point";
1842
- onAddFromParent() {
2944
+ onAddFromParent(parent) {
2945
+ super.onAddFromParent(parent);
1843
2946
  this.editor.container.add(this.container);
1844
2947
  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));
2948
+ const commandFlow = this.commandManager.addCommandFlow(this.commandName).add(this.createInterrupt()).add(this.createCursor("crosshair")).add(this.selectPoint.bind(this)).add(this.drag.bind(this)).addRollback(this.rollback.bind(this)).addRevokeRollback(this.revokeRollback.bind(this));
1846
2949
  commandFlow.addEventListener("finally", this.createFinally());
1847
2950
  commandFlow.addEventListener("completed", (e) => this.completed(e.data));
1848
2951
  this.eventInput.addKeyCombination(this.commandName, this.shortcutKeys);
@@ -1855,11 +2958,11 @@ class PointDrag extends CommandFlowComponent {
1855
2958
  selectPoint(next) {
1856
2959
  let currentPoint = null, circle = new THREE.Mesh(new THREE.SphereGeometry(0.05), new THREE.MeshBasicMaterial({ color: 16711935 })), currentLine = null;
1857
2960
  this.addEventRecord("selectPointStart").add(this.editor.addEventListener("pointerPositionChange", () => {
1858
- const { point, line, find, mode } = this.editor.renderManager.adsorption();
2961
+ const { point, line: line2, find, mode } = this.editor.renderManager.adsorption();
1859
2962
  if (find && mode === "point") {
1860
2963
  this.domElement.style.cursor = "none";
1861
2964
  circle.position.copy(point);
1862
- currentLine = line;
2965
+ currentLine = line2;
1863
2966
  currentPoint = point.clone();
1864
2967
  this.container.add(circle);
1865
2968
  } else {
@@ -1881,15 +2984,16 @@ class PointDrag extends CommandFlowComponent {
1881
2984
  * @param next
1882
2985
  * @param param1
1883
2986
  */
1884
- drag(next, { point, line }) {
2987
+ drag(next, { point, line: line2 }) {
1885
2988
  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 }));
2989
+ const mode = line2.start.equal(Point.from(point)) ? "start" : "end", start = mode == "start" ? new THREE.Vector3(line2.end.x, line2.end.y, 0) : new THREE.Vector3(line2.start.x, line2.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
2990
  this.container.add(lines);
1888
2991
  this.addEventRecord("clear").add(this.editor.addEventListener("pointerPositionChange", () => {
1889
2992
  let { point: point2, find } = this.editor.renderManager.adsorption(), cursor = "none";
1890
2993
  if (point2) {
2994
+ this.dispatchEvent({ type: "pointerMove", point: point2 });
1891
2995
  if (this.eventInput.isKeyDown("shift")) {
1892
- const p = line.projectPoint(Point.from(point2), false);
2996
+ const p = line2.projectPoint(Point.from(point2), false);
1893
2997
  point2.set(p?.x ?? point2.x, p?.y ?? point2.y, 0);
1894
2998
  find = true;
1895
2999
  cursor = "crosshair";
@@ -1908,30 +3012,62 @@ class PointDrag extends CommandFlowComponent {
1908
3012
  })).add(this.eventInput.addEventListener("codeChange", () => {
1909
3013
  if (this.eventInput.isKeyDown("mouse_0")) {
1910
3014
  this.canceEventRecord("selectPointStart");
1911
- next({ point: end, line, mode });
3015
+ next({ point: end, oldPoint: mode === "end" ? line2.end.clone() : line2.start.clone(), line: line2, mode });
1912
3016
  }
1913
3017
  })).add(() => circle.removeFromParent()).add(() => lines.removeFromParent());
1914
3018
  }
1915
3019
  /** 执行完成
1916
3020
  */
1917
3021
  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);
3022
+ const { line: line2, point, mode } = data;
3023
+ this.renderManager.removeLine(line2);
3024
+ if (mode === "end") line2.end.set(point.x, point.y);
3025
+ else if (mode === "start") line2.start.set(point.x, point.y);
3026
+ this.renderManager.addLine(line2);
1923
3027
  this.renderManager.draw();
1924
3028
  }
3029
+ /** 回滚操作
3030
+ * @param data
3031
+ */
3032
+ rollback(data) {
3033
+ const { line: line2, oldPoint, mode } = data;
3034
+ if (mode === "end") line2.end.set(oldPoint.x, oldPoint.y);
3035
+ else if (mode === "start") line2.start.set(oldPoint.x, oldPoint.y);
3036
+ this.renderManager.addLine(line2);
3037
+ this.renderManager.draw();
3038
+ return data;
3039
+ }
3040
+ /** 撤回回滚
3041
+ * @param lines
3042
+ * @returns
3043
+ */
3044
+ revokeRollback(data) {
3045
+ this.completed(data);
3046
+ return data;
3047
+ }
1925
3048
  }
1926
- function Editor2(dxfSystem) {
1927
- dxfSystem.addComponent(new Editor$1());
3049
+ function Editor_(dxfSystem, option = {}) {
3050
+ dxfSystem.addComponent(new Editor$1(option.viewPermission));
1928
3051
  dxfSystem.addComponent(new RenderManager());
1929
3052
  dxfSystem.addComponent(new Default());
1930
3053
  dxfSystem.addComponent(new DrawLine());
1931
3054
  dxfSystem.addComponent(new DrawDoorLine());
1932
3055
  dxfSystem.addComponent(new DrawWindow());
1933
3056
  dxfSystem.addComponent(new PointDrag());
3057
+ dxfSystem.addComponent(new DeleteSelectLine());
3058
+ dxfSystem.addComponent(new MergeLine());
3059
+ dxfSystem.addComponent(new VerticalCorrection());
3060
+ dxfSystem.addComponent(new ConnectionLine());
3061
+ dxfSystem.addComponent(new IntersectionConnectionLine());
3062
+ dxfSystem.addComponent(new DeleteSelectWindow());
3063
+ dxfSystem.addComponent(new SelectAll());
1934
3064
  }
3065
+ const Editor2 = Object.assign(Editor_, {
3066
+ create(option = {}) {
3067
+ return (dxfSystem) => Editor_(dxfSystem, option);
3068
+ }
3069
+ });
1935
3070
  export {
1936
- Editor2 as Editor
3071
+ Editor2 as Editor,
3072
+ Editor_
1937
3073
  };