build-dxf 0.0.16 → 0.0.17
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 +212 -23
- package/src/index2.js +56 -9
- package/src/utils/DxfSystem/components/Dxf.d.ts +12 -0
- package/src/utils/DxfSystem/components/LineAnalysis.d.ts +6 -0
- package/src/utils/DxfSystem/plugin/Editor/components/Editor.d.ts +21 -0
- package/src/utils/DxfSystem/plugin/Editor/index.d.ts +2 -0
- package/src/utils/DxfSystem/plugin/RenderPlugin/components/Renderer.d.ts +18 -2
- package/src/utils/Quadtree/LineSegment.d.ts +2 -2
- package/src/utils/Quadtree/Rectangle.d.ts +11 -0
package/package.json
CHANGED
package/src/build.js
CHANGED
|
@@ -592,6 +592,18 @@ class Box2 {
|
|
|
592
592
|
}
|
|
593
593
|
class Rectangle {
|
|
594
594
|
points;
|
|
595
|
+
get p0() {
|
|
596
|
+
return this.points[0];
|
|
597
|
+
}
|
|
598
|
+
get p1() {
|
|
599
|
+
return this.points[1];
|
|
600
|
+
}
|
|
601
|
+
get p2() {
|
|
602
|
+
return this.points[2];
|
|
603
|
+
}
|
|
604
|
+
get p3() {
|
|
605
|
+
return this.points[3];
|
|
606
|
+
}
|
|
595
607
|
get path() {
|
|
596
608
|
return this.points.flatMap((p, i) => {
|
|
597
609
|
const np = this.points[(i + 1) % this.points.length];
|
|
@@ -683,6 +695,40 @@ class Rectangle {
|
|
|
683
695
|
};
|
|
684
696
|
return isPointInRectangle(line.points[0]) && isPointInRectangle(line.points[1]);
|
|
685
697
|
}
|
|
698
|
+
/**
|
|
699
|
+
* 判断矩形是否与矩形相交
|
|
700
|
+
* @description 使用分离轴定理
|
|
701
|
+
* @param rectangle 矩形
|
|
702
|
+
* @returns 是否与矩形相交
|
|
703
|
+
*/
|
|
704
|
+
intersectRectangle(rectangle) {
|
|
705
|
+
const axes = [];
|
|
706
|
+
for (let i = 0; i < 4; i++) {
|
|
707
|
+
const p1 = this.points[i];
|
|
708
|
+
const p2 = this.points[(i + 1) % 4];
|
|
709
|
+
axes.push(p1.normal(p2));
|
|
710
|
+
}
|
|
711
|
+
for (let i = 0; i < 4; i++) {
|
|
712
|
+
const p1 = rectangle.points[i];
|
|
713
|
+
const p2 = rectangle.points[(i + 1) % 4];
|
|
714
|
+
axes.push(p1.normal(p2));
|
|
715
|
+
}
|
|
716
|
+
function projectRectangle(rect, axis) {
|
|
717
|
+
const projections = rect.points.map((point) => point.dot(axis));
|
|
718
|
+
return [Math.min(...projections), Math.max(...projections)];
|
|
719
|
+
}
|
|
720
|
+
function isProjectionOverlap(proj1, proj2) {
|
|
721
|
+
return proj1[0] < proj2[1] && proj2[0] < proj1[1];
|
|
722
|
+
}
|
|
723
|
+
for (const axis of axes) {
|
|
724
|
+
const proj1 = projectRectangle(this, axis);
|
|
725
|
+
const proj2 = projectRectangle(rectangle, axis);
|
|
726
|
+
if (!isProjectionOverlap(proj1, proj2)) {
|
|
727
|
+
return false;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
return true;
|
|
731
|
+
}
|
|
686
732
|
/**
|
|
687
733
|
* 判断点是否完全位于矩形内部
|
|
688
734
|
* @param point
|
|
@@ -734,7 +780,7 @@ class Rectangle {
|
|
|
734
780
|
}
|
|
735
781
|
class LineSegment {
|
|
736
782
|
points = [new Point(), new Point()];
|
|
737
|
-
userData;
|
|
783
|
+
userData = {};
|
|
738
784
|
get center() {
|
|
739
785
|
return new Point(
|
|
740
786
|
this.points[0].x + (this.points[1].x - this.points[0].x) * 0.5,
|
|
@@ -796,11 +842,11 @@ class LineSegment {
|
|
|
796
842
|
* @param width
|
|
797
843
|
* @returns {Rectangle}
|
|
798
844
|
*/
|
|
799
|
-
expandToRectangle(width = 0.1) {
|
|
845
|
+
expandToRectangle(width = 0.1, direct = "all") {
|
|
800
846
|
const p1 = this.start, p2 = this.end;
|
|
801
847
|
const normal = p2.normal(p1);
|
|
802
|
-
const pDirect = p2.direction(p1).mutiplyScalar(width * 0.5);
|
|
803
|
-
const nDirect = p1.direction(p2).mutiplyScalar(width * 0.5);
|
|
848
|
+
const pDirect = direct === "bothSides" ? Point.zero() : p2.direction(p1).mutiplyScalar(width * 0.5);
|
|
849
|
+
const nDirect = direct === "bothSides" ? Point.zero() : p1.direction(p2).mutiplyScalar(width * 0.5);
|
|
804
850
|
const offsetX = normal.x * width * 0.5;
|
|
805
851
|
const offsetY = normal.y * width * 0.5;
|
|
806
852
|
const point = [
|
|
@@ -1153,13 +1199,13 @@ class Dxf extends Component {
|
|
|
1153
1199
|
this.originalData = data;
|
|
1154
1200
|
this.lineSegments.length = 0;
|
|
1155
1201
|
const zList = [];
|
|
1156
|
-
this.data = data.map(({ start, end, insetionArr, isDoor = false }, index2) => {
|
|
1202
|
+
this.data = data.map(({ start, end, insetionArr, isDoor = false, isWindow }, index2) => {
|
|
1157
1203
|
zList.push(start.z ?? 0, end.z ?? 0);
|
|
1158
1204
|
const lineSegment = new LineSegment(
|
|
1159
1205
|
Point.from(start).mutiplyScalar(scale),
|
|
1160
1206
|
Point.from(end).mutiplyScalar(scale)
|
|
1161
1207
|
);
|
|
1162
|
-
lineSegment.userData = { isDoor };
|
|
1208
|
+
lineSegment.userData = { isDoor, isWindow };
|
|
1163
1209
|
this.lineSegments.push(lineSegment);
|
|
1164
1210
|
return [
|
|
1165
1211
|
lineSegment.points[0],
|
|
@@ -1481,27 +1527,41 @@ class Dxf extends Component {
|
|
|
1481
1527
|
}
|
|
1482
1528
|
});
|
|
1483
1529
|
const doorThickness = this.width * 0.2;
|
|
1484
|
-
|
|
1530
|
+
const list = [];
|
|
1531
|
+
d.addLayer("l_cyan", Drawing.ACI.CYAN, "DOTTED");
|
|
1485
1532
|
this.doorLineSegment.forEach((lineSegment) => {
|
|
1486
1533
|
if (lineSegment.length() < 0.4) return;
|
|
1487
1534
|
const line = lineSegment.clone().expansion(-this.width * 0.5);
|
|
1488
|
-
d.setActiveLayer("
|
|
1535
|
+
d.setActiveLayer("l_cyan");
|
|
1489
1536
|
if (line.length() < 1.2) {
|
|
1490
1537
|
line.expansion(-doorThickness * 0.5);
|
|
1491
1538
|
const normal = lineSegment.normal();
|
|
1492
|
-
|
|
1539
|
+
let door = new LineSegment(
|
|
1493
1540
|
line.start.clone(),
|
|
1494
1541
|
line.start.clone().add(normal.clone().multiplyScalar(line.length()))
|
|
1495
1542
|
);
|
|
1496
|
-
door.
|
|
1543
|
+
const box = door.clone().directionMove(door.normal(), line.length() * -0.5).expandToRectangle(line.length(), "bothSides");
|
|
1544
|
+
for (let j = 0; j < list.length; j++) {
|
|
1545
|
+
if (list[j].intersectRectangle(box)) {
|
|
1546
|
+
door = new LineSegment(
|
|
1547
|
+
line.start.clone(),
|
|
1548
|
+
line.start.clone().add(normal.clone().multiplyScalar(-line.length()))
|
|
1549
|
+
);
|
|
1550
|
+
break;
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
door.expansion(-doorThickness * 0.5).expandToRectangle(this.width * 0.2, "bothSides").path2D((p1, p2) => drawLine(p1, p2));
|
|
1497
1554
|
const a = line.length(), b = door.length(), r = (a ** 2 + b ** 2) / (2 * b), center = door.end.clone().add(door.direction().multiplyScalar(-r)), [startAngle, endAngle] = this.getArcAngleRange(center, line.end, door.end);
|
|
1498
1555
|
d.drawArc(center.x * s, center.y * s, r * s, Math.min(startAngle, endAngle), Math.max(startAngle, endAngle));
|
|
1556
|
+
list.push(box);
|
|
1499
1557
|
} else {
|
|
1500
1558
|
line.clone().expansion(-this.width * 0.5).expandToRectangle(this.width).path2D((p1, p2) => drawLine(p1, p2));
|
|
1501
|
-
line.clone().directionMove(line.normal(), doorThickness * 0.5).expansion(-line.length() * 0.
|
|
1502
|
-
line.clone().directionMove(line.normal(), -doorThickness * 0.5).expansion(-line.length() * 0.
|
|
1559
|
+
line.clone().directionMove(line.normal(), doorThickness * 0.5).directionMove(line.direction(), doorThickness * 0.5).expansion(-line.length() * 0.45, "end").forward(doorThickness * 0.5).expandToRectangle(doorThickness).path2D((p1, p2) => drawLine(p1, p2));
|
|
1560
|
+
line.clone().directionMove(line.normal(), -doorThickness * 0.5).directionMove(line.direction(), -doorThickness * 0.5).expansion(-line.length() * 0.45, "start").forward(-doorThickness * 0.5).expandToRectangle(doorThickness).path2D((p1, p2) => drawLine(p1, p2));
|
|
1503
1561
|
}
|
|
1504
1562
|
});
|
|
1563
|
+
d.addLayer("l_yellow", Drawing.ACI.YELLOW, "DOTTED");
|
|
1564
|
+
d.setActiveLayer("l_yellow");
|
|
1505
1565
|
return d.toDxfString();
|
|
1506
1566
|
}
|
|
1507
1567
|
/**
|
|
@@ -2138,7 +2198,6 @@ class LineAnalysis extends Component {
|
|
|
2138
2198
|
* 门的位置判断
|
|
2139
2199
|
*/
|
|
2140
2200
|
doorsAnalysis() {
|
|
2141
|
-
this.parent?.findComponentByName("Renderer");
|
|
2142
2201
|
const dxf = this.Dxf, doorPoints = [], pointVirtualGrid = this.pointVirtualGrid, quadtree = this.quadtree, doorSearchNearAngle = this.doorSearchNearAngle, doorSearchDistance = this.doorSearchDistance, doors = [];
|
|
2143
2202
|
const excludePoints = dxf.doors.flatMap((item) => {
|
|
2144
2203
|
const index2 = item[4];
|
|
@@ -2357,7 +2416,7 @@ class LineAnalysis extends Component {
|
|
|
2357
2416
|
};
|
|
2358
2417
|
}).filter((i) => !!i && i.start.distance(i.end) < doorSearchDistance);
|
|
2359
2418
|
doors.push(...doors_);
|
|
2360
|
-
searchNearRasult.forEach((item
|
|
2419
|
+
searchNearRasult.forEach((item) => {
|
|
2361
2420
|
const start = doorPoints[item.doorIndex].point.clone();
|
|
2362
2421
|
const end = doorPoints[item.findDoorIndex].point.clone();
|
|
2363
2422
|
const startLine = this.findLongLineSegment(doorPoints[item.doorIndex].line);
|
|
@@ -2392,18 +2451,26 @@ class LineAnalysis extends Component {
|
|
|
2392
2451
|
doors.forEach((p) => {
|
|
2393
2452
|
const line = new LineSegment(p?.start, p?.end);
|
|
2394
2453
|
const len = line.length();
|
|
2395
|
-
if (len < 0.
|
|
2396
|
-
const
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2454
|
+
if (len < 0.6) return;
|
|
2455
|
+
const normal = line.normal(), direction = line.direction(), step = (len - dxf.width * 2) / 2;
|
|
2456
|
+
for (let i = 0; i < 3; i++) {
|
|
2457
|
+
const point = line.start.clone().add(direction.clone().multiplyScalar(dxf.width + step * i));
|
|
2458
|
+
const rLine = new LineSegment(
|
|
2459
|
+
point,
|
|
2460
|
+
point.clone().add(normal.clone().multiplyScalar(1))
|
|
2461
|
+
);
|
|
2462
|
+
rLine.directionMove(normal, -0.5);
|
|
2463
|
+
const res = this.quadtree?.queryLineSegment(rLine);
|
|
2464
|
+
if (res?.length) return;
|
|
2465
|
+
}
|
|
2404
2466
|
dxf.doorLineSegment.push(line);
|
|
2405
2467
|
});
|
|
2406
2468
|
}
|
|
2469
|
+
/**
|
|
2470
|
+
*
|
|
2471
|
+
* @param line
|
|
2472
|
+
* @returns
|
|
2473
|
+
*/
|
|
2407
2474
|
findLongLineSegment(line) {
|
|
2408
2475
|
const resLine = line.clone();
|
|
2409
2476
|
const res1 = this.pointVirtualGrid.queryPoint(line.start);
|
|
@@ -2430,6 +2497,128 @@ class LineAnalysis extends Component {
|
|
|
2430
2497
|
}
|
|
2431
2498
|
return resLine;
|
|
2432
2499
|
}
|
|
2500
|
+
doorsAnalysis2() {
|
|
2501
|
+
const renderer = this.parent?.findComponentByName("Renderer");
|
|
2502
|
+
const dxf = this.Dxf, pointVirtualGrid = this.pointVirtualGrid, quadtree = this.quadtree;
|
|
2503
|
+
this.doorSearchNearAngle;
|
|
2504
|
+
this.doorSearchDistance;
|
|
2505
|
+
const doorsAnalysis = new DoorsAnalysis(dxf, pointVirtualGrid, quadtree, this.resultList, this.lineSegmentList);
|
|
2506
|
+
const possiblePoints = doorsAnalysis.searchPossiblePoints();
|
|
2507
|
+
possiblePoints.forEach((l) => {
|
|
2508
|
+
renderer.createPointMesh(l.point).position.z = dxf.originalZAverage;
|
|
2509
|
+
});
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2512
|
+
class DoorsAnalysis {
|
|
2513
|
+
// 所有可查找的点位
|
|
2514
|
+
possibleDoorPoints = [];
|
|
2515
|
+
doorPoint = [];
|
|
2516
|
+
dxf;
|
|
2517
|
+
pointVirtualGrid;
|
|
2518
|
+
quadtree;
|
|
2519
|
+
resultList;
|
|
2520
|
+
// 已过滤门的线段
|
|
2521
|
+
lineSegments;
|
|
2522
|
+
constructor(dxf, pointVirtualGrid, quadtree, resultList = [], lineSegments = []) {
|
|
2523
|
+
this.dxf = dxf;
|
|
2524
|
+
this.pointVirtualGrid = pointVirtualGrid;
|
|
2525
|
+
this.quadtree = quadtree;
|
|
2526
|
+
this.resultList = resultList;
|
|
2527
|
+
this.lineSegments = lineSegments;
|
|
2528
|
+
this.addPointsExcludeRule((line) => line.userData.isDoor);
|
|
2529
|
+
const excludeIndexMap = this.searchDoubleLinePoint();
|
|
2530
|
+
this.addPointsExcludeRule((_1, _2, index2, pointIndex) => {
|
|
2531
|
+
const excludeMode = excludeIndexMap.get(index2);
|
|
2532
|
+
if (typeof excludeMode === "number") {
|
|
2533
|
+
return excludeMode === -1 || excludeMode === pointIndex;
|
|
2534
|
+
}
|
|
2535
|
+
return false;
|
|
2536
|
+
});
|
|
2537
|
+
this.doorPoint = this.searchDoorPoint();
|
|
2538
|
+
this.addPointsExcludeRule((_1, point) => {
|
|
2539
|
+
return !!this.doorPoint.find((p1) => p1.point.equal(point));
|
|
2540
|
+
});
|
|
2541
|
+
this.possibleDoorPoints = this.searchPossiblePoints();
|
|
2542
|
+
}
|
|
2543
|
+
/**
|
|
2544
|
+
*
|
|
2545
|
+
* @param rule
|
|
2546
|
+
*/
|
|
2547
|
+
addPointsExcludeRule(rule) {
|
|
2548
|
+
this._pointsExcludeRule.push(rule);
|
|
2549
|
+
}
|
|
2550
|
+
_pointsExcludeRule = [];
|
|
2551
|
+
/**
|
|
2552
|
+
* 查找所有可能为门的点位
|
|
2553
|
+
*/
|
|
2554
|
+
searchPossiblePoints() {
|
|
2555
|
+
const dxf = this.dxf, doorPoints = [];
|
|
2556
|
+
dxf.lineSegments.forEach((line, i) => {
|
|
2557
|
+
line.points.forEach((p, j) => {
|
|
2558
|
+
for (let i2 = 0; i2 < this._pointsExcludeRule.length; i2++)
|
|
2559
|
+
if (this._pointsExcludeRule[i2](line, p, i2, j)) return;
|
|
2560
|
+
const res = this.pointVirtualGrid.queryPoint(p).filter((d) => d.userData?.index !== i);
|
|
2561
|
+
if (res.length === 0) {
|
|
2562
|
+
doorPoints.push({
|
|
2563
|
+
line,
|
|
2564
|
+
point: p,
|
|
2565
|
+
index: i
|
|
2566
|
+
});
|
|
2567
|
+
}
|
|
2568
|
+
});
|
|
2569
|
+
});
|
|
2570
|
+
return doorPoints;
|
|
2571
|
+
}
|
|
2572
|
+
/**
|
|
2573
|
+
* 查找已知为门的点位
|
|
2574
|
+
*/
|
|
2575
|
+
searchDoorPoint() {
|
|
2576
|
+
const doorPoints = [], dxf = this.dxf, pointVirtualGrid = this.pointVirtualGrid;
|
|
2577
|
+
dxf.doors.forEach((item) => {
|
|
2578
|
+
const index2 = item[4];
|
|
2579
|
+
const doorData = dxf.originalData[index2];
|
|
2580
|
+
if (doorData.drawDoorData) {
|
|
2581
|
+
const point = Point.from(doorData.drawDoorData.start);
|
|
2582
|
+
const direct = Point.from(doorData.drawDoorData.n);
|
|
2583
|
+
const resList = pointVirtualGrid.queryPoint(point).filter((res) => {
|
|
2584
|
+
if (res.userData?.index === index2) return false;
|
|
2585
|
+
const line = dxf.lineSegments[res.userData?.index];
|
|
2586
|
+
const direct2 = line.direction();
|
|
2587
|
+
if (line.start.equal(point)) direct2.multiplyScalar(-1);
|
|
2588
|
+
const angle = direct.angleBetween(direct2, "angle");
|
|
2589
|
+
return angle > 80 || angle < 10;
|
|
2590
|
+
});
|
|
2591
|
+
if (resList.length) {
|
|
2592
|
+
const index22 = resList[0].userData?.index;
|
|
2593
|
+
doorPoints.push({
|
|
2594
|
+
line: dxf.lineSegments[index22],
|
|
2595
|
+
point: Point.from(doorData.drawDoorData.start),
|
|
2596
|
+
index: index22,
|
|
2597
|
+
direct,
|
|
2598
|
+
sure: true
|
|
2599
|
+
});
|
|
2600
|
+
}
|
|
2601
|
+
}
|
|
2602
|
+
});
|
|
2603
|
+
return doorPoints;
|
|
2604
|
+
}
|
|
2605
|
+
/**
|
|
2606
|
+
* 查找双线墙的点位
|
|
2607
|
+
* @returns
|
|
2608
|
+
*/
|
|
2609
|
+
searchDoubleLinePoint() {
|
|
2610
|
+
const excludeIndexMap = /* @__PURE__ */ new Map();
|
|
2611
|
+
this.resultList.flatMap((p) => {
|
|
2612
|
+
const line0 = this.lineSegments[p.sourceIndex], line1 = this.lineSegments[p.targetIndex], start0 = line1.projectPoint(line0.start), end0 = line1.projectPoint(line0.end), start1 = line0.projectPoint(line1.start), end1 = line0.projectPoint(line1.end), mode0 = start0 && end0 ? -1 : start0 ? 0 : end0 ? 1 : -1, mode1 = start1 && end1 ? -1 : start1 ? 0 : end1 ? 1 : -1;
|
|
2613
|
+
if (excludeIndexMap.has(p.sourceIndex)) {
|
|
2614
|
+
if (excludeIndexMap.get(p.sourceIndex) != mode0) excludeIndexMap.set(p.sourceIndex, -1);
|
|
2615
|
+
} else excludeIndexMap.set(p.sourceIndex, mode0);
|
|
2616
|
+
if (excludeIndexMap.has(p.targetIndex)) {
|
|
2617
|
+
if (excludeIndexMap.get(p.targetIndex) != mode1) excludeIndexMap.set(p.targetIndex, -1);
|
|
2618
|
+
} else excludeIndexMap.set(p.targetIndex, mode1);
|
|
2619
|
+
});
|
|
2620
|
+
return excludeIndexMap;
|
|
2621
|
+
}
|
|
2433
2622
|
}
|
|
2434
2623
|
class DxfSystem extends ComponentManager {
|
|
2435
2624
|
Dxf;
|
package/src/index2.js
CHANGED
|
@@ -3363,6 +3363,7 @@ class Renderer extends Component {
|
|
|
3363
3363
|
container = new THREE.Group();
|
|
3364
3364
|
onUpdate;
|
|
3365
3365
|
onResize;
|
|
3366
|
+
pointer = new THREE.Vector2();
|
|
3366
3367
|
tweenTaskList = [];
|
|
3367
3368
|
constructor(description) {
|
|
3368
3369
|
super();
|
|
@@ -3395,10 +3396,10 @@ class Renderer extends Component {
|
|
|
3395
3396
|
Object.assign(this.orbitControls, description.orbitControls);
|
|
3396
3397
|
}
|
|
3397
3398
|
if (this.description.resizeObserver) {
|
|
3398
|
-
const
|
|
3399
|
+
const dom2 = this.description.resizeObserver;
|
|
3399
3400
|
this.resizeObserver = new ResizeObserver(() => {
|
|
3400
3401
|
const camera2 = this.camera;
|
|
3401
|
-
const { width, height } =
|
|
3402
|
+
const { width, height } = dom2.getBoundingClientRect();
|
|
3402
3403
|
this.renderer.setSize(width, height);
|
|
3403
3404
|
if (this.html2DRenderer) this.html2DRenderer.setSize(width, height);
|
|
3404
3405
|
if (this.html3DRenderer) this.html3DRenderer.setSize(width, height);
|
|
@@ -3412,8 +3413,9 @@ class Renderer extends Component {
|
|
|
3412
3413
|
}
|
|
3413
3414
|
camera2.updateProjectionMatrix();
|
|
3414
3415
|
this.onResize && this.onResize(width, height);
|
|
3416
|
+
this.dispatchEvent({ type: "resize", width, height });
|
|
3415
3417
|
});
|
|
3416
|
-
this.resizeObserver.observe(
|
|
3418
|
+
this.resizeObserver.observe(dom2);
|
|
3417
3419
|
}
|
|
3418
3420
|
this.renderer.setAnimationLoop(() => {
|
|
3419
3421
|
if (this.html2DRenderer) this.html2DRenderer.render(this.scene, this.camera);
|
|
@@ -3430,6 +3432,25 @@ class Renderer extends Component {
|
|
|
3430
3432
|
directLight.position.set(100, -100, 100);
|
|
3431
3433
|
this.scene.add(directLight);
|
|
3432
3434
|
camera.position.set(10, 10, 10);
|
|
3435
|
+
const dom = description.orbitControls?.domElement ?? this.description.canvas;
|
|
3436
|
+
dom.addEventListener("mousemove", (e) => {
|
|
3437
|
+
this.pointer.set(e.offsetX, e.offsetY);
|
|
3438
|
+
this.dispatchEvent({
|
|
3439
|
+
type: "mousemove",
|
|
3440
|
+
x: e.offsetX,
|
|
3441
|
+
y: e.offsetY,
|
|
3442
|
+
moveX: e.movementX,
|
|
3443
|
+
moveY: e.movementY
|
|
3444
|
+
});
|
|
3445
|
+
});
|
|
3446
|
+
dom.addEventListener("mousedown", (e) => {
|
|
3447
|
+
this.pointer.set(e.offsetX, e.offsetY);
|
|
3448
|
+
this.dispatchEvent({
|
|
3449
|
+
type: "mousedown",
|
|
3450
|
+
x: e.offsetX,
|
|
3451
|
+
y: e.offsetY
|
|
3452
|
+
});
|
|
3453
|
+
});
|
|
3433
3454
|
}
|
|
3434
3455
|
/**
|
|
3435
3456
|
* 世界坐标转屏幕坐标
|
|
@@ -7243,6 +7264,8 @@ const SelectLocalFile = Object.assign(selectLocalFileFun, {
|
|
|
7243
7264
|
if (text) return JSON.parse(text);
|
|
7244
7265
|
}
|
|
7245
7266
|
});
|
|
7267
|
+
function Editor(dxfSystem) {
|
|
7268
|
+
}
|
|
7246
7269
|
const _hoisted_1 = { class: "w-full flex justify-between absolute left-0 top-0 p-[10px] z-[1000] gap-[5px]" };
|
|
7247
7270
|
const _hoisted_2 = { class: "text-[14px] bg-[rgba(255,255,255,1)] rounded-[6px] p-[0px_10px]" };
|
|
7248
7271
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
@@ -7254,20 +7277,25 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
7254
7277
|
setup(__props) {
|
|
7255
7278
|
THREE.Object3D.DEFAULT_UP = new THREE.Vector3(0, 0, 1);
|
|
7256
7279
|
const props = __props;
|
|
7257
|
-
const elRef = ref(), originalLineVisible = ref(true), dxfVisible = ref(true), whiteModelVisible = ref(true), isLook = ref(false), dxfSystem = new DxfSystem().usePlugin(ModelDataPlugin).usePlugin(RenderPlugin), desPoint = dxfSystem.findComponentByType(DetailsPoint), domContainer = dxfSystem.findComponentByType(DomContainer), whiteModel = dxfSystem.findComponentByType(WhiteModel);
|
|
7280
|
+
const elRef = ref(), originalLineVisible = ref(true), dxfVisible = ref(true), whiteModelVisible = ref(true), isLook = ref(false), dxfSystem = new DxfSystem().usePlugin(ModelDataPlugin).usePlugin(RenderPlugin).usePlugin(Editor), desPoint = dxfSystem.findComponentByType(DetailsPoint), domContainer = dxfSystem.findComponentByType(DomContainer), whiteModel = dxfSystem.findComponentByType(WhiteModel);
|
|
7258
7281
|
watch(() => props.lines, () => props.lines && setLines(props.lines));
|
|
7259
7282
|
watch(() => props.detailsPoint, () => props.detailsPoint && desPoint?.set(props.detailsPoint));
|
|
7260
7283
|
function setLines(lines) {
|
|
7261
7284
|
if (lines) {
|
|
7262
|
-
|
|
7263
|
-
|
|
7285
|
+
localStorage.setItem("lines", JSON.stringify(lines));
|
|
7286
|
+
try {
|
|
7287
|
+
dxfSystem.Dxf.set(lines);
|
|
7288
|
+
dxfSystem.Dxf.lineOffset();
|
|
7289
|
+
} catch (error) {
|
|
7290
|
+
console.log(error);
|
|
7291
|
+
}
|
|
7264
7292
|
}
|
|
7265
7293
|
}
|
|
7266
7294
|
async function selectLocalFile() {
|
|
7267
7295
|
const data = await SelectLocalFile.json();
|
|
7268
7296
|
if (Array.isArray(data)) {
|
|
7269
|
-
|
|
7270
|
-
|
|
7297
|
+
localStorage.removeItem("orbitControls");
|
|
7298
|
+
setLines(data);
|
|
7271
7299
|
}
|
|
7272
7300
|
}
|
|
7273
7301
|
async function selectDetailsPointFile() {
|
|
@@ -7281,10 +7309,29 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
7281
7309
|
dxfSystem.Variable.addEventListener("originalLineVisible", (e) => originalLineVisible.value = e.value);
|
|
7282
7310
|
dxfSystem.Variable.addEventListener("dxfVisible", (e) => dxfVisible.value = e.value);
|
|
7283
7311
|
dxfSystem.Variable.addEventListener("whiteModelVisible", (e) => whiteModelVisible.value = e.value);
|
|
7284
|
-
|
|
7312
|
+
if (localStorage.getItem("lines")) {
|
|
7313
|
+
setLines(JSON.parse(localStorage.getItem("lines") ?? "{}"));
|
|
7314
|
+
} else {
|
|
7315
|
+
setLines(props.lines);
|
|
7316
|
+
}
|
|
7285
7317
|
props.detailsPoint && desPoint?.set(props.detailsPoint);
|
|
7286
7318
|
onMounted(() => domContainer && elRef.value?.appendChild(domContainer.domElement));
|
|
7287
7319
|
onUnmounted(() => dxfSystem.destroy());
|
|
7320
|
+
const renderer = dxfSystem.findComponentByType(Renderer);
|
|
7321
|
+
renderer.orbitControls?.addEventListener("change", () => {
|
|
7322
|
+
localStorage.setItem("orbitControls", JSON.stringify({
|
|
7323
|
+
position: renderer.camera.position.toArray(),
|
|
7324
|
+
target: renderer.orbitControls?.target.toArray()
|
|
7325
|
+
}));
|
|
7326
|
+
});
|
|
7327
|
+
const d = localStorage.getItem("orbitControls");
|
|
7328
|
+
if (d) {
|
|
7329
|
+
const data = JSON.parse(d);
|
|
7330
|
+
setTimeout(() => {
|
|
7331
|
+
renderer.camera.position.set(data.position[0], data.position[1], data.position[2]);
|
|
7332
|
+
renderer.orbitControls?.target.set(data.target[0], data.target[1], data.target[2]);
|
|
7333
|
+
});
|
|
7334
|
+
}
|
|
7288
7335
|
return (_ctx, _cache) => {
|
|
7289
7336
|
return openBlock(), createElementBlock("div", {
|
|
7290
7337
|
ref_key: "elRef",
|
|
@@ -35,6 +35,16 @@ export interface OriginalDataItem {
|
|
|
35
35
|
z: number;
|
|
36
36
|
};
|
|
37
37
|
};
|
|
38
|
+
isWindow?: boolean;
|
|
39
|
+
drawWindow?: {
|
|
40
|
+
p: {
|
|
41
|
+
x: number;
|
|
42
|
+
y: number;
|
|
43
|
+
z: number;
|
|
44
|
+
};
|
|
45
|
+
width: number;
|
|
46
|
+
full: boolean;
|
|
47
|
+
};
|
|
38
48
|
}
|
|
39
49
|
/**
|
|
40
50
|
* [开始点, 结束点, 相交点, 是否是门, 索引]
|
|
@@ -76,6 +86,7 @@ export declare class Dxf extends Component<{
|
|
|
76
86
|
doorLineSegment: LineSegment[];
|
|
77
87
|
lineSegments: LineSegment<{
|
|
78
88
|
isDoor: boolean;
|
|
89
|
+
isWindow: boolean;
|
|
79
90
|
}>[];
|
|
80
91
|
originalZAverage: number;
|
|
81
92
|
static EndType: {
|
|
@@ -92,6 +103,7 @@ export declare class Dxf extends Component<{
|
|
|
92
103
|
*/
|
|
93
104
|
get lines(): LineSegment<{
|
|
94
105
|
isDoor: boolean;
|
|
106
|
+
isWindow: boolean;
|
|
95
107
|
}>[];
|
|
96
108
|
/**初始化
|
|
97
109
|
* @param data 点云数据
|
|
@@ -84,6 +84,12 @@ export declare class LineAnalysis extends Component {
|
|
|
84
84
|
* 门的位置判断
|
|
85
85
|
*/
|
|
86
86
|
doorsAnalysis(): void;
|
|
87
|
+
/**
|
|
88
|
+
*
|
|
89
|
+
* @param line
|
|
90
|
+
* @returns
|
|
91
|
+
*/
|
|
87
92
|
findLongLineSegment(line: LineSegment): LineSegment<Record<string, any>>;
|
|
93
|
+
doorsAnalysis2(): void;
|
|
88
94
|
}
|
|
89
95
|
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Component, ComponentManager } from '../../../../ComponentManager';
|
|
2
|
+
import { Dxf } from '../../../components/Dxf';
|
|
3
|
+
import { Variable } from '../../../components/Variable';
|
|
4
|
+
import { Renderer } from '../../RenderPlugin/components';
|
|
5
|
+
import * as THREE from "three";
|
|
6
|
+
export declare class Editor extends Component<{
|
|
7
|
+
pointerPositionChange: {
|
|
8
|
+
position: THREE.Vector2;
|
|
9
|
+
};
|
|
10
|
+
}> {
|
|
11
|
+
static name: string;
|
|
12
|
+
container: THREE.Group<THREE.Object3DEventMap>;
|
|
13
|
+
get renderer(): Renderer;
|
|
14
|
+
get dxf(): Dxf;
|
|
15
|
+
get variable(): Variable;
|
|
16
|
+
plane: THREE.Mesh<THREE.PlaneGeometry, THREE.Material | THREE.Material[], THREE.Object3DEventMap>;
|
|
17
|
+
onAddFromParent(parent: ComponentManager): void;
|
|
18
|
+
private _exitEditCallBack?;
|
|
19
|
+
openEdit(): void;
|
|
20
|
+
exitEdit(): void;
|
|
21
|
+
}
|
|
@@ -19,7 +19,22 @@ export interface RendererDescription {
|
|
|
19
19
|
scene?: THREE.Scene;
|
|
20
20
|
camera?: THREE.PerspectiveCamera | THREE.OrthographicCamera;
|
|
21
21
|
}
|
|
22
|
-
export declare class Renderer extends Component
|
|
22
|
+
export declare class Renderer extends Component<{
|
|
23
|
+
resize: {
|
|
24
|
+
width: number;
|
|
25
|
+
height: number;
|
|
26
|
+
};
|
|
27
|
+
mousemove: {
|
|
28
|
+
x: number;
|
|
29
|
+
y: number;
|
|
30
|
+
moveX: number;
|
|
31
|
+
moveY: number;
|
|
32
|
+
};
|
|
33
|
+
mousedown: {
|
|
34
|
+
x: number;
|
|
35
|
+
y: number;
|
|
36
|
+
};
|
|
37
|
+
}> {
|
|
23
38
|
static name: string;
|
|
24
39
|
static CSS2DObject: typeof CSS2DObject;
|
|
25
40
|
static CSS3DObject: typeof CSS3DObject;
|
|
@@ -35,12 +50,13 @@ export declare class Renderer extends Component {
|
|
|
35
50
|
renderer: THREE.WebGLRenderer;
|
|
36
51
|
orbitControls?: OrbitControls;
|
|
37
52
|
private resizeObserver?;
|
|
38
|
-
|
|
53
|
+
description: RendererDescription;
|
|
39
54
|
html2DRenderer?: CSS2DRenderer;
|
|
40
55
|
html3DRenderer?: CSS3DRenderer;
|
|
41
56
|
container: THREE.Group<THREE.Object3DEventMap>;
|
|
42
57
|
onUpdate?: () => void;
|
|
43
58
|
onResize?: (width: number, height: number) => void;
|
|
59
|
+
pointer: THREE.Vector2;
|
|
44
60
|
private tweenTaskList;
|
|
45
61
|
constructor(description: RendererDescription);
|
|
46
62
|
/**
|
|
@@ -5,7 +5,7 @@ import { Rectangle } from './Rectangle';
|
|
|
5
5
|
*/
|
|
6
6
|
export declare class LineSegment<T = Record<string, any>> {
|
|
7
7
|
points: Point[];
|
|
8
|
-
userData
|
|
8
|
+
userData: T;
|
|
9
9
|
get center(): Point;
|
|
10
10
|
get start(): Point;
|
|
11
11
|
get end(): Point;
|
|
@@ -36,7 +36,7 @@ export declare class LineSegment<T = Record<string, any>> {
|
|
|
36
36
|
* @param width
|
|
37
37
|
* @returns {Rectangle}
|
|
38
38
|
*/
|
|
39
|
-
expandToRectangle(width?: number): Rectangle;
|
|
39
|
+
expandToRectangle(width?: number, direct?: "bothSides" | "all"): Rectangle;
|
|
40
40
|
/**
|
|
41
41
|
* 计算线段的长度
|
|
42
42
|
* @returns 线段的长度
|
|
@@ -6,6 +6,10 @@ import { Point } from './Point';
|
|
|
6
6
|
*/
|
|
7
7
|
export declare class Rectangle {
|
|
8
8
|
points: Point[];
|
|
9
|
+
get p0(): Point;
|
|
10
|
+
get p1(): Point;
|
|
11
|
+
get p2(): Point;
|
|
12
|
+
get p3(): Point;
|
|
9
13
|
get path(): number[];
|
|
10
14
|
path2D(callback?: (point1: Point, point2: Point) => void): number[];
|
|
11
15
|
constructor(points: Point[]);
|
|
@@ -21,6 +25,13 @@ export declare class Rectangle {
|
|
|
21
25
|
* @returns 是否完全在矩形内部
|
|
22
26
|
*/
|
|
23
27
|
containsLineSegment(line: LineSegment): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* 判断矩形是否与矩形相交
|
|
30
|
+
* @description 使用分离轴定理
|
|
31
|
+
* @param rectangle 矩形
|
|
32
|
+
* @returns 是否与矩形相交
|
|
33
|
+
*/
|
|
34
|
+
intersectRectangle(rectangle: Rectangle): boolean;
|
|
24
35
|
/**
|
|
25
36
|
* 判断点是否完全位于矩形内部
|
|
26
37
|
* @param point
|