build-dxf 0.0.66 → 0.0.67

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "build-dxf",
3
- "version": "0.0.66",
3
+ "version": "0.0.67",
4
4
  "description": "线段构建双线墙壁的dxf版本",
5
5
  "main": "./src/index.js",
6
6
  "types": "./src/index.d.ts",
package/src/build.d.ts CHANGED
@@ -27,7 +27,7 @@ export declare function createEditor(dom: HTMLDivElement, camera?: THREE.Camera,
27
27
  * @param originData
28
28
  * @param trajectory
29
29
  */
30
- export declare function getModels(originData: OriginalDataItem[], trajectory: any): Promise<{
30
+ export declare function getModels(originData: OriginalDataItem[], trajectory: any, itemList: any): Promise<{
31
31
  obj: File;
32
32
  glb: File;
33
33
  gltf: File;
@@ -36,6 +36,7 @@ type HandleJsonOption = {
36
36
  /** json数据或路径 */
37
37
  json: string | OriginalDataItem[];
38
38
  trajectory?: string | Record<string, any>;
39
+ itemInfo?: string | Record<string, any>;
39
40
  axisAlignCorrOption?: SetDataOption;
40
41
  download?: {
41
42
  json?: string;
package/src/build.js CHANGED
@@ -5441,7 +5441,7 @@ class BoundExt {
5441
5441
  lines = lines.filter((line) => {
5442
5442
  if (LineGroupType.hasType(line, "doubleWall")) return;
5443
5443
  if (line.userData.isDoor) {
5444
- if (!(vrLine.vertical(line, 5) || vrLine.parallel(line, 5))) return;
5444
+ if (!(vrLine.vertical(line, 0.1) || vrLine.parallel(line, 0.1))) return;
5445
5445
  }
5446
5446
  const center = line.center;
5447
5447
  const set2 = /* @__PURE__ */ new Set();
@@ -13048,7 +13048,13 @@ class Scenario {
13048
13048
  const cube = new THREE.Mesh(geometry, material);
13049
13049
  const edges = new THREE.EdgesGeometry(geometry);
13050
13050
  new THREE.LineSegments(edges, new THREE.LineBasicMaterial({ color: 0 }));
13051
- cube.name = num === 0 ? `双线墙${index2}` : `单线墙${index2}`;
13051
+ if (num === 0) {
13052
+ cube.name = `双线墙_${index2}`;
13053
+ cube.userData.category = "doubleWall";
13054
+ } else {
13055
+ cube.name = `单线墙_${index2}`;
13056
+ cube.userData.category = "wall";
13057
+ }
13052
13058
  return cube;
13053
13059
  }
13054
13060
  // 执行偏移
@@ -13241,7 +13247,8 @@ class Scenario {
13241
13247
  menModel.rotation.y = angleRad;
13242
13248
  menModel.scale.set(distance / size.x, height / size.y, wallWidth / size.z);
13243
13249
  menModel.position.set(data.center.x, data.center.y, groundClearance);
13244
- menModel.name = `窗${index2}`;
13250
+ menModel.name = `窗_${index2}`;
13251
+ menModel.userData.category = "window";
13245
13252
  this.group.add(menModel);
13246
13253
  }
13247
13254
  }
@@ -13382,10 +13389,12 @@ class Scenario {
13382
13389
  menModel.rotation.x = Math.PI / 2;
13383
13390
  menModel.rotation.y = angleRad;
13384
13391
  menModel.scale.set(distance / size.x, (Height ? Height : this.doorHeight) / size.y, DEFAULT_WALL_WIDTH / size.z);
13385
- menModel.name = `门${index2}`;
13392
+ menModel.name = `门_${index2}`;
13393
+ menModel.userData.category = "door";
13386
13394
  this.group.add(menModel);
13387
13395
  }
13388
- result.name = `额墙${index2}`;
13396
+ result.name = `额墙_${index2}`;
13397
+ result.userData.category = "partitionWall";
13389
13398
  this.group.add(result);
13390
13399
  }
13391
13400
  // 确定偏移角度
@@ -13519,7 +13528,8 @@ class Scenario {
13519
13528
  new THREE.LineSegments(edges, new THREE.LineBasicMaterial({ color: 0 }));
13520
13529
  this.installWindows(winDraw[x2], x2);
13521
13530
  let mesh = this.windowTreatment(winDraw[x2], Mesh2);
13522
- mesh.name = `单线墙${Number(x2) / 2}`;
13531
+ mesh.name = `单线墙_${Number(x2) / 2}`;
13532
+ mesh.userData.category = "wall";
13523
13533
  this.group.add(mesh);
13524
13534
  } else if (houMesh) {
13525
13535
  if (Number(x2) === winDraw.length - 1) {
@@ -13527,7 +13537,8 @@ class Scenario {
13527
13537
  this.installWindows(winDraw[x2], x2);
13528
13538
  new THREE.LineSegments(edges, new THREE.LineBasicMaterial({ color: 0 }));
13529
13539
  let mesh = this.windowTreatment(winDraw[x2], houMesh);
13530
- mesh.name = `单线墙${Number(x2) / 2}`;
13540
+ mesh.name = `单线墙_${Number(x2) / 2}`;
13541
+ mesh.userData.category = "wall";
13531
13542
  this.group.add(mesh);
13532
13543
  } else {
13533
13544
  this.installWindows(winDraw[x2], x2);
@@ -13539,7 +13550,8 @@ class Scenario {
13539
13550
  }
13540
13551
  }
13541
13552
  } else {
13542
- Mesh2.name = `单线墙${Number(x) / 2}`;
13553
+ Mesh2.name = `单线墙_${Number(x) / 2}`;
13554
+ Mesh2.userData.category = "wall";
13543
13555
  this.group.add(Mesh2);
13544
13556
  }
13545
13557
  }
@@ -13668,13 +13680,22 @@ class LoadModel {
13668
13680
  return promise;
13669
13681
  }
13670
13682
  }
13671
- LoadModel.addNameMap("water cooler", "饮水机");
13683
+ LoadModel.addNameMap("water cooler", "饮水机1");
13672
13684
  LoadModel.addNameMap("table", "桌子");
13673
13685
  LoadModel.addNameMap("chair", "椅子");
13674
13686
  LoadModel.addNameMap("switch", "开关");
13675
13687
  LoadModel.addNameMap("cabinet", "柜子");
13676
13688
  LoadModel.addNameMap("tv", "电视");
13677
13689
  LoadModel.addNameMap("socket", "插座");
13690
+ LoadModel.addNameMap("refrigerator", "冰箱");
13691
+ LoadModel.addNameMap("kitchen hood", "抽油烟机");
13692
+ LoadModel.addNameMap("toilet", "马桶");
13693
+ LoadModel.addNameMap("sofa", "沙发");
13694
+ LoadModel.addNameMap("the bed", "床");
13695
+ LoadModel.addNameMap("door", "门");
13696
+ LoadModel.addNameMap("window", "窗户");
13697
+ LoadModel.addNameMap("wall", "单线墙");
13698
+ LoadModel.addNameMap("doubleWall", "双线墙");
13678
13699
  let globalScenario;
13679
13700
  class SceneAutoGenerat {
13680
13701
  lines;
@@ -13704,23 +13725,61 @@ class SceneAutoGenerat {
13704
13725
  async init() {
13705
13726
  await this.buildWall();
13706
13727
  await this.buildItem();
13707
- this.buildPlane();
13708
13728
  }
13709
13729
  wallGroup = null;
13710
13730
  async buildWall() {
13711
13731
  this.wallGroup = await globalScenario.drawGraphics(this.lines, this.z, this.trajectory);
13712
13732
  this.scene.add(this.wallGroup);
13713
13733
  }
13714
- // 辅助函数:检测是否在距离阈值内
13715
- isCloseEnough(box3, wallBox, threshold) {
13716
- let dx = Math.max(0, Math.max(wallBox.min.x - box3.max.x, box3.min.x - wallBox.max.x));
13717
- let dy = Math.max(0, Math.max(wallBox.min.y - box3.max.y, box3.min.y - wallBox.max.y));
13718
- return dx <= threshold && dy <= threshold;
13719
- }
13720
- adsorption(walls, box3, proximityThreshold = 0.1) {
13734
+ directs = [
13735
+ [new THREE.Vector3(1, 0, 0), "x"],
13736
+ [new THREE.Vector3(-1, 0, 0), "x"],
13737
+ [new THREE.Vector3(0, 1, 0), "y"],
13738
+ [new THREE.Vector3(0, -1, 0), "y"]
13739
+ // [new THREE.Vector3(0, 0, 1), "z"],
13740
+ // [new THREE.Vector3(0, 0, -1), "z"]
13741
+ ];
13742
+ adsorption(walls, box3, proximityThreshold = 0.05) {
13743
+ let newPosition = new THREE.Vector3();
13744
+ const center = box3.getCenter(new THREE.Vector3()), size = box3.getSize(new THREE.Vector3()), raycaster = new THREE.Raycaster(), keyMap = /* @__PURE__ */ new Map(), results = this.directs.map((item) => {
13745
+ raycaster.set(center, item[0]);
13746
+ raycaster.near = 1e-4;
13747
+ raycaster.far = size[item[1]] * 0.5 + proximityThreshold;
13748
+ const intersects = raycaster.intersectObjects(walls, true);
13749
+ if (intersects.length) {
13750
+ keyMap.set(intersects[0], item);
13751
+ return intersects[0];
13752
+ }
13753
+ return;
13754
+ }).filter((i) => !!i);
13755
+ if (results.length) {
13756
+ let closestIntersection = results[0];
13757
+ results.forEach((result) => {
13758
+ if (result.distance <= closestIntersection.distance) {
13759
+ closestIntersection = result;
13760
+ }
13761
+ });
13762
+ const info = keyMap.get(closestIntersection), key = info[1];
13763
+ if (closestIntersection.face?.normal) {
13764
+ const normal = new THREE.Vector3().copy(closestIntersection.face.normal).applyMatrix3(new THREE.Matrix3().getNormalMatrix(closestIntersection.object.matrixWorld));
13765
+ newPosition.copy(closestIntersection.point).add(normal.clone().multiplyScalar(size[key] * 0.5));
13766
+ box3.min.set(
13767
+ newPosition.x - size.x * 0.5,
13768
+ newPosition.y - size.y * 0.5,
13769
+ newPosition.z - size.z * 0.5
13770
+ );
13771
+ box3.max.set(
13772
+ newPosition.x + size.x * 0.5,
13773
+ newPosition.y + size.y * 0.5,
13774
+ newPosition.z + size.z * 0.5
13775
+ );
13776
+ }
13777
+ }
13721
13778
  }
13722
13779
  async buildItem() {
13780
+ const walls = [];
13723
13781
  this.wallGroup?.traverse((object) => {
13782
+ if (object instanceof THREE.Mesh) walls.push(object);
13724
13783
  });
13725
13784
  this.itemList.forEach(async (item) => {
13726
13785
  let model = await LoadModel.loadGlb(item.category);
@@ -13729,8 +13788,13 @@ class SceneAutoGenerat {
13729
13788
  new THREE.Vector3().copy(item.box.min),
13730
13789
  new THREE.Vector3().copy(item.box.max)
13731
13790
  );
13791
+ let angle = 0;
13792
+ if (["socket", "switch"].includes(item.category)) {
13793
+ angle = this.adsorption(walls, containerBox3) ?? 0;
13794
+ }
13795
+ model.name = `${item.category}_${THREE.MathUtils.randFloat(0, 16777215).toString(16)}`;
13796
+ model.userData.category = item.category;
13732
13797
  const containerSize = containerBox3.getSize(new THREE.Vector3());
13733
- this.scene.add(new THREE.Box3Helper(containerBox3));
13734
13798
  const box3 = new THREE.Box3();
13735
13799
  model = model.clone(true);
13736
13800
  model.rotateX(Math.PI * 0.5);
@@ -13745,9 +13809,9 @@ class SceneAutoGenerat {
13745
13809
  });
13746
13810
  model.scale.set(containerSize.x / size.x, containerSize.z / size.z, containerSize.y / size.y);
13747
13811
  const group2 = new THREE.Group();
13748
- group2.position.copy(item.position);
13812
+ containerBox3.getCenter(group2.position);
13813
+ group2.rotation.z = angle;
13749
13814
  group2.add(model);
13750
- group2.add(new THREE.Mesh(new THREE.SphereGeometry(0.01), new THREE.MeshBasicMaterial({ color: 16711680 })));
13751
13815
  box3.setFromObject(group2);
13752
13816
  box3.getSize(size);
13753
13817
  group2.position.z -= size.z * 0.5;
@@ -13789,6 +13853,13 @@ class WhiteModel extends Component {
13789
13853
  originalWhiteMode = new THREE.Group();
13790
13854
  material = new THREE.MeshStandardMaterial({ color: 16777215, transparent: true, opacity: 0.8, side: THREE.DoubleSide });
13791
13855
  itemList = [];
13856
+ /** 设置物品列表
13857
+ * @param itemList
13858
+ */
13859
+ setItemList(itemList) {
13860
+ if (Array.isArray(itemList)) this.itemList = itemList;
13861
+ else if ("itemInfo" in itemList) this.itemList = itemList.itemInfo;
13862
+ }
13792
13863
  onAddFromParent(parent) {
13793
13864
  this.Dxf = parent.findComponentByName("Dxf");
13794
13865
  this.Variable = parent.findComponentByName("Variable");
@@ -14174,7 +14245,11 @@ async function createEditor(dom, camera, orbitControls = false, viewPermission)
14174
14245
  getFileAll: () => getFileAll(dxfSystem)
14175
14246
  };
14176
14247
  }
14177
- async function getModels(originData, trajectory) {
14248
+ async function getModels(originData, trajectory, itemList) {
14249
+ if ("itemInfo" in itemList) itemList = itemList.itemInfo;
14250
+ if (!Array.isArray(itemList)) {
14251
+ itemList = [];
14252
+ }
14178
14253
  const { lineSegments, originalZAverage } = originalDataToLineData(originData);
14179
14254
  const lines = BoundExt.boundExtbyTraj({
14180
14255
  lines: lineSegments,
@@ -14182,8 +14257,9 @@ async function getModels(originData, trajectory) {
14182
14257
  updateDoubleWallGroup: true,
14183
14258
  wallWidth: DEFAULT_WALL_WIDTH
14184
14259
  }).lines;
14185
- const scenario0 = new Scenario(new THREE.Scene(), {}, {}, {});
14186
- const model = await scenario0.drawGraphics(lines, originalZAverage, trajectory);
14260
+ const sceneAutoGenerat = new SceneAutoGenerat(lines, itemList, originalZAverage, trajectory);
14261
+ await sceneAutoGenerat.init();
14262
+ const model = sceneAutoGenerat.scene;
14187
14263
  const whiteModel = new WhiteModel();
14188
14264
  whiteModel.whiteModelGroup.add(model);
14189
14265
  const obj = new File([await whiteModel.toOBJBlob() || ""], "model.obj", { type: "application/octet-stream" });
@@ -14198,7 +14274,7 @@ async function getModels(originData, trajectory) {
14198
14274
  async function buildJson(opt) {
14199
14275
  const mp = await Promise.resolve().then(() => index);
14200
14276
  const dxfSystem = new DxfSystem();
14201
- let { json, trajectory, axisAlignCorrOption, download } = opt;
14277
+ let { json, trajectory, axisAlignCorrOption, download, itemInfo } = opt;
14202
14278
  dxfSystem.usePlugin(mp.ModelDataPlugin);
14203
14279
  const whiteModel = dxfSystem.findComponentByType(mp.components.WhiteModel);
14204
14280
  const threeVJia = dxfSystem.findComponentByName("ThreeVJia");
@@ -14217,6 +14293,20 @@ async function buildJson(opt) {
14217
14293
  }
14218
14294
  dxfSystem.CorrectionDxf.setTrajectory(trajectory);
14219
14295
  }
14296
+ if (itemInfo) {
14297
+ if (typeof itemInfo === "string") {
14298
+ if (typeof global !== "undefined") {
14299
+ const packageName = "fs";
14300
+ const { default: fs } = await import(
14301
+ /* @vite-ignore */
14302
+ packageName
14303
+ );
14304
+ const buffer = fs.readFileSync(itemInfo);
14305
+ itemInfo = JSON.parse(buffer.toString("utf-8"));
14306
+ } else throw new Error("非node环境不允许使用路径");
14307
+ }
14308
+ whiteModel?.setItemList(itemInfo);
14309
+ }
14220
14310
  await dxfSystem.Dxf.axisAlignCorr({
14221
14311
  groupMethod: "cross",
14222
14312
  fittingMethod: "max",
package/src/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import "three";
2
2
  import { l, D, m, i, o, g, j, k, h, n } from "./build.js";
3
3
  import "clipper-lib";
4
+ import "three-bvh-csg";
4
5
  export {
5
6
  l as Dxf,
6
7
  D as DxfSystem,
@@ -16,6 +16,10 @@ export declare class WhiteModel extends Component<{
16
16
  originalWhiteMode: THREE.Group<THREE.Object3DEventMap>;
17
17
  material: THREE.MeshStandardMaterial;
18
18
  itemList: any[];
19
+ /** 设置物品列表
20
+ * @param itemList
21
+ */
22
+ setItemList(itemList: any): void;
19
23
  onAddFromParent(parent: ComponentManager): void;
20
24
  updateModel(): Promise<void>;
21
25
  /**
@@ -12,7 +12,7 @@ export declare class SceneAutoGenerat {
12
12
  init(): Promise<void>;
13
13
  wallGroup: Group | null;
14
14
  buildWall(): Promise<void>;
15
- isCloseEnough(box3: THREE.Box3, wallBox: THREE.Box3, threshold: number): boolean;
15
+ directs: [THREE.Vector3, string][];
16
16
  adsorption(walls: THREE.Mesh[], box3: THREE.Box3, proximityThreshold?: number): void;
17
17
  buildItem(): Promise<void>;
18
18
  }
@@ -1 +0,0 @@
1
- export {};