CADViewComponent/src/createBoard.ts

219 lines
6.4 KiB
TypeScript
Raw Normal View History

2022-02-16 14:18:01 +08:00
import { CylinderGeometry, EdgesGeometry, Geometry, LineSegments, Matrix4, Mesh, MeshBasicMaterial, Shape, Vector2, Vector3 } from 'three';
2022-02-16 13:48:57 +08:00
import { boardUVGenerator2, ExtrudeSolid, Polyline } from 'webcad_ue4_api';
2018-05-31 21:01:30 +08:00
import { ColorMaterial } from './ColorPalette';
2022-02-16 13:48:57 +08:00
import { polar } from './GeUtils';
2021-03-03 15:07:59 +08:00
import { edgeMaterial } from './Material';
//解析二维圆弧类.
export class Arc2d
{
m_StartAn: number;
m_EndAn: number;
2020-04-30 17:12:30 +08:00
m_StartPoint: Vector2;
m_EndPoint: Vector2;
m_Center: Vector2;
m_Radius: number;
2020-04-30 17:12:30 +08:00
constructor(p1: Vector2, p2: Vector2, bul: number)
{
this.m_StartPoint = p1.clone();
this.m_EndPoint = p2.clone();
2020-04-30 17:12:30 +08:00
let vec: Vector2 = p2.clone().sub(p1);
let len = vec.length();
let an = vec.angle();
this.m_Radius = len / Math.sin(2 * Math.atan(bul)) / 2;
let allAngle = Math.atan(bul) * 4;
let delDis = bul * len / 2;
let toDis = this.m_Radius - delDis;
an += Math.PI * 0.5;
this.m_Center = p1.clone().add(p2);
this.m_Center.multiplyScalar(0.5);
polar(this.m_Center, an, toDis);
this.m_StartAn = p1.clone().sub(this.m_Center).angle();
this.m_EndAn = p2.clone().sub(this.m_Center).angle();
if (bul < 0)
{
//一个神奇的特性 它需要这么做
this.m_StartAn -= Math.PI;
this.m_EndAn -= Math.PI;
}
}
}
2020-04-30 17:12:30 +08:00
//创建轮廓 通过点表和凸度
2018-05-30 18:32:42 +08:00
export function createPath(pts: Vector2[], buls: number[], shapeOut?: Shape): Shape
{
2018-05-30 18:32:42 +08:00
let shape = shapeOut || new Shape();
if (pts.length === 0) return shape;
let firstPt = pts[0];
shape.moveTo(firstPt.x, firstPt.y);
for (let i = 0; i < pts.length - 1; i++)
{
let nextPt = pts[i + 1];
if (buls[i] == 0)
{
2022-02-16 13:48:57 +08:00
shape.lineTo(nextPt.x, nextPt.y);
}
else
{
let pt = pts[i];
//参考
//http://www.dorodnic.com/blog/tag/three-js/ 绘制一个齿轮
//https://www.kirupa.com/html5/drawing_circles_canvas.htm //html5
let arc2 = new Arc2d(pt, nextPt, buls[i]);
let cen = arc2.m_Center;
shape.absarc(cen.x, cen.y, arc2.m_Radius, arc2.m_StartAn, arc2.m_EndAn, buls[i] < 0);
}
}
return shape;
}
2020-04-30 17:12:30 +08:00
export function getVec(data: object): Vector3
{
2020-04-30 17:12:30 +08:00
return new Vector3(data["x"], data["y"], data["z"]);
}
2022-02-16 13:48:57 +08:00
function Conver2Ext(boardData: object): ExtrudeSolid
{
2020-04-30 17:12:30 +08:00
let pts: Vector2[] = [];
2018-07-02 12:07:16 +08:00
let buls: number[] = [];
let boardPts = boardData["Pts"];
let boardBuls = boardData["Buls"];
let boardHeight = boardData["H"];
2020-04-30 17:12:30 +08:00
let boardMat = new Matrix4();
let matInv: Matrix4 = new Matrix4();
//InitBoardMat
2018-10-29 14:49:40 +08:00
let xD = getVec(boardData["XVec"]);
let yD = getVec(boardData["YVec"]);
let ZD = getVec(boardData["ZVec"]);
let pBase = getVec(boardData["BasePoint"]);
2022-02-16 13:48:57 +08:00
pBase.add(ZD.clone().multiplyScalar(-boardHeight));
2018-10-29 14:49:40 +08:00
boardMat.makeBasis(xD, yD, ZD);
boardMat.setPosition(pBase);
2020-04-30 17:12:30 +08:00
matInv.getInverse(boardMat);
2018-05-29 09:27:09 +08:00
if (boardPts && boardPts.length !== 0)
for (let i = 0; i < boardPts.length; i++)
{
let pt = getVec(boardPts[i]);
if (boardPts[i].z !== undefined)
pt.applyMatrix4(matInv);
2020-04-30 17:12:30 +08:00
pts.push(new Vector2(pt.x, pt.y));
buls.push(boardBuls[i]);
}
else
{
let length = boardData["L"];
let width = boardData["W"];
pts.push(new Vector2(0, 0),
new Vector2(width, 0),
new Vector2(width, length),
new Vector2(0, length),
new Vector2(0, 0)
);
buls.push(0, 0, 0, 0, 0);
}
2022-02-16 13:48:57 +08:00
let ext = new ExtrudeSolid();
ext.OCSNoClone.copy(boardMat);
let pl = new Polyline(pts.map((p, i) => { return { pt: p, bul: buls[i] }; }));
ext.Thickness = boardHeight;
ext.ContourCurve = pl;
2022-02-16 13:48:57 +08:00
if (checkObjectArray(boardData, "SubBoardLocal"))
ext.Grooves.push(...boardData["SubBoardLocal"].map(Conver2Ext));
return ext;
}
2018-05-25 11:09:15 +08:00
2022-02-16 13:48:57 +08:00
//创建板件 暂时这么写
2022-02-16 14:18:01 +08:00
export function createBoard(boardData: object, boardMaterial: MeshBasicMaterial)
2022-02-16 13:48:57 +08:00
{
let ext = Conver2Ext(boardData);
if (boardData["BoardName"] === "地脚线")
Object.defineProperty(ext, "UCGenerator",
{
2022-02-16 13:48:57 +08:00
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 (checkObjectArray(boardData, "Drillings"))
{
let dris = boardData["Drillings"];
for (let dri of dris)
2018-05-25 11:09:15 +08:00
{
2022-02-16 13:48:57 +08:00
let geo = new CylinderGeometry(dri.r, dri.r, dri.h, 8);
geo.rotateX(Math.PI * 0.5);
2022-02-16 13:48:57 +08:00
if (dri.f === 0) //0正
geo.translate(dri.x, dri.y, -dri.h * 0.5 + boardData["H"]);
else //1反
geo.translate(dri.x, dri.y, dri.h * 0.5);
2022-02-16 13:48:57 +08:00
geo.applyMatrix4(ext.OCSNoClone);
2022-02-16 13:48:57 +08:00
let mesh = new Mesh(geo, ColorMaterial.GetBasicMaterial(1));
edges.push(mesh);
2018-05-25 11:09:15 +08:00
}
}
2022-02-16 13:48:57 +08:00
let mesh = new Mesh(ext.MeshGeometry, boardMaterial);
mesh.userData = ext.Normal;
edges.forEach(e => e.userData = ext.Normal);
mesh.applyMatrix4(ext.OCSNoClone);
mesh.updateWorldMatrix(false, true);
2018-05-25 11:09:15 +08:00
return { mesh, edges };
}
function checkObjectArray(obj: any, key: string)
{
return obj[key] && obj[key].length > 0;
}
2021-03-03 15:07:59 +08:00
export function createTemplateBoard(brDataList: any[], material: MeshBasicMaterial)
{
2018-05-25 11:09:15 +08:00
let meshs = [];
let edgesa = [];
2020-04-01 14:15:29 +08:00
let relations = {
blockMeshMap: new Map<number, number>(),
meshBlockMap: new Map<number, number>()
};
2018-05-25 11:09:15 +08:00
for (let d of brDataList)
{
2021-03-03 15:07:59 +08:00
let { mesh, edges } = createBoard(d, material);
2018-05-25 11:09:15 +08:00
meshs.push(mesh);
edgesa.push(...edges);
2020-04-01 14:15:29 +08:00
if (d['DataID'])
{
relations.blockMeshMap.set(d['DataID'], mesh.id);
relations.meshBlockMap.set(mesh.id, d['DataID']);
}
2018-05-25 11:09:15 +08:00
}
2020-04-01 14:15:29 +08:00
return { meshs, edgesa, relations };
}
2018-05-25 11:09:15 +08:00
export function createEdge(geo: Geometry): LineSegments
{
2020-04-30 17:12:30 +08:00
let edge = new EdgesGeometry(geo, 1);
return new LineSegments(edge, edgeMaterial);
}