import { CylinderGeometry, LineSegments, Matrix4, Mesh, MeshBasicMaterial, Vector2, Vector3 } from "three"; import { ExtrudeSolid, Polyline, boardUVGenerator2 } from "webcad_ue4_api"; import { ColorMaterial } from "./ColorPalette"; import { edgeMaterial } from "./Material"; import { DbText } from "./Text"; function getVec(data: object): Vector3 { return new Vector3(data["x"], data["y"], data["z"]); } enum BoardType { Layer = 0, Vertical = 1, Behind = 2 } export class SimpleBoard { BoardName: string; boardPts: any[]; boardBuls: any[]; xD: Vector3; yD: Vector3; zD: Vector3; height: number; width: number; thickness: number; pBase: Vector3; SubBoardLocal: any[]; Drillings: any[]; DataID: number; _BoardType: BoardType; _CustomNumber: string; constructor(boardData: any) { this.boardPts = boardData["Pts"]; this.boardBuls = boardData["Buls"]; this.pBase = getVec(boardData["BasePoint"]); this.xD = getVec(boardData["XVec"]); this.yD = getVec(boardData["YVec"]); this.zD = getVec(boardData["ZVec"]); this.SubBoardLocal = boardData["SubBoardLocal"] ?? []; this.Drillings = boardData["Drillings"] ?? []; this.height = boardData["L"]; this.width = boardData["W"]; this.thickness = boardData["H"]; this.BoardName = boardData["BoardName"]; this.DataID = boardData['DataID']; this._BoardType = boardData['BoardType']; this._CustomNumber = boardData['CustomNumber']; } public Conver2Ext(): ExtrudeSolid { let pts: Vector2[] = []; let buls: number[] = []; let boardMat = new Matrix4(); let matInv: Matrix4 = new Matrix4(); //InitBoardMat this.pBase.add(this.zD.clone().multiplyScalar(-this.thickness)); boardMat.makeBasis(this.xD, this.yD, this.zD); boardMat.setPosition(this.pBase); matInv.getInverse(boardMat); if (this.boardPts && this.boardPts.length !== 0) for (let i = 0; i < this.boardPts.length; i++) { let pt = getVec(this.boardPts[i]); if (this.boardPts[i].z !== undefined) pt.applyMatrix4(matInv); pts.push(new Vector2(pt.x, pt.y)); buls.push(this.boardBuls[i]); } else { pts.push(new Vector2(0, 0), new Vector2(this.width, 0), new Vector2(this.width, this.height), new Vector2(0, this.height), new Vector2(0, 0) ); buls.push(0, 0, 0, 0, 0); } let ext = new ExtrudeSolid(); ext.OCSNoClone.copy(boardMat); let pl = new Polyline(pts.map((p, i) => { return { pt: p, bul: buls[i] }; })); ext.Thickness = this.thickness; ext.ContourCurve = pl; if (this.SubBoardLocal.length > 0) ext.Grooves.push(...this.SubBoardLocal.map(sub => new SimpleBoard(sub).Conver2Ext())); return ext; } createBoard(boardMaterial: MeshBasicMaterial) { let ext = this.Conver2Ext(); if (this.BoardName === "地脚线") Object.defineProperty(ext, "UCGenerator", { get: function () { return boardUVGenerator2; }, }); //板件被镜像时. // if (!equalv3(xD.clone().cross(yD), ZD)) // { // for (let f of ext.faces) // [f.a, f.c] = [f.c, f.a]; // } //边 let edges: (LineSegments | Mesh)[] = [new LineSegments(ext.EdgeGeometry, edgeMaterial)]; edges[0].applyMatrix4(ext.OCSNoClone); if (this.Drillings.length > 0) { let dris = this.Drillings; for (let dri of dris) { let geo = new CylinderGeometry(dri.r, dri.r, dri.h, 8); geo.rotateX(Math.PI * 0.5); if (dri.f === 0) //0正 geo.translate(dri.x, dri.y, -dri.h * 0.5 + this.thickness); else //1反 geo.translate(dri.x, dri.y, dri.h * 0.5); geo.applyMatrix4(ext.OCSNoClone); let mesh = new Mesh(geo, ColorMaterial.GetBasicMaterial(1)); edges.push(mesh); } } let mesh = new Mesh(ext.MeshGeometry, boardMaterial); mesh.userData = ext.Normal; edges.forEach(e => e.userData = ext.Normal); // 自定义编号 if (this._CustomNumber) { mesh.add(this.createCustomNo()); } mesh.applyMatrix4(ext.OCSNoClone); mesh.updateWorldMatrix(false, true); return { mesh, edges }; } private createCustomNo() { let text = new DbText(this._CustomNumber?.toString(), 100); let position = new Vector3(this.width * 0.5, this.height * 0.5, this.thickness * 0.5); if (this._BoardType === BoardType.Layer) { text.applyMatrix4(new Matrix4().makeRotationZ(-Math.PI / 2).setPosition(position)); } else { text.applyMatrix4(new Matrix4().setPosition(position)); } // text.CreateDoubleMesh(this._BoardType === BoardType.Layer); return text; } }