2018-05-24 17:13:23 +08:00
|
|
|
import * as THREE from 'three';
|
2018-05-31 11:12:29 +08:00
|
|
|
import { Geometry, LineSegments, Shape, Vector2, CylinderGeometry } from 'three';
|
2018-05-24 17:13:23 +08:00
|
|
|
import { polar } from './GeUtils';
|
|
|
|
import { boardMaterial, edgeMaterial } from './Material';
|
|
|
|
import { RotateUVs } from './RotateUV';
|
2018-05-25 11:09:15 +08:00
|
|
|
import { ThreeBSP } from './ThreeCSG';
|
2018-05-24 17:13:23 +08:00
|
|
|
//解析二维圆弧类.
|
|
|
|
export class Arc2d
|
|
|
|
{
|
|
|
|
m_StartAn: number;
|
|
|
|
m_EndAn: number;
|
|
|
|
m_StartPoint: THREE.Vector2;
|
|
|
|
m_EndPoint: THREE.Vector2;
|
|
|
|
m_Center: THREE.Vector2;
|
|
|
|
m_Radius: number;
|
|
|
|
constructor(p1: THREE.Vector2, p2: THREE.Vector2, bul: number)
|
|
|
|
{
|
|
|
|
this.m_StartPoint = p1.clone();
|
|
|
|
this.m_EndPoint = p2.clone();
|
|
|
|
|
|
|
|
let vec: THREE.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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//创建轮廓 通过点表和凸度
|
2018-05-30 18:32:42 +08:00
|
|
|
export function createPath(pts: Vector2[], buls: number[], shapeOut?: Shape): Shape
|
2018-05-24 17:13:23 +08:00
|
|
|
{
|
2018-05-30 18:32:42 +08:00
|
|
|
let shape = shapeOut || new Shape();
|
2018-05-24 17:13:23 +08:00
|
|
|
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)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
export function getVec(data: object): THREE.Vector3
|
|
|
|
{
|
|
|
|
return new THREE.Vector3(data["x"], data["y"], data["z"]);
|
|
|
|
}
|
|
|
|
|
|
|
|
//创建板件 暂时这么写
|
|
|
|
export function createBoard(boardData: object)
|
|
|
|
{
|
|
|
|
let pts: THREE.Vector2[] = new Array();
|
|
|
|
let buls: number[] = new Array();
|
|
|
|
let boardPts = boardData["Pts"];
|
|
|
|
let boardBuls = boardData["Buls"];
|
|
|
|
|
|
|
|
let boardHeight = boardData["H"];
|
|
|
|
|
|
|
|
let boardMat = new THREE.Matrix4();
|
|
|
|
let matInv: THREE.Matrix4 = new THREE.Matrix4();
|
|
|
|
//InitBoardMat
|
|
|
|
{
|
|
|
|
let xD = getVec(boardData["XVec"]);
|
|
|
|
let yD = getVec(boardData["YVec"]);
|
|
|
|
let ZD = getVec(boardData["ZVec"]);
|
|
|
|
let pBase = getVec(boardData["BasePoint"]);
|
|
|
|
|
|
|
|
boardMat.makeBasis(xD, yD, ZD);
|
|
|
|
boardMat.setPosition(pBase);
|
|
|
|
matInv.getInverse(boardMat, true);
|
|
|
|
}
|
|
|
|
|
2018-05-29 09:27:09 +08:00
|
|
|
if (boardPts && boardPts.length !== 0)
|
2018-05-29 09:15:05 +08:00
|
|
|
for (let i = 0; i < boardPts.length; i++)
|
|
|
|
{
|
|
|
|
let pt = getVec(boardPts[i]);
|
2018-05-29 10:13:37 +08:00
|
|
|
if (boardPts[i].z !== undefined)
|
2018-05-29 09:15:05 +08:00
|
|
|
pt.applyMatrix4(matInv);
|
|
|
|
pts.push(new THREE.Vector2(pt.x, pt.y));
|
|
|
|
buls.push(boardBuls[i]);
|
|
|
|
}
|
|
|
|
else
|
2018-05-24 17:13:23 +08:00
|
|
|
{
|
2018-05-29 09:15:05 +08:00
|
|
|
let length = boardData["L"];
|
|
|
|
let width = boardData["W"];
|
|
|
|
let height = boardData["H"];
|
|
|
|
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);
|
2018-05-24 17:13:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
let sp = createPath(pts, buls);
|
|
|
|
let extrudeSettings = {
|
|
|
|
steps: 1,
|
|
|
|
bevelEnabled: false,
|
|
|
|
amount: boardHeight
|
|
|
|
};
|
|
|
|
|
2018-05-25 11:09:15 +08:00
|
|
|
let ext = new THREE.ExtrudeGeometry(sp, extrudeSettings) as Geometry;
|
2018-05-24 17:13:23 +08:00
|
|
|
ext.computeBoundingSphere();
|
|
|
|
ext.computeBoundingBox();
|
|
|
|
ext.translate(0, 0, -boardHeight)
|
|
|
|
ext.applyMatrix(boardMat);
|
|
|
|
|
2018-05-25 11:09:15 +08:00
|
|
|
//外边.
|
|
|
|
let edges = [createEdge(ext)];
|
2018-05-31 11:12:29 +08:00
|
|
|
|
|
|
|
|
2018-05-25 11:09:15 +08:00
|
|
|
//差集
|
2018-05-31 11:12:29 +08:00
|
|
|
if (checkObjectArray(boardData, "SubBoardLocal")
|
|
|
|
|| checkObjectArray(boardData, "Drillings"))
|
2018-05-24 17:13:23 +08:00
|
|
|
{
|
2018-05-25 11:09:15 +08:00
|
|
|
let thisCsg = new ThreeBSP(ext);
|
|
|
|
|
2018-05-31 11:12:29 +08:00
|
|
|
if (boardData["SubBoardLocal"])
|
|
|
|
{
|
|
|
|
let subBoardList = boardData["SubBoardLocal"].map(d => createBoard(d));
|
|
|
|
for (let br of subBoardList)
|
|
|
|
{
|
|
|
|
edges.push(...br.edges);
|
|
|
|
let subCsg = new ThreeBSP(br.mesh);
|
|
|
|
thisCsg = thisCsg.subtract(subCsg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (boardData["Drillings"])
|
2018-05-25 11:09:15 +08:00
|
|
|
{
|
2018-05-31 11:12:29 +08:00
|
|
|
let dris = boardData["Drillings"];
|
|
|
|
for (let dri of dris)
|
|
|
|
{
|
|
|
|
let geo = new CylinderGeometry(dri.r, dri.r, dri.h, 32);
|
|
|
|
geo.rotateX(Math.PI * 0.5);
|
|
|
|
geo.translate(dri.x, dri.y, 0);
|
|
|
|
geo.applyMatrix(boardMat);
|
|
|
|
|
|
|
|
edges.push(createEdge(geo));
|
|
|
|
|
|
|
|
let subCsg = new ThreeBSP(geo);
|
|
|
|
thisCsg = thisCsg.subtract(subCsg);
|
|
|
|
}
|
2018-05-25 11:09:15 +08:00
|
|
|
}
|
|
|
|
ext = thisCsg.toGeometry();
|
2018-05-24 17:13:23 +08:00
|
|
|
}
|
|
|
|
|
2018-05-25 11:09:15 +08:00
|
|
|
if (boardData["BoardName"] === "地脚线")
|
|
|
|
RotateUVs(ext);
|
|
|
|
|
2018-05-24 17:13:23 +08:00
|
|
|
let mesh = new THREE.Mesh(ext, boardMaterial);
|
2018-05-25 11:09:15 +08:00
|
|
|
return { mesh, edges };
|
2018-05-24 17:13:23 +08:00
|
|
|
}
|
|
|
|
|
2018-05-31 11:12:29 +08:00
|
|
|
function checkObjectArray(obj: any, key: string)
|
|
|
|
{
|
|
|
|
return obj[key] && obj[key].length > 0;
|
|
|
|
}
|
|
|
|
|
2018-05-24 17:13:23 +08:00
|
|
|
export function createTemplateBoard(brDataList: any[])
|
|
|
|
{
|
2018-05-25 11:09:15 +08:00
|
|
|
let meshs = [];
|
|
|
|
let edgesa = [];
|
|
|
|
for (let d of brDataList)
|
|
|
|
{
|
|
|
|
let { mesh, edges } = createBoard(d);
|
|
|
|
meshs.push(mesh);
|
|
|
|
edgesa.push(...edges);
|
|
|
|
}
|
|
|
|
return { meshs, edgesa };
|
2018-05-24 17:13:23 +08:00
|
|
|
}
|
|
|
|
|
2018-05-25 11:09:15 +08:00
|
|
|
export function createEdge(geo: Geometry): LineSegments
|
2018-05-24 17:13:23 +08:00
|
|
|
{
|
2018-05-25 11:09:15 +08:00
|
|
|
let edge = new THREE.EdgesGeometry(geo, 1);
|
2018-05-24 17:13:23 +08:00
|
|
|
return new LineSegments(edge, edgeMaterial);
|
|
|
|
}
|