build-dxf 0.1.8 → 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 +663 -1472
- 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;
|
|
@@ -8060,10 +7331,17 @@ class Scenario {
|
|
|
8060
7331
|
this.closedArray = lines.filter((item) => {
|
|
8061
7332
|
return LineGroupType.hasType(item, "doubleWall");
|
|
8062
7333
|
});
|
|
8063
|
-
|
|
7334
|
+
let groups = LineSegment.groupByPath(this.closedArray);
|
|
8064
7335
|
const set2 = new Set(this.closedArray);
|
|
8065
7336
|
let singleLineWall = lines.filter((line) => !set2.has(line) && !line.userData.isDoor && !line.userData.isBayWindow);
|
|
8066
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
|
+
});
|
|
8067
7345
|
this.TheHandlingOfTheDoor(menList);
|
|
8068
7346
|
this.overallTreatmentOfSingleLineWalls(singleLineWall);
|
|
8069
7347
|
for (const g in groups) {
|
|
@@ -8166,15 +7444,13 @@ class Scenario {
|
|
|
8166
7444
|
const geometry = this.createParallelepipedFromBase(basePoints, 2.8);
|
|
8167
7445
|
const material = new THREE.MeshStandardMaterial({
|
|
8168
7446
|
color: this.color,
|
|
8169
|
-
side: THREE.DoubleSide
|
|
8170
|
-
//
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
|
|
8174
|
-
|
|
8175
|
-
|
|
8176
|
-
polygonOffsetUnits: 10
|
|
8177
|
-
// 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,
|
|
8178
7454
|
});
|
|
8179
7455
|
const cube = new THREE.Mesh(geometry, material);
|
|
8180
7456
|
const edges = new THREE.EdgesGeometry(geometry);
|
|
@@ -8471,14 +7747,13 @@ class Scenario {
|
|
|
8471
7747
|
const geometry = this.createParallelepipedFromBase(basePoints, Height ? Height : this.WindowHeight);
|
|
8472
7748
|
const material = new THREE.MeshStandardMaterial({
|
|
8473
7749
|
color: this.color,
|
|
8474
|
-
side: THREE.DoubleSide
|
|
8475
|
-
//
|
|
8476
|
-
|
|
8477
|
-
|
|
8478
|
-
|
|
8479
|
-
|
|
8480
|
-
|
|
8481
|
-
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,
|
|
8482
7757
|
});
|
|
8483
7758
|
const brush1 = new Brush(mesh.geometry);
|
|
8484
7759
|
brush1.updateMatrixWorld();
|
|
@@ -8524,25 +7799,23 @@ class Scenario {
|
|
|
8524
7799
|
const result = evaluator.evaluate(brush1, brush2, SUBTRACTION);
|
|
8525
7800
|
const material = new THREE.MeshStandardMaterial({
|
|
8526
7801
|
color: this.color,
|
|
8527
|
-
side: THREE.DoubleSide
|
|
8528
|
-
//
|
|
8529
|
-
|
|
8530
|
-
|
|
8531
|
-
|
|
8532
|
-
|
|
8533
|
-
|
|
8534
|
-
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,
|
|
8535
7809
|
});
|
|
8536
7810
|
const material1 = new THREE.MeshStandardMaterial({
|
|
8537
7811
|
color: this.color,
|
|
8538
|
-
side: THREE.DoubleSide
|
|
8539
|
-
//
|
|
8540
|
-
|
|
8541
|
-
|
|
8542
|
-
|
|
8543
|
-
|
|
8544
|
-
|
|
8545
|
-
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,
|
|
8546
7819
|
});
|
|
8547
7820
|
result.material = material1;
|
|
8548
7821
|
new THREE.Mesh(geometry2, material);
|
|
@@ -15842,9 +15115,9 @@ class SceneAutoGenerat {
|
|
|
15842
15115
|
});
|
|
15843
15116
|
const contour = Point.fromByList(item.contour ?? []), rectangle = new Polygon(Qa(contour.map((p) => [p.x, p.y])).map((p) => Point.from(p)));
|
|
15844
15117
|
rectangle.pop();
|
|
15845
|
-
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);
|
|
15846
15119
|
const group2 = new THREE.Group();
|
|
15847
|
-
group2.position.set(center.x, center.y,
|
|
15120
|
+
group2.position.set(center.x, center.y, z);
|
|
15848
15121
|
group2.add(model);
|
|
15849
15122
|
this.scene.add(group2);
|
|
15850
15123
|
const box32 = new THREE.Box3();
|
|
@@ -15866,7 +15139,7 @@ class SceneAutoGenerat {
|
|
|
15866
15139
|
const direction2 = point1.y < point2.y ? point1.direction(point2) : point2.direction(point1);
|
|
15867
15140
|
group2.rotateZ(direction2.angleBetween2(direction));
|
|
15868
15141
|
this.scene.add(
|
|
15869
|
-
SceneAutoGenerat.itemParse(item
|
|
15142
|
+
SceneAutoGenerat.itemParse(item).box
|
|
15870
15143
|
);
|
|
15871
15144
|
}
|
|
15872
15145
|
/** 构建物品模型
|
|
@@ -15874,10 +15147,10 @@ class SceneAutoGenerat {
|
|
|
15874
15147
|
async buildItem() {
|
|
15875
15148
|
await Promise.all(this.itemList.map(async (item) => await this.getModel(item)));
|
|
15876
15149
|
}
|
|
15877
|
-
static itemParse(item
|
|
15150
|
+
static itemParse(item) {
|
|
15878
15151
|
const contour = Point.fromByList(item.contour), rectangle = new Polygon(Qa(contour.map((p) => [p.x, p.y])).map((p) => Point.from(p)));
|
|
15879
15152
|
rectangle.pop();
|
|
15880
|
-
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();
|
|
15881
15154
|
rectangle.forEach((p, i) => {
|
|
15882
15155
|
if (i === 0) shape.moveTo(p.x, p.y);
|
|
15883
15156
|
else shape.lineTo(p.x, p.y);
|
|
@@ -15890,11 +15163,34 @@ class SceneAutoGenerat {
|
|
|
15890
15163
|
lineSegments.position.z = z;
|
|
15891
15164
|
box3.setFromObject(lineSegments);
|
|
15892
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;
|
|
15893
15169
|
return {
|
|
15894
15170
|
box: lineSegments,
|
|
15895
15171
|
center,
|
|
15896
15172
|
category: item.category,
|
|
15897
|
-
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
|
+
]
|
|
15898
15194
|
};
|
|
15899
15195
|
}
|
|
15900
15196
|
}
|
|
@@ -15927,8 +15223,6 @@ class WhiteModel extends Component {
|
|
|
15927
15223
|
whiteModelGroup = new THREE.Group();
|
|
15928
15224
|
// dxf数据白模边缘线
|
|
15929
15225
|
whiteModelLineGroup = new THREE.Group();
|
|
15930
|
-
// 原始数据白模
|
|
15931
|
-
originalWhiteMode = new THREE.Group();
|
|
15932
15226
|
material = new THREE.MeshStandardMaterial({ color: 16777215, transparent: true, opacity: 0.8, side: THREE.DoubleSide });
|
|
15933
15227
|
itemList = [];
|
|
15934
15228
|
promise;
|
|
@@ -15942,8 +15236,7 @@ class WhiteModel extends Component {
|
|
|
15942
15236
|
onAddFromParent(parent) {
|
|
15943
15237
|
this.Dxf = parent.findComponentByName("Dxf");
|
|
15944
15238
|
this.Variable = parent.findComponentByName("Variable");
|
|
15945
|
-
this.
|
|
15946
|
-
this.Dxf?.addEventListener("lineOffset", () => {
|
|
15239
|
+
this.Dxf?.addEventListener("cadChange", () => {
|
|
15947
15240
|
this.promise = this.updateModel();
|
|
15948
15241
|
});
|
|
15949
15242
|
}
|
|
@@ -15951,12 +15244,10 @@ class WhiteModel extends Component {
|
|
|
15951
15244
|
const dxfSystem = this.parent;
|
|
15952
15245
|
this.Variable?.set("whiteModelVisible", false);
|
|
15953
15246
|
const dxf = this.Dxf;
|
|
15954
|
-
this.originalWhiteMode.clear();
|
|
15955
15247
|
this.whiteModelGroup.clear();
|
|
15956
15248
|
this.whiteModelLineGroup.clear();
|
|
15957
15249
|
this.whiteModelGroup.add(this.whiteModelLineGroup);
|
|
15958
15250
|
this.whiteModelGroup.position.z = dxf.originalZAverage;
|
|
15959
|
-
this.originalWhiteMode.position.z = dxf.originalZAverage;
|
|
15960
15251
|
const lines = dxfSystem.Dxf.getLineSegments(true);
|
|
15961
15252
|
const sceneAutoGenerat = new SceneAutoGenerat(lines, this.itemList, dxfSystem.Dxf.originalZAverage, dxfSystem.CorrectionDxf.trajectory);
|
|
15962
15253
|
await sceneAutoGenerat.init();
|
|
@@ -15965,7 +15256,7 @@ class WhiteModel extends Component {
|
|
|
15965
15256
|
this.whiteModelLineGroup.add(group2.clone(true));
|
|
15966
15257
|
}
|
|
15967
15258
|
const walls = dxf.originalData.map(({ start, end, insetionArr }) => {
|
|
15968
|
-
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);
|
|
15969
15260
|
return {
|
|
15970
15261
|
points,
|
|
15971
15262
|
indices,
|
|
@@ -15985,12 +15276,9 @@ class WhiteModel extends Component {
|
|
|
15985
15276
|
bevelSize: 0
|
|
15986
15277
|
});
|
|
15987
15278
|
if (geometry.attributes.position.array.filter((num) => Number.isNaN(num)).length) return;
|
|
15988
|
-
const mesh = new THREE.Mesh(geometry);
|
|
15989
|
-
this.originalWhiteMode?.add(mesh);
|
|
15990
15279
|
});
|
|
15991
15280
|
this.dispatchEvent({
|
|
15992
15281
|
type: "updateModel",
|
|
15993
|
-
originalWhiteMode: this.originalWhiteMode,
|
|
15994
15282
|
whiteModelGroup: this.whiteModelGroup
|
|
15995
15283
|
});
|
|
15996
15284
|
return this.whiteModelLineGroup;
|
|
@@ -16099,101 +15387,6 @@ class WhiteModel extends Component {
|
|
|
16099
15387
|
}
|
|
16100
15388
|
}
|
|
16101
15389
|
}
|
|
16102
|
-
class DetailsPoint extends Component {
|
|
16103
|
-
static name = "DetailsPoint";
|
|
16104
|
-
Dxf = null;
|
|
16105
|
-
WhiteModel = null;
|
|
16106
|
-
Variable = null;
|
|
16107
|
-
desPoints = [];
|
|
16108
|
-
raylines = [];
|
|
16109
|
-
data = [];
|
|
16110
|
-
onAddFromParent(parent) {
|
|
16111
|
-
this.Dxf = parent.findComponentByName("Dxf");
|
|
16112
|
-
this.Variable = parent.findComponentByName("Variable");
|
|
16113
|
-
this.Dxf?.addEventListener("setDta", () => {
|
|
16114
|
-
this.updateModel();
|
|
16115
|
-
});
|
|
16116
|
-
}
|
|
16117
|
-
/**
|
|
16118
|
-
* 设置值
|
|
16119
|
-
* @param data
|
|
16120
|
-
*/
|
|
16121
|
-
async set(data) {
|
|
16122
|
-
if (typeof data === "string") {
|
|
16123
|
-
if (typeof global !== "undefined") {
|
|
16124
|
-
const packageName = "fs";
|
|
16125
|
-
const { default: fs2 } = await import(
|
|
16126
|
-
/* @vite-ignore */
|
|
16127
|
-
packageName
|
|
16128
|
-
);
|
|
16129
|
-
const buffer = fs2.readFileSync(data);
|
|
16130
|
-
const json = JSON.parse(buffer.toString("utf-8"));
|
|
16131
|
-
this.set(json);
|
|
16132
|
-
return;
|
|
16133
|
-
} else {
|
|
16134
|
-
throw new Error("非node环境不允许使用路径");
|
|
16135
|
-
}
|
|
16136
|
-
}
|
|
16137
|
-
this.data = data;
|
|
16138
|
-
this.updateModel();
|
|
16139
|
-
}
|
|
16140
|
-
/**
|
|
16141
|
-
* 设置射线辅助
|
|
16142
|
-
*/
|
|
16143
|
-
racasterHelper(position, direction, far) {
|
|
16144
|
-
this.raylines.push([
|
|
16145
|
-
position.clone(),
|
|
16146
|
-
position.clone().add(direction.clone().multiplyScalar(far))
|
|
16147
|
-
]);
|
|
16148
|
-
direction.z = 0;
|
|
16149
|
-
this.raylines.push([
|
|
16150
|
-
position.clone(),
|
|
16151
|
-
position.clone().add(direction.clone().multiplyScalar(far))
|
|
16152
|
-
]);
|
|
16153
|
-
}
|
|
16154
|
-
_timer = null;
|
|
16155
|
-
/**
|
|
16156
|
-
* 更新模型
|
|
16157
|
-
*/
|
|
16158
|
-
updateModel() {
|
|
16159
|
-
if (this._timer) clearTimeout(this._timer);
|
|
16160
|
-
this._timer = setTimeout(() => {
|
|
16161
|
-
this._timer = null;
|
|
16162
|
-
const whiteModel = this.parent?.findComponentByName("WhiteModel");
|
|
16163
|
-
this.raylines.length = 0;
|
|
16164
|
-
this.desPoints.length = 0;
|
|
16165
|
-
this.data.forEach((item) => {
|
|
16166
|
-
const position = new THREE.Vector3(
|
|
16167
|
-
item.position.x,
|
|
16168
|
-
item.position.y,
|
|
16169
|
-
item.position.z
|
|
16170
|
-
);
|
|
16171
|
-
const direction = new THREE.Vector3(
|
|
16172
|
-
item.direction.x,
|
|
16173
|
-
item.direction.y,
|
|
16174
|
-
item.direction.z
|
|
16175
|
-
);
|
|
16176
|
-
const far = 100;
|
|
16177
|
-
this.racasterHelper(position, direction, far);
|
|
16178
|
-
direction.z = 0;
|
|
16179
|
-
const raycaster = new THREE.Raycaster(position, direction, 0, far);
|
|
16180
|
-
const list = raycaster.intersectObject(whiteModel.originalWhiteMode);
|
|
16181
|
-
if (list.length) {
|
|
16182
|
-
const { point } = list[0];
|
|
16183
|
-
this.desPoints.push({
|
|
16184
|
-
message: item.desc,
|
|
16185
|
-
position,
|
|
16186
|
-
intersection: point
|
|
16187
|
-
});
|
|
16188
|
-
}
|
|
16189
|
-
});
|
|
16190
|
-
this.dispatchEvent({
|
|
16191
|
-
type: "handleSuccess",
|
|
16192
|
-
desPoints: this.desPoints
|
|
16193
|
-
});
|
|
16194
|
-
}, 50);
|
|
16195
|
-
}
|
|
16196
|
-
}
|
|
16197
15390
|
class DxfLineModel extends Component {
|
|
16198
15391
|
static name = "DxfLineModel";
|
|
16199
15392
|
dxfLineModel = new THREE.LineSegments();
|
|
@@ -16204,16 +15397,22 @@ class DxfLineModel extends Component {
|
|
|
16204
15397
|
this.dxfModelGroup.add(this.dxfLineModel);
|
|
16205
15398
|
this.dxfModelGroup.add(this.dxfDoorsLineModel);
|
|
16206
15399
|
this.dxfDoorsLineModel.material = new THREE.LineBasicMaterial({ color: 16776960, vertexColors: true });
|
|
16207
|
-
dxf?.addEventListener("
|
|
15400
|
+
dxf?.addEventListener("cadChange", () => this.updateMode());
|
|
16208
15401
|
}
|
|
16209
15402
|
updateMode() {
|
|
16210
15403
|
const dxf = this.parent?.findComponentByName("Dxf");
|
|
16211
15404
|
this.dxfLineModel.clear();
|
|
16212
|
-
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
|
+
);
|
|
16213
15412
|
this.dxfLineModel.geometry = new THREE.BufferGeometry().setAttribute("position", new THREE.BufferAttribute(dxfArray, 3, true));
|
|
16214
15413
|
const doorsArray = new Float32Array(
|
|
16215
15414
|
dxf.doorLineSegment.flatMap(({ start, end }) => [start.x, start.y, 0, end.x, end.y, 0])
|
|
16216
|
-
)
|
|
15415
|
+
);
|
|
16217
15416
|
const doorsColorArray = new Float32Array(dxf.doorLineSegment.flatMap(() => [1, 0, 0, 0, 1, 0]));
|
|
16218
15417
|
this.dxfDoorsLineModel.geometry = new THREE.BufferGeometry().setAttribute("position", new THREE.BufferAttribute(doorsArray, 3, true)).setAttribute("color", new THREE.BufferAttribute(doorsColorArray, 3));
|
|
16219
15418
|
this.dxfModelGroup.position.z = dxf.originalZAverage;
|
|
@@ -16225,19 +15424,16 @@ class DxfLineModel extends Component {
|
|
|
16225
15424
|
}
|
|
16226
15425
|
const index$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
16227
15426
|
__proto__: null,
|
|
16228
|
-
DetailsPoint,
|
|
16229
15427
|
DxfLineModel,
|
|
16230
15428
|
WhiteModel
|
|
16231
15429
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
16232
15430
|
function ModelDataPlugin_(dxfSystem, option = {}) {
|
|
16233
15431
|
const {
|
|
16234
|
-
detailsPoint = true,
|
|
16235
15432
|
whiteModel = true,
|
|
16236
15433
|
dxfLineModel = true
|
|
16237
15434
|
} = option;
|
|
16238
15435
|
dxfLineModel && dxfSystem.addComponent(new DxfLineModel());
|
|
16239
15436
|
whiteModel && dxfSystem.addComponent(new WhiteModel());
|
|
16240
|
-
detailsPoint && dxfSystem.addComponent(new DetailsPoint());
|
|
16241
15437
|
}
|
|
16242
15438
|
const ModelDataPlugin = Object.assign(ModelDataPlugin_, {
|
|
16243
15439
|
create(option = {}) {
|
|
@@ -16638,12 +15834,9 @@ async function createEditor(dom, camera, orbitControls = false, viewPermission)
|
|
|
16638
15834
|
const rp = await loadRenderPlugin();
|
|
16639
15835
|
const editor = await loadEditorPlugin();
|
|
16640
15836
|
const dxfSystem = new DxfSystem().usePlugin(mp.ModelDataPlugin.create({
|
|
16641
|
-
detailsPoint: false,
|
|
16642
15837
|
whiteModel: true
|
|
16643
15838
|
})).usePlugin(rp.RenderPlugin.create({
|
|
16644
|
-
originalLine: false,
|
|
16645
15839
|
modelData: false,
|
|
16646
|
-
detailsPoint: false,
|
|
16647
15840
|
orbitControls,
|
|
16648
15841
|
camera
|
|
16649
15842
|
})).usePlugin(editor.EditorPlugin.create({ viewPermission }));
|
|
@@ -16687,45 +15880,44 @@ async function buildJson(opt) {
|
|
|
16687
15880
|
dxfSystem.usePlugin(mp.ModelDataPlugin);
|
|
16688
15881
|
const whiteModel = dxfSystem.findComponentByType(mp.components.WhiteModel);
|
|
16689
15882
|
const threeVJia = dxfSystem.findComponentByName("ThreeVJia");
|
|
16690
|
-
|
|
16691
|
-
|
|
16692
|
-
if (typeof trajectory === "string") {
|
|
15883
|
+
if (itemInfo) {
|
|
15884
|
+
if (typeof itemInfo === "string") {
|
|
16693
15885
|
if (typeof global !== "undefined") {
|
|
16694
15886
|
const packageName = "fs";
|
|
16695
15887
|
const { default: fs2 } = await import(
|
|
16696
15888
|
/* @vite-ignore */
|
|
16697
15889
|
packageName
|
|
16698
15890
|
);
|
|
16699
|
-
const buffer = fs2.readFileSync(
|
|
16700
|
-
|
|
15891
|
+
const buffer = fs2.readFileSync(itemInfo);
|
|
15892
|
+
itemInfo = JSON.parse(buffer.toString("utf-8"));
|
|
16701
15893
|
} else throw new Error("非node环境不允许使用路径");
|
|
16702
15894
|
}
|
|
16703
|
-
|
|
15895
|
+
whiteModel?.setItemList(itemInfo);
|
|
16704
15896
|
}
|
|
16705
|
-
if (
|
|
16706
|
-
|
|
15897
|
+
if (opt.axisAlignCorr !== false) dxfSystem.Dxf.addPreProcessor(PRE_PROCESSOR.AxisAlignCorr);
|
|
15898
|
+
if (trajectory) {
|
|
15899
|
+
if (typeof trajectory === "string") {
|
|
16707
15900
|
if (typeof global !== "undefined") {
|
|
16708
15901
|
const packageName = "fs";
|
|
16709
15902
|
const { default: fs2 } = await import(
|
|
16710
15903
|
/* @vite-ignore */
|
|
16711
15904
|
packageName
|
|
16712
15905
|
);
|
|
16713
|
-
const buffer = fs2.readFileSync(
|
|
16714
|
-
|
|
15906
|
+
const buffer = fs2.readFileSync(trajectory);
|
|
15907
|
+
trajectory = JSON.parse(buffer.toString("utf-8"));
|
|
16715
15908
|
} else throw new Error("非node环境不允许使用路径");
|
|
16716
15909
|
}
|
|
16717
|
-
|
|
15910
|
+
dxfSystem.CorrectionDxf.setTrajectory(trajectory);
|
|
16718
15911
|
}
|
|
16719
|
-
await dxfSystem.Dxf.
|
|
15912
|
+
await dxfSystem.Dxf.set(json, {
|
|
16720
15913
|
groupMethod: "cross",
|
|
16721
15914
|
fittingMethod: "max",
|
|
16722
15915
|
crossAxistThreshold: 0.08,
|
|
16723
15916
|
...axisAlignCorrOption
|
|
16724
15917
|
});
|
|
16725
|
-
dxfSystem.Dxf.lineOffset();
|
|
16726
15918
|
download?.json && await dxfSystem.Dxf.downloadOriginalData(download.json);
|
|
16727
|
-
download?.dxf && await dxfSystem.Dxf.
|
|
16728
|
-
download?.image && await dxfSystem.Dxf.
|
|
15919
|
+
download?.dxf && await dxfSystem.Dxf.downloadDxf(download.dxf);
|
|
15920
|
+
download?.image && await dxfSystem.Dxf.downloadDxfImage(download.image);
|
|
16729
15921
|
download?.correctionJson && await dxfSystem.CorrectionDxf.downloadOriginalData(download.correctionJson);
|
|
16730
15922
|
download?.correctionDxf && await dxfSystem.CorrectionDxf.downloadDxf(download.correctionDxf);
|
|
16731
15923
|
download?.correctionImage && await dxfSystem.CorrectionDxf.downloadDxfImage(download.correctionImage);
|
|
@@ -16741,7 +15933,7 @@ async function buildJson(opt) {
|
|
|
16741
15933
|
async function getFileAll(dxfSystem = gloabalDxfSystem) {
|
|
16742
15934
|
const whiteModel = dxfSystem.findComponentByName("WhiteModel");
|
|
16743
15935
|
const jpg = new File([await dxfSystem.CorrectionDxf.toDxfImageBlob()], "img.jpg", { type: "image/jpeg" });
|
|
16744
|
-
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" });
|
|
16745
15937
|
const correctionDxf = new File([dxfSystem.CorrectionDxf.toDxfBlob() ?? ""], "dxf.dxf", { type: "application/dxf" });
|
|
16746
15938
|
const glb = new File([await whiteModel.toGltfBlob(true)], "model.glb", { type: "application/octet-stream" });
|
|
16747
15939
|
const gltf2 = new File([await whiteModel.toGltfBlob(false)], "model.gltf", { type: "application/json" });
|
|
@@ -16764,29 +15956,28 @@ export {
|
|
|
16764
15956
|
Box2 as B,
|
|
16765
15957
|
Component as C,
|
|
16766
15958
|
DxfSystem as D,
|
|
16767
|
-
|
|
15959
|
+
LineSegment as L,
|
|
16768
15960
|
ModelDataPlugin as M,
|
|
16769
|
-
|
|
15961
|
+
PointVirtualGrid as P,
|
|
16770
15962
|
Quadtree as Q,
|
|
16771
15963
|
SelectLocalFile as S,
|
|
16772
15964
|
ThreeVJia as T,
|
|
16773
15965
|
Variable as V,
|
|
16774
15966
|
WhiteModel as W,
|
|
16775
|
-
|
|
16776
|
-
|
|
15967
|
+
Point as a,
|
|
15968
|
+
DoorsAnalysisComponent as b,
|
|
16777
15969
|
cloneUserData as c,
|
|
16778
|
-
|
|
16779
|
-
|
|
16780
|
-
|
|
16781
|
-
|
|
16782
|
-
|
|
16783
|
-
|
|
16784
|
-
|
|
16785
|
-
|
|
16786
|
-
|
|
16787
|
-
index
|
|
16788
|
-
|
|
16789
|
-
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,
|
|
16790
15981
|
recomputedWindow as r,
|
|
16791
15982
|
uuid as u
|
|
16792
15983
|
};
|