build-dxf 0.1.7 → 0.1.9
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.
- package/package.json +1 -1
- package/src/build.d.ts +1 -0
- package/src/build.js +667 -1475
- package/src/index.css +1 -1
- package/src/index.js +10 -10
- package/src/index2.js +4 -352
- package/src/index3.js +5000 -134
- package/src/{DomEventRegister.js → index4.js} +380 -247
- package/src/utils/DxfSystem/DxfSystem.d.ts +0 -3
- package/src/utils/DxfSystem/components/DoorsAnalysis.d.ts +1 -4
- package/src/utils/DxfSystem/components/Dxf.d.ts +66 -125
- package/src/utils/DxfSystem/components/DxfOld.d.ts +183 -0
- package/src/utils/DxfSystem/plugin/ModelDataPlugin/components/WhiteModel.d.ts +0 -2
- package/src/utils/DxfSystem/plugin/ModelDataPlugin/components/index.d.ts +0 -1
- package/src/utils/DxfSystem/plugin/ModelDataPlugin/index.d.ts +0 -1
- package/src/utils/DxfSystem/plugin/RenderPlugin/components/index.d.ts +0 -2
- package/src/utils/DxfSystem/plugin/RenderPlugin/index.d.ts +0 -2
- package/src/utils/DxfSystem/utils/LineGroupType.d.ts +1 -1
- package/src/utils/modelScenario/SceneAutoGenerat.d.ts +7 -1
- package/src/components/Card.vue.d.ts +0 -9
- package/src/utils/DxfSystem/components/LineAnalysis.d.ts +0 -77
- package/src/utils/DxfSystem/plugin/ModelDataPlugin/components/DetailsPoint.d.ts +0 -39
- package/src/utils/DxfSystem/plugin/RenderPlugin/components/DetailsPointRender.d.ts +0 -48
- package/src/utils/DxfSystem/plugin/RenderPlugin/components/OriginalLineRender.d.ts +0 -16
package/src/build.js
CHANGED
|
@@ -1558,7 +1558,8 @@ class LineSegment {
|
|
|
1558
1558
|
const [q1, q2] = this.points;
|
|
1559
1559
|
const dir = new Point(q2.x - q1.x, q2.y - q1.y);
|
|
1560
1560
|
if (dir.x === 0 && dir.y === 0) {
|
|
1561
|
-
|
|
1561
|
+
console.error("投影目标线段的两个点不能重合");
|
|
1562
|
+
return new LineSegment();
|
|
1562
1563
|
}
|
|
1563
1564
|
const projectPoint = (point) => {
|
|
1564
1565
|
const pq = new Point(point.x - q1.x, point.y - q1.y);
|
|
@@ -3079,7 +3080,7 @@ class LineGroupType {
|
|
|
3079
3080
|
return false;
|
|
3080
3081
|
}
|
|
3081
3082
|
/**
|
|
3082
|
-
*
|
|
3083
|
+
* 通过类型移除
|
|
3083
3084
|
* @param line
|
|
3084
3085
|
* @param id
|
|
3085
3086
|
* @returns
|
|
@@ -3935,6 +3936,10 @@ function buildDoubleWallGroup(lines, doorLines = [], grouped = true, clearIntern
|
|
|
3935
3936
|
let { newLines, rings } = findLargestCircle(lines), ringsSet = new Set(rings.flat());
|
|
3936
3937
|
if (grouped) {
|
|
3937
3938
|
const grid = new PointVirtualGrid(), internalEdges = /* @__PURE__ */ new Set();
|
|
3939
|
+
lines.forEach((line) => {
|
|
3940
|
+
LineGroupType.removeByType(line, "doubleWall");
|
|
3941
|
+
LineGroupType.removeByType(line, "wall");
|
|
3942
|
+
});
|
|
3938
3943
|
newLines.forEach((line) => !ringsSet.has(line) && grid.insert(line.center, line));
|
|
3939
3944
|
doorLines.forEach((line) => grid.insert(line.center, line));
|
|
3940
3945
|
const id = uuid();
|
|
@@ -3944,15 +3949,13 @@ function buildDoubleWallGroup(lines, doorLines = [], grouped = true, clearIntern
|
|
|
3944
3949
|
rings.forEach((group2) => {
|
|
3945
3950
|
const id2 = uuid();
|
|
3946
3951
|
group2.forEach((line) => {
|
|
3947
|
-
|
|
3948
|
-
LineGroupType.removeByType(line, "wall");
|
|
3952
|
+
LineGroupType.set(line, id2, "doubleWall");
|
|
3949
3953
|
});
|
|
3950
3954
|
clearInternalLine && grid.queryPolygon(Polygon.fromByLines(group2)).forEach((res) => internalEdges.add(res.userData));
|
|
3951
3955
|
});
|
|
3952
3956
|
newLines.forEach((line) => {
|
|
3953
3957
|
if (ringsSet.has(line) || LineGroupType.hasType(line, "bayWindow")) return;
|
|
3954
3958
|
LineGroupType.set(line, "default", "wall");
|
|
3955
|
-
LineGroupType.removeByType(line, "doubleWall");
|
|
3956
3959
|
});
|
|
3957
3960
|
newLines = newLines.filter((line) => !internalEdges.has(line));
|
|
3958
3961
|
const newDoorLines = doorLines.filter((line) => !internalEdges.has(line));
|
|
@@ -4854,7 +4857,7 @@ class Group {
|
|
|
4854
4857
|
}
|
|
4855
4858
|
}
|
|
4856
4859
|
const defaultWallWidth = 0.12;
|
|
4857
|
-
const units
|
|
4860
|
+
const units = {
|
|
4858
4861
|
Unitless: 1,
|
|
4859
4862
|
// 无单位,1米 = 1(无单位)
|
|
4860
4863
|
Inches: 39.37007874015748,
|
|
@@ -5091,7 +5094,7 @@ class CAD {
|
|
|
5091
5094
|
toDrawData(unit = "Millimeters") {
|
|
5092
5095
|
if (!this.needUpdate && this._cachedDrawData) return this._cachedDrawData;
|
|
5093
5096
|
this.needUpdate = false;
|
|
5094
|
-
const lines = this.groups.flatMap((group2) => group2.lines), s = units
|
|
5097
|
+
const lines = this.groups.flatMap((group2) => group2.lines), s = units[unit], expansionWidth = 2, box = Box2.fromByLineSegment(...lines).expansion(expansionWidth), center = box.center, data = {
|
|
5095
5098
|
unit,
|
|
5096
5099
|
lines: [],
|
|
5097
5100
|
arcs: [],
|
|
@@ -5653,7 +5656,7 @@ class BoundExt {
|
|
|
5653
5656
|
};
|
|
5654
5657
|
}
|
|
5655
5658
|
}
|
|
5656
|
-
const PRE_PROCESSOR = {
|
|
5659
|
+
const PRE_PROCESSOR$1 = {
|
|
5657
5660
|
DoorsAnalysis(lines) {
|
|
5658
5661
|
return lines;
|
|
5659
5662
|
},
|
|
@@ -5704,7 +5707,7 @@ const PRE_PROCESSOR = {
|
|
|
5704
5707
|
};
|
|
5705
5708
|
class CorrectionDxf extends Component {
|
|
5706
5709
|
static name = "CorrectionDxf";
|
|
5707
|
-
static PRE_PROCESSOR = PRE_PROCESSOR;
|
|
5710
|
+
static PRE_PROCESSOR = PRE_PROCESSOR$1;
|
|
5708
5711
|
width = 0.04;
|
|
5709
5712
|
originalData = [];
|
|
5710
5713
|
data = [];
|
|
@@ -5735,8 +5738,8 @@ class CorrectionDxf extends Component {
|
|
|
5735
5738
|
return this;
|
|
5736
5739
|
}
|
|
5737
5740
|
onAddFromParent(parent) {
|
|
5738
|
-
parent.Dxf.addEventListener("
|
|
5739
|
-
this.trajectory && this.addPreProcessor(PRE_PROCESSOR.BoundExt);
|
|
5741
|
+
parent.Dxf.addEventListener("cadChange", () => {
|
|
5742
|
+
this.trajectory && this.addPreProcessor(PRE_PROCESSOR$1.BoundExt);
|
|
5740
5743
|
const lines = parent.Dxf.getLineSegments(true);
|
|
5741
5744
|
this.set(lineDataToOriginalData(lines, parent.Dxf.originalZAverage), {
|
|
5742
5745
|
trajectory: this.trajectory ?? void 0
|
|
@@ -5829,6 +5832,11 @@ class CorrectionDxf extends Component {
|
|
|
5829
5832
|
originalData: this.originalData,
|
|
5830
5833
|
data: this.data
|
|
5831
5834
|
});
|
|
5835
|
+
let lines = this.getLineSegments(true);
|
|
5836
|
+
const doors = lines.filter((line) => line.userData.isDoor);
|
|
5837
|
+
lines = lines.filter((line) => !line.userData.isDoor);
|
|
5838
|
+
lines = buildDoubleWallGroup(lines, doors);
|
|
5839
|
+
lines.push(...doors);
|
|
5832
5840
|
this.cad = new CAD().usePlugin(new DxfDataPlugin(this.getLineSegments(true))).usePlugin(new DxfDrawPlugin());
|
|
5833
5841
|
const { angle, referenceLine } = CAD.obliquity(this.cad);
|
|
5834
5842
|
this.cad.rotateAndResetOrigin(angle);
|
|
@@ -5910,457 +5918,407 @@ function closedPathArea(points) {
|
|
|
5910
5918
|
}
|
|
5911
5919
|
return Math.abs(area) / 2;
|
|
5912
5920
|
}
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
// 毫米,1米 = 1000毫米
|
|
5924
|
-
Centimeters: 100,
|
|
5925
|
-
// 厘米,1米 = 100厘米
|
|
5926
|
-
Meters: 1,
|
|
5927
|
-
// 米,1米 = 1米
|
|
5928
|
-
Kilometers: 1e-3,
|
|
5929
|
-
// 千米,1米 = 0.001千米
|
|
5930
|
-
Microinches: 3937007874015748e-8,
|
|
5931
|
-
// 微英寸,1米 = 39370078.74015748微英寸
|
|
5932
|
-
Mils: 39370.07874015748,
|
|
5933
|
-
// 密耳,1米 = 39370.07874015748密耳
|
|
5934
|
-
Yards: 1.0936132983377078,
|
|
5935
|
-
// 码,1米 = 1.0936132983377078码
|
|
5936
|
-
Angstroms: 1e10,
|
|
5937
|
-
// 埃,1米 = 10^10埃
|
|
5938
|
-
Nanometers: 1e9,
|
|
5939
|
-
// 纳米,1米 = 10^9纳米
|
|
5940
|
-
Microns: 1e6,
|
|
5941
|
-
// 微米,1米 = 10^6微米
|
|
5942
|
-
Decimeters: 10,
|
|
5943
|
-
// 分米,1米 = 10分米
|
|
5944
|
-
Decameters: 0.1,
|
|
5945
|
-
// 十米,1米 = 0.1十米
|
|
5946
|
-
Hectometers: 0.01,
|
|
5947
|
-
// 百米,1米 = 0.01百米
|
|
5948
|
-
Gigameters: 1e-9,
|
|
5949
|
-
// 吉米,1米 = 10^-9吉米
|
|
5950
|
-
"Astronomical units": 6684587122268445e-27,
|
|
5951
|
-
// 天文单位,1米 = 0.000000000006684587122268445天文单位
|
|
5952
|
-
"Light years": 10570008340246154e-32,
|
|
5953
|
-
// 光年,1米 ≈ 0.00000000000000010570008340246154光年
|
|
5954
|
-
Parsecs: 3240779289666404e-32
|
|
5955
|
-
// 秒差距,1米 ≈ 0.00000000000000003240779289666404秒差距
|
|
5956
|
-
};
|
|
5957
|
-
function pathToLines(path) {
|
|
5958
|
-
const lineSegments = [];
|
|
5959
|
-
for (let i = 0; i < path.length; i++) {
|
|
5960
|
-
lineSegments.push(new LineSegment(
|
|
5961
|
-
path[i].clone(),
|
|
5962
|
-
path[(i + 1) % path.length].clone()
|
|
5963
|
-
));
|
|
5964
|
-
}
|
|
5965
|
-
return lineSegments;
|
|
5966
|
-
}
|
|
5967
|
-
function linesToPath(lineSegments) {
|
|
5968
|
-
return lineSegments.flatMap((line, index2) => {
|
|
5969
|
-
if (index2 === lineSegments.length - 1) [...line.points, lineSegments[0].points[0]];
|
|
5970
|
-
return [line.points[0]];
|
|
5971
|
-
});
|
|
5972
|
-
}
|
|
5973
|
-
class Dxf extends Component {
|
|
5974
|
-
static name = "Dxf";
|
|
5975
|
-
shortLine = 0.04;
|
|
5976
|
-
width = 0.04;
|
|
5977
|
-
scale = 1;
|
|
5978
|
-
originalData = [];
|
|
5979
|
-
data = [];
|
|
5980
|
-
originalBox = new Box2(0, 0, 0, 0);
|
|
5981
|
-
box = new Box2(0, 0, 0, 0);
|
|
5982
|
-
pointsGroups = [];
|
|
5983
|
-
wallsGroup = [];
|
|
5984
|
-
doors = [];
|
|
5985
|
-
doorLineSegment = [];
|
|
5986
|
-
verticalReferenceLine;
|
|
5987
|
-
lineSegments = [];
|
|
5988
|
-
originalZAverage = 0;
|
|
5989
|
-
static EndType = {
|
|
5990
|
-
etOpenSquare: 0,
|
|
5991
|
-
etOpenRound: 1,
|
|
5992
|
-
etOpenButt: 2
|
|
5993
|
-
// etClosedLine: 3,
|
|
5994
|
-
// etClosedPolygon: 4
|
|
5995
|
-
};
|
|
5996
|
-
static JoinType = {
|
|
5997
|
-
jtSquare: 0,
|
|
5998
|
-
jtRound: 1,
|
|
5999
|
-
jtMiter: 2
|
|
6000
|
-
};
|
|
6001
|
-
/** 原始数据组
|
|
6002
|
-
*/
|
|
6003
|
-
get lines() {
|
|
6004
|
-
return this.lineSegments;
|
|
6005
|
-
}
|
|
6006
|
-
/**初始化
|
|
6007
|
-
* @param width 墙体宽度
|
|
6008
|
-
* @param scale 缩放比例
|
|
6009
|
-
*/
|
|
6010
|
-
constructor(width = DEFAULT_WALL_WIDTH, scale = 1) {
|
|
6011
|
-
super();
|
|
6012
|
-
this.width = width;
|
|
6013
|
-
this.scale = scale;
|
|
6014
|
-
this.shortLine = width * 0.4;
|
|
6015
|
-
}
|
|
6016
|
-
/** 预处理数据
|
|
6017
|
-
* @param data
|
|
6018
|
-
*/
|
|
6019
|
-
preprocessing(data) {
|
|
6020
|
-
let { lineSegments, verticalReferenceIndex, originalZAverage } = originalDataToLineData(data);
|
|
6021
|
-
this.originalZAverage = originalZAverage;
|
|
6022
|
-
if (verticalReferenceIndex === -1) {
|
|
6023
|
-
const line = findVerticalReference(lineSegments);
|
|
6024
|
-
verticalReferenceIndex = lineSegments.indexOf(line);
|
|
6025
|
-
}
|
|
6026
|
-
const verticalReferenceLine = lineSegments[verticalReferenceIndex];
|
|
6027
|
-
verticalReferenceLine.userData.isVerticalReferenceLine = true;
|
|
6028
|
-
data[verticalReferenceIndex].isVerticalReferenceLine = true;
|
|
6029
|
-
this.verticalReferenceLine = verticalReferenceLine;
|
|
6030
|
-
this.dispatchEvent({
|
|
6031
|
-
type: "preprocessing",
|
|
6032
|
-
data,
|
|
6033
|
-
setData(originalDataItem) {
|
|
6034
|
-
lineSegments = originalDataItem.map(({ start, end, ...opt }) => {
|
|
6035
|
-
const lineSegment = new LineSegment(Point.from(start), Point.from(end));
|
|
6036
|
-
lineSegment.userData = opt;
|
|
6037
|
-
return lineSegment;
|
|
6038
|
-
});
|
|
6039
|
-
data = originalDataItem;
|
|
6040
|
-
}
|
|
6041
|
-
});
|
|
6042
|
-
return { lineSegments, data };
|
|
6043
|
-
}
|
|
6044
|
-
/** 设置
|
|
6045
|
-
* @param data 房屋结构数据,node环境可以为路径
|
|
6046
|
-
* @param width 墙体宽度
|
|
6047
|
-
* @param scale 缩放比例
|
|
6048
|
-
* @param axisAlignmentCorrection 需要执行轴对称垂直纠正
|
|
6049
|
-
* @param option
|
|
6050
|
-
* @returns
|
|
6051
|
-
*/
|
|
6052
|
-
async set(data, width = this.width, scale = this.scale) {
|
|
6053
|
-
if (typeof data === "string") {
|
|
6054
|
-
if (typeof global !== "undefined") {
|
|
6055
|
-
const packageName = "fs";
|
|
6056
|
-
const { default: fs2 } = await import(
|
|
6057
|
-
/* @vite-ignore */
|
|
6058
|
-
packageName
|
|
6059
|
-
);
|
|
6060
|
-
const buffer = fs2.readFileSync(data);
|
|
6061
|
-
const json = JSON.parse(buffer.toString("utf-8"));
|
|
6062
|
-
return this.set(json, width, scale);
|
|
5921
|
+
function findRingEdges(lines) {
|
|
5922
|
+
const lineUG = new LineSegmentUndirectedGraph(lines), unionFindSet = new UnionFindSet(lineUG.size), visited = /* @__PURE__ */ new Set(), ringEdges = [];
|
|
5923
|
+
function dfs(n1) {
|
|
5924
|
+
visited.add(n1);
|
|
5925
|
+
const neighbors = lineUG.getNeighbors(n1);
|
|
5926
|
+
neighbors?.forEach((n2) => {
|
|
5927
|
+
if (visited.has(n2)) return;
|
|
5928
|
+
if (unionFindSet.find(n1) === unionFindSet.find(n2)) {
|
|
5929
|
+
const line = lineUG.getLine(n1, n2);
|
|
5930
|
+
ringEdges.push(line);
|
|
6063
5931
|
} else {
|
|
6064
|
-
|
|
5932
|
+
unionFindSet.union(n1, n2);
|
|
6065
5933
|
}
|
|
6066
|
-
}
|
|
6067
|
-
if (data.length === 0) return;
|
|
6068
|
-
this.scale = scale;
|
|
6069
|
-
this.width = width;
|
|
6070
|
-
this.doorLineSegment.length = 0;
|
|
6071
|
-
if (data.length === 0) {
|
|
6072
|
-
this.lineSegments = [];
|
|
6073
|
-
this.originalData = data;
|
|
6074
|
-
} else {
|
|
6075
|
-
const res = this.preprocessing(data);
|
|
6076
|
-
data = res.data;
|
|
6077
|
-
this.lineSegments = res.lineSegments;
|
|
6078
|
-
this.originalData = data;
|
|
6079
|
-
}
|
|
6080
|
-
const zList = [];
|
|
6081
|
-
this.data = data.map(({ start, end, insetionArr, isDoor = false }, index2) => {
|
|
6082
|
-
zList.push(start.z ?? 0, end.z ?? 0);
|
|
6083
|
-
const lineSegment = this.lineSegments[index2];
|
|
6084
|
-
return [
|
|
6085
|
-
lineSegment.points[0],
|
|
6086
|
-
lineSegment.points[1],
|
|
6087
|
-
(insetionArr ?? []).map((i) => i.index),
|
|
6088
|
-
isDoor,
|
|
6089
|
-
index2
|
|
6090
|
-
];
|
|
6091
|
-
});
|
|
6092
|
-
this.originalZAverage = zList.reduce((count, num) => count + num, 0) / zList.length;
|
|
6093
|
-
this.computedOriginalSize(data, this.originalBox);
|
|
6094
|
-
this.dispatchEvent({
|
|
6095
|
-
type: "setDta",
|
|
6096
|
-
originalData: this.originalData,
|
|
6097
|
-
data: this.data
|
|
6098
|
-
});
|
|
6099
|
-
this.createGroups();
|
|
6100
|
-
this.computedSize();
|
|
6101
|
-
this.dispatchEvent({
|
|
6102
|
-
type: "createGroup",
|
|
6103
|
-
groups: this.pointsGroups
|
|
6104
5934
|
});
|
|
6105
5935
|
}
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
}
|
|
6122
|
-
group2.push([start, end]);
|
|
6123
|
-
insetionArr.forEach((i) => {
|
|
6124
|
-
if (!visited.has(i)) {
|
|
6125
|
-
dfs(i, group2, index2);
|
|
6126
|
-
}
|
|
6127
|
-
});
|
|
6128
|
-
};
|
|
6129
|
-
this.data.forEach((_, index2) => {
|
|
6130
|
-
if (this.lineSegments[index2]?.userData.isBayWindow) return;
|
|
6131
|
-
if (!visited.has(index2)) {
|
|
6132
|
-
const group2 = [];
|
|
6133
|
-
dfs(index2, group2);
|
|
6134
|
-
groups.push(group2);
|
|
6135
|
-
}
|
|
6136
|
-
});
|
|
6137
|
-
this.doors = [...doorSet];
|
|
6138
|
-
this.pointsGroups = groups;
|
|
6139
|
-
return groups;
|
|
5936
|
+
lineUG.forEach((n1) => {
|
|
5937
|
+
if (visited.has(n1)) return;
|
|
5938
|
+
dfs(n1);
|
|
5939
|
+
});
|
|
5940
|
+
return ringEdges;
|
|
5941
|
+
}
|
|
5942
|
+
function findMinRing(lines, ringEdges) {
|
|
5943
|
+
const grid = createPointVirtualGrid(lines), temLine = new LineSegment(), queryLine = new LineSegment(), rings = [], visited = /* @__PURE__ */ new Set();
|
|
5944
|
+
function getDirect(line, preDirect) {
|
|
5945
|
+
const center = line.center, direct = line.normal();
|
|
5946
|
+
temLine.start.copy(center);
|
|
5947
|
+
temLine.end.copy(center).add(direct.clone().multiplyScalar(1));
|
|
5948
|
+
const point = preDirect.getIntersection(temLine);
|
|
5949
|
+
temLine.end.copy(point);
|
|
5950
|
+
return temLine.clone();
|
|
6140
5951
|
}
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
const maxY = Math.max(...yArr);
|
|
6153
|
-
this.box.set(minX, minY, maxX, maxY);
|
|
6154
|
-
return this.box;
|
|
6155
|
-
}
|
|
6156
|
-
/** 线路拓扑
|
|
6157
|
-
* @description 处理线路拓扑,使线路有序链接,形成长路径
|
|
6158
|
-
* @param lines
|
|
6159
|
-
*/
|
|
6160
|
-
lineTopology(lines) {
|
|
6161
|
-
const visited = [];
|
|
6162
|
-
function dfs(index2, linePath) {
|
|
6163
|
-
const [_0, a2] = lines[index2];
|
|
6164
|
-
visited[index2] = true;
|
|
6165
|
-
linePath.push(a2);
|
|
6166
|
-
for (let i = 0; i < lines.length; i++) {
|
|
6167
|
-
const [b1, _1] = lines[i];
|
|
6168
|
-
if (!visited[i]) {
|
|
6169
|
-
if (Math.abs(a2.x - b1.x) < 1e-6 && Math.abs(a2.y - b1.y) < 1e-6) {
|
|
6170
|
-
return dfs(i, linePath);
|
|
6171
|
-
}
|
|
6172
|
-
}
|
|
6173
|
-
}
|
|
6174
|
-
}
|
|
6175
|
-
const linePaths = [];
|
|
6176
|
-
for (let i = 0; i < lines.length; i++) {
|
|
6177
|
-
if (!visited[i]) {
|
|
6178
|
-
const linePath = [lines[i][0]];
|
|
6179
|
-
dfs(i, linePath);
|
|
6180
|
-
linePaths.push(linePath);
|
|
5952
|
+
function find(edge, line, point, preLine, preDirect, path, isPreDirect = true) {
|
|
5953
|
+
if (path.length > lines.length) return;
|
|
5954
|
+
if (visited.has(line)) return;
|
|
5955
|
+
visited.add(line);
|
|
5956
|
+
let direct;
|
|
5957
|
+
const otherPoint = line.getAnotherPoint(point);
|
|
5958
|
+
if (isPreDirect) {
|
|
5959
|
+
if (line.vertical(preLine)) direct = getDirect(line, preDirect);
|
|
5960
|
+
else {
|
|
5961
|
+
const center = line.center, x = center.distance(preDirect.start), d0 = center.direction(preDirect.start);
|
|
5962
|
+
direct = preDirect.directionMove(d0, x);
|
|
6181
5963
|
}
|
|
6182
|
-
}
|
|
6183
|
-
|
|
6184
|
-
|
|
6185
|
-
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
}
|
|
6195
|
-
const filterLines = [lines[0]];
|
|
6196
|
-
for (let i = 1; i < lines.length; i++) {
|
|
6197
|
-
const line = lines[i];
|
|
6198
|
-
const preLine = lines[i - 1];
|
|
6199
|
-
if (preLine.includedAngle(line) < errAngle) {
|
|
6200
|
-
preLine.end.copy(line.end);
|
|
6201
|
-
} else {
|
|
6202
|
-
filterLines.push(line);
|
|
5964
|
+
} else direct = preDirect;
|
|
5965
|
+
let result = grid.queryPoint(otherPoint, true);
|
|
5966
|
+
if (result.length === 1) {
|
|
5967
|
+
const item = result[0], nextLine = item.userData, otherPoint1 = nextLine.getAnotherPoint(item.point), d0 = otherPoint1.direction(item.point);
|
|
5968
|
+
if (edge === nextLine) return path;
|
|
5969
|
+
if (nextLine.vertical(line)) {
|
|
5970
|
+
const d1 = otherPoint.direction(point), center = nextLine.center, isSameDirection = d0.angleBetween(direct.direction()) < 1e-9;
|
|
5971
|
+
direct.start.copy(center);
|
|
5972
|
+
direct.end.copy(center).add(d1.multiplyScalar(0.02));
|
|
5973
|
+
if (isSameDirection) direct.end.rotate(direct.start, Math.PI);
|
|
5974
|
+
path.push(nextLine);
|
|
5975
|
+
if (find(edge, nextLine, item.point, line, direct, path, false)) return path;
|
|
6203
5976
|
}
|
|
6204
|
-
}
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
const len2 = prev2.distance(curr2);
|
|
6223
|
-
if (len2 < this.width * 0.8) count++;
|
|
6224
|
-
else break;
|
|
6225
|
-
}
|
|
6226
|
-
if (count === 0 && i + count === path.length - 1) ;
|
|
6227
|
-
else if (i == 1 && count === 1) ;
|
|
6228
|
-
else if (count === 3) {
|
|
6229
|
-
filterLines.push(path[i + 1]);
|
|
6230
|
-
i += count;
|
|
6231
|
-
} else if (count === 5) {
|
|
6232
|
-
filterLines.push(path[i + 2]);
|
|
6233
|
-
i += count;
|
|
6234
|
-
} else {
|
|
6235
|
-
filterLines.push(curr);
|
|
5977
|
+
} else {
|
|
5978
|
+
queryLine.start.copy(direct.start).add(direct.direction().multiplyScalar(5e-3));
|
|
5979
|
+
const lines2 = [line, ...result.map((item) => {
|
|
5980
|
+
const line2 = item.userData;
|
|
5981
|
+
line2.length();
|
|
5982
|
+
return line2;
|
|
5983
|
+
})];
|
|
5984
|
+
for (let i = 0; i < result.length; i++) {
|
|
5985
|
+
const item = result[i], nextLine = item.userData;
|
|
5986
|
+
if (edge === nextLine) return path;
|
|
5987
|
+
if (result.length === 4 && nextLine.parallel(line)) continue;
|
|
5988
|
+
queryLine.end.copy(nextLine.center);
|
|
5989
|
+
if (!lines2.some((line1) => {
|
|
5990
|
+
if (line1 === nextLine) return false;
|
|
5991
|
+
return line1.intersectLineSegment(queryLine);
|
|
5992
|
+
})) {
|
|
5993
|
+
path.push(nextLine);
|
|
5994
|
+
return find(edge, nextLine, item.point, line, direct, path);
|
|
6236
5995
|
}
|
|
6237
|
-
} else {
|
|
6238
|
-
filterLines.push(curr);
|
|
6239
5996
|
}
|
|
6240
5997
|
}
|
|
6241
|
-
return filterLines;
|
|
6242
5998
|
}
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
}
|
|
6258
|
-
const lines = this.mergeSameDirectionLine(pathToLines(path)), filterLines = [lines[0]];
|
|
6259
|
-
for (let i = 1; i < lines.length; i++) {
|
|
6260
|
-
const line = lines[i];
|
|
6261
|
-
const preLine = lines[(lines.length + i - 1) % lines.length];
|
|
6262
|
-
if (line.length() > this.width * 0.9) {
|
|
6263
|
-
filterLines.push(line);
|
|
6264
|
-
continue;
|
|
5999
|
+
for (let i = 0; i < ringEdges.length; i++) {
|
|
6000
|
+
const line = ringEdges[i], center = line.center, startList = grid.queryPoint(line.start, true), endList = grid.queryPoint(line.end, true), minList = startList.length < endList.length ? startList : endList, directList = [], list = minList.filter((item) => {
|
|
6001
|
+
if (minList.length === 3 && item.userData?.parallel(line)) return false;
|
|
6002
|
+
const otherPoint = item.userData?.getAnotherPoint(item.point);
|
|
6003
|
+
directList.push(otherPoint.direction(item.point));
|
|
6004
|
+
return true;
|
|
6005
|
+
});
|
|
6006
|
+
const ringList = [];
|
|
6007
|
+
for (let i2 = 0; i2 < list.length; i2++) {
|
|
6008
|
+
const item = list[i2];
|
|
6009
|
+
let direct = directList[i2];
|
|
6010
|
+
if (item.userData?.parallel(line)) {
|
|
6011
|
+
const otherIndex = i2 ? 0 : 1, other = directList[otherIndex];
|
|
6012
|
+
direct = other.clone().multiplyScalar(-1);
|
|
6265
6013
|
}
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
-
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
continue;
|
|
6014
|
+
visited.clear();
|
|
6015
|
+
const directLine = new LineSegment(center.clone(), center.clone().add(direct.clone().multiplyScalar(0.2)));
|
|
6016
|
+
const path = find(line, item.userData, item.point, line, directLine, [line, item.userData]);
|
|
6017
|
+
if (path) {
|
|
6018
|
+
ringList.push([...path]);
|
|
6272
6019
|
}
|
|
6273
|
-
const line2 = lines[i + 2];
|
|
6274
|
-
if (line2 && preLine.includedAngle(line2) < 2) {
|
|
6275
|
-
i = i + 2;
|
|
6276
|
-
filterLines.push(line2);
|
|
6277
|
-
} else filterLines.push(line);
|
|
6278
6020
|
}
|
|
6279
|
-
|
|
6280
|
-
|
|
6281
|
-
|
|
6282
|
-
|
|
6283
|
-
* @todo 根据线段两端线段长度,选取参照物_|▔▔
|
|
6284
|
-
* @param path
|
|
6285
|
-
*/
|
|
6286
|
-
removeShortLine(path, shortLine = this.shortLine) {
|
|
6287
|
-
const lines = pathToLines(path), filterLines = [], PI_12 = Math.PI / 180;
|
|
6288
|
-
for (let i = 0; i < lines.length; i++) {
|
|
6289
|
-
const line = lines[i], len = line.length(), currentIndex = i;
|
|
6290
|
-
if (len > shortLine || filterLines.length === 0) {
|
|
6291
|
-
filterLines.push(line);
|
|
6292
|
-
continue;
|
|
6293
|
-
}
|
|
6294
|
-
let nextline = lines[++i];
|
|
6295
|
-
const preLine = filterLines[filterLines.length - 1], d1 = preLine.direction();
|
|
6296
|
-
while (i < lines.length) {
|
|
6297
|
-
const angle = d1.angleBetween(nextline.direction()) / PI_12;
|
|
6298
|
-
if (nextline.length() <= shortLine || angle < 4 || angle > 180 - 4) {
|
|
6299
|
-
nextline = lines[++i];
|
|
6300
|
-
} else break;
|
|
6301
|
-
}
|
|
6302
|
-
if (!nextline) continue;
|
|
6303
|
-
const targetLine = lines[i - 1];
|
|
6304
|
-
if (preLine.length() > targetLine.length()) {
|
|
6305
|
-
const intersectPoint = preLine.getIntersection(nextline);
|
|
6306
|
-
if (intersectPoint) {
|
|
6307
|
-
const p0 = preLine.points[1].clone(), p1 = nextline.points[0].clone();
|
|
6308
|
-
preLine.points[1].copy(intersectPoint);
|
|
6309
|
-
nextline.points[0].copy(intersectPoint);
|
|
6310
|
-
if (preLine.length() < this.width) {
|
|
6311
|
-
preLine.points[1].copy(p0);
|
|
6312
|
-
nextline.points[0].copy(p0);
|
|
6313
|
-
} else if (nextline.length() < this.width) {
|
|
6314
|
-
preLine.points[1].copy(p1);
|
|
6315
|
-
nextline.points[0].copy(p1);
|
|
6316
|
-
}
|
|
6317
|
-
} else {
|
|
6318
|
-
preLine.points[1].copy(nextline.points[0]);
|
|
6319
|
-
}
|
|
6320
|
-
filterLines.push(nextline);
|
|
6321
|
-
} else {
|
|
6322
|
-
i = currentIndex;
|
|
6323
|
-
}
|
|
6021
|
+
if (ringList.length === 2) {
|
|
6022
|
+
const set2 = new Set(ringList[0]);
|
|
6023
|
+
const count = ringList[1].filter((line2) => set2.has(line2)).length;
|
|
6024
|
+
if (count > 1) ringList.splice(0, 2, ringList[0].length < ringList[1].length ? ringList[0] : ringList[1]);
|
|
6324
6025
|
}
|
|
6325
|
-
|
|
6026
|
+
rings.push(...ringList);
|
|
6326
6027
|
}
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
|
|
6330
|
-
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
this.wallsGroup = solutions.map((ps2) => {
|
|
6339
|
-
let path = ps2.map((p) => Point.from(p).divisionScalar(scale));
|
|
6340
|
-
path = this.lineSegmentStraightening(path);
|
|
6341
|
-
if (endType == Dxf.EndType.etOpenSquare) path = this.squareRemoveBurr(path);
|
|
6342
|
-
return path;
|
|
6343
|
-
}).filter((points) => points.length > 4 || closedPathArea(points) > 0.2);
|
|
6344
|
-
this.dispatchEvent({
|
|
6345
|
-
type: "lineOffset",
|
|
6346
|
-
wallsGroup: this.wallsGroup
|
|
6028
|
+
return rings;
|
|
6029
|
+
}
|
|
6030
|
+
function ringsDeduplication(rings) {
|
|
6031
|
+
const map = new ArrayMap(), newRings = [];
|
|
6032
|
+
rings.forEach((ring) => map.append(ring.length, ring));
|
|
6033
|
+
for (const rings2 of map.values()) {
|
|
6034
|
+
const lineIndexGenerator = new LineIndexGenerator(rings2.flat());
|
|
6035
|
+
const ringMap = new ArrayMap();
|
|
6036
|
+
rings2.map((ring) => {
|
|
6037
|
+
const key = ring.map((line) => lineIndexGenerator.getIndex(line)).sort((a, b) => a - b).join(",");
|
|
6038
|
+
ringMap.append(key, ring);
|
|
6347
6039
|
});
|
|
6348
|
-
|
|
6040
|
+
ringMap.forEach((list) => newRings.push(list[0]));
|
|
6349
6041
|
}
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
|
|
6355
|
-
|
|
6042
|
+
return newRings;
|
|
6043
|
+
}
|
|
6044
|
+
function findMaxRing(lines, ringEdges) {
|
|
6045
|
+
const rings = findMinRing(lines, ringEdges), visited = /* @__PURE__ */ new Map(), unionFindSet = new UnionFindSet(rings.length), internalEdges = [];
|
|
6046
|
+
rings.forEach((ring, index2) => {
|
|
6047
|
+
for (let i = 0; i < ring.length; i++) {
|
|
6048
|
+
const line = ring[i];
|
|
6049
|
+
if (visited.has(line)) unionFindSet.union(index2, visited.get(line));
|
|
6050
|
+
else visited.set(line, index2);
|
|
6051
|
+
}
|
|
6052
|
+
});
|
|
6053
|
+
const countMap = new CountMap();
|
|
6054
|
+
const groups = unionFindSet.getAllSets().valueArray.map((list) => {
|
|
6055
|
+
let group2 = list.map((i) => rings[i]);
|
|
6056
|
+
if (group2.length === 1) return group2[0];
|
|
6057
|
+
countMap.clear();
|
|
6058
|
+
group2 = ringsDeduplication(group2);
|
|
6059
|
+
group2.forEach((lines2) => lines2.forEach((line) => countMap.set(line)));
|
|
6060
|
+
const ring = countMap.reduce((lines2, count, line) => {
|
|
6061
|
+
if (count === 1) lines2.push(line);
|
|
6062
|
+
else internalEdges.push(line);
|
|
6063
|
+
return lines2;
|
|
6064
|
+
}, []);
|
|
6065
|
+
return ring;
|
|
6066
|
+
});
|
|
6067
|
+
return {
|
|
6068
|
+
internalEdges,
|
|
6069
|
+
rings: groups
|
|
6070
|
+
};
|
|
6071
|
+
}
|
|
6072
|
+
function findClosedPolygons(lines) {
|
|
6073
|
+
const linesGroup = LineSegment.groupByPath(lines), rings = [], internalEdges = [];
|
|
6074
|
+
linesGroup.forEach((lines2, _) => {
|
|
6075
|
+
try {
|
|
6076
|
+
let ringEdges = findRingEdges(lines2);
|
|
6077
|
+
const result = findMaxRing(lines2, ringEdges);
|
|
6078
|
+
rings.push(...result.rings);
|
|
6079
|
+
internalEdges.push(...result.internalEdges);
|
|
6080
|
+
} catch (error) {
|
|
6081
|
+
console.warn("环查找出现异常:", error.message);
|
|
6082
|
+
}
|
|
6083
|
+
});
|
|
6084
|
+
const internalEdgesSet = /* @__PURE__ */ new Set([...internalEdges]);
|
|
6085
|
+
const groupsSet = /* @__PURE__ */ new Set([...rings.flat()]);
|
|
6086
|
+
lines = lines.filter((line) => !internalEdgesSet.has(line));
|
|
6087
|
+
lines.forEach((line) => !groupsSet.has(line));
|
|
6088
|
+
lines = [...new Set(lines)];
|
|
6089
|
+
return {
|
|
6090
|
+
newLines: lines,
|
|
6091
|
+
rings,
|
|
6092
|
+
internalEdges
|
|
6093
|
+
};
|
|
6094
|
+
}
|
|
6095
|
+
function createGroup(lineSegments) {
|
|
6096
|
+
const doors = [];
|
|
6097
|
+
lineSegments = lineSegments.filter((line) => {
|
|
6098
|
+
if (line.userData.isDoor) {
|
|
6099
|
+
doors.push(line);
|
|
6100
|
+
return false;
|
|
6101
|
+
}
|
|
6102
|
+
return true;
|
|
6103
|
+
});
|
|
6104
|
+
lineSegments = buildDoubleWallGroup(lineSegments);
|
|
6105
|
+
lineSegments = DoubleWallHelper.complementSide(lineSegments);
|
|
6106
|
+
lineSegments = buildDoubleWallGroup(lineSegments, doors, true, true);
|
|
6107
|
+
return [...lineSegments, ...doors];
|
|
6108
|
+
}
|
|
6109
|
+
function getGroups(lines, updateGroup = true) {
|
|
6110
|
+
if (updateGroup) lines = createGroup(lines);
|
|
6111
|
+
const map = lines.reduce((map2, line) => {
|
|
6112
|
+
const groups = LineGroupType.get(line);
|
|
6113
|
+
groups.forEach((group2) => {
|
|
6114
|
+
let id = group2.id ?? "wall";
|
|
6115
|
+
if (group2.type === "wall") id = "wall";
|
|
6116
|
+
map2.append(id, line);
|
|
6117
|
+
});
|
|
6118
|
+
return map2;
|
|
6119
|
+
}, new ArrayMap());
|
|
6120
|
+
return map;
|
|
6121
|
+
}
|
|
6122
|
+
function handleGroup(map) {
|
|
6123
|
+
const group2 = map.group((lines) => {
|
|
6124
|
+
if (LineGroupType.everyType(lines, "bayWindow")) return "wall";
|
|
6125
|
+
if (LineGroupType.everyType(lines, "doubleWall")) return "doubleWall";
|
|
6126
|
+
return "wall";
|
|
6127
|
+
}), walls = group2.get("wall") ?? [], doubleWalls = group2.get("doubleWall") ?? [];
|
|
6128
|
+
let newlines = [], doubleWallsSet = new Set(doubleWalls.flat());
|
|
6129
|
+
walls.forEach((lines) => {
|
|
6130
|
+
lines.forEach((line) => doubleWallsSet.has(line) || newlines.push(line));
|
|
6131
|
+
});
|
|
6132
|
+
doubleWalls.forEach((lines) => {
|
|
6133
|
+
lines = [...new Set(lines)];
|
|
6134
|
+
const groups = clippingDoubleWall(lines);
|
|
6135
|
+
groups.forEach((lines2) => {
|
|
6136
|
+
if (lines2.length < 4) return newlines.push(...lines2);
|
|
6137
|
+
lines2 = lines2.sort((a, b) => a.length() - b.length());
|
|
6138
|
+
const line1 = lines2[0], line2 = lines2[1];
|
|
6139
|
+
const newLine = new LineSegment(line1.center.clone(), line2.center.clone());
|
|
6140
|
+
mergeLineUserData(newLine, lines2);
|
|
6141
|
+
newLine.userData.wallWidth = line1.length();
|
|
6142
|
+
newlines.push(newLine);
|
|
6143
|
+
mergeWindow(newLine);
|
|
6144
|
+
});
|
|
6145
|
+
});
|
|
6146
|
+
newlines = newlines.map((line) => line.clone());
|
|
6147
|
+
return newlines.filter((line) => !line.userData.isBayWindow);
|
|
6148
|
+
}
|
|
6149
|
+
function toJson(lineSegments, name = "测试", communityName = "") {
|
|
6150
|
+
const scale = 1, idMap = /* @__PURE__ */ new Map();
|
|
6151
|
+
let index2 = 0;
|
|
6152
|
+
return {
|
|
6153
|
+
version: "2",
|
|
6154
|
+
name,
|
|
6155
|
+
communityName,
|
|
6156
|
+
city: "",
|
|
6157
|
+
province: "",
|
|
6158
|
+
height: 2.8 * scale,
|
|
6159
|
+
walls: lineSegments.map((line) => {
|
|
6160
|
+
if (line.userData.isDoor && !line.userData.doorDirectConnection) return;
|
|
6161
|
+
idMap.set(line, index2);
|
|
6162
|
+
return {
|
|
6163
|
+
ID: index2++,
|
|
6164
|
+
start: { x: line.start.x * scale, y: line.start.y * scale },
|
|
6165
|
+
end: { x: line.end.x * scale, y: line.end.y * scale },
|
|
6166
|
+
thickness: (line.userData.wallWidth ? line.userData.wallWidth : 0.12) * scale,
|
|
6167
|
+
type: "LINE",
|
|
6168
|
+
isDoor: line.userData.isDoor,
|
|
6169
|
+
loadBearingWall: false,
|
|
6170
|
+
height: 2.8 * scale
|
|
6171
|
+
};
|
|
6172
|
+
}).filter((i) => !!i),
|
|
6173
|
+
pillars: [],
|
|
6174
|
+
beams: [],
|
|
6175
|
+
holes: lineSegments.flatMap((line) => {
|
|
6176
|
+
if (line.userData.isDoor && line.userData.doorDirectConnection) {
|
|
6177
|
+
return {
|
|
6178
|
+
id: index2++,
|
|
6179
|
+
type: "DOOR",
|
|
6180
|
+
openSide: "RIGHT",
|
|
6181
|
+
start: {
|
|
6182
|
+
x: line.start.x * scale,
|
|
6183
|
+
y: line.start.y * scale
|
|
6184
|
+
},
|
|
6185
|
+
end: {
|
|
6186
|
+
x: line.end.x * scale,
|
|
6187
|
+
y: line.end.y * scale
|
|
6188
|
+
},
|
|
6189
|
+
height: 2.1 * scale,
|
|
6190
|
+
qroundClearance: 0 * scale,
|
|
6191
|
+
sillHeight: (line.userData?.sillHeight ?? 0) * scale
|
|
6192
|
+
};
|
|
6193
|
+
} else if (line.userData.isWindow && line.userData.drawWindow) {
|
|
6194
|
+
return line.userData.drawWindow.map((item) => {
|
|
6195
|
+
const center = Point.from(item.p);
|
|
6196
|
+
const start = center.clone().add(
|
|
6197
|
+
line.direction().multiplyScalar(item.width * 0.5)
|
|
6198
|
+
);
|
|
6199
|
+
const end = center.clone().add(
|
|
6200
|
+
line.direction().multiplyScalar(-item.width * 0.5)
|
|
6201
|
+
);
|
|
6202
|
+
return {
|
|
6203
|
+
id: index2++,
|
|
6204
|
+
type: "WINDOW",
|
|
6205
|
+
start: {
|
|
6206
|
+
x: start.x * scale,
|
|
6207
|
+
y: start.y * scale
|
|
6208
|
+
},
|
|
6209
|
+
end: {
|
|
6210
|
+
x: end.x * scale,
|
|
6211
|
+
y: end.y * scale
|
|
6212
|
+
},
|
|
6213
|
+
height: 1.6 * scale,
|
|
6214
|
+
groundClearance: (line.userData?.groundClearance ?? 0.9) * scale,
|
|
6215
|
+
sillHeight: (line.userData?.groundClearance ?? 0.9) * scale
|
|
6216
|
+
};
|
|
6217
|
+
});
|
|
6218
|
+
}
|
|
6219
|
+
}).filter((i) => !!i),
|
|
6220
|
+
rooms: []
|
|
6221
|
+
};
|
|
6222
|
+
}
|
|
6223
|
+
function lineDataToThreeVJiaJson(lineSegments, angle = 0, updateGroup = true) {
|
|
6224
|
+
const group2 = getGroups(lineSegments, updateGroup);
|
|
6225
|
+
let newLines = handleGroup(group2);
|
|
6226
|
+
newLines = LineSegmentUndirectedGraph.rotate(newLines, angle, (line, center, angle2) => {
|
|
6227
|
+
if (line.userData.drawWindow) {
|
|
6228
|
+
line.userData.drawWindow.forEach((windowItem) => {
|
|
6229
|
+
const point = Point.from(windowItem.p);
|
|
6230
|
+
point.rotate(center, angle2 * (Math.PI / 180));
|
|
6231
|
+
windowItem.p = point.toJson(windowItem.p.z);
|
|
6232
|
+
});
|
|
6233
|
+
}
|
|
6234
|
+
});
|
|
6235
|
+
return {
|
|
6236
|
+
lines: newLines,
|
|
6237
|
+
toJson(name = "测试", communityName = "") {
|
|
6238
|
+
return toJson(newLines, name, communityName);
|
|
6239
|
+
}
|
|
6240
|
+
};
|
|
6241
|
+
}
|
|
6242
|
+
const PRE_PROCESSOR = {
|
|
6243
|
+
DoorsAnalysis(lines) {
|
|
6244
|
+
return lines;
|
|
6245
|
+
},
|
|
6246
|
+
AxisAlignCorr(lines, option) {
|
|
6247
|
+
const verticalReferenceLine = findVerticalReference(lines);
|
|
6248
|
+
if (verticalReferenceLine) {
|
|
6356
6249
|
const t = performance.now();
|
|
6357
|
-
const lineSegments = AxisAlignCorr.correction(lines,
|
|
6250
|
+
const lineSegments = AxisAlignCorr.correction(lines, verticalReferenceLine, option);
|
|
6358
6251
|
console.log("垂直纠正消耗时间:", (performance.now() - t).toFixed(2), "ms", "处理线段数量:", lines.length);
|
|
6359
|
-
|
|
6360
|
-
await this.set(data);
|
|
6252
|
+
return lineSegments;
|
|
6361
6253
|
} else {
|
|
6362
|
-
|
|
6254
|
+
console.error("未找到一条垂直纠正基准轴线, 未做垂直纠正处理");
|
|
6255
|
+
}
|
|
6256
|
+
return lines;
|
|
6257
|
+
},
|
|
6258
|
+
BoundExt(lines, { trajectory, onBoundExt }) {
|
|
6259
|
+
if (!trajectory) {
|
|
6260
|
+
console.error("没有传入轨迹文件");
|
|
6261
|
+
return lines;
|
|
6363
6262
|
}
|
|
6263
|
+
let t = performance.now();
|
|
6264
|
+
lines = BoundExt.boundExtbyTraj({ lines, trajectory, wallWidth: DEFAULT_WALL_WIDTH, findCallBack: onBoundExt }).lines;
|
|
6265
|
+
console.log(`外墙外扩消耗时间: ${(performance.now() - t).toFixed(2)} ms 处理线段数量: ${lines.length}`);
|
|
6266
|
+
return lines;
|
|
6267
|
+
},
|
|
6268
|
+
AngleCorr(lines) {
|
|
6269
|
+
const box = Box2.fromByLineSegment(...lines), center = box.center, vrLine = findVerticalReference(lines), angle = -vrLine.direction().angleBetween(new Point(0, 1), "angle", "360") * (Math.PI / 180);
|
|
6270
|
+
lines.forEach((line) => {
|
|
6271
|
+
line.rotate(angle, center);
|
|
6272
|
+
if (line.userData.isWindow) {
|
|
6273
|
+
line.userData.drawWindow?.forEach((d) => {
|
|
6274
|
+
const p = Point.from(d.p);
|
|
6275
|
+
p.rotate(center, angle);
|
|
6276
|
+
d.p = p.toJson(d.p.z);
|
|
6277
|
+
});
|
|
6278
|
+
}
|
|
6279
|
+
});
|
|
6280
|
+
return lines;
|
|
6281
|
+
},
|
|
6282
|
+
ResetGeometricCenter(lines) {
|
|
6283
|
+
const box = Box2.fromByLineSegment(...lines), center = box.center;
|
|
6284
|
+
lines.forEach((line) => {
|
|
6285
|
+
line.start.division(center);
|
|
6286
|
+
line.end.division(center);
|
|
6287
|
+
});
|
|
6288
|
+
return lines;
|
|
6289
|
+
}
|
|
6290
|
+
};
|
|
6291
|
+
class Dxf extends Component {
|
|
6292
|
+
static name = "Dxf";
|
|
6293
|
+
static PRE_PROCESSOR = PRE_PROCESSOR;
|
|
6294
|
+
width = 0.04;
|
|
6295
|
+
originalData = [];
|
|
6296
|
+
data = [];
|
|
6297
|
+
box = new Box2(0, 0, 0, 0);
|
|
6298
|
+
cad = null;
|
|
6299
|
+
lineSegments = [];
|
|
6300
|
+
doorLineSegment = [];
|
|
6301
|
+
verticalReferenceLine;
|
|
6302
|
+
originalZAverage = 0;
|
|
6303
|
+
_preProcessorSet = /* @__PURE__ */ new Set();
|
|
6304
|
+
trajectory = null;
|
|
6305
|
+
onBoundExt;
|
|
6306
|
+
/** 原始数据组
|
|
6307
|
+
*/
|
|
6308
|
+
get lines() {
|
|
6309
|
+
return this.lineSegments;
|
|
6310
|
+
}
|
|
6311
|
+
/**初始化
|
|
6312
|
+
* @param width 墙体宽度
|
|
6313
|
+
*/
|
|
6314
|
+
constructor(width = 0.04) {
|
|
6315
|
+
super();
|
|
6316
|
+
this.width = width;
|
|
6317
|
+
}
|
|
6318
|
+
setTrajectory(trajectory, onBoundExt) {
|
|
6319
|
+
this.trajectory = trajectory;
|
|
6320
|
+
this.onBoundExt = this.onBoundExt ?? onBoundExt;
|
|
6321
|
+
return this;
|
|
6364
6322
|
}
|
|
6365
6323
|
/** 完整线段数据
|
|
6366
6324
|
* @returns
|
|
@@ -6380,253 +6338,110 @@ class Dxf extends Component {
|
|
|
6380
6338
|
return lines;
|
|
6381
6339
|
}
|
|
6382
6340
|
/**
|
|
6383
|
-
*
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
const point2 = points[nextIndex];
|
|
6392
|
-
array.push(point1.X * scale, point1.Y * scale, z, point2.X * scale, point2.Y * scale, z);
|
|
6393
|
-
}
|
|
6394
|
-
});
|
|
6395
|
-
return new Float32Array(array);
|
|
6396
|
-
}
|
|
6397
|
-
/** 获取角度范围
|
|
6398
|
-
* @param center
|
|
6399
|
-
* @param p1
|
|
6400
|
-
* @param p2
|
|
6401
|
-
* @returns
|
|
6402
|
-
*/
|
|
6403
|
-
getArcAngleRange(center, p1, p2) {
|
|
6404
|
-
const x1 = p1.x - center.x;
|
|
6405
|
-
const y1 = p1.y - center.y;
|
|
6406
|
-
const x2 = p2.x - center.x;
|
|
6407
|
-
const y2 = p2.y - center.y;
|
|
6408
|
-
let angle1 = Math.atan2(y1, x1);
|
|
6409
|
-
let angle2 = Math.atan2(y2, x2);
|
|
6410
|
-
angle1 = angle1 < 0 ? angle1 + 2 * Math.PI : angle1;
|
|
6411
|
-
angle2 = angle2 < 0 ? angle2 + 2 * Math.PI : angle2;
|
|
6412
|
-
let r1, r2;
|
|
6413
|
-
const diff = Math.abs(angle2 - angle1);
|
|
6414
|
-
if (diff <= Math.PI) {
|
|
6415
|
-
r1 = Math.min(angle1, angle2);
|
|
6416
|
-
r2 = Math.max(angle1, angle2);
|
|
6417
|
-
} else {
|
|
6418
|
-
r1 = Math.max(angle1, angle2);
|
|
6419
|
-
r2 = Math.min(angle1, angle2) + 2 * Math.PI;
|
|
6420
|
-
}
|
|
6421
|
-
return [r1 / (Math.PI / 180), r2 / (Math.PI / 180)];
|
|
6422
|
-
}
|
|
6423
|
-
/**
|
|
6424
|
-
* 线段数据转为原始json数据
|
|
6425
|
-
*/
|
|
6426
|
-
lineDataToOriginalData(lines, quadtree) {
|
|
6427
|
-
return lineDataToOriginalData(lines, this.originalZAverage, quadtree);
|
|
6428
|
-
}
|
|
6429
|
-
/**
|
|
6430
|
-
* 转为绘制数据
|
|
6431
|
-
*/
|
|
6432
|
-
toDrawDataJson(unit = "Millimeters") {
|
|
6433
|
-
const s = units[unit], data = {
|
|
6434
|
-
unit,
|
|
6435
|
-
line: [],
|
|
6436
|
-
arc: [],
|
|
6437
|
-
dimensionLine: [],
|
|
6438
|
-
center: this.box.center.toJson(),
|
|
6439
|
-
width: this.box.width * s,
|
|
6440
|
-
height: this.box.height * s,
|
|
6441
|
-
scale: s
|
|
6442
|
-
};
|
|
6443
|
-
let color = "white";
|
|
6444
|
-
function drawLine(p1, p2) {
|
|
6445
|
-
data.line.push([p1.x * s, p1.y * s, p2.x * s, p2.y * s, color]);
|
|
6446
|
-
}
|
|
6447
|
-
function drawArc(pos, radius, startAngle, endAngle) {
|
|
6448
|
-
data.arc.push([
|
|
6449
|
-
pos.x * s,
|
|
6450
|
-
pos.y * s,
|
|
6451
|
-
radius * s,
|
|
6452
|
-
startAngle,
|
|
6453
|
-
endAngle,
|
|
6454
|
-
color
|
|
6455
|
-
]);
|
|
6456
|
-
}
|
|
6457
|
-
for (let i = 0; i < this.originalData.length; i++) {
|
|
6458
|
-
const line = this.originalData[i];
|
|
6459
|
-
if (line.isVerticalReferenceLine) {
|
|
6460
|
-
data.dimensionLine.push([line.start.x * s, line.start.y * s, line.end.x * s, line.end.y * s]);
|
|
6461
|
-
break;
|
|
6462
|
-
}
|
|
6463
|
-
}
|
|
6464
|
-
this.wallsGroup.forEach((points) => {
|
|
6465
|
-
for (let i = 0; i < points.length; i++) {
|
|
6466
|
-
const point1 = points[i];
|
|
6467
|
-
const nextIndex = i === points.length - 1 ? 0 : i + 1;
|
|
6468
|
-
const point2 = points[nextIndex];
|
|
6469
|
-
drawLine(point1, point2);
|
|
6470
|
-
}
|
|
6471
|
-
});
|
|
6472
|
-
const doorThickness = this.width * 0.2;
|
|
6473
|
-
const list = [];
|
|
6474
|
-
this.doorLineSegment.forEach((lineSegment) => {
|
|
6475
|
-
if (lineSegment.length() < 0.4) return;
|
|
6476
|
-
const line = lineSegment.clone().expansion(-this.width * 0.5);
|
|
6477
|
-
color = "cyan";
|
|
6478
|
-
if (line.length() < 1.2) {
|
|
6479
|
-
line.expansion(-doorThickness * 0.5);
|
|
6480
|
-
const normal = lineSegment.normal();
|
|
6481
|
-
let door = new LineSegment(
|
|
6482
|
-
line.start.clone(),
|
|
6483
|
-
line.start.clone().add(normal.clone().multiplyScalar(line.length()))
|
|
6484
|
-
);
|
|
6485
|
-
const box = door.clone().directionMove(door.normal(), line.length() * -0.5).expandToRectangle(line.length(), "bothSides");
|
|
6486
|
-
for (let j = 0; j < list.length; j++) {
|
|
6487
|
-
if (list[j].intersectRectangle(box)) {
|
|
6488
|
-
door = new LineSegment(
|
|
6489
|
-
line.start.clone(),
|
|
6490
|
-
line.start.clone().add(normal.clone().multiplyScalar(-line.length()))
|
|
6491
|
-
);
|
|
6492
|
-
break;
|
|
6493
|
-
}
|
|
6494
|
-
}
|
|
6495
|
-
door.expansion(-doorThickness * 0.5).expandToRectangle(this.width * 0.2, "bothSides").path2D((p1, p2) => drawLine(p1, p2));
|
|
6496
|
-
const a = line.length(), b = door.length(), r = (a ** 2 + b ** 2) / (2 * b), center = door.end.clone().add(door.direction().multiplyScalar(-r)), [startAngle, endAngle] = this.getArcAngleRange(center, line.end, door.end);
|
|
6497
|
-
drawArc(center, r, Math.min(startAngle, endAngle), Math.max(startAngle, endAngle));
|
|
6498
|
-
list.push(box);
|
|
6499
|
-
} else {
|
|
6500
|
-
line.clone().expansion(-this.width * 0.5).expandToRectangle(this.width).path2D((p1, p2) => drawLine(p1, p2));
|
|
6501
|
-
line.clone().directionMove(line.normal(), doorThickness * 0.5).directionMove(line.direction(), doorThickness * 0.5).expansion(-line.length() * 0.45, "end").forward(doorThickness * 0.5).expandToRectangle(doorThickness).path2D((p1, p2) => drawLine(p1, p2));
|
|
6502
|
-
line.clone().directionMove(line.normal(), -doorThickness * 0.5).directionMove(line.direction(), -doorThickness * 0.5).expansion(-line.length() * 0.45, "start").forward(-doorThickness * 0.5).expandToRectangle(doorThickness).path2D((p1, p2) => drawLine(p1, p2));
|
|
6503
|
-
}
|
|
6341
|
+
* 预处理数据
|
|
6342
|
+
* @param data
|
|
6343
|
+
*/
|
|
6344
|
+
preprocessing(data, options) {
|
|
6345
|
+
let { lineSegments, originalZAverage } = originalDataToLineData(data);
|
|
6346
|
+
this.originalZAverage = originalZAverage;
|
|
6347
|
+
lineSegments.forEach((line) => {
|
|
6348
|
+
if (line.userData.isDoor && line.userData.doorDirectConnection) this.doorLineSegment.push(line);
|
|
6504
6349
|
});
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
if (!line.userData.isWindow) return false;
|
|
6508
|
-
if (Array.isArray(line.userData.drawWindow)) {
|
|
6509
|
-
line.userData.drawWindow.forEach((w) => {
|
|
6510
|
-
const { p, width } = w;
|
|
6511
|
-
const center = Point.from(p);
|
|
6512
|
-
const start = center.clone().add(line.direction().multiplyScalar(width * 0.5));
|
|
6513
|
-
const end = center.clone().add(line.direction().multiplyScalar(-width * 0.5));
|
|
6514
|
-
const blinds = new LineSegment(start, end);
|
|
6515
|
-
drawLine(blinds.start, blinds.end);
|
|
6516
|
-
blinds.expandToRectangle(this.width, "bothSides").path2D((p1, p2) => drawLine(p1, p2));
|
|
6517
|
-
});
|
|
6518
|
-
}
|
|
6350
|
+
this._preProcessorSet.forEach((handler) => {
|
|
6351
|
+
lineSegments = handler(lineSegments, options);
|
|
6519
6352
|
});
|
|
6520
|
-
|
|
6353
|
+
this.verticalReferenceLine = findVerticalReference(lineSegments);
|
|
6354
|
+
this.verticalReferenceLine.userData.isVerticalReferenceLine = true;
|
|
6355
|
+
return { lineSegments, data };
|
|
6521
6356
|
}
|
|
6522
|
-
/**
|
|
6523
|
-
* @param
|
|
6357
|
+
/** 添加预处理
|
|
6358
|
+
* @param handler
|
|
6524
6359
|
*/
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6528
|
-
|
|
6529
|
-
|
|
6530
|
-
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6360
|
+
addPreProcessor(handler) {
|
|
6361
|
+
this._preProcessorSet.add(handler);
|
|
6362
|
+
return this;
|
|
6363
|
+
}
|
|
6364
|
+
/** 删除预处理
|
|
6365
|
+
* @param handler
|
|
6366
|
+
*/
|
|
6367
|
+
removePreProcessor(handler) {
|
|
6368
|
+
this._preProcessorSet.delete(handler);
|
|
6369
|
+
return this;
|
|
6370
|
+
}
|
|
6371
|
+
/** 清空预处理
|
|
6372
|
+
* @returns
|
|
6373
|
+
*/
|
|
6374
|
+
clearPreProcessor() {
|
|
6375
|
+
this._preProcessorSet.clear();
|
|
6376
|
+
return this;
|
|
6377
|
+
}
|
|
6378
|
+
/** 设置
|
|
6379
|
+
* @param data 房屋结构数据,node环境可以为路径
|
|
6380
|
+
* @param width 墙体宽度
|
|
6381
|
+
* @param scale 缩放比例
|
|
6382
|
+
* @param axisAlignmentCorrection 需要执行轴对称垂直纠正
|
|
6383
|
+
* @param option
|
|
6384
|
+
* @returns
|
|
6385
|
+
*/
|
|
6386
|
+
async set(data, options = {}) {
|
|
6387
|
+
if (typeof data === "string") {
|
|
6388
|
+
if (typeof global !== "undefined") {
|
|
6389
|
+
const packageName = "fs";
|
|
6390
|
+
const { default: fs2 } = await import(
|
|
6391
|
+
/* @vite-ignore */
|
|
6392
|
+
packageName
|
|
6393
|
+
);
|
|
6394
|
+
const buffer = fs2.readFileSync(data);
|
|
6395
|
+
const json = JSON.parse(buffer.toString("utf-8"));
|
|
6396
|
+
return this.set(json, options);
|
|
6397
|
+
} else throw new Error("非node环境不允许使用路径");
|
|
6535
6398
|
}
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
6399
|
+
if (data.length === 0) return;
|
|
6400
|
+
this.doorLineSegment.length = 0;
|
|
6401
|
+
this.cad = null;
|
|
6402
|
+
if (data.length === 0) {
|
|
6403
|
+
this.lineSegments = [];
|
|
6404
|
+
this.originalData = data;
|
|
6405
|
+
} else {
|
|
6406
|
+
const res = this.preprocessing(data, options);
|
|
6407
|
+
data = res.data;
|
|
6408
|
+
this.lineSegments = res.lineSegments;
|
|
6409
|
+
this.originalData = data;
|
|
6548
6410
|
}
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
ctx.stroke();
|
|
6558
|
-
});
|
|
6559
|
-
data.arc.forEach(([x, y, radius, startAngle, endAngle, color]) => {
|
|
6560
|
-
ctx.strokeStyle = colors[color];
|
|
6561
|
-
ctx.beginPath();
|
|
6562
|
-
ctx.arc(x, y, radius, startAngle * (Math.PI / 180), endAngle * (Math.PI / 180));
|
|
6563
|
-
ctx.stroke();
|
|
6411
|
+
const zList = [];
|
|
6412
|
+
data.forEach(({ start, end }) => zList.push(start.z ?? 0, end.z ?? 0));
|
|
6413
|
+
this.originalZAverage = zList.reduce((count, num) => count + num, 0) / zList.length;
|
|
6414
|
+
this.box = Box2.fromByLineSegment(...this.lineSegments);
|
|
6415
|
+
this.dispatchEvent({
|
|
6416
|
+
type: "dataChange",
|
|
6417
|
+
originalData: this.originalData,
|
|
6418
|
+
data: this.data
|
|
6564
6419
|
});
|
|
6565
|
-
|
|
6566
|
-
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
ctx.fillStyle = "#fff";
|
|
6570
|
-
ctx.font = `${0.15 * data.scale}px Arial`;
|
|
6571
|
-
ctx.textAlign = "center";
|
|
6572
|
-
ctx.textBaseline = "middle";
|
|
6573
|
-
ctx.save();
|
|
6574
|
-
ctx.translate(x, minY + (maxY - minY) * 0.5);
|
|
6575
|
-
ctx.scale(1, -1);
|
|
6576
|
-
ctx.fillText((maxY - minY).toFixed(2) + "cm", 0, 0);
|
|
6577
|
-
ctx.restore();
|
|
6578
|
-
ctx.moveTo(x - 0.1 * data.scale, minY);
|
|
6579
|
-
ctx.lineTo(x + 0.1 * data.scale, minY);
|
|
6580
|
-
ctx.moveTo(x, minY);
|
|
6581
|
-
ctx.lineTo(x, h + minY);
|
|
6582
|
-
ctx.moveTo(x, maxY);
|
|
6583
|
-
ctx.lineTo(x, maxY - h);
|
|
6584
|
-
ctx.moveTo(x - 0.1 * data.scale, maxY);
|
|
6585
|
-
ctx.lineTo(x + 0.1 * data.scale, maxY);
|
|
6420
|
+
this.dispatchEvent({
|
|
6421
|
+
type: "setDta",
|
|
6422
|
+
originalData: this.originalData,
|
|
6423
|
+
data: this.data
|
|
6586
6424
|
});
|
|
6587
|
-
|
|
6588
|
-
|
|
6589
|
-
|
|
6590
|
-
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
} else {
|
|
6597
|
-
const buffer = canvas.toBuffer(type, { quality: 1 });
|
|
6598
|
-
return buffer;
|
|
6599
|
-
}
|
|
6600
|
-
}
|
|
6601
|
-
/**
|
|
6602
|
-
* 将点json结构转换为Dxf string
|
|
6603
|
-
*/
|
|
6604
|
-
toDxfString(unit = "Millimeters") {
|
|
6605
|
-
const d = new Drawing();
|
|
6606
|
-
d.setUnits(unit);
|
|
6607
|
-
d.addLayer("cyan", Drawing.ACI.CYAN, "DOTTED");
|
|
6608
|
-
d.addLayer("yellow", Drawing.ACI.YELLOW, "DOTTED");
|
|
6609
|
-
d.addLayer("white", Drawing.ACI.WHITE, "DOTTED");
|
|
6610
|
-
const data = this.toDrawDataJson();
|
|
6611
|
-
data.line.forEach((item) => {
|
|
6612
|
-
let [p1x, p1y, p2x, p2y, color] = item;
|
|
6613
|
-
d.setActiveLayer(color);
|
|
6614
|
-
d.drawLine(p1x, p1y, p2x, p2y);
|
|
6425
|
+
let lines = this.getLineSegments(true);
|
|
6426
|
+
const doors = lines.filter((line) => line.userData.isDoor);
|
|
6427
|
+
lines = lines.filter((line) => !line.userData.isDoor);
|
|
6428
|
+
lines = buildDoubleWallGroup(lines, doors);
|
|
6429
|
+
lines.push(...doors);
|
|
6430
|
+
this.cad = new CAD().usePlugin(new DxfDataPlugin(lines)).usePlugin(new DxfDrawPlugin());
|
|
6431
|
+
this.dispatchEvent({
|
|
6432
|
+
type: "cadChange",
|
|
6433
|
+
cad: this.cad
|
|
6615
6434
|
});
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
d.drawArc(x, y, r, startAngle, endAngle);
|
|
6435
|
+
this.dispatchEvent({
|
|
6436
|
+
type: "lineOffset",
|
|
6437
|
+
cad: this.cad
|
|
6620
6438
|
});
|
|
6621
|
-
return d.toDxfString();
|
|
6622
6439
|
}
|
|
6623
6440
|
/**
|
|
6624
|
-
*
|
|
6625
|
-
* @returns
|
|
6441
|
+
* 线段数据转为原始json数据
|
|
6626
6442
|
*/
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
return blob;
|
|
6443
|
+
lineDataToOriginalData(lines, quadtree) {
|
|
6444
|
+
return lineDataToOriginalData(lines, this.originalZAverage, quadtree);
|
|
6630
6445
|
}
|
|
6631
6446
|
/**
|
|
6632
6447
|
* 下载原始json
|
|
@@ -6643,277 +6458,44 @@ class Dxf extends Component {
|
|
|
6643
6458
|
a.click();
|
|
6644
6459
|
} else if (typeof global !== "undefined") {
|
|
6645
6460
|
const fs2 = await include("fs", false);
|
|
6646
|
-
fs2.writeFileSync(filename, content);
|
|
6647
|
-
}
|
|
6648
|
-
}
|
|
6649
|
-
/**
|
|
6650
|
-
* 下载
|
|
6651
|
-
* @param filename
|
|
6652
|
-
*/
|
|
6653
|
-
async download(filename, unit = "Millimeters") {
|
|
6654
|
-
if (typeof window !== "undefined") {
|
|
6655
|
-
const blob = this.toDxfBlob(unit);
|
|
6656
|
-
const a = document.createElement("a");
|
|
6657
|
-
a.href = URL.createObjectURL(blob);
|
|
6658
|
-
a.download = filename + ".dxf";
|
|
6659
|
-
a.click();
|
|
6660
|
-
} else if (typeof global !== "undefined") {
|
|
6661
|
-
const fs2 = await include("fs", false);
|
|
6662
|
-
fs2.writeFileSync(filename, this.toDxfString(unit));
|
|
6663
|
-
}
|
|
6664
|
-
}
|
|
6665
|
-
/**
|
|
6666
|
-
* 下载
|
|
6667
|
-
* @param filename
|
|
6668
|
-
*/
|
|
6669
|
-
async downloadImage(filename, unit = "Centimeters", type = "image/jpeg") {
|
|
6670
|
-
const blob = await this.toDxfImageBlob(unit, type);
|
|
6671
|
-
if (!blob) return false;
|
|
6672
|
-
if (typeof window !== "undefined") {
|
|
6673
|
-
const a = document.createElement("a");
|
|
6674
|
-
a.href = URL.createObjectURL(blob);
|
|
6675
|
-
a.download = filename;
|
|
6676
|
-
a.click();
|
|
6677
|
-
} else if (typeof global !== "undefined") {
|
|
6678
|
-
const fs2 = await include("fs", false);
|
|
6679
|
-
fs2.writeFileSync(filename, blob);
|
|
6680
|
-
} else {
|
|
6681
|
-
console.error("图片下载失败");
|
|
6682
|
-
}
|
|
6683
|
-
return true;
|
|
6684
|
-
}
|
|
6685
|
-
/**
|
|
6686
|
-
* 计算原始数据的边界框
|
|
6687
|
-
* @description 计算所有线段的起点和终点的最小最大值,形成一个边界框
|
|
6688
|
-
* @returns
|
|
6689
|
-
*/
|
|
6690
|
-
computedOriginalSize(data, originalBox = new Box2(0, 0, 0, 0)) {
|
|
6691
|
-
const xArr = data.flatMap((item) => [item.start.x, item.end.x]);
|
|
6692
|
-
const yArr = data.flatMap((item) => [item.start.y, item.end.y]);
|
|
6693
|
-
const minX = Math.min(...xArr);
|
|
6694
|
-
const minY = Math.min(...yArr);
|
|
6695
|
-
const maxX = Math.max(...xArr);
|
|
6696
|
-
const maxY = Math.max(...yArr);
|
|
6697
|
-
originalBox.set(minX, minY, maxX, maxY);
|
|
6698
|
-
return originalBox;
|
|
6699
|
-
}
|
|
6700
|
-
/**
|
|
6701
|
-
* 创建数据
|
|
6702
|
-
* @param pointsGroups
|
|
6703
|
-
* @returns
|
|
6704
|
-
*/
|
|
6705
|
-
static createData(pointsGroups, sealed = true) {
|
|
6706
|
-
let count = 0;
|
|
6707
|
-
const data = pointsGroups.flatMap((points) => {
|
|
6708
|
-
const lines = points.map((point, index2) => {
|
|
6709
|
-
const nextIndex = index2 === points.length - 1 ? 0 : index2 + 1;
|
|
6710
|
-
const nextPoint = points[nextIndex];
|
|
6711
|
-
return {
|
|
6712
|
-
start: { x: point.x, y: point.y },
|
|
6713
|
-
end: { x: nextPoint.x, y: nextPoint.y },
|
|
6714
|
-
insetionArr: [
|
|
6715
|
-
{
|
|
6716
|
-
index: nextIndex + count
|
|
6717
|
-
}
|
|
6718
|
-
]
|
|
6719
|
-
};
|
|
6720
|
-
});
|
|
6721
|
-
count += points.length;
|
|
6722
|
-
if (!sealed) {
|
|
6723
|
-
lines.pop();
|
|
6724
|
-
lines[lines.length - 1].insetionArr.length = 0;
|
|
6725
|
-
count--;
|
|
6726
|
-
}
|
|
6727
|
-
return lines;
|
|
6728
|
-
});
|
|
6729
|
-
return data;
|
|
6730
|
-
}
|
|
6731
|
-
}
|
|
6732
|
-
class Variable extends Component {
|
|
6733
|
-
static name = "Variable";
|
|
6734
|
-
originalLineVisible = true;
|
|
6735
|
-
dxfVisible = true;
|
|
6736
|
-
whiteModelVisible = true;
|
|
6737
|
-
isLook = false;
|
|
6738
|
-
currentWheel = 0;
|
|
6739
|
-
pointerMove = { x: 0, y: 0 };
|
|
6740
|
-
currentKeyUp = "";
|
|
6741
|
-
currentKeyDown = "";
|
|
6742
|
-
currentMouseUp = "";
|
|
6743
|
-
currentMouseDown = "";
|
|
6744
|
-
focus = false;
|
|
6745
|
-
set(key, value) {
|
|
6746
|
-
if (key in this) {
|
|
6747
|
-
const oldValue = this[key];
|
|
6748
|
-
this[key] = value;
|
|
6749
|
-
this.dispatchEvent({
|
|
6750
|
-
type: key,
|
|
6751
|
-
value,
|
|
6752
|
-
oldValue
|
|
6753
|
-
});
|
|
6754
|
-
}
|
|
6755
|
-
}
|
|
6756
|
-
get(key) {
|
|
6757
|
-
if (key in this) return this[key];
|
|
6758
|
-
}
|
|
6759
|
-
}
|
|
6760
|
-
class LineAnalysis extends Component {
|
|
6761
|
-
static name = "LineAnalysis";
|
|
6762
|
-
Dxf = null;
|
|
6763
|
-
Variable = null;
|
|
6764
|
-
lineSegmentList = [];
|
|
6765
|
-
container = new THREE.Group();
|
|
6766
|
-
// 误差角度
|
|
6767
|
-
errorAngle = 4;
|
|
6768
|
-
width = 0.4;
|
|
6769
|
-
/**
|
|
6770
|
-
*
|
|
6771
|
-
* @param parent
|
|
6772
|
-
*/
|
|
6773
|
-
onAddFromParent(parent) {
|
|
6774
|
-
this.Dxf = parent.findComponentByType(Dxf);
|
|
6775
|
-
this.Variable = this.parent?.findComponentByType(Variable);
|
|
6776
|
-
this.Dxf.addEventListener("setDta", () => {
|
|
6777
|
-
this.lineAnalysis();
|
|
6778
|
-
this.dispatchEvent({ type: "analysisCompleted" });
|
|
6779
|
-
});
|
|
6780
|
-
}
|
|
6781
|
-
/**
|
|
6782
|
-
*
|
|
6783
|
-
* @param p1
|
|
6784
|
-
* @param p2
|
|
6785
|
-
* @param width
|
|
6786
|
-
* @returns
|
|
6461
|
+
fs2.writeFileSync(filename, content);
|
|
6462
|
+
}
|
|
6463
|
+
}
|
|
6464
|
+
/** 获取绘制数据
|
|
6787
6465
|
*/
|
|
6788
|
-
|
|
6789
|
-
|
|
6790
|
-
const pDirect = p2.direction(p1).mutiplyScalar(width * 0.5);
|
|
6791
|
-
const nDirect = p1.direction(p2).mutiplyScalar(width * 0.5);
|
|
6792
|
-
const offsetX = normal.x * width * 0.5;
|
|
6793
|
-
const offsetY = normal.y * width * 0.5;
|
|
6794
|
-
return {
|
|
6795
|
-
points: [
|
|
6796
|
-
// 第一条线
|
|
6797
|
-
new Point(p1.x + offsetX, p1.y + offsetY).add(nDirect),
|
|
6798
|
-
new Point(p2.x + offsetX, p2.y + offsetY).add(pDirect),
|
|
6799
|
-
// 第二条线
|
|
6800
|
-
new Point(p1.x - offsetX, p1.y - offsetY).add(nDirect),
|
|
6801
|
-
new Point(p2.x - offsetX, p2.y - offsetY).add(pDirect)
|
|
6802
|
-
],
|
|
6803
|
-
indices: [0, 1, 1, 3, 3, 2, 2, 0],
|
|
6804
|
-
rectIndices: [0, 1, 3, 2, 0]
|
|
6805
|
-
};
|
|
6466
|
+
toDrawData(unit = "Millimeters") {
|
|
6467
|
+
return this.cad?.toDrawData(unit);
|
|
6806
6468
|
}
|
|
6807
|
-
|
|
6808
|
-
|
|
6809
|
-
* 追加数据
|
|
6810
|
-
* @param p1
|
|
6811
|
-
* @param p2
|
|
6469
|
+
/** 获取 dxf 图片 二进制对象
|
|
6470
|
+
* @param type
|
|
6812
6471
|
*/
|
|
6813
|
-
|
|
6814
|
-
|
|
6815
|
-
dxf.data.push([p1.clone(), p2.clone(), [], false, dxf.data.length]);
|
|
6816
|
-
this.appendLineSegmentList.push(new LineSegment(p1.clone(), p2.clone()));
|
|
6472
|
+
async toDxfImageBlob(unit = "Centimeters", type = "image/jpeg", background = "#000") {
|
|
6473
|
+
return this.cad?.toDxfImageBlob(unit, type, background);
|
|
6817
6474
|
}
|
|
6818
|
-
/**
|
|
6819
|
-
* @param
|
|
6475
|
+
/** 下载 dxf 图片
|
|
6476
|
+
* @param filename
|
|
6820
6477
|
*/
|
|
6821
|
-
|
|
6822
|
-
|
|
6823
|
-
const project0 = result.project, project1 = result.project2;
|
|
6824
|
-
if (project0.includedAngle(project1) > 135) {
|
|
6825
|
-
project1.points = [project1.points[1], project1.points[0]];
|
|
6826
|
-
}
|
|
6827
|
-
this.addData(project0.points[0], project1.points[0]);
|
|
6828
|
-
this.addData(project0.points[1], project1.points[1]);
|
|
6829
|
-
const leftHeight = project0.points[0].distance(project1.points[0]), rightHeight = project0.points[1].distance(project1.points[1]), count = Math.ceil(Math.max(leftHeight, rightHeight) / dxf.width), leftFragment = leftHeight / count, rightFragment = rightHeight / count, leftDirection = project1.points[0].direction(project0.points[0]), rightDirection = project1.points[1].direction(project0.points[1]), leftP = project0.points[0].clone(), rightP = project0.points[1].clone(), direction = rightP.direction(leftP);
|
|
6830
|
-
direction.multiplyScalar(dxf.width * 0.5);
|
|
6831
|
-
const _leftP = leftP.clone().add(direction), _rightP = rightP.clone().add(direction.multiplyScalar(-1)), d1 = leftP.direction(rightP), d2 = _leftP.direction(_rightP);
|
|
6832
|
-
if (d1.x > 0 && d2.x < 0 || d1.x < 0 && d2.x > 0 || d1.y > 0 && d2.y < 0 || d1.y < 0 && d2.y > 0) return;
|
|
6833
|
-
leftP.set(_leftP.x, _leftP.y);
|
|
6834
|
-
rightP.set(_rightP.x, _rightP.y);
|
|
6835
|
-
for (let i = 1; i < count; i++) {
|
|
6836
|
-
const left = leftDirection.clone().multiplyScalar(leftFragment * i), right = rightDirection.clone().multiplyScalar(rightFragment * i), p1 = leftP.clone().add(left), p2 = rightP.clone().add(right);
|
|
6837
|
-
this.addData(p1, p2);
|
|
6838
|
-
}
|
|
6478
|
+
async downloadDxfImage(filename, unit = "Centimeters", type = "image/jpeg") {
|
|
6479
|
+
return this.cad?.downloadDxfImage(filename, unit, type);
|
|
6839
6480
|
}
|
|
6840
|
-
quadtree;
|
|
6841
6481
|
/**
|
|
6842
|
-
*
|
|
6482
|
+
* 将点json结构转换为Dxf 字符串
|
|
6843
6483
|
*/
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
const lineSegmentList = [];
|
|
6847
|
-
this.quadtree = new Quadtree(dxf.originalBox, 2);
|
|
6848
|
-
dxf.lineSegments.forEach((lineSegment) => {
|
|
6849
|
-
if (lineSegment.userData?.isDoor) return;
|
|
6850
|
-
this.quadtree?.insert({
|
|
6851
|
-
line: lineSegment,
|
|
6852
|
-
userData: lineSegmentList.length
|
|
6853
|
-
});
|
|
6854
|
-
lineSegmentList.push(lineSegment);
|
|
6855
|
-
});
|
|
6856
|
-
this.lineSegmentList = lineSegmentList;
|
|
6484
|
+
toDxfString(unit = "Millimeters") {
|
|
6485
|
+
return this.cad?.toDxfString(unit);
|
|
6857
6486
|
}
|
|
6858
|
-
|
|
6859
|
-
|
|
6860
|
-
|
|
6861
|
-
* @description 判断两条线段距离是否较短且趋近平行,然后查找两条线段的重合部分的投影线,以此判断两根线是否需要合并
|
|
6862
|
-
* @param data
|
|
6487
|
+
/**
|
|
6488
|
+
* 将点云结构转换为 DXF 二进制对象
|
|
6489
|
+
* @returns
|
|
6863
6490
|
*/
|
|
6864
|
-
|
|
6865
|
-
this.
|
|
6866
|
-
const quadtree = this.quadtree;
|
|
6867
|
-
const lineSegmentList = this.lineSegmentList;
|
|
6868
|
-
const visited = /* @__PURE__ */ new Set(), resultList = [];
|
|
6869
|
-
lineSegmentList.forEach((_0, i) => {
|
|
6870
|
-
const sourceLineSegment = lineSegmentList[i], rectangle = Rectangle.fromByLineSegment(sourceLineSegment, this.width * 2, false, -0.01), ids = quadtree.queryRect(rectangle).map((i2) => i2.userData).filter((index2) => index2 !== i);
|
|
6871
|
-
ids.forEach((id) => {
|
|
6872
|
-
try {
|
|
6873
|
-
if (visited.has(`${i}-${id}`) || visited.has(`${id}-${i}`)) return;
|
|
6874
|
-
const res = this.projectionAnalysis(id, i, sourceLineSegment, lineSegmentList);
|
|
6875
|
-
if (res) resultList.push(res);
|
|
6876
|
-
visited.add(`${i}-${id}`);
|
|
6877
|
-
} catch (error) {
|
|
6878
|
-
}
|
|
6879
|
-
});
|
|
6880
|
-
});
|
|
6881
|
-
this.appendLineSegmentList.length = 0;
|
|
6882
|
-
this.resultList = resultList;
|
|
6491
|
+
toDxfBlob(unit = "Millimeters") {
|
|
6492
|
+
return this.cad?.toDxfBlob(unit);
|
|
6883
6493
|
}
|
|
6884
|
-
/**
|
|
6885
|
-
* @param
|
|
6886
|
-
* @param sourceLineSegment
|
|
6887
|
-
* @param lineSegmentList
|
|
6888
|
-
* @returns
|
|
6494
|
+
/** 下载Dxf
|
|
6495
|
+
* @param filename
|
|
6889
6496
|
*/
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
if (angle < this.errorAngle || angle > 180 - this.errorAngle) {
|
|
6893
|
-
let data;
|
|
6894
|
-
const p1 = temLineSegment.projectLineSegment(sourceLineSegment), p2 = sourceLineSegment.projectLineSegment(temLineSegment);
|
|
6895
|
-
if (p1.getLength() > p2.getLength()) {
|
|
6896
|
-
data = {
|
|
6897
|
-
target: temLineSegment,
|
|
6898
|
-
targetIndex: index2,
|
|
6899
|
-
source: sourceLineSegment,
|
|
6900
|
-
sourceIndex,
|
|
6901
|
-
project: p1,
|
|
6902
|
-
project2: p2
|
|
6903
|
-
};
|
|
6904
|
-
} else {
|
|
6905
|
-
data = {
|
|
6906
|
-
target: sourceLineSegment,
|
|
6907
|
-
targetIndex: sourceIndex,
|
|
6908
|
-
source: temLineSegment,
|
|
6909
|
-
sourceIndex: index2,
|
|
6910
|
-
project: p2,
|
|
6911
|
-
project2: p1
|
|
6912
|
-
};
|
|
6913
|
-
}
|
|
6914
|
-
if (!data || data.project.getLength() < 0.2 || data.project2.getLength() < 0.2) return;
|
|
6915
|
-
return data;
|
|
6916
|
-
}
|
|
6497
|
+
async downloadDxf(filename, unit = "Millimeters") {
|
|
6498
|
+
return this.cad?.downloadDxf(filename, unit);
|
|
6917
6499
|
}
|
|
6918
6500
|
}
|
|
6919
6501
|
class DoorsAnalysis {
|
|
@@ -6933,15 +6515,13 @@ class DoorsAnalysis {
|
|
|
6933
6515
|
doorSearchNearAngle = 110;
|
|
6934
6516
|
doorSearchDistance = 2;
|
|
6935
6517
|
doors = [];
|
|
6936
|
-
lineAnalysis;
|
|
6937
6518
|
continueFind = true;
|
|
6938
|
-
constructor(
|
|
6939
|
-
this.
|
|
6940
|
-
this.
|
|
6519
|
+
constructor(dxf, skipFindDoor) {
|
|
6520
|
+
this.dxf = dxf;
|
|
6521
|
+
this.lineSegments = dxf.lineSegments.filter((lineSegment) => !lineSegment.userData?.isDoor);
|
|
6941
6522
|
this.findPointVirtualGrid = new PointVirtualGrid();
|
|
6942
|
-
this.quadtree =
|
|
6943
|
-
this.resultList =
|
|
6944
|
-
this.lineSegments = lineAnalysis.lineSegmentList;
|
|
6523
|
+
this.quadtree = createQuadtree(this.lineSegments);
|
|
6524
|
+
this.resultList = DoubleWallHelper.findDoubleLine(this.lineSegments).resultList;
|
|
6945
6525
|
this.dxf.doorLineSegment.length = 0;
|
|
6946
6526
|
this.lineSegments.forEach((line) => {
|
|
6947
6527
|
line.points.forEach((p) => {
|
|
@@ -7050,20 +6630,13 @@ class DoorsAnalysis {
|
|
|
7050
6630
|
*/
|
|
7051
6631
|
getDoorPoint() {
|
|
7052
6632
|
const doorPoints = [], calculatedDoorPoint = [], dxf = this.dxf, pointVirtualGrid = this.pointVirtualGrid;
|
|
7053
|
-
dxf.
|
|
7054
|
-
|
|
7055
|
-
const doorData =
|
|
6633
|
+
dxf.lineSegments.forEach((doorLine, index2) => {
|
|
6634
|
+
if (!doorLine.userData?.isDoor) return;
|
|
6635
|
+
const doorData = doorLine.userData;
|
|
7056
6636
|
if (doorData.doorDirectConnection) {
|
|
7057
|
-
const { start, end, ...opt } = doorData;
|
|
7058
6637
|
this.continueFind = false;
|
|
7059
|
-
|
|
7060
|
-
|
|
7061
|
-
...cloneUserData(opt),
|
|
7062
|
-
doorDirectConnection: true,
|
|
7063
|
-
isDoor: true
|
|
7064
|
-
};
|
|
7065
|
-
this.dxf.doorLineSegment.push(line);
|
|
7066
|
-
line.points.forEach((point) => {
|
|
6638
|
+
this.dxf.doorLineSegment.push(doorLine);
|
|
6639
|
+
doorLine.points.forEach((point) => {
|
|
7067
6640
|
const res = pointVirtualGrid.queryPoint(point);
|
|
7068
6641
|
if (res.length) {
|
|
7069
6642
|
calculatedDoorPoint.push({
|
|
@@ -7090,7 +6663,7 @@ class DoorsAnalysis {
|
|
|
7090
6663
|
uuid: uuid()
|
|
7091
6664
|
});
|
|
7092
6665
|
} else {
|
|
7093
|
-
console.warn(`门的线段顺序${
|
|
6666
|
+
console.warn(`门的线段顺序${index2} 没有drawDoorData属性`);
|
|
7094
6667
|
}
|
|
7095
6668
|
});
|
|
7096
6669
|
return { doorPoints, calculatedDoorPoint };
|
|
@@ -7354,7 +6927,6 @@ class DoorsAnalysisComponent extends Component {
|
|
|
7354
6927
|
doorSearchDistance = 2;
|
|
7355
6928
|
DoorsAnalysis;
|
|
7356
6929
|
skipFindDoor = false;
|
|
7357
|
-
needsSaveDoor = false;
|
|
7358
6930
|
doors = [];
|
|
7359
6931
|
/**
|
|
7360
6932
|
*
|
|
@@ -7362,164 +6934,13 @@ class DoorsAnalysisComponent extends Component {
|
|
|
7362
6934
|
*/
|
|
7363
6935
|
onAddFromParent(parent) {
|
|
7364
6936
|
const dxf = parent.findComponentByType(Dxf);
|
|
7365
|
-
|
|
7366
|
-
|
|
7367
|
-
this.DoorsAnalysis = new DoorsAnalysis(lineAnalysis, this.skipFindDoor);
|
|
7368
|
-
if (this.needsSaveDoor) {
|
|
7369
|
-
this.doors = dxf.doors.map((item) => dxf.lineSegments[item[4]]);
|
|
7370
|
-
}
|
|
6937
|
+
dxf.addEventListener("dataChange", () => {
|
|
6938
|
+
this.DoorsAnalysis = new DoorsAnalysis(dxf, this.skipFindDoor);
|
|
7371
6939
|
this.skipFindDoor = false;
|
|
7372
6940
|
this.dispatchEvent({ type: "analysisCompleted" });
|
|
7373
6941
|
});
|
|
7374
6942
|
}
|
|
7375
6943
|
}
|
|
7376
|
-
function createGroup(lineSegments) {
|
|
7377
|
-
const doors = [];
|
|
7378
|
-
lineSegments = lineSegments.filter((line) => {
|
|
7379
|
-
if (line.userData.isDoor) {
|
|
7380
|
-
doors.push(line);
|
|
7381
|
-
return false;
|
|
7382
|
-
}
|
|
7383
|
-
return true;
|
|
7384
|
-
});
|
|
7385
|
-
lineSegments = buildDoubleWallGroup(lineSegments);
|
|
7386
|
-
lineSegments = DoubleWallHelper.complementSide(lineSegments);
|
|
7387
|
-
lineSegments = buildDoubleWallGroup(lineSegments, doors, true, true);
|
|
7388
|
-
return [...lineSegments, ...doors];
|
|
7389
|
-
}
|
|
7390
|
-
function getGroups(lines, updateGroup = true) {
|
|
7391
|
-
if (updateGroup) lines = createGroup(lines);
|
|
7392
|
-
const map = lines.reduce((map2, line) => {
|
|
7393
|
-
const groups = LineGroupType.get(line);
|
|
7394
|
-
groups.forEach((group2) => {
|
|
7395
|
-
let id = group2.id ?? "wall";
|
|
7396
|
-
if (group2.type === "wall") id = "wall";
|
|
7397
|
-
map2.append(id, line);
|
|
7398
|
-
});
|
|
7399
|
-
return map2;
|
|
7400
|
-
}, new ArrayMap());
|
|
7401
|
-
return map;
|
|
7402
|
-
}
|
|
7403
|
-
function handleGroup(map) {
|
|
7404
|
-
const group2 = map.group((lines) => {
|
|
7405
|
-
if (LineGroupType.everyType(lines, "bayWindow")) return "wall";
|
|
7406
|
-
if (LineGroupType.everyType(lines, "doubleWall")) return "doubleWall";
|
|
7407
|
-
return "wall";
|
|
7408
|
-
}), walls = group2.get("wall") ?? [], doubleWalls = group2.get("doubleWall") ?? [];
|
|
7409
|
-
let newlines = [], doubleWallsSet = new Set(doubleWalls.flat());
|
|
7410
|
-
walls.forEach((lines) => {
|
|
7411
|
-
lines.forEach((line) => doubleWallsSet.has(line) || newlines.push(line));
|
|
7412
|
-
});
|
|
7413
|
-
doubleWalls.forEach((lines) => {
|
|
7414
|
-
lines = [...new Set(lines)];
|
|
7415
|
-
const groups = clippingDoubleWall(lines);
|
|
7416
|
-
groups.forEach((lines2) => {
|
|
7417
|
-
if (lines2.length < 4) return newlines.push(...lines2);
|
|
7418
|
-
lines2 = lines2.sort((a, b) => a.length() - b.length());
|
|
7419
|
-
const line1 = lines2[0], line2 = lines2[1];
|
|
7420
|
-
const newLine = new LineSegment(line1.center.clone(), line2.center.clone());
|
|
7421
|
-
mergeLineUserData(newLine, lines2);
|
|
7422
|
-
newLine.userData.wallWidth = line1.length();
|
|
7423
|
-
newlines.push(newLine);
|
|
7424
|
-
mergeWindow(newLine);
|
|
7425
|
-
});
|
|
7426
|
-
});
|
|
7427
|
-
newlines = newlines.map((line) => line.clone());
|
|
7428
|
-
return newlines.filter((line) => !line.userData.isBayWindow);
|
|
7429
|
-
}
|
|
7430
|
-
function toJson(lineSegments, name = "测试", communityName = "") {
|
|
7431
|
-
const scale = 1, idMap = /* @__PURE__ */ new Map();
|
|
7432
|
-
let index2 = 0;
|
|
7433
|
-
return {
|
|
7434
|
-
version: "2",
|
|
7435
|
-
name,
|
|
7436
|
-
communityName,
|
|
7437
|
-
city: "",
|
|
7438
|
-
province: "",
|
|
7439
|
-
height: 2.8 * scale,
|
|
7440
|
-
walls: lineSegments.map((line) => {
|
|
7441
|
-
if (line.userData.isDoor && !line.userData.doorDirectConnection) return;
|
|
7442
|
-
idMap.set(line, index2);
|
|
7443
|
-
return {
|
|
7444
|
-
ID: index2++,
|
|
7445
|
-
start: { x: line.start.x * scale, y: line.start.y * scale },
|
|
7446
|
-
end: { x: line.end.x * scale, y: line.end.y * scale },
|
|
7447
|
-
thickness: (line.userData.wallWidth ? line.userData.wallWidth : 0.12) * scale,
|
|
7448
|
-
type: "LINE",
|
|
7449
|
-
isDoor: line.userData.isDoor,
|
|
7450
|
-
loadBearingWall: false,
|
|
7451
|
-
height: 2.8 * scale
|
|
7452
|
-
};
|
|
7453
|
-
}).filter((i) => !!i),
|
|
7454
|
-
pillars: [],
|
|
7455
|
-
beams: [],
|
|
7456
|
-
holes: lineSegments.flatMap((line) => {
|
|
7457
|
-
if (line.userData.isDoor && line.userData.doorDirectConnection) {
|
|
7458
|
-
return {
|
|
7459
|
-
id: index2++,
|
|
7460
|
-
type: "DOOR",
|
|
7461
|
-
openSide: "RIGHT",
|
|
7462
|
-
start: {
|
|
7463
|
-
x: line.start.x * scale,
|
|
7464
|
-
y: line.start.y * scale
|
|
7465
|
-
},
|
|
7466
|
-
end: {
|
|
7467
|
-
x: line.end.x * scale,
|
|
7468
|
-
y: line.end.y * scale
|
|
7469
|
-
},
|
|
7470
|
-
height: 2.1 * scale,
|
|
7471
|
-
qroundClearance: 0 * scale,
|
|
7472
|
-
sillHeight: (line.userData?.sillHeight ?? 0) * scale
|
|
7473
|
-
};
|
|
7474
|
-
} else if (line.userData.isWindow && line.userData.drawWindow) {
|
|
7475
|
-
return line.userData.drawWindow.map((item) => {
|
|
7476
|
-
const center = Point.from(item.p);
|
|
7477
|
-
const start = center.clone().add(
|
|
7478
|
-
line.direction().multiplyScalar(item.width * 0.5)
|
|
7479
|
-
);
|
|
7480
|
-
const end = center.clone().add(
|
|
7481
|
-
line.direction().multiplyScalar(-item.width * 0.5)
|
|
7482
|
-
);
|
|
7483
|
-
return {
|
|
7484
|
-
id: index2++,
|
|
7485
|
-
type: "WINDOW",
|
|
7486
|
-
start: {
|
|
7487
|
-
x: start.x * scale,
|
|
7488
|
-
y: start.y * scale
|
|
7489
|
-
},
|
|
7490
|
-
end: {
|
|
7491
|
-
x: end.x * scale,
|
|
7492
|
-
y: end.y * scale
|
|
7493
|
-
},
|
|
7494
|
-
height: 1.6 * scale,
|
|
7495
|
-
groundClearance: (line.userData?.groundClearance ?? 0.9) * scale,
|
|
7496
|
-
sillHeight: (line.userData?.groundClearance ?? 0.9) * scale
|
|
7497
|
-
};
|
|
7498
|
-
});
|
|
7499
|
-
}
|
|
7500
|
-
}).filter((i) => !!i),
|
|
7501
|
-
rooms: []
|
|
7502
|
-
};
|
|
7503
|
-
}
|
|
7504
|
-
function lineDataToThreeVJiaJson(lineSegments, angle = 0, updateGroup = true) {
|
|
7505
|
-
const group2 = getGroups(lineSegments, updateGroup);
|
|
7506
|
-
let newLines = handleGroup(group2);
|
|
7507
|
-
newLines = LineSegmentUndirectedGraph.rotate(newLines, angle, (line, center, angle2) => {
|
|
7508
|
-
if (line.userData.drawWindow) {
|
|
7509
|
-
line.userData.drawWindow.forEach((windowItem) => {
|
|
7510
|
-
const point = Point.from(windowItem.p);
|
|
7511
|
-
point.rotate(center, angle2 * (Math.PI / 180));
|
|
7512
|
-
windowItem.p = point.toJson(windowItem.p.z);
|
|
7513
|
-
});
|
|
7514
|
-
}
|
|
7515
|
-
});
|
|
7516
|
-
return {
|
|
7517
|
-
lines: newLines,
|
|
7518
|
-
toJson(name = "测试", communityName = "") {
|
|
7519
|
-
return toJson(newLines, name, communityName);
|
|
7520
|
-
}
|
|
7521
|
-
};
|
|
7522
|
-
}
|
|
7523
6944
|
class ThreeVJia extends Component {
|
|
7524
6945
|
static name = "ThreeVJia";
|
|
7525
6946
|
lineSegments = [];
|
|
@@ -7569,10 +6990,37 @@ class ThreeVJia extends Component {
|
|
|
7569
6990
|
}
|
|
7570
6991
|
}
|
|
7571
6992
|
}
|
|
6993
|
+
class Variable extends Component {
|
|
6994
|
+
static name = "Variable";
|
|
6995
|
+
originalLineVisible = true;
|
|
6996
|
+
dxfVisible = true;
|
|
6997
|
+
whiteModelVisible = true;
|
|
6998
|
+
isLook = false;
|
|
6999
|
+
currentWheel = 0;
|
|
7000
|
+
pointerMove = { x: 0, y: 0 };
|
|
7001
|
+
currentKeyUp = "";
|
|
7002
|
+
currentKeyDown = "";
|
|
7003
|
+
currentMouseUp = "";
|
|
7004
|
+
currentMouseDown = "";
|
|
7005
|
+
focus = false;
|
|
7006
|
+
set(key, value) {
|
|
7007
|
+
if (key in this) {
|
|
7008
|
+
const oldValue = this[key];
|
|
7009
|
+
this[key] = value;
|
|
7010
|
+
this.dispatchEvent({
|
|
7011
|
+
type: key,
|
|
7012
|
+
value,
|
|
7013
|
+
oldValue
|
|
7014
|
+
});
|
|
7015
|
+
}
|
|
7016
|
+
}
|
|
7017
|
+
get(key) {
|
|
7018
|
+
if (key in this) return this[key];
|
|
7019
|
+
}
|
|
7020
|
+
}
|
|
7572
7021
|
class DxfSystem extends ComponentManager {
|
|
7573
7022
|
Dxf;
|
|
7574
7023
|
Variable;
|
|
7575
|
-
LineAnalysis;
|
|
7576
7024
|
DoorsAnalysis;
|
|
7577
7025
|
CorrectionDxf;
|
|
7578
7026
|
wallWidth;
|
|
@@ -7588,11 +7036,9 @@ class DxfSystem extends ComponentManager {
|
|
|
7588
7036
|
this.Dxf = new Dxf(this.wallWidth);
|
|
7589
7037
|
this.CorrectionDxf = new CorrectionDxf(this.wallWidth);
|
|
7590
7038
|
this.Variable = new Variable();
|
|
7591
|
-
this.LineAnalysis = new LineAnalysis();
|
|
7592
7039
|
this.DoorsAnalysis = new DoorsAnalysisComponent();
|
|
7593
7040
|
this.addComponent(this.Variable);
|
|
7594
7041
|
this.addComponent(this.Dxf);
|
|
7595
|
-
this.addComponent(this.LineAnalysis);
|
|
7596
7042
|
this.addComponent(this.DoorsAnalysis);
|
|
7597
7043
|
this.addComponent(this.CorrectionDxf);
|
|
7598
7044
|
this.addComponent(new ThreeVJia());
|
|
@@ -7612,187 +7058,12 @@ class DxfSystem extends ComponentManager {
|
|
|
7612
7058
|
}
|
|
7613
7059
|
}
|
|
7614
7060
|
const components = {
|
|
7615
|
-
LineAnalysis,
|
|
7616
7061
|
ThreeVJia,
|
|
7617
7062
|
Variable,
|
|
7618
7063
|
Dxf,
|
|
7619
7064
|
DoorsAnalysisComponent,
|
|
7620
7065
|
CorrectionDxf
|
|
7621
7066
|
};
|
|
7622
|
-
function findRingEdges(lines) {
|
|
7623
|
-
const lineUG = new LineSegmentUndirectedGraph(lines), unionFindSet = new UnionFindSet(lineUG.size), visited = /* @__PURE__ */ new Set(), ringEdges = [];
|
|
7624
|
-
function dfs(n1) {
|
|
7625
|
-
visited.add(n1);
|
|
7626
|
-
const neighbors = lineUG.getNeighbors(n1);
|
|
7627
|
-
neighbors?.forEach((n2) => {
|
|
7628
|
-
if (visited.has(n2)) return;
|
|
7629
|
-
if (unionFindSet.find(n1) === unionFindSet.find(n2)) {
|
|
7630
|
-
const line = lineUG.getLine(n1, n2);
|
|
7631
|
-
ringEdges.push(line);
|
|
7632
|
-
} else {
|
|
7633
|
-
unionFindSet.union(n1, n2);
|
|
7634
|
-
}
|
|
7635
|
-
});
|
|
7636
|
-
}
|
|
7637
|
-
lineUG.forEach((n1) => {
|
|
7638
|
-
if (visited.has(n1)) return;
|
|
7639
|
-
dfs(n1);
|
|
7640
|
-
});
|
|
7641
|
-
return ringEdges;
|
|
7642
|
-
}
|
|
7643
|
-
function findMinRing(lines, ringEdges) {
|
|
7644
|
-
const grid = createPointVirtualGrid(lines), temLine = new LineSegment(), queryLine = new LineSegment(), rings = [], visited = /* @__PURE__ */ new Set();
|
|
7645
|
-
function getDirect(line, preDirect) {
|
|
7646
|
-
const center = line.center, direct = line.normal();
|
|
7647
|
-
temLine.start.copy(center);
|
|
7648
|
-
temLine.end.copy(center).add(direct.clone().multiplyScalar(1));
|
|
7649
|
-
const point = preDirect.getIntersection(temLine);
|
|
7650
|
-
temLine.end.copy(point);
|
|
7651
|
-
return temLine.clone();
|
|
7652
|
-
}
|
|
7653
|
-
function find(edge, line, point, preLine, preDirect, path, isPreDirect = true) {
|
|
7654
|
-
if (path.length > lines.length) return;
|
|
7655
|
-
if (visited.has(line)) return;
|
|
7656
|
-
visited.add(line);
|
|
7657
|
-
let direct;
|
|
7658
|
-
const otherPoint = line.getAnotherPoint(point);
|
|
7659
|
-
if (isPreDirect) {
|
|
7660
|
-
if (line.vertical(preLine)) direct = getDirect(line, preDirect);
|
|
7661
|
-
else {
|
|
7662
|
-
const center = line.center, x = center.distance(preDirect.start), d0 = center.direction(preDirect.start);
|
|
7663
|
-
direct = preDirect.directionMove(d0, x);
|
|
7664
|
-
}
|
|
7665
|
-
} else direct = preDirect;
|
|
7666
|
-
let result = grid.queryPoint(otherPoint, true);
|
|
7667
|
-
if (result.length === 1) {
|
|
7668
|
-
const item = result[0], nextLine = item.userData, otherPoint1 = nextLine.getAnotherPoint(item.point), d0 = otherPoint1.direction(item.point);
|
|
7669
|
-
if (edge === nextLine) return path;
|
|
7670
|
-
if (nextLine.vertical(line)) {
|
|
7671
|
-
const d1 = otherPoint.direction(point), center = nextLine.center, isSameDirection = d0.angleBetween(direct.direction()) < 1e-9;
|
|
7672
|
-
direct.start.copy(center);
|
|
7673
|
-
direct.end.copy(center).add(d1.multiplyScalar(0.02));
|
|
7674
|
-
if (isSameDirection) direct.end.rotate(direct.start, Math.PI);
|
|
7675
|
-
path.push(nextLine);
|
|
7676
|
-
if (find(edge, nextLine, item.point, line, direct, path, false)) return path;
|
|
7677
|
-
}
|
|
7678
|
-
} else {
|
|
7679
|
-
queryLine.start.copy(direct.start).add(direct.direction().multiplyScalar(5e-3));
|
|
7680
|
-
const lines2 = [line, ...result.map((item) => {
|
|
7681
|
-
const line2 = item.userData;
|
|
7682
|
-
line2.length();
|
|
7683
|
-
return line2;
|
|
7684
|
-
})];
|
|
7685
|
-
for (let i = 0; i < result.length; i++) {
|
|
7686
|
-
const item = result[i], nextLine = item.userData;
|
|
7687
|
-
if (edge === nextLine) return path;
|
|
7688
|
-
if (result.length === 4 && nextLine.parallel(line)) continue;
|
|
7689
|
-
queryLine.end.copy(nextLine.center);
|
|
7690
|
-
if (!lines2.some((line1) => {
|
|
7691
|
-
if (line1 === nextLine) return false;
|
|
7692
|
-
return line1.intersectLineSegment(queryLine);
|
|
7693
|
-
})) {
|
|
7694
|
-
path.push(nextLine);
|
|
7695
|
-
return find(edge, nextLine, item.point, line, direct, path);
|
|
7696
|
-
}
|
|
7697
|
-
}
|
|
7698
|
-
}
|
|
7699
|
-
}
|
|
7700
|
-
for (let i = 0; i < ringEdges.length; i++) {
|
|
7701
|
-
const line = ringEdges[i], center = line.center, startList = grid.queryPoint(line.start, true), endList = grid.queryPoint(line.end, true), minList = startList.length < endList.length ? startList : endList, directList = [], list = minList.filter((item) => {
|
|
7702
|
-
if (minList.length === 3 && item.userData?.parallel(line)) return false;
|
|
7703
|
-
const otherPoint = item.userData?.getAnotherPoint(item.point);
|
|
7704
|
-
directList.push(otherPoint.direction(item.point));
|
|
7705
|
-
return true;
|
|
7706
|
-
});
|
|
7707
|
-
const ringList = [];
|
|
7708
|
-
for (let i2 = 0; i2 < list.length; i2++) {
|
|
7709
|
-
const item = list[i2];
|
|
7710
|
-
let direct = directList[i2];
|
|
7711
|
-
if (item.userData?.parallel(line)) {
|
|
7712
|
-
const otherIndex = i2 ? 0 : 1, other = directList[otherIndex];
|
|
7713
|
-
direct = other.clone().multiplyScalar(-1);
|
|
7714
|
-
}
|
|
7715
|
-
visited.clear();
|
|
7716
|
-
const directLine = new LineSegment(center.clone(), center.clone().add(direct.clone().multiplyScalar(0.2)));
|
|
7717
|
-
const path = find(line, item.userData, item.point, line, directLine, [line, item.userData]);
|
|
7718
|
-
if (path) {
|
|
7719
|
-
ringList.push([...path]);
|
|
7720
|
-
}
|
|
7721
|
-
}
|
|
7722
|
-
if (ringList.length === 2) {
|
|
7723
|
-
const set2 = new Set(ringList[0]);
|
|
7724
|
-
const count = ringList[1].filter((line2) => set2.has(line2)).length;
|
|
7725
|
-
if (count > 1) ringList.splice(0, 2, ringList[0].length < ringList[1].length ? ringList[0] : ringList[1]);
|
|
7726
|
-
}
|
|
7727
|
-
rings.push(...ringList);
|
|
7728
|
-
}
|
|
7729
|
-
return rings;
|
|
7730
|
-
}
|
|
7731
|
-
function ringsDeduplication(rings) {
|
|
7732
|
-
const map = new ArrayMap(), newRings = [];
|
|
7733
|
-
rings.forEach((ring) => map.append(ring.length, ring));
|
|
7734
|
-
for (const rings2 of map.values()) {
|
|
7735
|
-
const lineIndexGenerator = new LineIndexGenerator(rings2.flat());
|
|
7736
|
-
const ringMap = new ArrayMap();
|
|
7737
|
-
rings2.map((ring) => {
|
|
7738
|
-
const key = ring.map((line) => lineIndexGenerator.getIndex(line)).sort((a, b) => a - b).join(",");
|
|
7739
|
-
ringMap.append(key, ring);
|
|
7740
|
-
});
|
|
7741
|
-
ringMap.forEach((list) => newRings.push(list[0]));
|
|
7742
|
-
}
|
|
7743
|
-
return newRings;
|
|
7744
|
-
}
|
|
7745
|
-
function findMaxRing(lines, ringEdges) {
|
|
7746
|
-
const rings = findMinRing(lines, ringEdges), visited = /* @__PURE__ */ new Map(), unionFindSet = new UnionFindSet(rings.length), internalEdges = [];
|
|
7747
|
-
rings.forEach((ring, index2) => {
|
|
7748
|
-
for (let i = 0; i < ring.length; i++) {
|
|
7749
|
-
const line = ring[i];
|
|
7750
|
-
if (visited.has(line)) unionFindSet.union(index2, visited.get(line));
|
|
7751
|
-
else visited.set(line, index2);
|
|
7752
|
-
}
|
|
7753
|
-
});
|
|
7754
|
-
const countMap = new CountMap();
|
|
7755
|
-
const groups = unionFindSet.getAllSets().valueArray.map((list) => {
|
|
7756
|
-
let group2 = list.map((i) => rings[i]);
|
|
7757
|
-
if (group2.length === 1) return group2[0];
|
|
7758
|
-
countMap.clear();
|
|
7759
|
-
group2 = ringsDeduplication(group2);
|
|
7760
|
-
group2.forEach((lines2) => lines2.forEach((line) => countMap.set(line)));
|
|
7761
|
-
const ring = countMap.reduce((lines2, count, line) => {
|
|
7762
|
-
if (count === 1) lines2.push(line);
|
|
7763
|
-
else internalEdges.push(line);
|
|
7764
|
-
return lines2;
|
|
7765
|
-
}, []);
|
|
7766
|
-
return ring;
|
|
7767
|
-
});
|
|
7768
|
-
return {
|
|
7769
|
-
internalEdges,
|
|
7770
|
-
rings: groups
|
|
7771
|
-
};
|
|
7772
|
-
}
|
|
7773
|
-
function findClosedPolygons(lines) {
|
|
7774
|
-
const linesGroup = LineSegment.groupByPath(lines), rings = [], internalEdges = [];
|
|
7775
|
-
linesGroup.forEach((lines2, _) => {
|
|
7776
|
-
try {
|
|
7777
|
-
let ringEdges = findRingEdges(lines2);
|
|
7778
|
-
const result = findMaxRing(lines2, ringEdges);
|
|
7779
|
-
rings.push(...result.rings);
|
|
7780
|
-
internalEdges.push(...result.internalEdges);
|
|
7781
|
-
} catch (error) {
|
|
7782
|
-
console.warn("环查找出现异常:", error.message);
|
|
7783
|
-
}
|
|
7784
|
-
});
|
|
7785
|
-
const internalEdgesSet = /* @__PURE__ */ new Set([...internalEdges]);
|
|
7786
|
-
const groupsSet = /* @__PURE__ */ new Set([...rings.flat()]);
|
|
7787
|
-
lines = lines.filter((line) => !internalEdgesSet.has(line));
|
|
7788
|
-
lines.forEach((line) => !groupsSet.has(line));
|
|
7789
|
-
lines = [...new Set(lines)];
|
|
7790
|
-
return {
|
|
7791
|
-
newLines: lines,
|
|
7792
|
-
rings,
|
|
7793
|
-
internalEdges
|
|
7794
|
-
};
|
|
7795
|
-
}
|
|
7796
7067
|
function drawLines$1(lines, parameters, offset = 1e-3) {
|
|
7797
7068
|
if (Array.isArray(lines) && lines[0] instanceof Point) {
|
|
7798
7069
|
const _lines = lines;
|
|
@@ -7998,7 +7269,7 @@ class Scenario {
|
|
|
7998
7269
|
this.doorGroup.name = "";
|
|
7999
7270
|
this.texture = null;
|
|
8000
7271
|
this.numdu = 1;
|
|
8001
|
-
this.color =
|
|
7272
|
+
this.color = 16777215;
|
|
8002
7273
|
this.doorModely = null;
|
|
8003
7274
|
this.windowModely = null;
|
|
8004
7275
|
this.CabinetModel = null;
|
|
@@ -8016,10 +7287,12 @@ class Scenario {
|
|
|
8016
7287
|
}
|
|
8017
7288
|
// 绘制图形
|
|
8018
7289
|
async drawGraphics(lines, z, trajectoryJson) {
|
|
7290
|
+
const doorLines = lines.filter((line) => line.userData.isDoor);
|
|
7291
|
+
lines = buildDoubleWallGroup(lines.filter((line) => !line.userData.isDoor), doorLines);
|
|
7292
|
+
lines.push(...doorLines);
|
|
8019
7293
|
await this.modelLoader();
|
|
8020
7294
|
await this.windowModelLoader();
|
|
8021
7295
|
this.height = z;
|
|
8022
|
-
console.log("this.height", this.height);
|
|
8023
7296
|
this.lines = lines;
|
|
8024
7297
|
if (this.group) {
|
|
8025
7298
|
this.scene.remove(this.group);
|
|
@@ -8058,10 +7331,17 @@ class Scenario {
|
|
|
8058
7331
|
this.closedArray = lines.filter((item) => {
|
|
8059
7332
|
return LineGroupType.hasType(item, "doubleWall");
|
|
8060
7333
|
});
|
|
8061
|
-
|
|
7334
|
+
let groups = LineSegment.groupByPath(this.closedArray);
|
|
8062
7335
|
const set2 = new Set(this.closedArray);
|
|
8063
7336
|
let singleLineWall = lines.filter((line) => !set2.has(line) && !line.userData.isDoor && !line.userData.isBayWindow);
|
|
8064
7337
|
let menList = lines.filter((line) => line.userData.isDoor);
|
|
7338
|
+
groups = groups.filter((group2) => {
|
|
7339
|
+
if (group2.length < 4) {
|
|
7340
|
+
singleLineWall.push(...group2);
|
|
7341
|
+
return false;
|
|
7342
|
+
}
|
|
7343
|
+
return true;
|
|
7344
|
+
});
|
|
8065
7345
|
this.TheHandlingOfTheDoor(menList);
|
|
8066
7346
|
this.overallTreatmentOfSingleLineWalls(singleLineWall);
|
|
8067
7347
|
for (const g in groups) {
|
|
@@ -8108,7 +7388,7 @@ class Scenario {
|
|
|
8108
7388
|
});
|
|
8109
7389
|
let d = [];
|
|
8110
7390
|
for (const i2 in c) {
|
|
8111
|
-
d.push(new THREE.Vector3(c[i2].dian.x, c[i2].dian.y,
|
|
7391
|
+
d.push(new THREE.Vector3(c[i2].dian.x, c[i2].dian.y, c[i2].dian.z));
|
|
8112
7392
|
}
|
|
8113
7393
|
const seen = /* @__PURE__ */ new Set();
|
|
8114
7394
|
const E = d.filter((coord) => {
|
|
@@ -8164,15 +7444,13 @@ class Scenario {
|
|
|
8164
7444
|
const geometry = this.createParallelepipedFromBase(basePoints, 2.8);
|
|
8165
7445
|
const material = new THREE.MeshStandardMaterial({
|
|
8166
7446
|
color: this.color,
|
|
8167
|
-
side: THREE.DoubleSide
|
|
8168
|
-
//
|
|
8169
|
-
|
|
8170
|
-
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
|
|
8174
|
-
polygonOffsetUnits: 10
|
|
8175
|
-
// wireframe: true
|
|
7447
|
+
side: THREE.DoubleSide
|
|
7448
|
+
// roughness: this.numdu,
|
|
7449
|
+
// metalness: 0.0,
|
|
7450
|
+
// envMapRotation: new THREE.Euler(0, 0, 0),
|
|
7451
|
+
// polygonOffset: true,
|
|
7452
|
+
// polygonOffsetFactor: 10,
|
|
7453
|
+
// polygonOffsetUnits: 10,
|
|
8176
7454
|
});
|
|
8177
7455
|
const cube = new THREE.Mesh(geometry, material);
|
|
8178
7456
|
const edges = new THREE.EdgesGeometry(geometry);
|
|
@@ -8429,7 +7707,6 @@ class Scenario {
|
|
|
8429
7707
|
let size = new THREE.Vector3();
|
|
8430
7708
|
box32.getSize(size);
|
|
8431
7709
|
cabinetModel.rotation.x = Math.PI / 2;
|
|
8432
|
-
console.log("卡农看:", cabinetModel.geometry);
|
|
8433
7710
|
cabinetModel.scale.set(0.7 / size.x, 0.7 / size.y, 0.3 / size.z);
|
|
8434
7711
|
this.group.add(cabinetModel);
|
|
8435
7712
|
}
|
|
@@ -8470,14 +7747,13 @@ class Scenario {
|
|
|
8470
7747
|
const geometry = this.createParallelepipedFromBase(basePoints, Height ? Height : this.WindowHeight);
|
|
8471
7748
|
const material = new THREE.MeshStandardMaterial({
|
|
8472
7749
|
color: this.color,
|
|
8473
|
-
side: THREE.DoubleSide
|
|
8474
|
-
//
|
|
8475
|
-
|
|
8476
|
-
|
|
8477
|
-
|
|
8478
|
-
|
|
8479
|
-
|
|
8480
|
-
polygonOffsetUnits: 10
|
|
7750
|
+
side: THREE.DoubleSide
|
|
7751
|
+
// roughness: this.numdu,
|
|
7752
|
+
// metalness: 0.0,
|
|
7753
|
+
// envMapRotation: new THREE.Euler(0, 0, 0),
|
|
7754
|
+
// polygonOffset: true,
|
|
7755
|
+
// polygonOffsetFactor: 10,
|
|
7756
|
+
// polygonOffsetUnits: 10,
|
|
8481
7757
|
});
|
|
8482
7758
|
const brush1 = new Brush(mesh.geometry);
|
|
8483
7759
|
brush1.updateMatrixWorld();
|
|
@@ -8523,25 +7799,23 @@ class Scenario {
|
|
|
8523
7799
|
const result = evaluator.evaluate(brush1, brush2, SUBTRACTION);
|
|
8524
7800
|
const material = new THREE.MeshStandardMaterial({
|
|
8525
7801
|
color: this.color,
|
|
8526
|
-
side: THREE.DoubleSide
|
|
8527
|
-
//
|
|
8528
|
-
|
|
8529
|
-
|
|
8530
|
-
|
|
8531
|
-
|
|
8532
|
-
|
|
8533
|
-
polygonOffsetUnits: 10
|
|
7802
|
+
side: THREE.DoubleSide
|
|
7803
|
+
// roughness: this.numdu,
|
|
7804
|
+
// metalness: 0.0,
|
|
7805
|
+
// envMapRotation: new THREE.Euler(0, 0, 0),
|
|
7806
|
+
// polygonOffset: true,
|
|
7807
|
+
// polygonOffsetFactor: 10,
|
|
7808
|
+
// polygonOffsetUnits: 10,
|
|
8534
7809
|
});
|
|
8535
7810
|
const material1 = new THREE.MeshStandardMaterial({
|
|
8536
7811
|
color: this.color,
|
|
8537
|
-
side: THREE.DoubleSide
|
|
8538
|
-
//
|
|
8539
|
-
|
|
8540
|
-
|
|
8541
|
-
|
|
8542
|
-
|
|
8543
|
-
|
|
8544
|
-
polygonOffsetUnits: 10
|
|
7812
|
+
side: THREE.DoubleSide
|
|
7813
|
+
// roughness: this.numdu,
|
|
7814
|
+
// metalness: 0.0,
|
|
7815
|
+
// envMapRotation: new THREE.Euler(0, 0, 0),
|
|
7816
|
+
// polygonOffset: true,
|
|
7817
|
+
// polygonOffsetFactor: 10,
|
|
7818
|
+
// polygonOffsetUnits: 10,
|
|
8545
7819
|
});
|
|
8546
7820
|
result.material = material1;
|
|
8547
7821
|
new THREE.Mesh(geometry2, material);
|
|
@@ -15841,9 +15115,9 @@ class SceneAutoGenerat {
|
|
|
15841
15115
|
});
|
|
15842
15116
|
const contour = Point.fromByList(item.contour ?? []), rectangle = new Polygon(Qa(contour.map((p) => [p.x, p.y])).map((p) => Point.from(p)));
|
|
15843
15117
|
rectangle.pop();
|
|
15844
|
-
const max = rectangle.getMaxLengthInfo(), min = rectangle.getMinLengthInfo(), center = rectangle.getCenter(), direction = max.start.y < max.end.y ? max.start.direction(max.end) : max.end.direction(max.start), height = Math.abs(item.box.max.z -
|
|
15118
|
+
const z = item.box.min.z, max = rectangle.getMaxLengthInfo(), min = rectangle.getMinLengthInfo(), center = rectangle.getCenter(), direction = max.start.y < max.end.y ? max.start.direction(max.end) : max.end.direction(max.start), height = Math.abs(item.box.max.z - z);
|
|
15845
15119
|
const group2 = new THREE.Group();
|
|
15846
|
-
group2.position.set(center.x, center.y,
|
|
15120
|
+
group2.position.set(center.x, center.y, z);
|
|
15847
15121
|
group2.add(model);
|
|
15848
15122
|
this.scene.add(group2);
|
|
15849
15123
|
const box32 = new THREE.Box3();
|
|
@@ -15865,7 +15139,7 @@ class SceneAutoGenerat {
|
|
|
15865
15139
|
const direction2 = point1.y < point2.y ? point1.direction(point2) : point2.direction(point1);
|
|
15866
15140
|
group2.rotateZ(direction2.angleBetween2(direction));
|
|
15867
15141
|
this.scene.add(
|
|
15868
|
-
SceneAutoGenerat.itemParse(item
|
|
15142
|
+
SceneAutoGenerat.itemParse(item).box
|
|
15869
15143
|
);
|
|
15870
15144
|
}
|
|
15871
15145
|
/** 构建物品模型
|
|
@@ -15873,10 +15147,10 @@ class SceneAutoGenerat {
|
|
|
15873
15147
|
async buildItem() {
|
|
15874
15148
|
await Promise.all(this.itemList.map(async (item) => await this.getModel(item)));
|
|
15875
15149
|
}
|
|
15876
|
-
static itemParse(item
|
|
15150
|
+
static itemParse(item) {
|
|
15877
15151
|
const contour = Point.fromByList(item.contour), rectangle = new Polygon(Qa(contour.map((p) => [p.x, p.y])).map((p) => Point.from(p)));
|
|
15878
15152
|
rectangle.pop();
|
|
15879
|
-
const height = Math.abs(item.box.max.z - z), max = rectangle.getMaxLengthInfo(), direction = max.start.y < max.end.y ? max.start.direction(max.end) : max.end.direction(max.start), shape = new THREE.Shape();
|
|
15153
|
+
const z = item.box.min.z, height = Math.abs(item.box.max.z - z), max = rectangle.getMaxLengthInfo(), min = rectangle.getMinLengthInfo(), direction = max.start.y < max.end.y ? max.start.direction(max.end) : max.end.direction(max.start), shape = new THREE.Shape();
|
|
15880
15154
|
rectangle.forEach((p, i) => {
|
|
15881
15155
|
if (i === 0) shape.moveTo(p.x, p.y);
|
|
15882
15156
|
else shape.lineTo(p.x, p.y);
|
|
@@ -15889,11 +15163,34 @@ class SceneAutoGenerat {
|
|
|
15889
15163
|
lineSegments.position.z = z;
|
|
15890
15164
|
box3.setFromObject(lineSegments);
|
|
15891
15165
|
const center = box3.getCenter(new THREE.Vector3());
|
|
15166
|
+
const maxLine = new LineSegment(max.start, max.end), minLine = new LineSegment(min.start, min.end);
|
|
15167
|
+
const zStart = new THREE.Vector3().copy(rectangle[0].toJson(z)), zEnd = zStart.clone();
|
|
15168
|
+
zEnd.z += height;
|
|
15892
15169
|
return {
|
|
15893
15170
|
box: lineSegments,
|
|
15894
15171
|
center,
|
|
15895
15172
|
category: item.category,
|
|
15896
|
-
angle: direction.angleBetween(new Point(0, 1), "angle", "360") * (Math.PI / 180) + Math.PI * 0.5
|
|
15173
|
+
angle: direction.angleBetween(new Point(0, 1), "angle", "360") * (Math.PI / 180) + Math.PI * 0.5,
|
|
15174
|
+
info: [
|
|
15175
|
+
{
|
|
15176
|
+
center: new THREE.Vector3().copy(maxLine.center.toJson(z)),
|
|
15177
|
+
start: new THREE.Vector3().copy(maxLine.start.toJson(z)),
|
|
15178
|
+
end: new THREE.Vector3().copy(maxLine.start.toJson(z)),
|
|
15179
|
+
length: maxLine.length()
|
|
15180
|
+
},
|
|
15181
|
+
{
|
|
15182
|
+
center: new THREE.Vector3().copy(minLine.center.toJson(z)),
|
|
15183
|
+
start: new THREE.Vector3().copy(minLine.start.toJson(z)),
|
|
15184
|
+
end: new THREE.Vector3().copy(minLine.start.toJson(z)),
|
|
15185
|
+
length: minLine.length()
|
|
15186
|
+
},
|
|
15187
|
+
{
|
|
15188
|
+
center: zStart.clone().add(zEnd).multiplyScalar(0.5),
|
|
15189
|
+
start: zStart,
|
|
15190
|
+
end: zEnd,
|
|
15191
|
+
length: height
|
|
15192
|
+
}
|
|
15193
|
+
]
|
|
15897
15194
|
};
|
|
15898
15195
|
}
|
|
15899
15196
|
}
|
|
@@ -15926,8 +15223,6 @@ class WhiteModel extends Component {
|
|
|
15926
15223
|
whiteModelGroup = new THREE.Group();
|
|
15927
15224
|
// dxf数据白模边缘线
|
|
15928
15225
|
whiteModelLineGroup = new THREE.Group();
|
|
15929
|
-
// 原始数据白模
|
|
15930
|
-
originalWhiteMode = new THREE.Group();
|
|
15931
15226
|
material = new THREE.MeshStandardMaterial({ color: 16777215, transparent: true, opacity: 0.8, side: THREE.DoubleSide });
|
|
15932
15227
|
itemList = [];
|
|
15933
15228
|
promise;
|
|
@@ -15941,8 +15236,7 @@ class WhiteModel extends Component {
|
|
|
15941
15236
|
onAddFromParent(parent) {
|
|
15942
15237
|
this.Dxf = parent.findComponentByName("Dxf");
|
|
15943
15238
|
this.Variable = parent.findComponentByName("Variable");
|
|
15944
|
-
this.
|
|
15945
|
-
this.Dxf?.addEventListener("lineOffset", () => {
|
|
15239
|
+
this.Dxf?.addEventListener("cadChange", () => {
|
|
15946
15240
|
this.promise = this.updateModel();
|
|
15947
15241
|
});
|
|
15948
15242
|
}
|
|
@@ -15950,12 +15244,10 @@ class WhiteModel extends Component {
|
|
|
15950
15244
|
const dxfSystem = this.parent;
|
|
15951
15245
|
this.Variable?.set("whiteModelVisible", false);
|
|
15952
15246
|
const dxf = this.Dxf;
|
|
15953
|
-
this.originalWhiteMode.clear();
|
|
15954
15247
|
this.whiteModelGroup.clear();
|
|
15955
15248
|
this.whiteModelLineGroup.clear();
|
|
15956
15249
|
this.whiteModelGroup.add(this.whiteModelLineGroup);
|
|
15957
15250
|
this.whiteModelGroup.position.z = dxf.originalZAverage;
|
|
15958
|
-
this.originalWhiteMode.position.z = dxf.originalZAverage;
|
|
15959
15251
|
const lines = dxfSystem.Dxf.getLineSegments(true);
|
|
15960
15252
|
const sceneAutoGenerat = new SceneAutoGenerat(lines, this.itemList, dxfSystem.Dxf.originalZAverage, dxfSystem.CorrectionDxf.trajectory);
|
|
15961
15253
|
await sceneAutoGenerat.init();
|
|
@@ -15964,7 +15256,7 @@ class WhiteModel extends Component {
|
|
|
15964
15256
|
this.whiteModelLineGroup.add(group2.clone(true));
|
|
15965
15257
|
}
|
|
15966
15258
|
const walls = dxf.originalData.map(({ start, end, insetionArr }) => {
|
|
15967
|
-
const startVec3 = new Point(start.x, start.y)
|
|
15259
|
+
const startVec3 = new Point(start.x, start.y), endVec3 = new Point(end.x, end.y), { points, indices, rectIndices } = lineSqueezing(startVec3, endVec3, dxf.width);
|
|
15968
15260
|
return {
|
|
15969
15261
|
points,
|
|
15970
15262
|
indices,
|
|
@@ -15984,12 +15276,9 @@ class WhiteModel extends Component {
|
|
|
15984
15276
|
bevelSize: 0
|
|
15985
15277
|
});
|
|
15986
15278
|
if (geometry.attributes.position.array.filter((num) => Number.isNaN(num)).length) return;
|
|
15987
|
-
const mesh = new THREE.Mesh(geometry);
|
|
15988
|
-
this.originalWhiteMode?.add(mesh);
|
|
15989
15279
|
});
|
|
15990
15280
|
this.dispatchEvent({
|
|
15991
15281
|
type: "updateModel",
|
|
15992
|
-
originalWhiteMode: this.originalWhiteMode,
|
|
15993
15282
|
whiteModelGroup: this.whiteModelGroup
|
|
15994
15283
|
});
|
|
15995
15284
|
return this.whiteModelLineGroup;
|
|
@@ -16098,101 +15387,6 @@ class WhiteModel extends Component {
|
|
|
16098
15387
|
}
|
|
16099
15388
|
}
|
|
16100
15389
|
}
|
|
16101
|
-
class DetailsPoint extends Component {
|
|
16102
|
-
static name = "DetailsPoint";
|
|
16103
|
-
Dxf = null;
|
|
16104
|
-
WhiteModel = null;
|
|
16105
|
-
Variable = null;
|
|
16106
|
-
desPoints = [];
|
|
16107
|
-
raylines = [];
|
|
16108
|
-
data = [];
|
|
16109
|
-
onAddFromParent(parent) {
|
|
16110
|
-
this.Dxf = parent.findComponentByName("Dxf");
|
|
16111
|
-
this.Variable = parent.findComponentByName("Variable");
|
|
16112
|
-
this.Dxf?.addEventListener("setDta", () => {
|
|
16113
|
-
this.updateModel();
|
|
16114
|
-
});
|
|
16115
|
-
}
|
|
16116
|
-
/**
|
|
16117
|
-
* 设置值
|
|
16118
|
-
* @param data
|
|
16119
|
-
*/
|
|
16120
|
-
async set(data) {
|
|
16121
|
-
if (typeof data === "string") {
|
|
16122
|
-
if (typeof global !== "undefined") {
|
|
16123
|
-
const packageName = "fs";
|
|
16124
|
-
const { default: fs2 } = await import(
|
|
16125
|
-
/* @vite-ignore */
|
|
16126
|
-
packageName
|
|
16127
|
-
);
|
|
16128
|
-
const buffer = fs2.readFileSync(data);
|
|
16129
|
-
const json = JSON.parse(buffer.toString("utf-8"));
|
|
16130
|
-
this.set(json);
|
|
16131
|
-
return;
|
|
16132
|
-
} else {
|
|
16133
|
-
throw new Error("非node环境不允许使用路径");
|
|
16134
|
-
}
|
|
16135
|
-
}
|
|
16136
|
-
this.data = data;
|
|
16137
|
-
this.updateModel();
|
|
16138
|
-
}
|
|
16139
|
-
/**
|
|
16140
|
-
* 设置射线辅助
|
|
16141
|
-
*/
|
|
16142
|
-
racasterHelper(position, direction, far) {
|
|
16143
|
-
this.raylines.push([
|
|
16144
|
-
position.clone(),
|
|
16145
|
-
position.clone().add(direction.clone().multiplyScalar(far))
|
|
16146
|
-
]);
|
|
16147
|
-
direction.z = 0;
|
|
16148
|
-
this.raylines.push([
|
|
16149
|
-
position.clone(),
|
|
16150
|
-
position.clone().add(direction.clone().multiplyScalar(far))
|
|
16151
|
-
]);
|
|
16152
|
-
}
|
|
16153
|
-
_timer = null;
|
|
16154
|
-
/**
|
|
16155
|
-
* 更新模型
|
|
16156
|
-
*/
|
|
16157
|
-
updateModel() {
|
|
16158
|
-
if (this._timer) clearTimeout(this._timer);
|
|
16159
|
-
this._timer = setTimeout(() => {
|
|
16160
|
-
this._timer = null;
|
|
16161
|
-
const whiteModel = this.parent?.findComponentByName("WhiteModel");
|
|
16162
|
-
this.raylines.length = 0;
|
|
16163
|
-
this.desPoints.length = 0;
|
|
16164
|
-
this.data.forEach((item) => {
|
|
16165
|
-
const position = new THREE.Vector3(
|
|
16166
|
-
item.position.x,
|
|
16167
|
-
item.position.y,
|
|
16168
|
-
item.position.z
|
|
16169
|
-
);
|
|
16170
|
-
const direction = new THREE.Vector3(
|
|
16171
|
-
item.direction.x,
|
|
16172
|
-
item.direction.y,
|
|
16173
|
-
item.direction.z
|
|
16174
|
-
);
|
|
16175
|
-
const far = 100;
|
|
16176
|
-
this.racasterHelper(position, direction, far);
|
|
16177
|
-
direction.z = 0;
|
|
16178
|
-
const raycaster = new THREE.Raycaster(position, direction, 0, far);
|
|
16179
|
-
const list = raycaster.intersectObject(whiteModel.originalWhiteMode);
|
|
16180
|
-
if (list.length) {
|
|
16181
|
-
const { point } = list[0];
|
|
16182
|
-
this.desPoints.push({
|
|
16183
|
-
message: item.desc,
|
|
16184
|
-
position,
|
|
16185
|
-
intersection: point
|
|
16186
|
-
});
|
|
16187
|
-
}
|
|
16188
|
-
});
|
|
16189
|
-
this.dispatchEvent({
|
|
16190
|
-
type: "handleSuccess",
|
|
16191
|
-
desPoints: this.desPoints
|
|
16192
|
-
});
|
|
16193
|
-
}, 50);
|
|
16194
|
-
}
|
|
16195
|
-
}
|
|
16196
15390
|
class DxfLineModel extends Component {
|
|
16197
15391
|
static name = "DxfLineModel";
|
|
16198
15392
|
dxfLineModel = new THREE.LineSegments();
|
|
@@ -16203,16 +15397,22 @@ class DxfLineModel extends Component {
|
|
|
16203
15397
|
this.dxfModelGroup.add(this.dxfLineModel);
|
|
16204
15398
|
this.dxfModelGroup.add(this.dxfDoorsLineModel);
|
|
16205
15399
|
this.dxfDoorsLineModel.material = new THREE.LineBasicMaterial({ color: 16776960, vertexColors: true });
|
|
16206
|
-
dxf?.addEventListener("
|
|
15400
|
+
dxf?.addEventListener("cadChange", () => this.updateMode());
|
|
16207
15401
|
}
|
|
16208
15402
|
updateMode() {
|
|
16209
15403
|
const dxf = this.parent?.findComponentByName("Dxf");
|
|
16210
15404
|
this.dxfLineModel.clear();
|
|
16211
|
-
const
|
|
15405
|
+
const cad = dxf.cad;
|
|
15406
|
+
const dxfArray = new Float32Array(
|
|
15407
|
+
cad.groups.flatMap((group2) => {
|
|
15408
|
+
if (group2.type !== "unionGroupAll") return [];
|
|
15409
|
+
return group2.lines.flatMap((line) => line.points.flatMap((p) => [p.x, p.y, 0]));
|
|
15410
|
+
})
|
|
15411
|
+
);
|
|
16212
15412
|
this.dxfLineModel.geometry = new THREE.BufferGeometry().setAttribute("position", new THREE.BufferAttribute(dxfArray, 3, true));
|
|
16213
15413
|
const doorsArray = new Float32Array(
|
|
16214
15414
|
dxf.doorLineSegment.flatMap(({ start, end }) => [start.x, start.y, 0, end.x, end.y, 0])
|
|
16215
|
-
)
|
|
15415
|
+
);
|
|
16216
15416
|
const doorsColorArray = new Float32Array(dxf.doorLineSegment.flatMap(() => [1, 0, 0, 0, 1, 0]));
|
|
16217
15417
|
this.dxfDoorsLineModel.geometry = new THREE.BufferGeometry().setAttribute("position", new THREE.BufferAttribute(doorsArray, 3, true)).setAttribute("color", new THREE.BufferAttribute(doorsColorArray, 3));
|
|
16218
15418
|
this.dxfModelGroup.position.z = dxf.originalZAverage;
|
|
@@ -16224,19 +15424,16 @@ class DxfLineModel extends Component {
|
|
|
16224
15424
|
}
|
|
16225
15425
|
const index$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
16226
15426
|
__proto__: null,
|
|
16227
|
-
DetailsPoint,
|
|
16228
15427
|
DxfLineModel,
|
|
16229
15428
|
WhiteModel
|
|
16230
15429
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
16231
15430
|
function ModelDataPlugin_(dxfSystem, option = {}) {
|
|
16232
15431
|
const {
|
|
16233
|
-
detailsPoint = true,
|
|
16234
15432
|
whiteModel = true,
|
|
16235
15433
|
dxfLineModel = true
|
|
16236
15434
|
} = option;
|
|
16237
15435
|
dxfLineModel && dxfSystem.addComponent(new DxfLineModel());
|
|
16238
15436
|
whiteModel && dxfSystem.addComponent(new WhiteModel());
|
|
16239
|
-
detailsPoint && dxfSystem.addComponent(new DetailsPoint());
|
|
16240
15437
|
}
|
|
16241
15438
|
const ModelDataPlugin = Object.assign(ModelDataPlugin_, {
|
|
16242
15439
|
create(option = {}) {
|
|
@@ -16637,12 +15834,9 @@ async function createEditor(dom, camera, orbitControls = false, viewPermission)
|
|
|
16637
15834
|
const rp = await loadRenderPlugin();
|
|
16638
15835
|
const editor = await loadEditorPlugin();
|
|
16639
15836
|
const dxfSystem = new DxfSystem().usePlugin(mp.ModelDataPlugin.create({
|
|
16640
|
-
detailsPoint: false,
|
|
16641
15837
|
whiteModel: true
|
|
16642
15838
|
})).usePlugin(rp.RenderPlugin.create({
|
|
16643
|
-
originalLine: false,
|
|
16644
15839
|
modelData: false,
|
|
16645
|
-
detailsPoint: false,
|
|
16646
15840
|
orbitControls,
|
|
16647
15841
|
camera
|
|
16648
15842
|
})).usePlugin(editor.EditorPlugin.create({ viewPermission }));
|
|
@@ -16686,45 +15880,44 @@ async function buildJson(opt) {
|
|
|
16686
15880
|
dxfSystem.usePlugin(mp.ModelDataPlugin);
|
|
16687
15881
|
const whiteModel = dxfSystem.findComponentByType(mp.components.WhiteModel);
|
|
16688
15882
|
const threeVJia = dxfSystem.findComponentByName("ThreeVJia");
|
|
16689
|
-
|
|
16690
|
-
|
|
16691
|
-
if (typeof trajectory === "string") {
|
|
15883
|
+
if (itemInfo) {
|
|
15884
|
+
if (typeof itemInfo === "string") {
|
|
16692
15885
|
if (typeof global !== "undefined") {
|
|
16693
15886
|
const packageName = "fs";
|
|
16694
15887
|
const { default: fs2 } = await import(
|
|
16695
15888
|
/* @vite-ignore */
|
|
16696
15889
|
packageName
|
|
16697
15890
|
);
|
|
16698
|
-
const buffer = fs2.readFileSync(
|
|
16699
|
-
|
|
15891
|
+
const buffer = fs2.readFileSync(itemInfo);
|
|
15892
|
+
itemInfo = JSON.parse(buffer.toString("utf-8"));
|
|
16700
15893
|
} else throw new Error("非node环境不允许使用路径");
|
|
16701
15894
|
}
|
|
16702
|
-
|
|
15895
|
+
whiteModel?.setItemList(itemInfo);
|
|
16703
15896
|
}
|
|
16704
|
-
if (
|
|
16705
|
-
|
|
15897
|
+
if (opt.axisAlignCorr !== false) dxfSystem.Dxf.addPreProcessor(PRE_PROCESSOR.AxisAlignCorr);
|
|
15898
|
+
if (trajectory) {
|
|
15899
|
+
if (typeof trajectory === "string") {
|
|
16706
15900
|
if (typeof global !== "undefined") {
|
|
16707
15901
|
const packageName = "fs";
|
|
16708
15902
|
const { default: fs2 } = await import(
|
|
16709
15903
|
/* @vite-ignore */
|
|
16710
15904
|
packageName
|
|
16711
15905
|
);
|
|
16712
|
-
const buffer = fs2.readFileSync(
|
|
16713
|
-
|
|
15906
|
+
const buffer = fs2.readFileSync(trajectory);
|
|
15907
|
+
trajectory = JSON.parse(buffer.toString("utf-8"));
|
|
16714
15908
|
} else throw new Error("非node环境不允许使用路径");
|
|
16715
15909
|
}
|
|
16716
|
-
|
|
15910
|
+
dxfSystem.CorrectionDxf.setTrajectory(trajectory);
|
|
16717
15911
|
}
|
|
16718
|
-
await dxfSystem.Dxf.
|
|
15912
|
+
await dxfSystem.Dxf.set(json, {
|
|
16719
15913
|
groupMethod: "cross",
|
|
16720
15914
|
fittingMethod: "max",
|
|
16721
15915
|
crossAxistThreshold: 0.08,
|
|
16722
15916
|
...axisAlignCorrOption
|
|
16723
15917
|
});
|
|
16724
|
-
dxfSystem.Dxf.lineOffset();
|
|
16725
15918
|
download?.json && await dxfSystem.Dxf.downloadOriginalData(download.json);
|
|
16726
|
-
download?.dxf && await dxfSystem.Dxf.
|
|
16727
|
-
download?.image && await dxfSystem.Dxf.
|
|
15919
|
+
download?.dxf && await dxfSystem.Dxf.downloadDxf(download.dxf);
|
|
15920
|
+
download?.image && await dxfSystem.Dxf.downloadDxfImage(download.image);
|
|
16728
15921
|
download?.correctionJson && await dxfSystem.CorrectionDxf.downloadOriginalData(download.correctionJson);
|
|
16729
15922
|
download?.correctionDxf && await dxfSystem.CorrectionDxf.downloadDxf(download.correctionDxf);
|
|
16730
15923
|
download?.correctionImage && await dxfSystem.CorrectionDxf.downloadDxfImage(download.correctionImage);
|
|
@@ -16740,7 +15933,7 @@ async function buildJson(opt) {
|
|
|
16740
15933
|
async function getFileAll(dxfSystem = gloabalDxfSystem) {
|
|
16741
15934
|
const whiteModel = dxfSystem.findComponentByName("WhiteModel");
|
|
16742
15935
|
const jpg = new File([await dxfSystem.CorrectionDxf.toDxfImageBlob()], "img.jpg", { type: "image/jpeg" });
|
|
16743
|
-
const dxf = new File([dxfSystem.Dxf.toDxfBlob()], "dxf.dxf", { type: "application/dxf" });
|
|
15936
|
+
const dxf = new File([dxfSystem.Dxf.toDxfBlob() ?? ""], "dxf.dxf", { type: "application/dxf" });
|
|
16744
15937
|
const correctionDxf = new File([dxfSystem.CorrectionDxf.toDxfBlob() ?? ""], "dxf.dxf", { type: "application/dxf" });
|
|
16745
15938
|
const glb = new File([await whiteModel.toGltfBlob(true)], "model.glb", { type: "application/octet-stream" });
|
|
16746
15939
|
const gltf2 = new File([await whiteModel.toGltfBlob(false)], "model.gltf", { type: "application/json" });
|
|
@@ -16763,29 +15956,28 @@ export {
|
|
|
16763
15956
|
Box2 as B,
|
|
16764
15957
|
Component as C,
|
|
16765
15958
|
DxfSystem as D,
|
|
16766
|
-
|
|
15959
|
+
LineSegment as L,
|
|
16767
15960
|
ModelDataPlugin as M,
|
|
16768
|
-
|
|
15961
|
+
PointVirtualGrid as P,
|
|
16769
15962
|
Quadtree as Q,
|
|
16770
15963
|
SelectLocalFile as S,
|
|
16771
15964
|
ThreeVJia as T,
|
|
16772
15965
|
Variable as V,
|
|
16773
15966
|
WhiteModel as W,
|
|
16774
|
-
|
|
16775
|
-
|
|
15967
|
+
Point as a,
|
|
15968
|
+
DoorsAnalysisComponent as b,
|
|
16776
15969
|
cloneUserData as c,
|
|
16777
|
-
|
|
16778
|
-
|
|
16779
|
-
|
|
16780
|
-
|
|
16781
|
-
|
|
16782
|
-
|
|
16783
|
-
|
|
16784
|
-
|
|
16785
|
-
|
|
16786
|
-
index
|
|
16787
|
-
|
|
16788
|
-
components as o,
|
|
15970
|
+
Lines as d,
|
|
15971
|
+
CommandManager as e,
|
|
15972
|
+
createEditor as f,
|
|
15973
|
+
getModels as g,
|
|
15974
|
+
buildJson as h,
|
|
15975
|
+
getFileAll as i,
|
|
15976
|
+
getGlobalDxfSystem as j,
|
|
15977
|
+
Dxf as k,
|
|
15978
|
+
index$1 as l,
|
|
15979
|
+
index as m,
|
|
15980
|
+
components as n,
|
|
16789
15981
|
recomputedWindow as r,
|
|
16790
15982
|
uuid as u
|
|
16791
15983
|
};
|