build-dxf 0.1.109 → 0.1.110
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 +310 -288
- package/src/dxfSystem/components/Dxf.d.ts +1 -14
- package/src/dxfSystem/plugins/editor/components/CommandFlow/CFComponent.d.ts +6 -6
- package/src/dxfSystem/type.d.ts +5 -13
- package/src/dxfSystem/utils/CAD/drawData.d.ts +43 -0
- package/src/dxfSystem/utils/CAD/drawDxfImage.d.ts +2 -0
- package/src/dxfSystem/utils/CAD/drawDxfString.d.ts +3 -0
- package/src/dxfSystem/utils/{CAD.d.ts → CAD/index.d.ts} +12 -10
- package/src/dxfSystem/utils/lineSegmentClipping.d.ts +1 -1
- package/src/utils/algorithms/LineSegment.d.ts +7 -5
- package/src/utils/algorithms/LineSegmentUtils.d.ts +1 -0
- package/src/utils/algorithms/Point.d.ts +1 -1
- package/src/utils/algorithms/Quadtree.d.ts +1 -0
package/package.json
CHANGED
package/src/build.js
CHANGED
|
@@ -399,9 +399,9 @@ class LineSegment {
|
|
|
399
399
|
currentData = {};
|
|
400
400
|
// line: any
|
|
401
401
|
uuid = uuid();
|
|
402
|
-
|
|
402
|
+
_length = 0;
|
|
403
403
|
get len() {
|
|
404
|
-
return this
|
|
404
|
+
return this._length;
|
|
405
405
|
}
|
|
406
406
|
get start() {
|
|
407
407
|
return this.points[0];
|
|
@@ -409,11 +409,11 @@ class LineSegment {
|
|
|
409
409
|
get end() {
|
|
410
410
|
return this.points[1];
|
|
411
411
|
}
|
|
412
|
-
|
|
412
|
+
_center = Point.zero();
|
|
413
413
|
get center() {
|
|
414
|
-
return this
|
|
414
|
+
return this._center.clone();
|
|
415
415
|
}
|
|
416
|
-
|
|
416
|
+
_direction = Point.zero();
|
|
417
417
|
constructor(p1, p2) {
|
|
418
418
|
this.set(p1 ?? this.start, p2 ?? this.end);
|
|
419
419
|
this.start.currentData[LineSegment.LINE_SYMBOL] = this;
|
|
@@ -422,12 +422,12 @@ class LineSegment {
|
|
|
422
422
|
}
|
|
423
423
|
_initLenListener() {
|
|
424
424
|
const distanceUpdate = () => {
|
|
425
|
-
this
|
|
426
|
-
this
|
|
425
|
+
this._length = this.points[0].distance(this.points[1]);
|
|
426
|
+
this._center.set(
|
|
427
427
|
this.points[0].x + (this.points[1].x - this.points[0].x) * 0.5,
|
|
428
428
|
this.points[0].y + (this.points[1].y - this.points[0].y) * 0.5
|
|
429
429
|
);
|
|
430
|
-
this
|
|
430
|
+
this._direction = this.points[1].directionFrom(this.points[0]);
|
|
431
431
|
};
|
|
432
432
|
this.points.forEach((p2) => fields.forEach((k) => {
|
|
433
433
|
let value = p2[k];
|
|
@@ -455,12 +455,12 @@ class LineSegment {
|
|
|
455
455
|
const dx = direct.x * half;
|
|
456
456
|
const dy = direct.y * half;
|
|
457
457
|
this.start.set(
|
|
458
|
-
this
|
|
459
|
-
this
|
|
458
|
+
this._center.x - dx,
|
|
459
|
+
this._center.y - dy
|
|
460
460
|
);
|
|
461
461
|
this.end.set(
|
|
462
|
-
this
|
|
463
|
-
this
|
|
462
|
+
this._center.x + dx,
|
|
463
|
+
this._center.y + dy
|
|
464
464
|
);
|
|
465
465
|
return this;
|
|
466
466
|
}
|
|
@@ -477,7 +477,7 @@ class LineSegment {
|
|
|
477
477
|
* @returns
|
|
478
478
|
*/
|
|
479
479
|
length(_ = false) {
|
|
480
|
-
return this
|
|
480
|
+
return this._length;
|
|
481
481
|
}
|
|
482
482
|
/** 开始点向线段内收缩 width
|
|
483
483
|
* @param width
|
|
@@ -500,35 +500,35 @@ class LineSegment {
|
|
|
500
500
|
* @param line
|
|
501
501
|
* @returns
|
|
502
502
|
*/
|
|
503
|
-
isSameEndpoint(line) {
|
|
504
|
-
return this.start.equal(line.start) || this.start.equal(line.end) || this.end.equal(line.start) || this.end.equal(line.end);
|
|
503
|
+
isSameEndpoint(line, eps = 1e-9) {
|
|
504
|
+
return this.start.equal(line.start, eps) || this.start.equal(line.end, eps) || this.end.equal(line.start, eps) || this.end.equal(line.end, eps);
|
|
505
505
|
}
|
|
506
506
|
/**
|
|
507
507
|
* 相同端点是否为开始
|
|
508
508
|
* @param line
|
|
509
509
|
* @returns
|
|
510
510
|
*/
|
|
511
|
-
isSameEndpointAsStart(line) {
|
|
512
|
-
return this.start.equal(line.start) || this.start.equal(line.end);
|
|
511
|
+
isSameEndpointAsStart(line, eps = 1e-9) {
|
|
512
|
+
return this.start.equal(line.start, eps) || this.start.equal(line.end, eps);
|
|
513
513
|
}
|
|
514
514
|
/**
|
|
515
515
|
* 相同端点是否为结束
|
|
516
516
|
* @param line
|
|
517
517
|
* @returns
|
|
518
518
|
*/
|
|
519
|
-
isSameEndpointAsEnd(line) {
|
|
520
|
-
return this.end.equal(line.start) || this.end.equal(line.end);
|
|
519
|
+
isSameEndpointAsEnd(line, eps = 1e-9) {
|
|
520
|
+
return this.end.equal(line.start, eps) || this.end.equal(line.end, eps);
|
|
521
521
|
}
|
|
522
522
|
/**
|
|
523
523
|
* 获取共线点
|
|
524
524
|
* @param line
|
|
525
525
|
* @returns
|
|
526
526
|
*/
|
|
527
|
-
getSameEndpoint(line) {
|
|
528
|
-
if (this.start.equal(line.start)) return [this.start, line.start];
|
|
529
|
-
else if (this.start.equal(line.end)) return [this.start, line.end];
|
|
530
|
-
else if (this.end.equal(line.start)) return [this.end, line.start];
|
|
531
|
-
else if (this.end.equal(line.end)) return [this.end, line.end];
|
|
527
|
+
getSameEndpoint(line, eps = 1e-9) {
|
|
528
|
+
if (this.start.equal(line.start, eps)) return [this.start, line.start];
|
|
529
|
+
else if (this.start.equal(line.end, eps)) return [this.start, line.end];
|
|
530
|
+
else if (this.end.equal(line.start, eps)) return [this.end, line.start];
|
|
531
|
+
else if (this.end.equal(line.end, eps)) return [this.end, line.end];
|
|
532
532
|
return null;
|
|
533
533
|
}
|
|
534
534
|
/**
|
|
@@ -608,7 +608,7 @@ class LineSegment {
|
|
|
608
608
|
* @returns
|
|
609
609
|
*/
|
|
610
610
|
direction() {
|
|
611
|
-
return this
|
|
611
|
+
return this._direction.clone();
|
|
612
612
|
}
|
|
613
613
|
/**
|
|
614
614
|
* 获取发向量-左法线
|
|
@@ -1058,8 +1058,8 @@ class Point {
|
|
|
1058
1058
|
* @param point
|
|
1059
1059
|
* @returns
|
|
1060
1060
|
*/
|
|
1061
|
-
equal(point2) {
|
|
1062
|
-
return Math.abs(point2.x - this.x) <
|
|
1061
|
+
equal(point2, eps = 1e-9) {
|
|
1062
|
+
return Math.abs(point2.x - this.x) < eps && Math.abs(point2.y - this.y) < eps;
|
|
1063
1063
|
}
|
|
1064
1064
|
/**
|
|
1065
1065
|
*
|
|
@@ -2417,6 +2417,11 @@ class Quadtree {
|
|
|
2417
2417
|
}));
|
|
2418
2418
|
return array;
|
|
2419
2419
|
}
|
|
2420
|
+
static from(lines) {
|
|
2421
|
+
const quadtree = new Quadtree(Box2.fromByLineSegment(...lines));
|
|
2422
|
+
lines.forEach((line) => quadtree.insert({ line, userData: void 0 }));
|
|
2423
|
+
return quadtree;
|
|
2424
|
+
}
|
|
2420
2425
|
}
|
|
2421
2426
|
class WallInsertObject {
|
|
2422
2427
|
static mountedObjectType = [];
|
|
@@ -3655,6 +3660,33 @@ class LineSegmentUtils {
|
|
|
3655
3660
|
}
|
|
3656
3661
|
return points;
|
|
3657
3662
|
}
|
|
3663
|
+
static resolveIntersection(lines, onClip) {
|
|
3664
|
+
const quadtree = Quadtree.from(lines), queryLine = new LineSegment(), arrayMap = new ArrayMap();
|
|
3665
|
+
for (let i = 0; i < lines.length; i++) {
|
|
3666
|
+
const line = lines[i];
|
|
3667
|
+
queryLine.copy(line).setLength(line.len + 0.04);
|
|
3668
|
+
quadtree.queryLineSegment(queryLine).forEach((res) => {
|
|
3669
|
+
if (res.line === line) return;
|
|
3670
|
+
if (line.isSameEndpoint(res.line, 1e-4)) return;
|
|
3671
|
+
const point2 = res.line.getIntersection(line);
|
|
3672
|
+
if (!point2) return;
|
|
3673
|
+
arrayMap.append(res.line, point2);
|
|
3674
|
+
});
|
|
3675
|
+
}
|
|
3676
|
+
const newLines = [];
|
|
3677
|
+
const removeSet = /* @__PURE__ */ new Set();
|
|
3678
|
+
arrayMap.forEach((points, line) => {
|
|
3679
|
+
if (points.length) {
|
|
3680
|
+
let lines2 = LineSegmentUtils.clippingByPoints(line, points);
|
|
3681
|
+
onClip?.(line, lines2);
|
|
3682
|
+
newLines.push(...lines2);
|
|
3683
|
+
removeSet.add(line);
|
|
3684
|
+
} else newLines.push(line);
|
|
3685
|
+
});
|
|
3686
|
+
lines = lines.filter((line) => !removeSet.has(line));
|
|
3687
|
+
lines.push(...newLines);
|
|
3688
|
+
return lines;
|
|
3689
|
+
}
|
|
3658
3690
|
/** 对线段组统计,找到主导方向线
|
|
3659
3691
|
* @param lineSegments
|
|
3660
3692
|
* @returns
|
|
@@ -6010,39 +6042,25 @@ function migration(newLine, oldLine) {
|
|
|
6010
6042
|
});
|
|
6011
6043
|
}
|
|
6012
6044
|
function lineSegmentClipping(lines, minLen = 1e-9, dedup = true) {
|
|
6013
|
-
|
|
6014
|
-
|
|
6015
|
-
|
|
6016
|
-
|
|
6017
|
-
|
|
6018
|
-
|
|
6019
|
-
if (!point2 || line.start.equal(point2) || line.end.equal(point2)) return;
|
|
6020
|
-
return point2;
|
|
6021
|
-
}).filter((i) => !!i);
|
|
6022
|
-
if (points.length) {
|
|
6023
|
-
const newLines2 = LineSegmentUtils.clippingByPoints(line, points);
|
|
6024
|
-
newLines2.map((newLine) => migration(newLine, line));
|
|
6025
|
-
if (line.userData.isBayWindow) {
|
|
6026
|
-
newLines2.sort((a2, b4) => b4.length() - a2.length());
|
|
6027
|
-
for (let i = 1; i < newLines2.length; i++) {
|
|
6028
|
-
newLines2[i].userData.isBayWindow = false;
|
|
6029
|
-
}
|
|
6045
|
+
lines = LineSegmentUtils.resolveIntersection(lines, (line, newLines) => {
|
|
6046
|
+
newLines.map((newLine) => migration(newLine, line));
|
|
6047
|
+
if (line.userData.isBayWindow) {
|
|
6048
|
+
newLines.sort((a2, b4) => b4.length() - a2.length());
|
|
6049
|
+
for (let i = 1; i < newLines.length; i++) {
|
|
6050
|
+
newLines[i].userData.isBayWindow = false;
|
|
6030
6051
|
}
|
|
6031
|
-
if (line.userData.isBalconyRailing) {
|
|
6032
|
-
const len = line.length();
|
|
6033
|
-
newLines2.forEach((line2) => {
|
|
6034
|
-
if (line2.length() / len < 0.2) {
|
|
6035
|
-
delete line2.userData.isBalconyRailing;
|
|
6036
|
-
}
|
|
6037
|
-
});
|
|
6038
|
-
}
|
|
6039
|
-
return newLines2;
|
|
6040
6052
|
}
|
|
6041
|
-
|
|
6053
|
+
if (line.userData.isBalconyRailing) {
|
|
6054
|
+
const len = line.length();
|
|
6055
|
+
newLines.forEach((line2) => {
|
|
6056
|
+
if (line2.length() / len < 0.2) {
|
|
6057
|
+
delete line2.userData.isBalconyRailing;
|
|
6058
|
+
}
|
|
6059
|
+
});
|
|
6060
|
+
}
|
|
6042
6061
|
});
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
return dedup ? LineSegmentUtils.deduplication(newLines) : newLines;
|
|
6062
|
+
lines = lines.filter((line) => line.length() >= minLen);
|
|
6063
|
+
return dedup ? LineSegmentUtils.deduplication(lines) : lines;
|
|
6046
6064
|
}
|
|
6047
6065
|
class LineIndexGenerator {
|
|
6048
6066
|
index = 0;
|
|
@@ -6641,7 +6659,6 @@ function clippingDoubleWall(lines) {
|
|
|
6641
6659
|
}
|
|
6642
6660
|
const miniCircles = new MiniCircles();
|
|
6643
6661
|
function clippingInsertObjectDoubleWall(lines) {
|
|
6644
|
-
if (lines.length === 4) return [lines];
|
|
6645
6662
|
const hasInsertObject = lines.some((line) => WallInsertObject.isInsertObject(line));
|
|
6646
6663
|
if (!hasInsertObject) return clippingDoubleWall(lines);
|
|
6647
6664
|
const quadtree = createQuadtree(lines), poly = Polygon.fromByLines2(lines), far = 10;
|
|
@@ -6653,7 +6670,7 @@ function clippingInsertObjectDoubleWall(lines) {
|
|
|
6653
6670
|
if (!poly.pointWithin(center.add(normal.clone().multiplyScalar(1e-6)))) normal.multiplyScalar(-1);
|
|
6654
6671
|
WallInsertObject.forEachInsertObjectData(line, (data) => data.forEach((d2) => {
|
|
6655
6672
|
const wioLine = wallInsertObjectToLine(line, d2);
|
|
6656
|
-
wioLine.setLength(wioLine.len
|
|
6673
|
+
wioLine.setLength(wioLine.len - 4e-3);
|
|
6657
6674
|
const len = wioLine.length();
|
|
6658
6675
|
let startResults = quadtree.raycaster(wioLine.start, normal, 1e-4, far).filter((item) => item.targetLine.isParallelTo(wioLine));
|
|
6659
6676
|
let endResults = quadtree.raycaster(wioLine.end, normal, 1e-4, far).filter((item) => item.targetLine.isParallelTo(wioLine));
|
|
@@ -9689,6 +9706,7 @@ class ThreeVJiaPipeline extends Pipeline {
|
|
|
9689
9706
|
if (info) {
|
|
9690
9707
|
const { dottedLine, windowLine, depth, side } = info, line = new LineSegment(dottedLine.start.clone(), dottedLine.end.clone()), win = windowLine?.userData.drawWindow && windowLine.userData.drawWindow[0];
|
|
9691
9708
|
if (side === "LEFT") line.swapValue();
|
|
9709
|
+
line.translate(-DEFAULT_WALL_WIDTH * 0.5, line.normal());
|
|
9692
9710
|
line.userData = {
|
|
9693
9711
|
groundClearance: win?.groundClearance ?? 0,
|
|
9694
9712
|
height: win?.height,
|
|
@@ -9815,7 +9833,7 @@ class ThreeVJiaPipeline extends Pipeline {
|
|
|
9815
9833
|
if (roomPloys.length === 0) return json;
|
|
9816
9834
|
publicInfo.itemInfo.forEach((item, i) => {
|
|
9817
9835
|
if (!placeHoldersMap[item.category]) return;
|
|
9818
|
-
const itemPoly = new Polygon(
|
|
9836
|
+
const contour = item.quadContour ?? item.contour, itemPoly = new Polygon(contour.map((p2) => Point.from(p2).rotate(json.center, json.angle))), center = itemPoly.getCenter(), index2 = roomPloys.findIndex((poly) => poly.pointWithin(center));
|
|
9819
9837
|
if (index2 < 0) return;
|
|
9820
9838
|
json.placeHolders.push({
|
|
9821
9839
|
name: placeHoldersMap[item.category],
|
|
@@ -9977,39 +9995,6 @@ const tools = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
|
|
|
9977
9995
|
toOriginalDataItem,
|
|
9978
9996
|
wallInsertObjectToLine
|
|
9979
9997
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
9980
|
-
class Group {
|
|
9981
|
-
type = "";
|
|
9982
|
-
userData = { color: "#fff" };
|
|
9983
|
-
constructor(lines = [], type = "", userData = {}) {
|
|
9984
|
-
this.type = type;
|
|
9985
|
-
this.addLine(...lines);
|
|
9986
|
-
Object.assign(this.userData, userData);
|
|
9987
|
-
}
|
|
9988
|
-
lines = [];
|
|
9989
|
-
/** 添加线段
|
|
9990
|
-
* @param arg
|
|
9991
|
-
*/
|
|
9992
|
-
addLine(...arg) {
|
|
9993
|
-
this.lines.push(...arg);
|
|
9994
|
-
}
|
|
9995
|
-
removeLine(...lines) {
|
|
9996
|
-
if (lines.length === 0) return;
|
|
9997
|
-
if (lines.length === 1) {
|
|
9998
|
-
const index2 = this.lines.indexOf(lines[0]);
|
|
9999
|
-
this.lines.splice(index2, 1);
|
|
10000
|
-
return;
|
|
10001
|
-
}
|
|
10002
|
-
const set2 = new Set(lines);
|
|
10003
|
-
this.lines = this.lines.filter((line) => !set2.has(line));
|
|
10004
|
-
}
|
|
10005
|
-
clone() {
|
|
10006
|
-
const group = new this.constructor();
|
|
10007
|
-
group.type = this.type;
|
|
10008
|
-
group.lines = this.lines.map((line) => line.clone());
|
|
10009
|
-
Object.assign(group.userData, this.userData);
|
|
10010
|
-
return group;
|
|
10011
|
-
}
|
|
10012
|
-
}
|
|
10013
9998
|
const units = {
|
|
10014
9999
|
Unitless: 1,
|
|
10015
10000
|
// 无单位,1米 = 1(无单位)
|
|
@@ -10054,6 +10039,223 @@ const units = {
|
|
|
10054
10039
|
Parsecs: 3240779289666404e-32
|
|
10055
10040
|
// 秒差距,1米 ≈ 0.00000000000000003240779289666404秒差距
|
|
10056
10041
|
};
|
|
10042
|
+
function toDrawData(unit = "Centimeters") {
|
|
10043
|
+
if (!this.needUpdate && this._cachedDrawDataMap.has(unit)) return this._cachedDrawDataMap.get(unit);
|
|
10044
|
+
this._cachedDrawDataMap.clear();
|
|
10045
|
+
this.needUpdate = false;
|
|
10046
|
+
const lines = this.groups.flatMap((group) => group.lines), s = units[unit], expansionWidth = 2, box = Box2.fromByLineSegment(...lines).expansion(expansionWidth), center = box.center, data = {
|
|
10047
|
+
unit,
|
|
10048
|
+
lines: [],
|
|
10049
|
+
lines2: [],
|
|
10050
|
+
arcs: [],
|
|
10051
|
+
texts: [],
|
|
10052
|
+
center: center.clone().multiplyScalar(s).toJson(),
|
|
10053
|
+
width: box.width * s,
|
|
10054
|
+
height: box.height * s,
|
|
10055
|
+
scale: s
|
|
10056
|
+
};
|
|
10057
|
+
let color = "white";
|
|
10058
|
+
function drawText2(str, p2) {
|
|
10059
|
+
data.texts.push([str, p2.x * s, p2.y * s, color]);
|
|
10060
|
+
}
|
|
10061
|
+
function drawLine(p1, p2) {
|
|
10062
|
+
data.lines.push([p1.x * s, p1.y * s, p2.x * s, p2.y * s, color]);
|
|
10063
|
+
}
|
|
10064
|
+
function drawLine2(p1, p2) {
|
|
10065
|
+
data.lines2.push([p1.x * s, p1.y * s, p2.x * s, p2.y * s, color]);
|
|
10066
|
+
}
|
|
10067
|
+
function drawDottedLine(p1, p2, dash = 0.04, gap = 0.05, mode = "line") {
|
|
10068
|
+
const distance2 = dash + gap;
|
|
10069
|
+
let current = 0;
|
|
10070
|
+
const direction = p2.directionFrom(p1);
|
|
10071
|
+
const length = p1.distance(p2);
|
|
10072
|
+
while (current < length) {
|
|
10073
|
+
const dashEnd = Math.min(current + dash, length);
|
|
10074
|
+
const start = p1.clone().add(direction.clone().multiplyScalar(current));
|
|
10075
|
+
const end = p1.clone().add(direction.clone().multiplyScalar(dashEnd));
|
|
10076
|
+
if (mode === "line") drawLine(start, end);
|
|
10077
|
+
else drawLine2(start, end);
|
|
10078
|
+
current += distance2;
|
|
10079
|
+
}
|
|
10080
|
+
}
|
|
10081
|
+
const line = new LineSegment();
|
|
10082
|
+
function drawRulerLine(p1, p2) {
|
|
10083
|
+
line.set(p1, p2);
|
|
10084
|
+
const length = line.length();
|
|
10085
|
+
const angle = line.direction().angle(new Point(0, 1), { unit: "degree", range: "180" });
|
|
10086
|
+
const p1C = p1.clone();
|
|
10087
|
+
const p2C = p2.clone();
|
|
10088
|
+
const offset = expansionWidth * 0.4;
|
|
10089
|
+
if (Math.min(angle, 180 - angle) < 1) {
|
|
10090
|
+
if (p1.x < center.x) {
|
|
10091
|
+
p1C.x = box.minX + offset;
|
|
10092
|
+
p2C.x = box.minX + offset;
|
|
10093
|
+
} else {
|
|
10094
|
+
p1C.x = box.maxX - offset;
|
|
10095
|
+
p2C.x = box.maxX - offset;
|
|
10096
|
+
}
|
|
10097
|
+
} else {
|
|
10098
|
+
if (p1.y < center.y) {
|
|
10099
|
+
p1C.y = box.minY + offset;
|
|
10100
|
+
p2C.y = box.minY + offset;
|
|
10101
|
+
} else {
|
|
10102
|
+
p1C.y = box.maxY - offset;
|
|
10103
|
+
p2C.y = box.maxY - offset;
|
|
10104
|
+
}
|
|
10105
|
+
}
|
|
10106
|
+
line.set(p1C, p2C);
|
|
10107
|
+
drawDottedLine(p1C, p1, 0.04, 0.05, "line2");
|
|
10108
|
+
drawDottedLine(p2C, p2, 0.04, 0.05, "line2");
|
|
10109
|
+
drawLine2(p1C, p2C);
|
|
10110
|
+
color = "white";
|
|
10111
|
+
drawText2((length * 1e3).toFixed(0) + "mm", line.center);
|
|
10112
|
+
}
|
|
10113
|
+
function drawArc(pos, radius, startAngle, endAngle) {
|
|
10114
|
+
data.arcs.push([
|
|
10115
|
+
pos.x * s,
|
|
10116
|
+
pos.y * s,
|
|
10117
|
+
radius * s,
|
|
10118
|
+
startAngle,
|
|
10119
|
+
endAngle,
|
|
10120
|
+
color
|
|
10121
|
+
]);
|
|
10122
|
+
}
|
|
10123
|
+
this.groups.forEach((group) => {
|
|
10124
|
+
const set2 = this._drawHandlerMap.get(group.type);
|
|
10125
|
+
if (!set2) return;
|
|
10126
|
+
const option = { group, drawArc, drawLine, drawDottedLine, drawText: drawText2, drawRulerLine, setColor(c) {
|
|
10127
|
+
color = c;
|
|
10128
|
+
} };
|
|
10129
|
+
set2.forEach((fun) => fun.handler(option));
|
|
10130
|
+
});
|
|
10131
|
+
this._cachedDrawDataMap.set(unit, data);
|
|
10132
|
+
return data;
|
|
10133
|
+
}
|
|
10134
|
+
async function toDxfImageBlob(data, type = "image/jpeg", background = "#000") {
|
|
10135
|
+
const margin = 0 * data.scale;
|
|
10136
|
+
let canvas;
|
|
10137
|
+
if (typeof window !== "undefined") {
|
|
10138
|
+
canvas = document.createElement("canvas");
|
|
10139
|
+
} else if (typeof global !== "undefined") {
|
|
10140
|
+
const { createCanvas } = await include("canvas");
|
|
10141
|
+
canvas = createCanvas(data.width + margin * 2, data.height + margin * 2);
|
|
10142
|
+
} else {
|
|
10143
|
+
throw new Error("创建画布失败");
|
|
10144
|
+
}
|
|
10145
|
+
const colors = {
|
|
10146
|
+
cyan: "cyan",
|
|
10147
|
+
yellow: "yellow",
|
|
10148
|
+
white: "white"
|
|
10149
|
+
};
|
|
10150
|
+
canvas.width = data.width + margin * 2;
|
|
10151
|
+
canvas.height = data.height + margin * 2;
|
|
10152
|
+
const ctx = canvas.getContext("2d");
|
|
10153
|
+
if (background) {
|
|
10154
|
+
ctx.fillStyle = background;
|
|
10155
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
10156
|
+
}
|
|
10157
|
+
ctx.translate(-data.center.x + data.width * 0.5 + margin, data.center.y + data.height * 0.5 + margin);
|
|
10158
|
+
ctx.scale(1, -1);
|
|
10159
|
+
data.lines.forEach(([p1x, p1y, p2x, p2y, color]) => {
|
|
10160
|
+
ctx.strokeStyle = colors[color] ?? color;
|
|
10161
|
+
ctx.beginPath();
|
|
10162
|
+
ctx.moveTo(p1x, p1y);
|
|
10163
|
+
ctx.lineTo(p2x, p2y);
|
|
10164
|
+
ctx.closePath();
|
|
10165
|
+
ctx.stroke();
|
|
10166
|
+
});
|
|
10167
|
+
data.lines2.forEach(([p1x, p1y, p2x, p2y, color]) => {
|
|
10168
|
+
ctx.strokeStyle = colors[color] ?? color;
|
|
10169
|
+
ctx.beginPath();
|
|
10170
|
+
ctx.moveTo(p1x, p1y);
|
|
10171
|
+
ctx.lineTo(p2x, p2y);
|
|
10172
|
+
ctx.closePath();
|
|
10173
|
+
ctx.stroke();
|
|
10174
|
+
});
|
|
10175
|
+
data.arcs.forEach(([x, y, radius, startAngle, endAngle, color]) => {
|
|
10176
|
+
ctx.strokeStyle = colors[color];
|
|
10177
|
+
ctx.beginPath();
|
|
10178
|
+
ctx.arc(x, y, radius, startAngle * (Math.PI / 180), endAngle * (Math.PI / 180));
|
|
10179
|
+
ctx.stroke();
|
|
10180
|
+
});
|
|
10181
|
+
data.texts.forEach(([str, x, y, color]) => {
|
|
10182
|
+
ctx.fillStyle = colors[color] ?? color ?? "#fff";
|
|
10183
|
+
ctx.font = `${0.15 * data.scale}px Arial`;
|
|
10184
|
+
ctx.textAlign = "center";
|
|
10185
|
+
ctx.textBaseline = "middle";
|
|
10186
|
+
ctx.save();
|
|
10187
|
+
ctx.translate(x, y);
|
|
10188
|
+
ctx.scale(1, -1);
|
|
10189
|
+
ctx.fillText(str, 0, 0);
|
|
10190
|
+
ctx.restore();
|
|
10191
|
+
});
|
|
10192
|
+
if ("toBlob" in canvas) {
|
|
10193
|
+
return new Promise((resolve) => {
|
|
10194
|
+
canvas.toBlob((b4) => {
|
|
10195
|
+
resolve(b4);
|
|
10196
|
+
}, type, 1);
|
|
10197
|
+
});
|
|
10198
|
+
} else {
|
|
10199
|
+
const buffer = canvas.toBuffer(type, { quality: 1 });
|
|
10200
|
+
return buffer;
|
|
10201
|
+
}
|
|
10202
|
+
}
|
|
10203
|
+
function drawDxfString(data, unit = "Millimeters") {
|
|
10204
|
+
const d2 = new Drawing();
|
|
10205
|
+
d2.setUnits(unit);
|
|
10206
|
+
d2.addLayer("cyan", Drawing.ACI.CYAN, "DOTTED");
|
|
10207
|
+
d2.addLayer("yellow", Drawing.ACI.YELLOW, "DOTTED");
|
|
10208
|
+
d2.addLayer("white", Drawing.ACI.WHITE, "DOTTED");
|
|
10209
|
+
d2.addLayer("blue", Drawing.ACI.BLUE, "DOTTED");
|
|
10210
|
+
d2.addLayer("green", Drawing.ACI.GREEN, "DOTTED");
|
|
10211
|
+
d2.addLayer("layer", Drawing.ACI.LAYER, "DOTTED");
|
|
10212
|
+
d2.addLayer("magenta", Drawing.ACI.MAGENTA, "DOTTED");
|
|
10213
|
+
d2.addLayer("red", Drawing.ACI.RED, "DOTTED");
|
|
10214
|
+
data.lines.forEach((item) => {
|
|
10215
|
+
let [p1x, p1y, p2x, p2y, color] = item;
|
|
10216
|
+
d2.setActiveLayer(color);
|
|
10217
|
+
d2.drawLine(p1x, p1y, p2x, p2y);
|
|
10218
|
+
});
|
|
10219
|
+
data.arcs.forEach((item) => {
|
|
10220
|
+
const [x, y, r2, startAngle, endAngle, color] = item;
|
|
10221
|
+
d2.setActiveLayer(color);
|
|
10222
|
+
d2.drawArc(x, y, r2, startAngle, endAngle);
|
|
10223
|
+
});
|
|
10224
|
+
return d2.toDxfString();
|
|
10225
|
+
}
|
|
10226
|
+
class Group {
|
|
10227
|
+
type = "";
|
|
10228
|
+
userData = { color: "#fff" };
|
|
10229
|
+
constructor(lines = [], type = "", userData = {}) {
|
|
10230
|
+
this.type = type;
|
|
10231
|
+
this.addLine(...lines);
|
|
10232
|
+
Object.assign(this.userData, userData);
|
|
10233
|
+
}
|
|
10234
|
+
lines = [];
|
|
10235
|
+
/** 添加线段
|
|
10236
|
+
* @param arg
|
|
10237
|
+
*/
|
|
10238
|
+
addLine(...arg) {
|
|
10239
|
+
this.lines.push(...arg);
|
|
10240
|
+
}
|
|
10241
|
+
removeLine(...lines) {
|
|
10242
|
+
if (lines.length === 0) return;
|
|
10243
|
+
if (lines.length === 1) {
|
|
10244
|
+
const index2 = this.lines.indexOf(lines[0]);
|
|
10245
|
+
this.lines.splice(index2, 1);
|
|
10246
|
+
return;
|
|
10247
|
+
}
|
|
10248
|
+
const set2 = new Set(lines);
|
|
10249
|
+
this.lines = this.lines.filter((line) => !set2.has(line));
|
|
10250
|
+
}
|
|
10251
|
+
clone() {
|
|
10252
|
+
const group = new this.constructor();
|
|
10253
|
+
group.type = this.type;
|
|
10254
|
+
group.lines = this.lines.map((line) => line.clone());
|
|
10255
|
+
Object.assign(group.userData, this.userData);
|
|
10256
|
+
return group;
|
|
10257
|
+
}
|
|
10258
|
+
}
|
|
10057
10259
|
class CAD {
|
|
10058
10260
|
groups = [];
|
|
10059
10261
|
_drawHandlerMap = new SetMap();
|
|
@@ -10199,169 +10401,14 @@ class CAD {
|
|
|
10199
10401
|
*/
|
|
10200
10402
|
_cachedDrawDataMap = /* @__PURE__ */ new Map();
|
|
10201
10403
|
toDrawData(unit = "Centimeters") {
|
|
10202
|
-
|
|
10203
|
-
this._cachedDrawDataMap.clear();
|
|
10204
|
-
this.needUpdate = false;
|
|
10205
|
-
const lines = this.groups.flatMap((group) => group.lines), s = units[unit], expansionWidth = 2, box = Box2.fromByLineSegment(...lines).expansion(expansionWidth), center = box.center, data = {
|
|
10206
|
-
unit,
|
|
10207
|
-
lines: [],
|
|
10208
|
-
lines2: [],
|
|
10209
|
-
arcs: [],
|
|
10210
|
-
texts: [],
|
|
10211
|
-
center: center.clone().multiplyScalar(s).toJson(),
|
|
10212
|
-
width: box.width * s,
|
|
10213
|
-
height: box.height * s,
|
|
10214
|
-
scale: s
|
|
10215
|
-
};
|
|
10216
|
-
let color = "white";
|
|
10217
|
-
function drawText2(str, p2) {
|
|
10218
|
-
data.texts.push([str, p2.x * s, p2.y * s, color]);
|
|
10219
|
-
}
|
|
10220
|
-
function drawLine(p1, p2) {
|
|
10221
|
-
data.lines.push([p1.x * s, p1.y * s, p2.x * s, p2.y * s, color]);
|
|
10222
|
-
}
|
|
10223
|
-
function drawLine2(p1, p2) {
|
|
10224
|
-
data.lines2.push([p1.x * s, p1.y * s, p2.x * s, p2.y * s, color]);
|
|
10225
|
-
}
|
|
10226
|
-
function drawDottedLine(p1, p2, dash = 0.04, gap = 0.05, mode = "line") {
|
|
10227
|
-
const distance2 = dash + gap;
|
|
10228
|
-
let current = 0;
|
|
10229
|
-
const direction = p2.directionFrom(p1);
|
|
10230
|
-
const length = p1.distance(p2);
|
|
10231
|
-
while (current < length) {
|
|
10232
|
-
const dashEnd = Math.min(current + dash, length);
|
|
10233
|
-
const start = p1.clone().add(direction.clone().multiplyScalar(current));
|
|
10234
|
-
const end = p1.clone().add(direction.clone().multiplyScalar(dashEnd));
|
|
10235
|
-
if (mode === "line") drawLine(start, end);
|
|
10236
|
-
else drawLine2(start, end);
|
|
10237
|
-
current += distance2;
|
|
10238
|
-
}
|
|
10239
|
-
}
|
|
10240
|
-
const line = new LineSegment();
|
|
10241
|
-
function drawRulerLine(p1, p2) {
|
|
10242
|
-
line.set(p1, p2);
|
|
10243
|
-
const length = line.length();
|
|
10244
|
-
const angle = line.direction().angle(new Point(0, 1), { unit: "degree", range: "180" });
|
|
10245
|
-
const p1C = p1.clone();
|
|
10246
|
-
const p2C = p2.clone();
|
|
10247
|
-
const offset = expansionWidth * 0.4;
|
|
10248
|
-
if (Math.min(angle, 180 - angle) < 1) {
|
|
10249
|
-
if (p1.x < center.x) {
|
|
10250
|
-
p1C.x = box.minX + offset;
|
|
10251
|
-
p2C.x = box.minX + offset;
|
|
10252
|
-
} else {
|
|
10253
|
-
p1C.x = box.maxX - offset;
|
|
10254
|
-
p2C.x = box.maxX - offset;
|
|
10255
|
-
}
|
|
10256
|
-
} else {
|
|
10257
|
-
if (p1.y < center.y) {
|
|
10258
|
-
p1C.y = box.minY + offset;
|
|
10259
|
-
p2C.y = box.minY + offset;
|
|
10260
|
-
} else {
|
|
10261
|
-
p1C.y = box.maxY - offset;
|
|
10262
|
-
p2C.y = box.maxY - offset;
|
|
10263
|
-
}
|
|
10264
|
-
}
|
|
10265
|
-
line.set(p1C, p2C);
|
|
10266
|
-
drawDottedLine(p1C, p1, 0.04, 0.05, "line2");
|
|
10267
|
-
drawDottedLine(p2C, p2, 0.04, 0.05, "line2");
|
|
10268
|
-
drawLine2(p1C, p2C);
|
|
10269
|
-
color = "white";
|
|
10270
|
-
drawText2((length * 1e3).toFixed(0) + "mm", line.center);
|
|
10271
|
-
}
|
|
10272
|
-
function drawArc(pos, radius, startAngle, endAngle) {
|
|
10273
|
-
data.arcs.push([
|
|
10274
|
-
pos.x * s,
|
|
10275
|
-
pos.y * s,
|
|
10276
|
-
radius * s,
|
|
10277
|
-
startAngle,
|
|
10278
|
-
endAngle,
|
|
10279
|
-
color
|
|
10280
|
-
]);
|
|
10281
|
-
}
|
|
10282
|
-
this.groups.forEach((group) => {
|
|
10283
|
-
const set2 = this._drawHandlerMap.get(group.type);
|
|
10284
|
-
if (!set2) return;
|
|
10285
|
-
const option = { group, drawArc, drawLine, drawDottedLine, drawRulerLine, setColor(c) {
|
|
10286
|
-
color = c;
|
|
10287
|
-
} };
|
|
10288
|
-
set2.forEach((fun) => fun.handler(option));
|
|
10289
|
-
});
|
|
10290
|
-
this._cachedDrawDataMap.set(unit, data);
|
|
10291
|
-
return data;
|
|
10404
|
+
return toDrawData.call(this, unit);
|
|
10292
10405
|
}
|
|
10293
10406
|
/** 转为图片
|
|
10294
10407
|
* @param type
|
|
10295
10408
|
*/
|
|
10296
10409
|
async toDxfImageBlob(unit = "Centimeters", type = "image/jpeg", background = "#000") {
|
|
10297
10410
|
const data = this.toDrawData(unit);
|
|
10298
|
-
|
|
10299
|
-
let canvas;
|
|
10300
|
-
if (typeof window !== "undefined") {
|
|
10301
|
-
canvas = document.createElement("canvas");
|
|
10302
|
-
} else if (typeof global !== "undefined") {
|
|
10303
|
-
const { createCanvas } = await include("canvas");
|
|
10304
|
-
canvas = createCanvas(data.width + margin * 2, data.height + margin * 2);
|
|
10305
|
-
} else {
|
|
10306
|
-
throw new Error("创建画布失败");
|
|
10307
|
-
}
|
|
10308
|
-
const colors = {
|
|
10309
|
-
cyan: "cyan",
|
|
10310
|
-
yellow: "yellow",
|
|
10311
|
-
white: "white"
|
|
10312
|
-
};
|
|
10313
|
-
canvas.width = data.width + margin * 2;
|
|
10314
|
-
canvas.height = data.height + margin * 2;
|
|
10315
|
-
const ctx = canvas.getContext("2d");
|
|
10316
|
-
if (background) {
|
|
10317
|
-
ctx.fillStyle = background;
|
|
10318
|
-
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
10319
|
-
}
|
|
10320
|
-
ctx.translate(-data.center.x + data.width * 0.5 + margin, data.center.y + data.height * 0.5 + margin);
|
|
10321
|
-
ctx.scale(1, -1);
|
|
10322
|
-
data.lines.forEach(([p1x, p1y, p2x, p2y, color]) => {
|
|
10323
|
-
ctx.strokeStyle = colors[color] ?? color;
|
|
10324
|
-
ctx.beginPath();
|
|
10325
|
-
ctx.moveTo(p1x, p1y);
|
|
10326
|
-
ctx.lineTo(p2x, p2y);
|
|
10327
|
-
ctx.closePath();
|
|
10328
|
-
ctx.stroke();
|
|
10329
|
-
});
|
|
10330
|
-
data.lines2.forEach(([p1x, p1y, p2x, p2y, color]) => {
|
|
10331
|
-
ctx.strokeStyle = colors[color] ?? color;
|
|
10332
|
-
ctx.beginPath();
|
|
10333
|
-
ctx.moveTo(p1x, p1y);
|
|
10334
|
-
ctx.lineTo(p2x, p2y);
|
|
10335
|
-
ctx.closePath();
|
|
10336
|
-
ctx.stroke();
|
|
10337
|
-
});
|
|
10338
|
-
data.arcs.forEach(([x, y, radius, startAngle, endAngle, color]) => {
|
|
10339
|
-
ctx.strokeStyle = colors[color];
|
|
10340
|
-
ctx.beginPath();
|
|
10341
|
-
ctx.arc(x, y, radius, startAngle * (Math.PI / 180), endAngle * (Math.PI / 180));
|
|
10342
|
-
ctx.stroke();
|
|
10343
|
-
});
|
|
10344
|
-
data.texts.forEach(([str, x, y, color]) => {
|
|
10345
|
-
ctx.fillStyle = colors[color] ?? color ?? "#fff";
|
|
10346
|
-
ctx.font = `${0.15 * data.scale}px Arial`;
|
|
10347
|
-
ctx.textAlign = "center";
|
|
10348
|
-
ctx.textBaseline = "middle";
|
|
10349
|
-
ctx.save();
|
|
10350
|
-
ctx.translate(x, y);
|
|
10351
|
-
ctx.scale(1, -1);
|
|
10352
|
-
ctx.fillText(str, 0, 0);
|
|
10353
|
-
ctx.restore();
|
|
10354
|
-
});
|
|
10355
|
-
if ("toBlob" in canvas) {
|
|
10356
|
-
return new Promise((resolve) => {
|
|
10357
|
-
canvas.toBlob((b4) => {
|
|
10358
|
-
resolve(b4);
|
|
10359
|
-
}, type, 1);
|
|
10360
|
-
});
|
|
10361
|
-
} else {
|
|
10362
|
-
const buffer = canvas.toBuffer(type, { quality: 1 });
|
|
10363
|
-
return buffer;
|
|
10364
|
-
}
|
|
10411
|
+
return toDxfImageBlob(data, type, background);
|
|
10365
10412
|
}
|
|
10366
10413
|
/** 下载为图片
|
|
10367
10414
|
* @param filename
|
|
@@ -10389,28 +10436,8 @@ class CAD {
|
|
|
10389
10436
|
* 将点json结构转换为Dxf string
|
|
10390
10437
|
*/
|
|
10391
10438
|
toDxfString(unit = "Millimeters") {
|
|
10392
|
-
const d2 = new Drawing();
|
|
10393
|
-
d2.setUnits(unit);
|
|
10394
|
-
d2.addLayer("cyan", Drawing.ACI.CYAN, "DOTTED");
|
|
10395
|
-
d2.addLayer("yellow", Drawing.ACI.YELLOW, "DOTTED");
|
|
10396
|
-
d2.addLayer("white", Drawing.ACI.WHITE, "DOTTED");
|
|
10397
|
-
d2.addLayer("blue", Drawing.ACI.BLUE, "DOTTED");
|
|
10398
|
-
d2.addLayer("green", Drawing.ACI.GREEN, "DOTTED");
|
|
10399
|
-
d2.addLayer("layer", Drawing.ACI.LAYER, "DOTTED");
|
|
10400
|
-
d2.addLayer("magenta", Drawing.ACI.MAGENTA, "DOTTED");
|
|
10401
|
-
d2.addLayer("red", Drawing.ACI.RED, "DOTTED");
|
|
10402
10439
|
const data = this.toDrawData(unit);
|
|
10403
|
-
data
|
|
10404
|
-
let [p1x, p1y, p2x, p2y, color] = item;
|
|
10405
|
-
d2.setActiveLayer(color);
|
|
10406
|
-
d2.drawLine(p1x, p1y, p2x, p2y);
|
|
10407
|
-
});
|
|
10408
|
-
data.arcs.forEach((item) => {
|
|
10409
|
-
const [x, y, r2, startAngle, endAngle, color] = item;
|
|
10410
|
-
d2.setActiveLayer(color);
|
|
10411
|
-
d2.drawArc(x, y, r2, startAngle, endAngle);
|
|
10412
|
-
});
|
|
10413
|
-
return d2.toDxfString();
|
|
10440
|
+
return drawDxfString(data, unit);
|
|
10414
10441
|
}
|
|
10415
10442
|
/**
|
|
10416
10443
|
* 将点云结构转换为DXF格式
|
|
@@ -10560,15 +10587,6 @@ class DxfDrawPlugin {
|
|
|
10560
10587
|
});
|
|
10561
10588
|
}
|
|
10562
10589
|
});
|
|
10563
|
-
cad.addDrawHandler({
|
|
10564
|
-
type: ["ruler"],
|
|
10565
|
-
handler({ drawRulerLine, setColor, group }) {
|
|
10566
|
-
setColor("cyan");
|
|
10567
|
-
group.lines.forEach((line) => {
|
|
10568
|
-
drawRulerLine(line.start, line.end);
|
|
10569
|
-
});
|
|
10570
|
-
}
|
|
10571
|
-
});
|
|
10572
10590
|
cad.addDrawHandler({
|
|
10573
10591
|
type: ["balconyRailing"],
|
|
10574
10592
|
handler({ group, setColor, drawLine }) {
|
|
@@ -10580,17 +10598,19 @@ class DxfDrawPlugin {
|
|
|
10580
10598
|
});
|
|
10581
10599
|
}
|
|
10582
10600
|
}
|
|
10583
|
-
class DxfDataPlugin
|
|
10601
|
+
class DxfDataPlugin {
|
|
10584
10602
|
manager;
|
|
10585
10603
|
lines = [];
|
|
10604
|
+
pipeline;
|
|
10586
10605
|
constructor(lines) {
|
|
10587
|
-
super();
|
|
10588
10606
|
this.lines = lines;
|
|
10589
10607
|
this.manager = WallGroupManager.fromByLines(lines);
|
|
10590
|
-
this.
|
|
10591
|
-
|
|
10592
|
-
|
|
10593
|
-
|
|
10608
|
+
this.pipeline = new Pipeline();
|
|
10609
|
+
this.manager.forEach((group) => {
|
|
10610
|
+
const option = { lines: group.lines };
|
|
10611
|
+
this.pipeline.run(group.type, option);
|
|
10612
|
+
group.lines = option.lines;
|
|
10613
|
+
});
|
|
10594
10614
|
}
|
|
10595
10615
|
install(cad) {
|
|
10596
10616
|
const wallGroupManager = this.manager, lines = this.lines;
|
|
@@ -10613,6 +10633,7 @@ class DxfDataPlugin extends Pipeline {
|
|
|
10613
10633
|
cad.addGroupAndOffset([...untreatedWall], { type: "wall" });
|
|
10614
10634
|
cad.addGroups(untreatedDoubleWallGroup, "doubleWall");
|
|
10615
10635
|
cad.unionGroupAll("wall");
|
|
10636
|
+
cad.addGroup(cad.getAllLines(), "measurement");
|
|
10616
10637
|
const offsetWidth = 0.05;
|
|
10617
10638
|
cad.addGroupAndOffset(balconyRailingLines, {
|
|
10618
10639
|
offsetHalfWidth: offsetWidth * 0.5,
|
|
@@ -11157,9 +11178,9 @@ class DoubleWallHelper {
|
|
|
11157
11178
|
quadtree.insert(line);
|
|
11158
11179
|
lines.push(line);
|
|
11159
11180
|
});
|
|
11160
|
-
lines = lineSegmentClipping(lines, 1e-9);
|
|
11161
11181
|
quadtree.clear();
|
|
11162
11182
|
lines.push(...otherLines);
|
|
11183
|
+
lines = lineSegmentClipping(lines, 1e-9);
|
|
11163
11184
|
PointUtils.adsorb(lines.flatMap((line) => line.points), 1e-4);
|
|
11164
11185
|
return lines.filter((line) => line.length() > 1e-9);
|
|
11165
11186
|
}
|
|
@@ -11340,7 +11361,8 @@ function correction(lines, targettLine, option) {
|
|
|
11340
11361
|
new WallInsertObject(newLines).recomputed().merge();
|
|
11341
11362
|
newLines.push(...otherLines);
|
|
11342
11363
|
newLines = removeDangline(newLines, 0.15, true);
|
|
11343
|
-
|
|
11364
|
+
newLines = newLines.filter((line) => line.length() > 1e-9);
|
|
11365
|
+
return newLines;
|
|
11344
11366
|
}
|
|
11345
11367
|
function axisAlignCorr(lines, option, verticalReferenceLine) {
|
|
11346
11368
|
verticalReferenceLine = verticalReferenceLine ?? LineSegmentUtils.findDominantDirectionLine(lines.filter((line) => !line.userData.isDoor));
|
|
@@ -71,20 +71,7 @@ export declare class Dxf<TEventMap extends {} = {}> extends Component<{
|
|
|
71
71
|
downloadOriginalData(filename: string): Promise<void>;
|
|
72
72
|
/** 获取绘制数据
|
|
73
73
|
*/
|
|
74
|
-
toDrawData(unit?: Unit):
|
|
75
|
-
unit: Unit;
|
|
76
|
-
lines: [number, number, number, number, string][];
|
|
77
|
-
lines2: [number, number, number, number, string][];
|
|
78
|
-
arcs: [number, number, number, number, number, string][];
|
|
79
|
-
texts: [string, number, number, string][];
|
|
80
|
-
center: {
|
|
81
|
-
x: number;
|
|
82
|
-
y: number;
|
|
83
|
-
};
|
|
84
|
-
width: number;
|
|
85
|
-
height: number;
|
|
86
|
-
scale: number;
|
|
87
|
-
} | undefined;
|
|
74
|
+
toDrawData(unit?: Unit): import('../utils/CAD/drawData').DrawData | undefined;
|
|
88
75
|
/** 获取 dxf 图片 二进制对象
|
|
89
76
|
* @param type
|
|
90
77
|
*/
|
|
@@ -169,12 +169,12 @@ export declare class CommandFlowComponent<TEventMap extends {} = {}> extends Com
|
|
|
169
169
|
}): {
|
|
170
170
|
readonly ended: boolean;
|
|
171
171
|
end: () => void;
|
|
172
|
-
next: (mode_: "all" | "
|
|
172
|
+
next: (mode_: "all" | "line" | "point" | "empty" | "line_point" | "line_empty" | "point_empty" | "null") => Promise<{
|
|
173
173
|
point: Point;
|
|
174
174
|
line?: LineSegment;
|
|
175
175
|
} | null>;
|
|
176
176
|
setBaseLine(line: LineSegment<Record<string, any>> | null, point: Point | null): void;
|
|
177
|
-
points(mode_: "all" | "
|
|
177
|
+
points(mode_: "all" | "line" | "point" | "empty" | "line_point" | "line_empty" | "point_empty" | "null"): {
|
|
178
178
|
next(): Promise<{
|
|
179
179
|
value: {
|
|
180
180
|
point: Point;
|
|
@@ -190,15 +190,15 @@ export declare class CommandFlowComponent<TEventMap extends {} = {}> extends Com
|
|
|
190
190
|
awaitEach(callBack: (result: {
|
|
191
191
|
point: Point<Record<string, any>>;
|
|
192
192
|
line?: LineSegment;
|
|
193
|
-
} | null) => void, mode_?: "all" | "
|
|
193
|
+
} | null) => void, mode_?: "all" | "line" | "point" | "empty" | "line_point" | "line_empty" | "point_empty" | "null"): Promise<{
|
|
194
194
|
readonly ended: boolean;
|
|
195
195
|
end: () => void;
|
|
196
|
-
next: (mode_: "all" | "
|
|
196
|
+
next: (mode_: "all" | "line" | "point" | "empty" | "line_point" | "line_empty" | "point_empty" | "null") => Promise<{
|
|
197
197
|
point: Point;
|
|
198
198
|
line?: LineSegment;
|
|
199
199
|
} | null>;
|
|
200
200
|
setBaseLine(line: LineSegment<Record<string, any>> | null, point: Point | null): void;
|
|
201
|
-
points(mode_: "all" | "
|
|
201
|
+
points(mode_: "all" | "line" | "point" | "empty" | "line_point" | "line_empty" | "point_empty" | "null"): {
|
|
202
202
|
next(): Promise<{
|
|
203
203
|
value: {
|
|
204
204
|
point: Point;
|
|
@@ -214,7 +214,7 @@ export declare class CommandFlowComponent<TEventMap extends {} = {}> extends Com
|
|
|
214
214
|
awaitEach(callBack: (result: {
|
|
215
215
|
point: Point<Record<string, any>>;
|
|
216
216
|
line?: LineSegment;
|
|
217
|
-
} | null) => void, mode_?: "all" | "
|
|
217
|
+
} | null) => void, mode_?: "all" | "line" | "point" | "empty" | "line_point" | "line_empty" | "point_empty" | "null"): Promise</*elided*/ any>;
|
|
218
218
|
}>;
|
|
219
219
|
};
|
|
220
220
|
/**
|
package/src/dxfSystem/type.d.ts
CHANGED
|
@@ -103,19 +103,6 @@ export type OriginalDataItem = {
|
|
|
103
103
|
* [开始点, 结束点, 相交点, 是否是门, 索引]
|
|
104
104
|
*/
|
|
105
105
|
export type DataItem = [Point, Point, number[], boolean, number];
|
|
106
|
-
export type DrawData = {
|
|
107
|
-
unit: Unit;
|
|
108
|
-
line: [number, number, number, number, string][];
|
|
109
|
-
arc: [number, number, number, number, number, string][];
|
|
110
|
-
dimensionLine: number[][];
|
|
111
|
-
center: {
|
|
112
|
-
x: number;
|
|
113
|
-
y: number;
|
|
114
|
-
};
|
|
115
|
-
width: number;
|
|
116
|
-
height: number;
|
|
117
|
-
scale: number;
|
|
118
|
-
};
|
|
119
106
|
export type FittingMethodType = "average" | "max";
|
|
120
107
|
export type SetDataOption = {
|
|
121
108
|
/**
|
|
@@ -190,6 +177,11 @@ export type ItemInfo = {
|
|
|
190
177
|
y: number;
|
|
191
178
|
z: number;
|
|
192
179
|
}[];
|
|
180
|
+
quadContour?: {
|
|
181
|
+
x: number;
|
|
182
|
+
y: number;
|
|
183
|
+
z: number;
|
|
184
|
+
}[];
|
|
193
185
|
direction: {
|
|
194
186
|
x: number;
|
|
195
187
|
y: number;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Unit } from '../../type';
|
|
2
|
+
import { CAD } from '.';
|
|
3
|
+
export type DrawData = {
|
|
4
|
+
unit: Unit;
|
|
5
|
+
lines: [number, number, number, number, string][];
|
|
6
|
+
lines2: [number, number, number, number, string][];
|
|
7
|
+
arcs: [number, number, number, number, number, string][];
|
|
8
|
+
texts: [string, number, number, string][];
|
|
9
|
+
center: {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
};
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
scale: number;
|
|
16
|
+
};
|
|
17
|
+
export declare const units: {
|
|
18
|
+
Unitless: number;
|
|
19
|
+
Inches: number;
|
|
20
|
+
Feet: number;
|
|
21
|
+
Miles: number;
|
|
22
|
+
Millimeters: number;
|
|
23
|
+
Centimeters: number;
|
|
24
|
+
Meters: number;
|
|
25
|
+
Kilometers: number;
|
|
26
|
+
Microinches: number;
|
|
27
|
+
Mils: number;
|
|
28
|
+
Yards: number;
|
|
29
|
+
Angstroms: number;
|
|
30
|
+
Nanometers: number;
|
|
31
|
+
Microns: number;
|
|
32
|
+
Decimeters: number;
|
|
33
|
+
Decameters: number;
|
|
34
|
+
Hectometers: number;
|
|
35
|
+
Gigameters: number;
|
|
36
|
+
"Astronomical units": number;
|
|
37
|
+
"Light years": number;
|
|
38
|
+
Parsecs: number;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* 转为绘制数据
|
|
42
|
+
*/
|
|
43
|
+
export declare function toDrawData(this: CAD, unit?: Unit): DrawData;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { LineSegment } from '
|
|
2
|
-
import { LineUserData, Unit } from '
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { LineSegment } from '../../../utils/algorithms/LineSegment';
|
|
2
|
+
import { LineUserData, Unit } from '../../type';
|
|
3
|
+
import { SetMap } from '../../../utils/algorithms/Map';
|
|
4
|
+
import { Point } from '../../../utils/algorithms/Point';
|
|
5
|
+
import { WallGroupManager } from '../WallGroupManager';
|
|
6
|
+
import { Pipeline } from '../../../utils/algorithms/Pipeline';
|
|
6
7
|
type LineSegmentType = LineSegment<LineUserData>;
|
|
7
8
|
type JoinType = "jtMiter" | "jtSquare" | "jtRound";
|
|
8
9
|
type EndType = "etOpenSquare" | "etOpenButt" | "etOpenRound";
|
|
@@ -26,6 +27,7 @@ export type CADDrawHandler = {
|
|
|
26
27
|
drawArc(pos: Point, radius: number, startAngle: number, endAngle: number): void;
|
|
27
28
|
drawDottedLine(p1: Point, p2: Point, dash?: number, gap?: number): void;
|
|
28
29
|
drawRulerLine(p1: Point, p2: Point): void;
|
|
30
|
+
drawText(str: string, p: Point): void;
|
|
29
31
|
group: Group;
|
|
30
32
|
setColor: (color: string) => void;
|
|
31
33
|
}) => void;
|
|
@@ -51,7 +53,7 @@ declare class Group {
|
|
|
51
53
|
*/
|
|
52
54
|
export declare class CAD {
|
|
53
55
|
groups: Group[];
|
|
54
|
-
|
|
56
|
+
_drawHandlerMap: SetMap<string, CADDrawHandler>;
|
|
55
57
|
needUpdate: boolean;
|
|
56
58
|
getAllLines(): LineSegmentType[];
|
|
57
59
|
/** 添加组
|
|
@@ -98,8 +100,8 @@ export declare class CAD {
|
|
|
98
100
|
/**
|
|
99
101
|
* 转为绘制数据
|
|
100
102
|
*/
|
|
101
|
-
|
|
102
|
-
toDrawData(unit?: Unit): DrawData;
|
|
103
|
+
_cachedDrawDataMap: Map<string, DrawData>;
|
|
104
|
+
toDrawData(unit?: Unit): import('./drawData').DrawData;
|
|
103
105
|
/** 转为图片
|
|
104
106
|
* @param type
|
|
105
107
|
*/
|
|
@@ -157,11 +159,11 @@ type DataOption = {
|
|
|
157
159
|
};
|
|
158
160
|
/** dxf 数据处理插件
|
|
159
161
|
*/
|
|
160
|
-
export declare class DxfDataPlugin
|
|
162
|
+
export declare class DxfDataPlugin implements ICADPlugin {
|
|
161
163
|
manager: WallGroupManager;
|
|
162
164
|
lines: LineSegment<LineUserData>[];
|
|
165
|
+
pipeline: Pipeline<DataOption>;
|
|
163
166
|
constructor(lines: LineSegment<LineUserData>[]);
|
|
164
|
-
init(): void;
|
|
165
167
|
install(cad: CAD): void;
|
|
166
168
|
}
|
|
167
169
|
export {};
|
|
@@ -5,4 +5,4 @@ import { LineUserData } from '../type';
|
|
|
5
5
|
* @param minLen
|
|
6
6
|
* @returns
|
|
7
7
|
*/
|
|
8
|
-
export declare function lineSegmentClipping(lines: LineSegment<LineUserData>[], minLen?: number, dedup?: boolean): LineSegment<Record<string, any>>[];
|
|
8
|
+
export declare function lineSegmentClipping(lines: LineSegment<LineUserData>[], minLen?: number, dedup?: boolean): LineSegment<Record<string, any>>[] | LineSegment<LineUserData>[];
|
|
@@ -4,16 +4,18 @@ import { Rectangle } from './Rectangle';
|
|
|
4
4
|
* 非轴对称线段
|
|
5
5
|
*/
|
|
6
6
|
export declare class LineSegment<T = Record<string, any>> {
|
|
7
|
-
#private;
|
|
8
7
|
static get LINE_SYMBOL(): symbol;
|
|
9
8
|
points: Point[];
|
|
10
9
|
userData: T;
|
|
11
10
|
currentData: Record<string | number | symbol, any>;
|
|
12
11
|
uuid: string;
|
|
12
|
+
private _length;
|
|
13
13
|
get len(): number;
|
|
14
14
|
get start(): Point<Record<string, any>>;
|
|
15
15
|
get end(): Point<Record<string, any>>;
|
|
16
|
+
_center: Point<Record<string, any>>;
|
|
16
17
|
get center(): Point<Record<string, any>>;
|
|
18
|
+
_direction: Point<Record<string, any>>;
|
|
17
19
|
constructor(p1?: Point, p2?: Point);
|
|
18
20
|
private _initLenListener;
|
|
19
21
|
set(p1: Point, p2: Point): this;
|
|
@@ -41,25 +43,25 @@ export declare class LineSegment<T = Record<string, any>> {
|
|
|
41
43
|
* @param line
|
|
42
44
|
* @returns
|
|
43
45
|
*/
|
|
44
|
-
isSameEndpoint(line: LineSegment): boolean;
|
|
46
|
+
isSameEndpoint(line: LineSegment, eps?: number): boolean;
|
|
45
47
|
/**
|
|
46
48
|
* 相同端点是否为开始
|
|
47
49
|
* @param line
|
|
48
50
|
* @returns
|
|
49
51
|
*/
|
|
50
|
-
isSameEndpointAsStart(line: LineSegment): boolean;
|
|
52
|
+
isSameEndpointAsStart(line: LineSegment, eps?: number): boolean;
|
|
51
53
|
/**
|
|
52
54
|
* 相同端点是否为结束
|
|
53
55
|
* @param line
|
|
54
56
|
* @returns
|
|
55
57
|
*/
|
|
56
|
-
isSameEndpointAsEnd(line: LineSegment): boolean;
|
|
58
|
+
isSameEndpointAsEnd(line: LineSegment, eps?: number): boolean;
|
|
57
59
|
/**
|
|
58
60
|
* 获取共线点
|
|
59
61
|
* @param line
|
|
60
62
|
* @returns
|
|
61
63
|
*/
|
|
62
|
-
getSameEndpoint(line: LineSegment): Point<Record<string, any>>[] | null;
|
|
64
|
+
getSameEndpoint(line: LineSegment, eps?: number): Point<Record<string, any>>[] | null;
|
|
63
65
|
/**
|
|
64
66
|
* 判断一个点是否在当前线段上(包含端点)
|
|
65
67
|
* @param point 要判断的点
|
|
@@ -113,6 +113,7 @@ export declare class LineSegmentUtils {
|
|
|
113
113
|
* @returns
|
|
114
114
|
*/
|
|
115
115
|
static flatPoints(lines: LineSegment[] | LineSegment): any[];
|
|
116
|
+
static resolveIntersection<T>(lines: LineSegment[], onClip?: (target: LineSegment<T>, newLines: LineSegment<T>[]) => void): LineSegment<T>[];
|
|
116
117
|
/** 对线段组统计,找到主导方向线
|
|
117
118
|
* @param lineSegments
|
|
118
119
|
* @returns
|