build-dxf 0.1.56 → 0.1.57
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
CHANGED
package/src/build.js
CHANGED
|
@@ -4883,19 +4883,35 @@ class Polygon extends Array {
|
|
|
4883
4883
|
this.forEach((p2) => p2.multiplyScalar(scale2));
|
|
4884
4884
|
return this;
|
|
4885
4885
|
}
|
|
4886
|
+
round() {
|
|
4887
|
+
this.forEach((p2) => {
|
|
4888
|
+
p2.x = Math.round(p2.x);
|
|
4889
|
+
p2.y = Math.round(p2.y);
|
|
4890
|
+
});
|
|
4891
|
+
return this;
|
|
4892
|
+
}
|
|
4886
4893
|
/**
|
|
4887
4894
|
* @param polygon
|
|
4888
4895
|
*/
|
|
4889
|
-
union(
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4896
|
+
union(polygons, scale2 = 1) {
|
|
4897
|
+
polygons = Polygon.booleanOp(this, polygons, {
|
|
4898
|
+
scale: scale2,
|
|
4899
|
+
type: "Union"
|
|
4900
|
+
});
|
|
4901
|
+
if (polygons.length !== 1) return false;
|
|
4902
|
+
this.set(polygons[0]);
|
|
4903
|
+
return true;
|
|
4904
|
+
}
|
|
4905
|
+
/** 差集
|
|
4906
|
+
* @param polygon
|
|
4907
|
+
*/
|
|
4908
|
+
difference(polygons, scale2 = 1) {
|
|
4909
|
+
polygons = Polygon.booleanOp(this, polygons, {
|
|
4910
|
+
scale: scale2,
|
|
4911
|
+
type: "Difference"
|
|
4912
|
+
});
|
|
4913
|
+
if (polygons.length !== 1) return false;
|
|
4914
|
+
this.set(polygons[0]);
|
|
4899
4915
|
return true;
|
|
4900
4916
|
}
|
|
4901
4917
|
/** 拆分为凸包
|
|
@@ -4936,6 +4952,10 @@ class Polygon extends Array {
|
|
|
4936
4952
|
}
|
|
4937
4953
|
return this;
|
|
4938
4954
|
}
|
|
4955
|
+
clone() {
|
|
4956
|
+
const polygon2 = new Polygon([...this].map((p2) => p2.clone()));
|
|
4957
|
+
return polygon2;
|
|
4958
|
+
}
|
|
4939
4959
|
/** 通过线段创建, 默认路径只有一条
|
|
4940
4960
|
* @param lines
|
|
4941
4961
|
* @returns
|
|
@@ -5023,6 +5043,53 @@ class Polygon extends Array {
|
|
|
5023
5043
|
}
|
|
5024
5044
|
return polygon2;
|
|
5025
5045
|
}
|
|
5046
|
+
/**
|
|
5047
|
+
* @param poly
|
|
5048
|
+
*/
|
|
5049
|
+
static ensureCCW(poly) {
|
|
5050
|
+
if (!ClipperLib.Clipper.Orientation(poly)) poly.reverse();
|
|
5051
|
+
}
|
|
5052
|
+
/** 布尔运算
|
|
5053
|
+
* @param subject
|
|
5054
|
+
* @param polygons
|
|
5055
|
+
* @param scale 数据缩放
|
|
5056
|
+
* @returns
|
|
5057
|
+
*/
|
|
5058
|
+
static booleanOp(subject, clips, opt) {
|
|
5059
|
+
const { type = "Union", subjectFillType = "NonZero", clipFillType = "NonZero", scale: scale2 = 100 } = opt;
|
|
5060
|
+
if (subject instanceof Polygon) subject = [subject];
|
|
5061
|
+
if (clips instanceof Polygon) clips = [clips];
|
|
5062
|
+
subject = subject.map((subject2) => subject2.clone().scale(scale2).round());
|
|
5063
|
+
clips = clips.map((clips2) => clips2.clone().scale(scale2).round());
|
|
5064
|
+
const clipper = new ClipperLib.Clipper();
|
|
5065
|
+
clipper.StrictlySimple = true;
|
|
5066
|
+
clipper.PreserveCollinear = true;
|
|
5067
|
+
subject = subject.map((p2) => {
|
|
5068
|
+
p2 = ClipperLib.Clipper.CleanPolygon(p2, 0.5 * scale2 / 100);
|
|
5069
|
+
Polygon.ensureCCW(p2);
|
|
5070
|
+
return p2;
|
|
5071
|
+
});
|
|
5072
|
+
clips = clips.map((p2) => {
|
|
5073
|
+
p2 = ClipperLib.Clipper.CleanPolygon(p2, 0.5 * scale2 / 100);
|
|
5074
|
+
Polygon.ensureCCW(p2);
|
|
5075
|
+
return p2;
|
|
5076
|
+
});
|
|
5077
|
+
clipper.AddPaths(subject, ClipperLib.PolyType.ptSubject, true);
|
|
5078
|
+
clipper.AddPaths(clips, ClipperLib.PolyType.ptClip, true);
|
|
5079
|
+
let solutions = [];
|
|
5080
|
+
clipper.Execute(
|
|
5081
|
+
ClipperLib.ClipType["ct" + type],
|
|
5082
|
+
solutions,
|
|
5083
|
+
ClipperLib.PolyFillType["pft" + subjectFillType],
|
|
5084
|
+
ClipperLib.PolyFillType["pft" + clipFillType]
|
|
5085
|
+
);
|
|
5086
|
+
const inv = 1 / scale2;
|
|
5087
|
+
const results = solutions.map((solution) => {
|
|
5088
|
+
solution = solution.map((p2) => new Point(p2.X * inv, p2.Y * inv));
|
|
5089
|
+
return new Polygon(solution);
|
|
5090
|
+
}).filter((poly) => Math.abs(poly.area()) > 0.01);
|
|
5091
|
+
return results;
|
|
5092
|
+
}
|
|
5026
5093
|
}
|
|
5027
5094
|
async function include(path, exportDefault = true) {
|
|
5028
5095
|
if (typeof global !== "undefined" && typeof require !== "undefined") {
|
|
@@ -5464,11 +5531,41 @@ function getLineIndexByCenter(targetLines, lines) {
|
|
|
5464
5531
|
});
|
|
5465
5532
|
return indices;
|
|
5466
5533
|
}
|
|
5534
|
+
function lazy(fn2) {
|
|
5535
|
+
let cached = false;
|
|
5536
|
+
let value;
|
|
5537
|
+
let type;
|
|
5538
|
+
return Object.freeze({
|
|
5539
|
+
get isValueCreated() {
|
|
5540
|
+
return cached;
|
|
5541
|
+
},
|
|
5542
|
+
get value() {
|
|
5543
|
+
if (!cached) {
|
|
5544
|
+
value = fn2();
|
|
5545
|
+
cached = true;
|
|
5546
|
+
}
|
|
5547
|
+
return value;
|
|
5548
|
+
},
|
|
5549
|
+
get cachedValue() {
|
|
5550
|
+
return cached ? value : void 0;
|
|
5551
|
+
},
|
|
5552
|
+
get valueType() {
|
|
5553
|
+
if (type === void 0) type = typeof this.value;
|
|
5554
|
+
return type;
|
|
5555
|
+
},
|
|
5556
|
+
reset() {
|
|
5557
|
+
cached = false;
|
|
5558
|
+
type = void 0;
|
|
5559
|
+
value = void 0;
|
|
5560
|
+
}
|
|
5561
|
+
});
|
|
5562
|
+
}
|
|
5467
5563
|
const tools = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
5468
5564
|
__proto__: null,
|
|
5469
5565
|
createPointVirtualGrid,
|
|
5470
5566
|
createQuadtree,
|
|
5471
5567
|
getLineIndexByCenter,
|
|
5568
|
+
lazy,
|
|
5472
5569
|
mToMm,
|
|
5473
5570
|
mmTom
|
|
5474
5571
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -16537,23 +16634,41 @@ class SceneAutoGenerat {
|
|
|
16537
16634
|
child.updateWorldMatrix(false, false);
|
|
16538
16635
|
});
|
|
16539
16636
|
}
|
|
16637
|
+
createGeometryByLines(lines) {
|
|
16638
|
+
const shape = new THREE.Shape();
|
|
16639
|
+
Polygon.fromByLinePath(lines, polygon);
|
|
16640
|
+
polygon.forEach((p2, i) => i === 0 ? shape.moveTo(p2.x, p2.y) : shape.lineTo(p2.x, p2.y));
|
|
16641
|
+
shape.closePath();
|
|
16642
|
+
const geometry = new THREE.ShapeGeometry(shape);
|
|
16643
|
+
return geometry;
|
|
16644
|
+
}
|
|
16540
16645
|
buildPlane(lines) {
|
|
16541
16646
|
lines = lineSegmentClipping(lines, 0);
|
|
16542
|
-
|
|
16543
|
-
|
|
16544
|
-
|
|
16545
|
-
|
|
16546
|
-
|
|
16547
|
-
|
|
16548
|
-
|
|
16549
|
-
|
|
16550
|
-
|
|
16551
|
-
|
|
16552
|
-
|
|
16553
|
-
|
|
16554
|
-
|
|
16555
|
-
|
|
16556
|
-
|
|
16647
|
+
LineSegment.groupByPath(lines).forEach((lines2, i) => {
|
|
16648
|
+
const removeSet = findDiscretePointLine2(lines2, null, true);
|
|
16649
|
+
lines2 = lines2.filter((line) => !removeSet.has(line) && !line.userData.isBayWindow);
|
|
16650
|
+
const doors = lines2.filter((line) => line.userData.isDoor), maxiCircles2 = new MaxiCircles(), { circles } = maxiCircles2.miniCircle(lines2, { circleEdges: doors, side: Side.IN }), { circles: outCircles } = maxiCircles2.miniCircle(lines2, { circleEdges: doors, side: Side.OUT }), ploys = circles.map(((p2) => Polygon.fromByLinePath(p2)));
|
|
16651
|
+
outCircles.forEach((circle) => {
|
|
16652
|
+
const polygon2 = Polygon.fromByLinePath(circle);
|
|
16653
|
+
const newPolys = Polygon.booleanOp(polygon2, ploys, { scale: 100, type: "Difference" });
|
|
16654
|
+
newPolys.forEach((poly, j) => {
|
|
16655
|
+
const geometry = this.createGeometryByLines(poly.toLines());
|
|
16656
|
+
const mesh = new THREE.Mesh(geometry, new THREE.MeshStandardMaterial({ color: 11184810, side: THREE.DoubleSide }));
|
|
16657
|
+
mesh.position.z = this.z;
|
|
16658
|
+
mesh.name = `平面_out_${i}_${j}`;
|
|
16659
|
+
mesh.userData.category = "plane";
|
|
16660
|
+
this.scene.add(mesh);
|
|
16661
|
+
});
|
|
16662
|
+
});
|
|
16663
|
+
circles.forEach((circle, j) => {
|
|
16664
|
+
const geometry = this.createGeometryByLines(circle);
|
|
16665
|
+
const mesh = new THREE.Mesh(geometry, new THREE.MeshStandardMaterial({ color: 11184810, side: THREE.DoubleSide }));
|
|
16666
|
+
mesh.position.z = this.z;
|
|
16667
|
+
mesh.name = `平面_${i}_${j}`;
|
|
16668
|
+
mesh.userData.category = "plane";
|
|
16669
|
+
mesh.userData.room = true;
|
|
16670
|
+
this.scene.add(mesh);
|
|
16671
|
+
});
|
|
16557
16672
|
});
|
|
16558
16673
|
}
|
|
16559
16674
|
wallGroup = null;
|
|
@@ -19896,16 +20011,14 @@ function hasCircle(lineData, startIndex, direction) {
|
|
|
19896
20011
|
path
|
|
19897
20012
|
});
|
|
19898
20013
|
if (result) {
|
|
19899
|
-
let indices =
|
|
19900
|
-
let originalDataIndices =
|
|
20014
|
+
let indices = lazy(() => getLineIndexByCenter(result, findlines).filter((i) => i > -1));
|
|
20015
|
+
let originalDataIndices = lazy(() => getLineIndexByCenter(result, lines).filter((i) => i > -1));
|
|
19901
20016
|
return {
|
|
19902
20017
|
get originalIndices() {
|
|
19903
|
-
|
|
19904
|
-
return originalDataIndices;
|
|
20018
|
+
return originalDataIndices.value;
|
|
19905
20019
|
},
|
|
19906
20020
|
get indices() {
|
|
19907
|
-
|
|
19908
|
-
return indices;
|
|
20021
|
+
return indices.value;
|
|
19909
20022
|
},
|
|
19910
20023
|
circle: result,
|
|
19911
20024
|
originalLines: lines,
|
|
@@ -11,6 +11,7 @@ export declare class SceneAutoGenerat {
|
|
|
11
11
|
angle: number;
|
|
12
12
|
constructor(lines: LineSegment[], itemList: any[], z: number, trajectory?: any);
|
|
13
13
|
init(): Promise<void>;
|
|
14
|
+
private createGeometryByLines;
|
|
14
15
|
buildPlane(lines: LineSegment<LineUserData>[]): void;
|
|
15
16
|
wallGroup: Group | null;
|
|
16
17
|
/** 构建墙壁
|
|
@@ -8,3 +8,13 @@ export declare function createQuadtree<T = any>(lines: LineSegment<T>[]): Quadtr
|
|
|
8
8
|
export declare function mToMm(value: number): number;
|
|
9
9
|
export declare function mmTom(value: number): number;
|
|
10
10
|
export declare function getLineIndexByCenter(targetLines: LineSegment[], lines: LineSegment[]): number[];
|
|
11
|
+
type JSValueType = "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function";
|
|
12
|
+
export interface Lazy<T> {
|
|
13
|
+
readonly value: T;
|
|
14
|
+
readonly cachedValue: T | undefined;
|
|
15
|
+
readonly isValueCreated: boolean;
|
|
16
|
+
readonly valueType: JSValueType;
|
|
17
|
+
reset(): void;
|
|
18
|
+
}
|
|
19
|
+
export declare function lazy<T>(fn: () => T): Lazy<T>;
|
|
20
|
+
export {};
|
package/src/utils/Polygon.d.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { Box2 } from './Box2';
|
|
2
2
|
import { LineSegment } from './LineSegment';
|
|
3
3
|
import { Point } from './Point';
|
|
4
|
+
type BooleanOpType = "Union" | "Intersection" | "Difference" | "Xor";
|
|
5
|
+
type FillType = "EvenOdd" | "NonZero" | "Positive" | "Negative";
|
|
6
|
+
type BooleanOpOption = {
|
|
7
|
+
type: BooleanOpType;
|
|
8
|
+
scale: number;
|
|
9
|
+
subjectFillType?: FillType;
|
|
10
|
+
clipFillType?: FillType;
|
|
11
|
+
};
|
|
4
12
|
export declare class Polygon<T = any> extends Array<Point<T>> {
|
|
5
13
|
[Symbol.iterator](): ArrayIterator<Point<T>>;
|
|
6
14
|
constructor(points?: Point<T>[]);
|
|
@@ -55,10 +63,15 @@ export declare class Polygon<T = any> extends Array<Point<T>> {
|
|
|
55
63
|
* @param scale
|
|
56
64
|
*/
|
|
57
65
|
scale(scale?: number): this;
|
|
66
|
+
round(): this;
|
|
58
67
|
/**
|
|
59
68
|
* @param polygon
|
|
60
69
|
*/
|
|
61
|
-
union(
|
|
70
|
+
union(polygons: Polygon | Polygon[], scale?: number): boolean;
|
|
71
|
+
/** 差集
|
|
72
|
+
* @param polygon
|
|
73
|
+
*/
|
|
74
|
+
difference(polygons: Polygon | Polygon[], scale?: number): boolean;
|
|
62
75
|
/** 拆分为凸包
|
|
63
76
|
* @returns
|
|
64
77
|
*/
|
|
@@ -70,6 +83,7 @@ export declare class Polygon<T = any> extends Array<Point<T>> {
|
|
|
70
83
|
toLines(closed?: boolean): LineSegment<Record<string, any>>[];
|
|
71
84
|
toArrays(): [number, number][];
|
|
72
85
|
close(): this;
|
|
86
|
+
clone(): Polygon<Record<string, any>>;
|
|
73
87
|
/** 通过线段创建, 默认路径只有一条
|
|
74
88
|
* @param lines
|
|
75
89
|
* @returns
|
|
@@ -92,4 +106,16 @@ export declare class Polygon<T = any> extends Array<Point<T>> {
|
|
|
92
106
|
* @returns
|
|
93
107
|
*/
|
|
94
108
|
static fromByLinePath(lines: LineSegment[], polygon?: Polygon<any>): Polygon<any>;
|
|
109
|
+
/**
|
|
110
|
+
* @param poly
|
|
111
|
+
*/
|
|
112
|
+
static ensureCCW(poly: Polygon): void;
|
|
113
|
+
/** 布尔运算
|
|
114
|
+
* @param subject
|
|
115
|
+
* @param polygons
|
|
116
|
+
* @param scale 数据缩放
|
|
117
|
+
* @returns
|
|
118
|
+
*/
|
|
119
|
+
static booleanOp(subject: Polygon | Polygon[], clips: Polygon | Polygon[], opt: BooleanOpOption): Polygon<Record<string, any>>[];
|
|
95
120
|
}
|
|
121
|
+
export {};
|