build-dxf 0.1.55 → 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.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DxfSystem } from './utils/DxfSystem';
|
|
2
|
-
import { OriginalDataItem, SetDataOption } from './utils/DxfSystem/type';
|
|
2
|
+
import { LineUserData, OriginalDataItem, SetDataOption } from './utils/DxfSystem/type';
|
|
3
3
|
import { WhiteModel } from './utils/DxfSystem/plugin/ModelDataPlugin/components/WhiteModel';
|
|
4
|
+
import { LineSegment } from './utils';
|
|
4
5
|
import * as THREE from "three";
|
|
5
6
|
export { Dxf } from './utils/DxfSystem/components/Dxf';
|
|
6
7
|
export * from './utils/DxfSystem/DxfSystem';
|
|
@@ -83,4 +84,10 @@ export declare function getGlobalDxfSystem(): DxfSystem | null;
|
|
|
83
84
|
* @param direction
|
|
84
85
|
* @returns
|
|
85
86
|
*/
|
|
86
|
-
export declare function hasCircle(lineData: OriginalDataItem[], startIndex: number, direction: any):
|
|
87
|
+
export declare function hasCircle(lineData: OriginalDataItem[], startIndex: number, direction: any): {
|
|
88
|
+
readonly originalIndices: number[];
|
|
89
|
+
readonly indices: number[];
|
|
90
|
+
circle: LineSegment<Record<string, any>>[];
|
|
91
|
+
originalLines: LineSegment<LineUserData>[];
|
|
92
|
+
lines: LineSegment<Record<string, any>>[];
|
|
93
|
+
} | null;
|
package/src/build.js
CHANGED
|
@@ -711,9 +711,9 @@ class Quadtree {
|
|
|
711
711
|
* 插入线段节点
|
|
712
712
|
* @param node 线段节点
|
|
713
713
|
*/
|
|
714
|
-
insert(node) {
|
|
714
|
+
insert(node, userData) {
|
|
715
715
|
if (node instanceof LineSegment) {
|
|
716
|
-
this.insert({ line: node, userData: {} });
|
|
716
|
+
this.insert({ line: node, userData: userData ?? {} });
|
|
717
717
|
return;
|
|
718
718
|
}
|
|
719
719
|
if (!this.isLeaf) {
|
|
@@ -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") {
|
|
@@ -5443,8 +5510,9 @@ function createPointVirtualGrid(lines) {
|
|
|
5443
5510
|
}
|
|
5444
5511
|
function createQuadtree(lines) {
|
|
5445
5512
|
const quadtree = new Quadtree(Box2.fromByLineSegment(...lines));
|
|
5446
|
-
for (
|
|
5447
|
-
|
|
5513
|
+
for (let i = 0; i < lines.length; i++) {
|
|
5514
|
+
const seg = lines[i];
|
|
5515
|
+
quadtree.insert(seg, { index: i });
|
|
5448
5516
|
}
|
|
5449
5517
|
return quadtree;
|
|
5450
5518
|
}
|
|
@@ -5454,10 +5522,50 @@ function mToMm(value) {
|
|
|
5454
5522
|
function mmTom(value) {
|
|
5455
5523
|
return Number((value / 1e3).toFixed(4));
|
|
5456
5524
|
}
|
|
5525
|
+
function getLineIndexByCenter(targetLines, lines) {
|
|
5526
|
+
const grid = createQuadtree(lines);
|
|
5527
|
+
const indices = targetLines.map((line) => {
|
|
5528
|
+
const res = grid.queryPoint(line.center);
|
|
5529
|
+
if (res.length) return res[0].userData.index;
|
|
5530
|
+
return -1;
|
|
5531
|
+
});
|
|
5532
|
+
return indices;
|
|
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
|
+
}
|
|
5457
5563
|
const tools = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
5458
5564
|
__proto__: null,
|
|
5459
5565
|
createPointVirtualGrid,
|
|
5460
5566
|
createQuadtree,
|
|
5567
|
+
getLineIndexByCenter,
|
|
5568
|
+
lazy,
|
|
5461
5569
|
mToMm,
|
|
5462
5570
|
mmTom
|
|
5463
5571
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -16526,23 +16634,41 @@ class SceneAutoGenerat {
|
|
|
16526
16634
|
child.updateWorldMatrix(false, false);
|
|
16527
16635
|
});
|
|
16528
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
|
+
}
|
|
16529
16645
|
buildPlane(lines) {
|
|
16530
16646
|
lines = lineSegmentClipping(lines, 0);
|
|
16531
|
-
|
|
16532
|
-
|
|
16533
|
-
|
|
16534
|
-
|
|
16535
|
-
|
|
16536
|
-
|
|
16537
|
-
|
|
16538
|
-
|
|
16539
|
-
|
|
16540
|
-
|
|
16541
|
-
|
|
16542
|
-
|
|
16543
|
-
|
|
16544
|
-
|
|
16545
|
-
|
|
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
|
+
});
|
|
16546
16672
|
});
|
|
16547
16673
|
}
|
|
16548
16674
|
wallGroup = null;
|
|
@@ -19869,22 +19995,37 @@ function getGlobalDxfSystem() {
|
|
|
19869
19995
|
function hasCircle(lineData, startIndex, direction) {
|
|
19870
19996
|
let lines = originalDataToLineData(lineData).lineSegments;
|
|
19871
19997
|
const center = lines[startIndex].center;
|
|
19872
|
-
|
|
19873
|
-
let removeSet = findDiscretePointLine2(
|
|
19874
|
-
|
|
19875
|
-
const list =
|
|
19876
|
-
if (list.length === 0) return
|
|
19998
|
+
let findlines = lineSegmentClipping(lines.map((line2) => line2.clone()), 1e-9);
|
|
19999
|
+
let removeSet = findDiscretePointLine2(findlines, /* @__PURE__ */ new Set(), true);
|
|
20000
|
+
findlines = findlines.filter((line2) => !removeSet.has(line2));
|
|
20001
|
+
const list = findlines.filter((line2) => line2.userData.isBayWindow && line2.isPointOnSegment(center));
|
|
20002
|
+
if (list.length === 0) return null;
|
|
19877
20003
|
const miniCircles = new MiniCircles(), line = list[0], direct = Point.from(direction), entity = line.center.add(direct.multiplyScalar(1e-8)), path = /* @__PURE__ */ new Set([line]);
|
|
19878
20004
|
const result = miniCircles.findSameSidePath({
|
|
19879
20005
|
line,
|
|
19880
20006
|
currentPoint: line.start,
|
|
19881
20007
|
exitPoint: line.start,
|
|
19882
20008
|
entity: entity.clone(),
|
|
19883
|
-
grid:
|
|
20009
|
+
grid: findlines,
|
|
19884
20010
|
side: Side.IN,
|
|
19885
20011
|
path
|
|
19886
20012
|
});
|
|
19887
|
-
|
|
20013
|
+
if (result) {
|
|
20014
|
+
let indices = lazy(() => getLineIndexByCenter(result, findlines).filter((i) => i > -1));
|
|
20015
|
+
let originalDataIndices = lazy(() => getLineIndexByCenter(result, lines).filter((i) => i > -1));
|
|
20016
|
+
return {
|
|
20017
|
+
get originalIndices() {
|
|
20018
|
+
return originalDataIndices.value;
|
|
20019
|
+
},
|
|
20020
|
+
get indices() {
|
|
20021
|
+
return indices.value;
|
|
20022
|
+
},
|
|
20023
|
+
circle: result,
|
|
20024
|
+
originalLines: lines,
|
|
20025
|
+
lines: findlines
|
|
20026
|
+
};
|
|
20027
|
+
}
|
|
20028
|
+
return null;
|
|
19888
20029
|
}
|
|
19889
20030
|
export {
|
|
19890
20031
|
ArrayMap as A,
|
|
@@ -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
|
/** 构建墙壁
|
|
@@ -2,6 +2,19 @@ import { PointVirtualGrid } from '../../PointVirtualGrid';
|
|
|
2
2
|
import { LineSegment } from '../../LineSegment';
|
|
3
3
|
import { Quadtree } from '../../Quadtree';
|
|
4
4
|
export declare function createPointVirtualGrid<T = any>(lines: LineSegment<T>[]): PointVirtualGrid<LineSegment<T>>;
|
|
5
|
-
export declare function createQuadtree<T = any>(lines: LineSegment<T>[]): Quadtree<
|
|
5
|
+
export declare function createQuadtree<T = any>(lines: LineSegment<T>[]): Quadtree<{
|
|
6
|
+
index: number;
|
|
7
|
+
}>;
|
|
6
8
|
export declare function mToMm(value: number): number;
|
|
7
9
|
export declare function mmTom(value: number): number;
|
|
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 {};
|
package/src/utils/Quadtree.d.ts
CHANGED