build-dxf 0.1.107 → 0.1.109
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.js +229 -187
- package/src/dxfSystem/components/Dxf.d.ts +1 -1
- package/src/dxfSystem/plugins/editor/components/UIService.d.ts +1 -0
- package/src/dxfSystem/plugins/editor/pages/EditorTool/EditorTool.vue.d.ts +1 -1
- package/src/dxfSystem/plugins/index.d.ts +1 -0
- package/src/dxfSystem/utils/CAD.d.ts +1 -9
- package/src/dxfSystem/utils/index.d.ts +1 -1
- package/src/dxfSystem/utils/{DoubleWallHelper.d.ts → linePipeline/builtin/DoubleWallHelper.d.ts} +3 -3
- package/src/dxfSystem/utils/linePipeline/index.d.ts +3 -3
- package/src/index.css +2 -2
- package/src/index3.js +53 -26
- package/src/utils/algorithms/LineSegmentUtils.d.ts +5 -0
package/package.json
CHANGED
package/src/build.js
CHANGED
|
@@ -905,6 +905,7 @@ class LineSegment {
|
|
|
905
905
|
* @returns
|
|
906
906
|
*/
|
|
907
907
|
intersectLineSegment(line, endpoint = true) {
|
|
908
|
+
const EPSILON = 1e-10;
|
|
908
909
|
const p1 = this.start;
|
|
909
910
|
const p2 = this.end;
|
|
910
911
|
const p3 = line.start;
|
|
@@ -913,7 +914,7 @@ class LineSegment {
|
|
|
913
914
|
return (b4.x - a2.x) * (c.y - a2.y) - (b4.y - a2.y) * (c.x - a2.x);
|
|
914
915
|
}
|
|
915
916
|
function isPointOnSegment(pt2, segStart, segEnd) {
|
|
916
|
-
return Math.min(segStart.x, segEnd.x) -
|
|
917
|
+
return Math.min(segStart.x, segEnd.x) - EPSILON <= pt2.x && pt2.x <= Math.max(segStart.x, segEnd.x) + EPSILON && Math.min(segStart.y, segEnd.y) - EPSILON <= pt2.y && pt2.y <= Math.max(segStart.y, segEnd.y) + EPSILON;
|
|
917
918
|
}
|
|
918
919
|
const d1 = crossProduct(p1, p2, p3);
|
|
919
920
|
const d2 = crossProduct(p1, p2, p4);
|
|
@@ -923,16 +924,16 @@ class LineSegment {
|
|
|
923
924
|
return true;
|
|
924
925
|
}
|
|
925
926
|
if (endpoint) {
|
|
926
|
-
if (Math.abs(d1) <
|
|
927
|
+
if (Math.abs(d1) < EPSILON && isPointOnSegment(p3, p1, p2)) {
|
|
927
928
|
return true;
|
|
928
929
|
}
|
|
929
|
-
if (Math.abs(d2) <
|
|
930
|
+
if (Math.abs(d2) < EPSILON && isPointOnSegment(p4, p1, p2)) {
|
|
930
931
|
return true;
|
|
931
932
|
}
|
|
932
|
-
if (Math.abs(d3) <
|
|
933
|
+
if (Math.abs(d3) < EPSILON && isPointOnSegment(p1, p3, p4)) {
|
|
933
934
|
return true;
|
|
934
935
|
}
|
|
935
|
-
if (Math.abs(d4) <
|
|
936
|
+
if (Math.abs(d4) < EPSILON && isPointOnSegment(p2, p3, p4)) {
|
|
936
937
|
return true;
|
|
937
938
|
}
|
|
938
939
|
}
|
|
@@ -2460,7 +2461,11 @@ class WallInsertObject {
|
|
|
2460
2461
|
*/
|
|
2461
2462
|
static isDouble(line) {
|
|
2462
2463
|
if (line.userData.isPassageEntrance && line.userData.passageEntrance?.length) {
|
|
2463
|
-
return line.userData.passageEntrance.some((item) =>
|
|
2464
|
+
return line.userData.passageEntrance.some((item) => {
|
|
2465
|
+
const nearId = this.getNearId(item);
|
|
2466
|
+
const id = this.getId(item);
|
|
2467
|
+
return typeof nearId === "number" && typeof id === "number" && id !== nearId;
|
|
2468
|
+
});
|
|
2464
2469
|
}
|
|
2465
2470
|
return false;
|
|
2466
2471
|
}
|
|
@@ -3193,6 +3198,23 @@ class LineSegmentUtils {
|
|
|
3193
3198
|
}
|
|
3194
3199
|
return new Point(x / totalWeight, y / totalWeight);
|
|
3195
3200
|
}
|
|
3201
|
+
/** 自定义分组
|
|
3202
|
+
* @param lines
|
|
3203
|
+
* @returns
|
|
3204
|
+
*/
|
|
3205
|
+
static group(lines, callBackFun) {
|
|
3206
|
+
const arrayMap = new ArrayMap();
|
|
3207
|
+
for (let i = 0; i < lines.length; i++) {
|
|
3208
|
+
const line = lines[i];
|
|
3209
|
+
const key = callBackFun(line);
|
|
3210
|
+
arrayMap.append(key, line);
|
|
3211
|
+
}
|
|
3212
|
+
const result = arrayMap.reduce((list, lines2, key) => {
|
|
3213
|
+
list[key] = lines2;
|
|
3214
|
+
return list;
|
|
3215
|
+
}, {});
|
|
3216
|
+
return result;
|
|
3217
|
+
}
|
|
3196
3218
|
/** 通过在同一路径上且平行的线段分组
|
|
3197
3219
|
* @param lines
|
|
3198
3220
|
*/
|
|
@@ -5991,7 +6013,7 @@ function lineSegmentClipping(lines, minLen = 1e-9, dedup = true) {
|
|
|
5991
6013
|
const quadtree = new Quadtree(Box2.fromByLineSegment(...lines));
|
|
5992
6014
|
lines.forEach((line) => quadtree.insert({ line, userData: void 0 }));
|
|
5993
6015
|
let newLines = lines.flatMap((line) => {
|
|
5994
|
-
const points = quadtree.
|
|
6016
|
+
const points = quadtree.queryLineSegment(line).map((res) => {
|
|
5995
6017
|
if (res.line === line) return;
|
|
5996
6018
|
const point2 = res.line.getIntersection(line);
|
|
5997
6019
|
if (!point2 || line.start.equal(point2) || line.end.equal(point2)) return;
|
|
@@ -9479,7 +9501,7 @@ function initData(lines) {
|
|
|
9479
9501
|
continue;
|
|
9480
9502
|
}
|
|
9481
9503
|
if (line.userData.isPassageEntrance && line.userData.passageEntrance?.length) {
|
|
9482
|
-
const isDoubleDoor =
|
|
9504
|
+
const isDoubleDoor = WIO.isDouble(line);
|
|
9483
9505
|
if (isDoubleDoor) peDoubleDoors.push(line);
|
|
9484
9506
|
else peDoors.push(line);
|
|
9485
9507
|
continue;
|
|
@@ -9572,6 +9594,10 @@ const holeTypeMap = {
|
|
|
9572
9594
|
passageEntrance: "WALL_HOLE",
|
|
9573
9595
|
bay_window: "BAY_WINDOW"
|
|
9574
9596
|
};
|
|
9597
|
+
const placeHoldersMap = {
|
|
9598
|
+
switch: "开关",
|
|
9599
|
+
socket: "插座"
|
|
9600
|
+
};
|
|
9575
9601
|
const WALL_HEIGHT_KEY = /* @__PURE__ */ Symbol("height");
|
|
9576
9602
|
class ThreeVJiaPipeline extends Pipeline {
|
|
9577
9603
|
manager;
|
|
@@ -9604,17 +9630,10 @@ class ThreeVJiaPipeline extends Pipeline {
|
|
|
9604
9630
|
if (lines2.length < 4) return lines2;
|
|
9605
9631
|
let newLine = null;
|
|
9606
9632
|
let wallWidth = 0;
|
|
9607
|
-
|
|
9608
|
-
|
|
9609
|
-
|
|
9610
|
-
|
|
9611
|
-
wallWidth = Math.min(len1, len2);
|
|
9612
|
-
} else {
|
|
9613
|
-
lines2 = [...lines2].sort((a2, b4) => a2.length() - b4.length());
|
|
9614
|
-
const line1 = lines2[0], line2 = lines2[1];
|
|
9615
|
-
newLine = new LineSegment(line1.center.clone(), line2.center.clone());
|
|
9616
|
-
wallWidth = line1.length();
|
|
9617
|
-
}
|
|
9633
|
+
lines2 = [...lines2].sort((a2, b4) => a2.length() - b4.length());
|
|
9634
|
+
const line1 = lines2[0], line2 = lines2[1];
|
|
9635
|
+
newLine = new LineSegment(line1.center.clone(), line2.center.clone());
|
|
9636
|
+
wallWidth = line1.length();
|
|
9618
9637
|
mergeLineUserData(newLine, lines2);
|
|
9619
9638
|
newLine.userData.wallWidth = wallWidth;
|
|
9620
9639
|
return [newLine];
|
|
@@ -9795,13 +9814,13 @@ class ThreeVJiaPipeline extends Pipeline {
|
|
|
9795
9814
|
const rooms = json.rooms, roomPloys = rooms.map((room) => new Polygon(room.polygon.map((p2) => Point.from(p2))));
|
|
9796
9815
|
if (roomPloys.length === 0) return json;
|
|
9797
9816
|
publicInfo.itemInfo.forEach((item, i) => {
|
|
9798
|
-
if (item.category
|
|
9817
|
+
if (!placeHoldersMap[item.category]) return;
|
|
9799
9818
|
const itemPoly = new Polygon(item.contour.map((p2) => Point.from(p2).rotate(json.center, json.angle))), center = itemPoly.getCenter(), index2 = roomPloys.findIndex((poly) => poly.pointWithin(center));
|
|
9800
9819
|
if (index2 < 0) return;
|
|
9801
9820
|
json.placeHolders.push({
|
|
9802
|
-
name: item.category,
|
|
9803
|
-
polygon:
|
|
9804
|
-
direction: item.direction,
|
|
9821
|
+
name: placeHoldersMap[item.category],
|
|
9822
|
+
polygon: itemPoly.getMinimumBoundingRectangle().map((p2) => p2.toJson2D()),
|
|
9823
|
+
direction: Point.from(item.direction).rotate(Point.zero(), json.angle),
|
|
9805
9824
|
height: item.box.max.z - item.box.min.z,
|
|
9806
9825
|
sillHeight: item.box.min.z - z,
|
|
9807
9826
|
roomId: rooms[index2].roomTypeId,
|
|
@@ -10568,6 +10587,10 @@ class DxfDataPlugin extends Pipeline {
|
|
|
10568
10587
|
super();
|
|
10569
10588
|
this.lines = lines;
|
|
10570
10589
|
this.manager = WallGroupManager.fromByLines(lines);
|
|
10590
|
+
this.init();
|
|
10591
|
+
}
|
|
10592
|
+
init() {
|
|
10593
|
+
this.manager.forEach((group) => this.run(group.type, { lines: group.lines }));
|
|
10571
10594
|
}
|
|
10572
10595
|
install(cad) {
|
|
10573
10596
|
const wallGroupManager = this.manager, lines = this.lines;
|
|
@@ -10610,168 +10633,6 @@ class DxfDataPlugin extends Pipeline {
|
|
|
10610
10633
|
cad.addGroup(bayWindowLines, "bayWindow");
|
|
10611
10634
|
}
|
|
10612
10635
|
}
|
|
10613
|
-
class DoubleWallHelper {
|
|
10614
|
-
static errorAngle = 4;
|
|
10615
|
-
/** 线段投影分析
|
|
10616
|
-
* @param index
|
|
10617
|
-
* @param sourceLineSegment
|
|
10618
|
-
* @param lineSegmentList
|
|
10619
|
-
* @returns
|
|
10620
|
-
*/
|
|
10621
|
-
static projectionAnalysis(index2, sourceIndex, sourceLineSegment, lineSegmentList) {
|
|
10622
|
-
const temLineSegment = lineSegmentList[index2], direct = sourceLineSegment.direction(), temDirect = temLineSegment.direction(), angle = direct.angle(temDirect, { unit: "degree", range: "180" });
|
|
10623
|
-
if (angle < this.errorAngle || angle > 180 - this.errorAngle) {
|
|
10624
|
-
let data;
|
|
10625
|
-
let dist = sourceLineSegment.distanceToSegment(temLineSegment);
|
|
10626
|
-
const p1 = temLineSegment.projectLineSegment(sourceLineSegment), p2 = sourceLineSegment.projectLineSegment(temLineSegment);
|
|
10627
|
-
if (p1.length() > p2.length()) {
|
|
10628
|
-
data = {
|
|
10629
|
-
target: temLineSegment,
|
|
10630
|
-
targetIndex: index2,
|
|
10631
|
-
source: sourceLineSegment,
|
|
10632
|
-
sourceIndex,
|
|
10633
|
-
project: p1,
|
|
10634
|
-
project2: p2,
|
|
10635
|
-
minDistance: dist
|
|
10636
|
-
};
|
|
10637
|
-
} else {
|
|
10638
|
-
data = {
|
|
10639
|
-
target: sourceLineSegment,
|
|
10640
|
-
targetIndex: sourceIndex,
|
|
10641
|
-
source: temLineSegment,
|
|
10642
|
-
sourceIndex: index2,
|
|
10643
|
-
project: p2,
|
|
10644
|
-
project2: p1,
|
|
10645
|
-
minDistance: dist
|
|
10646
|
-
};
|
|
10647
|
-
}
|
|
10648
|
-
if (!data || data.project.length() < 0.08 || data.project2.length() < 0.08) return;
|
|
10649
|
-
return data;
|
|
10650
|
-
}
|
|
10651
|
-
}
|
|
10652
|
-
/** 查找
|
|
10653
|
-
* @param lines
|
|
10654
|
-
* @param wallWidth
|
|
10655
|
-
* @returns
|
|
10656
|
-
*/
|
|
10657
|
-
static findDoubleLine(lines, wallWidth = 0.4) {
|
|
10658
|
-
let walls = lines.filter((line) => !line.userData.isDoor), visited = /* @__PURE__ */ new Set(), resultList = [];
|
|
10659
|
-
walls = walls.filter((line) => !line.userData.isWindowWall);
|
|
10660
|
-
let quadtree = new Quadtree(Box2.fromByLineSegment(...walls));
|
|
10661
|
-
walls.forEach((line, index2) => quadtree.insert({ line, userData: index2 }));
|
|
10662
|
-
walls.forEach((sourceLineSegment, i) => {
|
|
10663
|
-
const rectangle = Rectangle.fromByLineSegment(sourceLineSegment, wallWidth * 2, false, -0.01), ids = quadtree.queryRect(rectangle).map((i2) => i2.userData).filter((index2) => index2 !== i);
|
|
10664
|
-
ids.forEach((id) => {
|
|
10665
|
-
try {
|
|
10666
|
-
if (visited.has(`${i}-${id}`) || visited.has(`${id}-${i}`)) return;
|
|
10667
|
-
const res = this.projectionAnalysis(id, i, sourceLineSegment, walls);
|
|
10668
|
-
if (res) resultList.push(res);
|
|
10669
|
-
visited.add(`${i}-${id}`);
|
|
10670
|
-
} catch (error) {
|
|
10671
|
-
console.log(error);
|
|
10672
|
-
}
|
|
10673
|
-
});
|
|
10674
|
-
});
|
|
10675
|
-
resultList.forEach((result) => {
|
|
10676
|
-
const project0 = result.project, project1 = result.project2;
|
|
10677
|
-
if (project0.angle(project1, { unit: "degree", range: "180" }) > 135) {
|
|
10678
|
-
project1.points = [project1.points[1], project1.points[0]];
|
|
10679
|
-
}
|
|
10680
|
-
});
|
|
10681
|
-
return {
|
|
10682
|
-
resultList,
|
|
10683
|
-
walls,
|
|
10684
|
-
quadtree
|
|
10685
|
-
};
|
|
10686
|
-
}
|
|
10687
|
-
/** 补双线墙壁
|
|
10688
|
-
* @param lines
|
|
10689
|
-
* @param wallWidth
|
|
10690
|
-
* @returns
|
|
10691
|
-
*/
|
|
10692
|
-
static complementSide(lines, obstacleAegment = [], wallWidth = 0.4) {
|
|
10693
|
-
const otherLines = [];
|
|
10694
|
-
lines = lines.filter((line) => {
|
|
10695
|
-
if (line.userData.isBayWindow || line.userData.isBalconyRailing || LineGroupType.hasType(line, "bayWindow") && line.userData.isWindow) {
|
|
10696
|
-
otherLines.push(line);
|
|
10697
|
-
return false;
|
|
10698
|
-
}
|
|
10699
|
-
return true;
|
|
10700
|
-
});
|
|
10701
|
-
let { resultList, quadtree } = this.findDoubleLine(lines, wallWidth), removeLines = /* @__PURE__ */ new Set(), clipingMap = /* @__PURE__ */ new Map(), appendLines = [];
|
|
10702
|
-
function addClipingMap(line, line1) {
|
|
10703
|
-
if (!clipingMap.has(line)) clipingMap.set(line, []);
|
|
10704
|
-
const startProj = line.projectPoint(line1.start);
|
|
10705
|
-
const endProj = line.projectPoint(line1.end);
|
|
10706
|
-
const list = clipingMap.get(line);
|
|
10707
|
-
if (startProj) list.push(startProj);
|
|
10708
|
-
if (endProj) list.push(endProj);
|
|
10709
|
-
removeLines.add(line);
|
|
10710
|
-
quadtree.remove(line);
|
|
10711
|
-
}
|
|
10712
|
-
resultList.forEach((result) => {
|
|
10713
|
-
const project0 = result.project, project1 = result.project2, line0 = result.source, line1 = result.target;
|
|
10714
|
-
const newLine1 = new LineSegment(project0.start.clone(), project1.start.clone());
|
|
10715
|
-
const newLine2 = new LineSegment(project0.end.clone(), project1.end.clone());
|
|
10716
|
-
newLine1.userData.height = line0.userData.height;
|
|
10717
|
-
newLine1.userData.rooftopPz = line0.userData.rooftopPz;
|
|
10718
|
-
newLine2.userData.height = line1.userData.height;
|
|
10719
|
-
newLine2.userData.rooftopPz = line1.userData.rooftopPz;
|
|
10720
|
-
appendLines.push(newLine1, newLine2);
|
|
10721
|
-
addClipingMap(line0, project0);
|
|
10722
|
-
addClipingMap(line1, project1);
|
|
10723
|
-
});
|
|
10724
|
-
clipingMap.forEach((list, line) => {
|
|
10725
|
-
const newLines = LineSegmentUtils.clippingByPoints(line, list);
|
|
10726
|
-
newLines.forEach((newLine) => {
|
|
10727
|
-
newLine.userData.height = line.userData.height;
|
|
10728
|
-
newLine.userData.rooftopPz = line.userData.rooftopPz;
|
|
10729
|
-
});
|
|
10730
|
-
lines.push(...newLines);
|
|
10731
|
-
});
|
|
10732
|
-
lines = lines.filter((line) => !removeLines.has(line));
|
|
10733
|
-
quadtree.clear();
|
|
10734
|
-
quadtree = createQuadtree([...lines, ...otherLines, ...obstacleAegment]);
|
|
10735
|
-
appendLines = lineSegmentClipping(appendLines, 1e-9);
|
|
10736
|
-
appendLines.flatMap((line) => {
|
|
10737
|
-
const queryLines = quadtree.queryRect(line.toRectangle(1e-3, "butt")).filter((item) => item.line.isParallelTo(line)).map((item) => item.line);
|
|
10738
|
-
if (queryLines.length) {
|
|
10739
|
-
const newLines = LineSegmentUtils.clippingByLines(line, queryLines);
|
|
10740
|
-
if (newLines) return newLines.forEach((newLine) => {
|
|
10741
|
-
newLine.userData.height = line.userData.height;
|
|
10742
|
-
newLine.userData.rooftopPz = line.userData.rooftopPz;
|
|
10743
|
-
quadtree.insert(newLine);
|
|
10744
|
-
lines.push(newLine);
|
|
10745
|
-
});
|
|
10746
|
-
}
|
|
10747
|
-
quadtree.insert(line);
|
|
10748
|
-
lines.push(line);
|
|
10749
|
-
});
|
|
10750
|
-
lines = lineSegmentClipping(lines, 1e-9);
|
|
10751
|
-
quadtree.clear();
|
|
10752
|
-
lines.push(...otherLines);
|
|
10753
|
-
PointUtils.adsorb(lines.flatMap((line) => line.points), 1e-4);
|
|
10754
|
-
return lines.filter((line) => line.length() > 1e-9);
|
|
10755
|
-
}
|
|
10756
|
-
/**
|
|
10757
|
-
* 创建分组
|
|
10758
|
-
*/
|
|
10759
|
-
static buildGroup(lineSegments) {
|
|
10760
|
-
const otherLines = [];
|
|
10761
|
-
lineSegments = lineSegments.filter((line) => {
|
|
10762
|
-
if (line.userData.isDoor || line.userData.isBalconyRailing || line.userData.isBayWindowWin || line.userData.isBayWindow) {
|
|
10763
|
-
otherLines.push(line);
|
|
10764
|
-
return false;
|
|
10765
|
-
}
|
|
10766
|
-
return true;
|
|
10767
|
-
});
|
|
10768
|
-
lineSegments = BuildGroup.doubleWall(lineSegments, true);
|
|
10769
|
-
lineSegments = this.complementSide(lineSegments, otherLines);
|
|
10770
|
-
WIO.recomputed(lineSegments);
|
|
10771
|
-
lineSegments = BuildGroup.doubleWall(lineSegments, true);
|
|
10772
|
-
return [...lineSegments, ...otherLines];
|
|
10773
|
-
}
|
|
10774
|
-
}
|
|
10775
10636
|
function parallel(line, baseline) {
|
|
10776
10637
|
const currentAngle = Math.atan2(line.end.y - line.start.y, line.end.x - line.start.x);
|
|
10777
10638
|
const targetAngle = Math.atan2(baseline.end.y - baseline.start.y, baseline.end.x - baseline.start.x);
|
|
@@ -11159,6 +11020,168 @@ class AlignToParallelSegments {
|
|
|
11159
11020
|
];
|
|
11160
11021
|
}
|
|
11161
11022
|
}
|
|
11023
|
+
class DoubleWallHelper {
|
|
11024
|
+
static errorAngle = 4;
|
|
11025
|
+
/** 线段投影分析
|
|
11026
|
+
* @param index
|
|
11027
|
+
* @param sourceLineSegment
|
|
11028
|
+
* @param lineSegmentList
|
|
11029
|
+
* @returns
|
|
11030
|
+
*/
|
|
11031
|
+
static projectionAnalysis(index2, sourceIndex, sourceLineSegment, lineSegmentList) {
|
|
11032
|
+
const temLineSegment = lineSegmentList[index2], direct = sourceLineSegment.direction(), temDirect = temLineSegment.direction(), angle = direct.angle(temDirect, { unit: "degree", range: "180" });
|
|
11033
|
+
if (angle < this.errorAngle || angle > 180 - this.errorAngle) {
|
|
11034
|
+
let data;
|
|
11035
|
+
let dist = sourceLineSegment.distanceToSegment(temLineSegment);
|
|
11036
|
+
const p1 = temLineSegment.projectLineSegment(sourceLineSegment), p2 = sourceLineSegment.projectLineSegment(temLineSegment);
|
|
11037
|
+
if (p1.length() > p2.length()) {
|
|
11038
|
+
data = {
|
|
11039
|
+
target: temLineSegment,
|
|
11040
|
+
targetIndex: index2,
|
|
11041
|
+
source: sourceLineSegment,
|
|
11042
|
+
sourceIndex,
|
|
11043
|
+
project: p1,
|
|
11044
|
+
project2: p2,
|
|
11045
|
+
minDistance: dist
|
|
11046
|
+
};
|
|
11047
|
+
} else {
|
|
11048
|
+
data = {
|
|
11049
|
+
target: sourceLineSegment,
|
|
11050
|
+
targetIndex: sourceIndex,
|
|
11051
|
+
source: temLineSegment,
|
|
11052
|
+
sourceIndex: index2,
|
|
11053
|
+
project: p2,
|
|
11054
|
+
project2: p1,
|
|
11055
|
+
minDistance: dist
|
|
11056
|
+
};
|
|
11057
|
+
}
|
|
11058
|
+
if (!data || data.project.length() < 0.08 || data.project2.length() < 0.08) return;
|
|
11059
|
+
return data;
|
|
11060
|
+
}
|
|
11061
|
+
}
|
|
11062
|
+
/** 查找
|
|
11063
|
+
* @param lines
|
|
11064
|
+
* @param wallWidth
|
|
11065
|
+
* @returns
|
|
11066
|
+
*/
|
|
11067
|
+
static findDoubleLine(lines, wallWidth = 0.4) {
|
|
11068
|
+
let walls = lines.filter((line) => !line.userData.isDoor), visited = /* @__PURE__ */ new Set(), resultList = [];
|
|
11069
|
+
walls = walls.filter((line) => !line.userData.isWindowWall);
|
|
11070
|
+
let quadtree = new Quadtree(Box2.fromByLineSegment(...walls));
|
|
11071
|
+
walls.forEach((line, index2) => quadtree.insert({ line, userData: index2 }));
|
|
11072
|
+
walls.forEach((sourceLineSegment, i) => {
|
|
11073
|
+
const rectangle = Rectangle.fromByLineSegment(sourceLineSegment, wallWidth * 2, false, -0.01), ids = quadtree.queryRect(rectangle).map((i2) => i2.userData).filter((index2) => index2 !== i);
|
|
11074
|
+
ids.forEach((id) => {
|
|
11075
|
+
try {
|
|
11076
|
+
if (visited.has(`${i}-${id}`) || visited.has(`${id}-${i}`)) return;
|
|
11077
|
+
const res = this.projectionAnalysis(id, i, sourceLineSegment, walls);
|
|
11078
|
+
if (res) resultList.push(res);
|
|
11079
|
+
visited.add(`${i}-${id}`);
|
|
11080
|
+
} catch (error) {
|
|
11081
|
+
console.log(error);
|
|
11082
|
+
}
|
|
11083
|
+
});
|
|
11084
|
+
});
|
|
11085
|
+
resultList.forEach((result) => {
|
|
11086
|
+
const project0 = result.project, project1 = result.project2;
|
|
11087
|
+
if (project0.angle(project1, { unit: "degree", range: "180" }) > 135) {
|
|
11088
|
+
project1.points = [project1.points[1], project1.points[0]];
|
|
11089
|
+
}
|
|
11090
|
+
});
|
|
11091
|
+
return {
|
|
11092
|
+
resultList,
|
|
11093
|
+
walls,
|
|
11094
|
+
quadtree
|
|
11095
|
+
};
|
|
11096
|
+
}
|
|
11097
|
+
/** 补双线墙壁
|
|
11098
|
+
* @param lines
|
|
11099
|
+
* @param wallWidth
|
|
11100
|
+
* @returns
|
|
11101
|
+
*/
|
|
11102
|
+
static complementSide(lines, obstacleAegment = [], wallWidth = 0.4) {
|
|
11103
|
+
const otherLines = [];
|
|
11104
|
+
lines = lines.filter((line) => {
|
|
11105
|
+
if (line.userData.isBayWindow || line.userData.isBalconyRailing || LineGroupType.hasType(line, "bayWindow") && line.userData.isWindow) {
|
|
11106
|
+
otherLines.push(line);
|
|
11107
|
+
return false;
|
|
11108
|
+
}
|
|
11109
|
+
return true;
|
|
11110
|
+
});
|
|
11111
|
+
let { resultList, quadtree } = this.findDoubleLine(lines, wallWidth), removeLines = /* @__PURE__ */ new Set(), clipingMap = /* @__PURE__ */ new Map(), appendLines = [];
|
|
11112
|
+
function addClipingMap(line, line1) {
|
|
11113
|
+
if (!clipingMap.has(line)) clipingMap.set(line, []);
|
|
11114
|
+
const startProj = line.projectPoint(line1.start);
|
|
11115
|
+
const endProj = line.projectPoint(line1.end);
|
|
11116
|
+
const list = clipingMap.get(line);
|
|
11117
|
+
if (startProj) list.push(startProj);
|
|
11118
|
+
if (endProj) list.push(endProj);
|
|
11119
|
+
removeLines.add(line);
|
|
11120
|
+
quadtree.remove(line);
|
|
11121
|
+
}
|
|
11122
|
+
resultList.forEach((result) => {
|
|
11123
|
+
const project0 = result.project, project1 = result.project2, line0 = result.source, line1 = result.target;
|
|
11124
|
+
const newLine1 = new LineSegment(project0.start.clone(), project1.start.clone());
|
|
11125
|
+
const newLine2 = new LineSegment(project0.end.clone(), project1.end.clone());
|
|
11126
|
+
newLine1.userData.height = line0.userData.height;
|
|
11127
|
+
newLine1.userData.rooftopPz = line0.userData.rooftopPz;
|
|
11128
|
+
newLine2.userData.height = line1.userData.height;
|
|
11129
|
+
newLine2.userData.rooftopPz = line1.userData.rooftopPz;
|
|
11130
|
+
appendLines.push(newLine1, newLine2);
|
|
11131
|
+
addClipingMap(line0, project0);
|
|
11132
|
+
addClipingMap(line1, project1);
|
|
11133
|
+
});
|
|
11134
|
+
clipingMap.forEach((list, line) => {
|
|
11135
|
+
const newLines = LineSegmentUtils.clippingByPoints(line, list);
|
|
11136
|
+
newLines.forEach((newLine) => {
|
|
11137
|
+
newLine.userData.height = line.userData.height;
|
|
11138
|
+
newLine.userData.rooftopPz = line.userData.rooftopPz;
|
|
11139
|
+
});
|
|
11140
|
+
lines.push(...newLines);
|
|
11141
|
+
});
|
|
11142
|
+
lines = lines.filter((line) => !removeLines.has(line));
|
|
11143
|
+
quadtree.clear();
|
|
11144
|
+
quadtree = createQuadtree([...lines, ...otherLines, ...obstacleAegment]);
|
|
11145
|
+
appendLines = lineSegmentClipping(appendLines, 1e-9);
|
|
11146
|
+
appendLines.flatMap((line) => {
|
|
11147
|
+
const queryLines = quadtree.queryRect(line.toRectangle(1e-3, "butt")).filter((item) => item.line.isParallelTo(line)).map((item) => item.line);
|
|
11148
|
+
if (queryLines.length) {
|
|
11149
|
+
const newLines = LineSegmentUtils.clippingByLines(line, queryLines);
|
|
11150
|
+
if (newLines) return newLines.forEach((newLine) => {
|
|
11151
|
+
newLine.userData.height = line.userData.height;
|
|
11152
|
+
newLine.userData.rooftopPz = line.userData.rooftopPz;
|
|
11153
|
+
quadtree.insert(newLine);
|
|
11154
|
+
lines.push(newLine);
|
|
11155
|
+
});
|
|
11156
|
+
}
|
|
11157
|
+
quadtree.insert(line);
|
|
11158
|
+
lines.push(line);
|
|
11159
|
+
});
|
|
11160
|
+
lines = lineSegmentClipping(lines, 1e-9);
|
|
11161
|
+
quadtree.clear();
|
|
11162
|
+
lines.push(...otherLines);
|
|
11163
|
+
PointUtils.adsorb(lines.flatMap((line) => line.points), 1e-4);
|
|
11164
|
+
return lines.filter((line) => line.length() > 1e-9);
|
|
11165
|
+
}
|
|
11166
|
+
/**
|
|
11167
|
+
* 创建分组
|
|
11168
|
+
*/
|
|
11169
|
+
static buildGroup(lineSegments) {
|
|
11170
|
+
const otherLines = [];
|
|
11171
|
+
lineSegments = lineSegments.filter((line) => {
|
|
11172
|
+
if (line.userData.isDoor || line.userData.isBalconyRailing || line.userData.isBayWindowWin || line.userData.isBayWindow) {
|
|
11173
|
+
otherLines.push(line);
|
|
11174
|
+
return false;
|
|
11175
|
+
}
|
|
11176
|
+
return true;
|
|
11177
|
+
});
|
|
11178
|
+
lineSegments = BuildGroup.doubleWall(lineSegments, true);
|
|
11179
|
+
lineSegments = this.complementSide(lineSegments, otherLines);
|
|
11180
|
+
WIO.recomputed(lineSegments);
|
|
11181
|
+
lineSegments = BuildGroup.doubleWall(lineSegments, true);
|
|
11182
|
+
return [...lineSegments, ...otherLines];
|
|
11183
|
+
}
|
|
11184
|
+
}
|
|
11162
11185
|
function shortDistanceLink(lines, radius = 0.1) {
|
|
11163
11186
|
const dpSet = findDiscretePoint(lines.filter((line) => !line.userData.isDoor)), pointVirtualGrid = createPointSpatialHash(dpSet.map((v2) => v2)), appendLines = [], visited = /* @__PURE__ */ new Set();
|
|
11164
11187
|
const getWeight2 = (target, point2, line) => {
|
|
@@ -11303,8 +11326,10 @@ function correction(lines, targettLine, option) {
|
|
|
11303
11326
|
lines = lineSegmentClipping(lines, 1e-9);
|
|
11304
11327
|
lines = removeDangline(lines, 0.1, false);
|
|
11305
11328
|
lines = removeShortDoor(lines);
|
|
11306
|
-
let newLines =
|
|
11307
|
-
|
|
11329
|
+
let { otherLines = [], newLines = [] } = LineSegmentUtils.group(lines, (line) => {
|
|
11330
|
+
if (line.userData.isDoor || line.userData.isBalconyRailing) return "otherLines";
|
|
11331
|
+
return "newLines";
|
|
11332
|
+
});
|
|
11308
11333
|
newLines = BuildGroup.bayWindow(newLines, false);
|
|
11309
11334
|
const { wallGroup = true } = option ?? {};
|
|
11310
11335
|
if (wallGroup) {
|
|
@@ -11335,7 +11360,22 @@ function axisAlignCorr(lines, option, verticalReferenceLine) {
|
|
|
11335
11360
|
}
|
|
11336
11361
|
return lines;
|
|
11337
11362
|
}
|
|
11363
|
+
function sparse(trajectory2, size2 = 0.4) {
|
|
11364
|
+
const idSet = /* @__PURE__ */ new Set();
|
|
11365
|
+
Object.keys(trajectory2 ?? {}).forEach((key) => {
|
|
11366
|
+
const p2 = trajectory2[key], i = Math.round(p2.x / size2), j = Math.round(p2.y / size2), id = BigInt(i) << 32n | BigInt(j) & 0xffffffffn;
|
|
11367
|
+
if (idSet.has(id)) {
|
|
11368
|
+
delete trajectory2[key];
|
|
11369
|
+
return;
|
|
11370
|
+
}
|
|
11371
|
+
idSet.add(id);
|
|
11372
|
+
});
|
|
11373
|
+
}
|
|
11338
11374
|
function init(lines, option) {
|
|
11375
|
+
if (option.trajectory) {
|
|
11376
|
+
sparse(option.trajectory, 0.2);
|
|
11377
|
+
sparse(option.trajectory, 0.5);
|
|
11378
|
+
}
|
|
11339
11379
|
BuildGroup.doubleWall.setTrajectory(option.trajectory);
|
|
11340
11380
|
lines = lines.map((line) => line.clone());
|
|
11341
11381
|
return lines;
|
|
@@ -11652,6 +11692,8 @@ class BoundExt {
|
|
|
11652
11692
|
let appendLines = [];
|
|
11653
11693
|
exteriorLines.forEach((line) => {
|
|
11654
11694
|
const mode = line.userData.expandDirect, direction = mode === "left" ? line.getRightDirection() : line.getLeftDirection();
|
|
11695
|
+
const intersectCount = quadtree.raycaster(line.center, direction, 1e-3, wallWidth).length;
|
|
11696
|
+
if (intersectCount > 0) return;
|
|
11655
11697
|
line.points.forEach((point2) => {
|
|
11656
11698
|
const id = point2.hashCode();
|
|
11657
11699
|
arrayMap.append(id, { point: point2, line });
|
|
@@ -30,7 +30,7 @@ export declare class Dxf<TEventMap extends {} = {}> extends Component<{
|
|
|
30
30
|
doorLineSegment: LineSegment[];
|
|
31
31
|
verticalReferenceLine?: LineSegment<LineUserData>;
|
|
32
32
|
originalZAverage: number;
|
|
33
|
-
linePipeline: LinePipeline
|
|
33
|
+
linePipeline: LinePipeline<SetDataOption>;
|
|
34
34
|
/** 原始数据组
|
|
35
35
|
*/
|
|
36
36
|
get lines(): LineSegment<LineUserData>[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -152,17 +152,8 @@ export declare class DxfDrawPlugin implements ICADPlugin {
|
|
|
152
152
|
private getArcAngleRange;
|
|
153
153
|
install(cad: CAD): void;
|
|
154
154
|
}
|
|
155
|
-
type DrawDataOption = {
|
|
156
|
-
openPaths: LineSegment[][];
|
|
157
|
-
closedPath: LineSegment[][];
|
|
158
|
-
hole: {
|
|
159
|
-
line: LineSegment;
|
|
160
|
-
belong: number;
|
|
161
|
-
}[];
|
|
162
|
-
};
|
|
163
155
|
type DataOption = {
|
|
164
156
|
lines: LineSegment[];
|
|
165
|
-
drawData: DrawDataOption;
|
|
166
157
|
};
|
|
167
158
|
/** dxf 数据处理插件
|
|
168
159
|
*/
|
|
@@ -170,6 +161,7 @@ export declare class DxfDataPlugin extends Pipeline<DataOption> implements ICADP
|
|
|
170
161
|
manager: WallGroupManager;
|
|
171
162
|
lines: LineSegment<LineUserData>[];
|
|
172
163
|
constructor(lines: LineSegment<LineUserData>[]);
|
|
164
|
+
init(): void;
|
|
173
165
|
install(cad: CAD): void;
|
|
174
166
|
}
|
|
175
167
|
export {};
|
package/src/dxfSystem/utils/{DoubleWallHelper.d.ts → linePipeline/builtin/DoubleWallHelper.d.ts}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { LineSegment } from '
|
|
2
|
-
import { Quadtree } from '
|
|
3
|
-
import { LineUserData } from '
|
|
1
|
+
import { LineSegment } from '../../../../utils/algorithms/LineSegment';
|
|
2
|
+
import { Quadtree } from '../../../../utils/algorithms/Quadtree';
|
|
3
|
+
import { LineUserData } from '../../../type';
|
|
4
4
|
type ProjectionAnalysisResult = {
|
|
5
5
|
source: LineSegment;
|
|
6
6
|
sourceIndex: number;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LineSegment } from '../../../utils/algorithms/LineSegment';
|
|
2
2
|
import { Pipeline } from '../../../utils/algorithms/Pipeline';
|
|
3
3
|
import { LineUserData, SetDataOption } from '../../type';
|
|
4
|
-
export declare class LinePipeline extends Pipeline<LineSegment[],
|
|
4
|
+
export declare class LinePipeline<T = SetDataOption> extends Pipeline<LineSegment[], T> {
|
|
5
5
|
static get builtin(): {
|
|
6
6
|
init: typeof import('./builtin/init').init;
|
|
7
7
|
DoorToHole: typeof import('./builtin/doorToHole').doorToHole;
|
|
@@ -14,7 +14,7 @@ export declare class LinePipeline extends Pipeline<LineSegment[], SetDataOption>
|
|
|
14
14
|
RemoveShortDoubleWall: typeof import('./builtin/removeShortDoubleWall').removeShortDoubleWall;
|
|
15
15
|
};
|
|
16
16
|
constructor();
|
|
17
|
-
add(handle: (lines: LineSegment<LineUserData>[], option:
|
|
17
|
+
add(handle: (lines: LineSegment<LineUserData>[], option: T) => LineSegment<LineUserData>[]): this;
|
|
18
18
|
clear(): this;
|
|
19
|
-
execute(data: LineSegment<Record<string, any>>[], option:
|
|
19
|
+
execute(data: LineSegment<Record<string, any>>[], option: T): LineSegment<Record<string, any>>[];
|
|
20
20
|
}
|
package/src/index.css
CHANGED
|
@@ -1236,10 +1236,10 @@ button[data-v-624dc8f8]:active {
|
|
|
1236
1236
|
color: #a7a7a7
|
|
1237
1237
|
}
|
|
1238
1238
|
|
|
1239
|
-
[data-v-
|
|
1239
|
+
[data-v-e23c82bd] {
|
|
1240
1240
|
font-family: 宋体;
|
|
1241
1241
|
}
|
|
1242
|
-
.button[data-v-
|
|
1242
|
+
.button[data-v-e23c82bd] {
|
|
1243
1243
|
padding: 5px 10px;
|
|
1244
1244
|
border: none;
|
|
1245
1245
|
background: var(--primary-color);
|
package/src/index3.js
CHANGED
|
@@ -16663,6 +16663,22 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
16663
16663
|
line1.angle(line2, { unit: "degree", range: "180" })
|
|
16664
16664
|
);
|
|
16665
16665
|
}
|
|
16666
|
+
function intersectionTest() {
|
|
16667
|
+
if (defaultComponent.selectLines.length !== 2) {
|
|
16668
|
+
ElMessage.warning({ message: "请选择两条线段" });
|
|
16669
|
+
return;
|
|
16670
|
+
}
|
|
16671
|
+
const line1 = defaultComponent.selectLines[0];
|
|
16672
|
+
const line2 = defaultComponent.selectLines[1];
|
|
16673
|
+
const point = line1.getIntersection(line2);
|
|
16674
|
+
if (point) {
|
|
16675
|
+
drawPoint(point);
|
|
16676
|
+
} else {
|
|
16677
|
+
ElMessage.warning({
|
|
16678
|
+
message: "没有交点"
|
|
16679
|
+
});
|
|
16680
|
+
}
|
|
16681
|
+
}
|
|
16666
16682
|
function commandConfirm() {
|
|
16667
16683
|
variable.set("currentKeyDown", "enter");
|
|
16668
16684
|
queueMicrotask(() => variable.set("currentKeyUp", "enter"));
|
|
@@ -16919,7 +16935,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
16919
16935
|
title: "取消命令(Esc)",
|
|
16920
16936
|
class: "active:scale-[0.7] transition-all flex items-center justify-center",
|
|
16921
16937
|
onClick: _cache[0] || (_cache[0] = (e) => (unref(editor).cancelCommand(), e.stopPropagation()))
|
|
16922
|
-
}, [..._cache[
|
|
16938
|
+
}, [..._cache[22] || (_cache[22] = [
|
|
16923
16939
|
createElementVNode("svg", {
|
|
16924
16940
|
fill: "#fff",
|
|
16925
16941
|
width: "16",
|
|
@@ -16937,7 +16953,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
16937
16953
|
onClick: commandConfirm,
|
|
16938
16954
|
title: "确认命令(Enter)",
|
|
16939
16955
|
class: "active:scale-[0.7] transition-all flex items-center justify-center"
|
|
16940
|
-
}, [..._cache[
|
|
16956
|
+
}, [..._cache[23] || (_cache[23] = [
|
|
16941
16957
|
createElementVNode("svg", {
|
|
16942
16958
|
fill: "#fff",
|
|
16943
16959
|
width: "16",
|
|
@@ -16960,7 +16976,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
16960
16976
|
modelValue: dxfVisible.value,
|
|
16961
16977
|
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => dxfVisible.value = $event)
|
|
16962
16978
|
}, {
|
|
16963
|
-
default: withCtx(() => [..._cache[
|
|
16979
|
+
default: withCtx(() => [..._cache[24] || (_cache[24] = [
|
|
16964
16980
|
createTextVNode("Dxf", -1)
|
|
16965
16981
|
])]),
|
|
16966
16982
|
_: 1
|
|
@@ -16970,7 +16986,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
16970
16986
|
modelValue: unref(editor).renderManager.lineAdsorption.value,
|
|
16971
16987
|
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => unref(editor).renderManager.lineAdsorption.value = $event)
|
|
16972
16988
|
}, {
|
|
16973
|
-
default: withCtx(() => [..._cache[
|
|
16989
|
+
default: withCtx(() => [..._cache[25] || (_cache[25] = [
|
|
16974
16990
|
createTextVNode("线吸附", -1)
|
|
16975
16991
|
])]),
|
|
16976
16992
|
_: 1
|
|
@@ -16981,7 +16997,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
16981
16997
|
modelValue: unref(editor).renderManager.pointAdsorption.value,
|
|
16982
16998
|
"onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => unref(editor).renderManager.pointAdsorption.value = $event)
|
|
16983
16999
|
}, {
|
|
16984
|
-
default: withCtx(() => [..._cache[
|
|
17000
|
+
default: withCtx(() => [..._cache[26] || (_cache[26] = [
|
|
16985
17001
|
createTextVNode("点吸附", -1)
|
|
16986
17002
|
])]),
|
|
16987
17003
|
_: 1
|
|
@@ -17027,7 +17043,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
17027
17043
|
createVNode(unref(ElDropdownMenu), null, {
|
|
17028
17044
|
default: withCtx(() => [
|
|
17029
17045
|
createVNode(unref(ElDropdownItem), { onClick: selectLocalFile }, {
|
|
17030
|
-
default: withCtx(() => [..._cache[
|
|
17046
|
+
default: withCtx(() => [..._cache[28] || (_cache[28] = [
|
|
17031
17047
|
createTextVNode(" 选择文件 ", -1)
|
|
17032
17048
|
])]),
|
|
17033
17049
|
_: 1
|
|
@@ -17035,7 +17051,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
17035
17051
|
createVNode(unref(ElDropdownItem), {
|
|
17036
17052
|
onClick: _cache[4] || (_cache[4] = ($event) => unref(dxfSystem).CorrectionDxf.downloadOriginalData("json.json"))
|
|
17037
17053
|
}, {
|
|
17038
|
-
default: withCtx(() => [..._cache[
|
|
17054
|
+
default: withCtx(() => [..._cache[29] || (_cache[29] = [
|
|
17039
17055
|
createTextVNode(" 下载Json ", -1)
|
|
17040
17056
|
])]),
|
|
17041
17057
|
_: 1
|
|
@@ -17043,7 +17059,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
17043
17059
|
createVNode(unref(ElDropdownItem), {
|
|
17044
17060
|
onClick: _cache[5] || (_cache[5] = ($event) => unref(dxfSystem).CorrectionDxf.downloadDxf("test.dxf"))
|
|
17045
17061
|
}, {
|
|
17046
|
-
default: withCtx(() => [..._cache[
|
|
17062
|
+
default: withCtx(() => [..._cache[30] || (_cache[30] = [
|
|
17047
17063
|
createTextVNode(" 下载DXF ", -1)
|
|
17048
17064
|
])]),
|
|
17049
17065
|
_: 1
|
|
@@ -17051,7 +17067,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
17051
17067
|
createVNode(unref(ElDropdownItem), {
|
|
17052
17068
|
onClick: _cache[6] || (_cache[6] = ($event) => unref(dxfSystem).CorrectionDxf.downloadDxfImage("dxf.jpg"))
|
|
17053
17069
|
}, {
|
|
17054
|
-
default: withCtx(() => [..._cache[
|
|
17070
|
+
default: withCtx(() => [..._cache[31] || (_cache[31] = [
|
|
17055
17071
|
createTextVNode(" 下载JPG ", -1)
|
|
17056
17072
|
])]),
|
|
17057
17073
|
_: 1
|
|
@@ -17059,7 +17075,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
17059
17075
|
createVNode(unref(ElDropdownItem), {
|
|
17060
17076
|
onClick: _cache[7] || (_cache[7] = ($event) => unref(whiteModel).downloadGltf("test.glb", true))
|
|
17061
17077
|
}, {
|
|
17062
|
-
default: withCtx(() => [..._cache[
|
|
17078
|
+
default: withCtx(() => [..._cache[32] || (_cache[32] = [
|
|
17063
17079
|
createTextVNode(" 下载白膜 ", -1)
|
|
17064
17080
|
])]),
|
|
17065
17081
|
_: 1
|
|
@@ -17067,7 +17083,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
17067
17083
|
createVNode(unref(ElDropdownItem), {
|
|
17068
17084
|
onClick: _cache[8] || (_cache[8] = ($event) => unref(threeVJia).download())
|
|
17069
17085
|
}, {
|
|
17070
|
-
default: withCtx(() => [..._cache[
|
|
17086
|
+
default: withCtx(() => [..._cache[33] || (_cache[33] = [
|
|
17071
17087
|
createTextVNode(" 下载三维家JSON ", -1)
|
|
17072
17088
|
])]),
|
|
17073
17089
|
_: 1
|
|
@@ -17089,7 +17105,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
17089
17105
|
}, null, 8, ["modelValue"])
|
|
17090
17106
|
]),
|
|
17091
17107
|
default: withCtx(() => [
|
|
17092
|
-
_cache[
|
|
17108
|
+
_cache[34] || (_cache[34] = createElementVNode("div", { class: "w-full" }, "z值调整", -1))
|
|
17093
17109
|
]),
|
|
17094
17110
|
_: 1
|
|
17095
17111
|
})) : createCommentVNode("", true)
|
|
@@ -17128,6 +17144,17 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
17128
17144
|
}, "角度测试", 32)
|
|
17129
17145
|
]),
|
|
17130
17146
|
_: 1
|
|
17147
|
+
}),
|
|
17148
|
+
createVNode(unref(ElDropdownItem), null, {
|
|
17149
|
+
default: withCtx(() => [
|
|
17150
|
+
createElementVNode("div", {
|
|
17151
|
+
class: "w-full",
|
|
17152
|
+
onMousedown: _cache[14] || (_cache[14] = withModifiers(() => {
|
|
17153
|
+
}, ["stop"])),
|
|
17154
|
+
onClick: withModifiers(intersectionTest, ["stop", "prevent"])
|
|
17155
|
+
}, "交点测试", 32)
|
|
17156
|
+
]),
|
|
17157
|
+
_: 1
|
|
17131
17158
|
})
|
|
17132
17159
|
]),
|
|
17133
17160
|
_: 1
|
|
@@ -17138,7 +17165,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
17138
17165
|
size: "small",
|
|
17139
17166
|
class: "mt-[10px] w-full"
|
|
17140
17167
|
}, {
|
|
17141
|
-
default: withCtx(() => [..._cache[
|
|
17168
|
+
default: withCtx(() => [..._cache[27] || (_cache[27] = [
|
|
17142
17169
|
createTextVNode("其他功能", -1)
|
|
17143
17170
|
])]),
|
|
17144
17171
|
_: 1
|
|
@@ -17149,16 +17176,16 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
17149
17176
|
])) : (openBlock(), createElementBlock("div", {
|
|
17150
17177
|
key: 1,
|
|
17151
17178
|
class: normalizeClass([{ "translate-y-full": isMainCommand.value }, "z-8 absolute left-0 bottom-0 transition-transform w-full bg-white p-[5px] box-border text-[14px]"]),
|
|
17152
|
-
onMousedown: _cache[
|
|
17153
|
-
onPointerdown: _cache[
|
|
17179
|
+
onMousedown: _cache[18] || (_cache[18] = (e) => e.stopPropagation()),
|
|
17180
|
+
onPointerdown: _cache[19] || (_cache[19] = (e) => e.stopPropagation())
|
|
17154
17181
|
}, [
|
|
17155
17182
|
createElementVNode("div", _hoisted_14, [
|
|
17156
17183
|
createVNode(unref(ElCheckbox), {
|
|
17157
17184
|
size: "small",
|
|
17158
17185
|
modelValue: dxfVisible.value,
|
|
17159
|
-
"onUpdate:modelValue": _cache[
|
|
17186
|
+
"onUpdate:modelValue": _cache[15] || (_cache[15] = ($event) => dxfVisible.value = $event)
|
|
17160
17187
|
}, {
|
|
17161
|
-
default: withCtx(() => [..._cache[
|
|
17188
|
+
default: withCtx(() => [..._cache[35] || (_cache[35] = [
|
|
17162
17189
|
createTextVNode("Dxf", -1)
|
|
17163
17190
|
])]),
|
|
17164
17191
|
_: 1
|
|
@@ -17166,9 +17193,9 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
17166
17193
|
createVNode(unref(ElCheckbox), {
|
|
17167
17194
|
size: "small",
|
|
17168
17195
|
modelValue: unref(editor).renderManager.lineAdsorption.value,
|
|
17169
|
-
"onUpdate:modelValue": _cache[
|
|
17196
|
+
"onUpdate:modelValue": _cache[16] || (_cache[16] = ($event) => unref(editor).renderManager.lineAdsorption.value = $event)
|
|
17170
17197
|
}, {
|
|
17171
|
-
default: withCtx(() => [..._cache[
|
|
17198
|
+
default: withCtx(() => [..._cache[36] || (_cache[36] = [
|
|
17172
17199
|
createTextVNode("线吸附", -1)
|
|
17173
17200
|
])]),
|
|
17174
17201
|
_: 1
|
|
@@ -17177,9 +17204,9 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
17177
17204
|
disabled: !unref(editor).renderManager.lineAdsorption.value,
|
|
17178
17205
|
size: "small",
|
|
17179
17206
|
modelValue: unref(editor).renderManager.pointAdsorption.value,
|
|
17180
|
-
"onUpdate:modelValue": _cache[
|
|
17207
|
+
"onUpdate:modelValue": _cache[17] || (_cache[17] = ($event) => unref(editor).renderManager.pointAdsorption.value = $event)
|
|
17181
17208
|
}, {
|
|
17182
|
-
default: withCtx(() => [..._cache[
|
|
17209
|
+
default: withCtx(() => [..._cache[37] || (_cache[37] = [
|
|
17183
17210
|
createTextVNode("点吸附", -1)
|
|
17184
17211
|
])]),
|
|
17185
17212
|
_: 1
|
|
@@ -17238,13 +17265,13 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
17238
17265
|
}, [
|
|
17239
17266
|
isMainCommand.value ? (openBlock(), createElementBlock("div", {
|
|
17240
17267
|
key: 0,
|
|
17241
|
-
onMousemove: _cache[
|
|
17268
|
+
onMousemove: _cache[21] || (_cache[21] = (e) => e.stopPropagation()),
|
|
17242
17269
|
class: "cursor-pointer z-8 box-border bg-[rgba(0,0,0,0.5)] rounded-[6px] p-[5px] absolute left-[50%] translate-x-[-50%] top-[20px] flex gap-[5px] items-center"
|
|
17243
17270
|
}, [
|
|
17244
17271
|
createElementVNode("button", {
|
|
17245
|
-
onClick: _cache[
|
|
17272
|
+
onClick: _cache[20] || (_cache[20] = (e) => (unref(editor).cancelCommand(), e.stopPropagation())),
|
|
17246
17273
|
class: "bg-transparent! button cursor-pointer"
|
|
17247
|
-
}, [..._cache[
|
|
17274
|
+
}, [..._cache[38] || (_cache[38] = [
|
|
17248
17275
|
createElementVNode("svg", {
|
|
17249
17276
|
fill: "#fff",
|
|
17250
17277
|
viewBox: "0 0 1024 1024",
|
|
@@ -17260,7 +17287,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
17260
17287
|
key: 0,
|
|
17261
17288
|
onClick: commandConfirm,
|
|
17262
17289
|
class: "button bg-transparent! cursor-pointer"
|
|
17263
|
-
}, [..._cache[
|
|
17290
|
+
}, [..._cache[39] || (_cache[39] = [
|
|
17264
17291
|
createElementVNode("svg", {
|
|
17265
17292
|
fill: "#28c932",
|
|
17266
17293
|
viewBox: "0 0 1026 1024",
|
|
@@ -17281,7 +17308,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
17281
17308
|
};
|
|
17282
17309
|
}
|
|
17283
17310
|
});
|
|
17284
|
-
const EditorToolContent = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-
|
|
17311
|
+
const EditorToolContent = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-e23c82bd"]]);
|
|
17285
17312
|
class StorageHelper {
|
|
17286
17313
|
static get(key, defaultValue = void 0) {
|
|
17287
17314
|
const value = localStorage.getItem(key);
|
|
@@ -18,6 +18,11 @@ export declare class LineSegmentUtils {
|
|
|
18
18
|
* @param lines
|
|
19
19
|
*/
|
|
20
20
|
static getLinesCenter(lines: LineSegment[]): Point<Record<string, any>>;
|
|
21
|
+
/** 自定义分组
|
|
22
|
+
* @param lines
|
|
23
|
+
* @returns
|
|
24
|
+
*/
|
|
25
|
+
static group<T = any, K extends string | number | symbol = string>(lines: LineSegment<T>[], callBackFun: (line: LineSegment<T>) => K): Partial<Record<K, LineSegment<T>[]>>;
|
|
21
26
|
/** 通过在同一路径上且平行的线段分组
|
|
22
27
|
* @param lines
|
|
23
28
|
*/
|