mirror of https://gitee.com/cf-fz/WebCAD.git
parent
090e3d0c9f
commit
dee1988364
@ -1,10 +1,22 @@
|
|||||||
import { HotCMD } from "../../Hot/HotCommand";
|
import { HotCMD } from "../../Hot/HotCommand";
|
||||||
import { Command } from "../../Editor/CommandMachine";
|
import { Command } from "../../Editor/CommandMachine";
|
||||||
|
import { app } from "../../ApplicationServices/Application";
|
||||||
|
import { PromptStatus } from "../../Editor/PromptResult";
|
||||||
|
import { Board } from "../../DatabaseServices/Board";
|
||||||
|
import { Production } from "../../Production/Product";
|
||||||
|
|
||||||
@HotCMD
|
@HotCMD
|
||||||
export class Test implements Command
|
export class Test implements Command
|
||||||
{
|
{
|
||||||
async exec()
|
async exec()
|
||||||
{
|
{
|
||||||
|
let enRes = await app.m_Editor.GetEntity();
|
||||||
|
|
||||||
|
if (enRes.Status === PromptStatus.OK)
|
||||||
|
{
|
||||||
|
let en = enRes.Entity as Board;
|
||||||
|
|
||||||
|
console.log(Production.GetBoardSplitOrderData(en));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,317 @@
|
|||||||
|
import { Matrix4, Vector2, Vector3 } from "three";
|
||||||
|
import { EBoardKeyList } from "../Common/BoardKeyList";
|
||||||
|
import { Vec3DTo2D } from "../Common/CurveUtils";
|
||||||
|
import { Vector2ApplyMatrix4 } from "../Common/Matrix4Utils";
|
||||||
|
import { GangDrill, GangDrillType } from "../DatabaseServices/3DSolid/GangDrill";
|
||||||
|
import { Arc } from "../DatabaseServices/Arc";
|
||||||
|
import { Board } from "../DatabaseServices/Board";
|
||||||
|
import { Circle } from "../DatabaseServices/Circle";
|
||||||
|
import { Polyline } from "../DatabaseServices/Polyline";
|
||||||
|
import { Vec2 } from "../Geometry/CheckIntersect";
|
||||||
|
import { equaln, equalv3, isParallelTo } from "../Geometry/GeUtils";
|
||||||
|
import { getBoardSealingCurves, getBoardSealingData as getBoardHighSeal, getSealedBoardContour } from "../GraphicsSystem/CalcEdgeSealing";
|
||||||
|
import { FeedingToolPath } from "../GraphicsSystem/ToolPath/FeedingToolPath";
|
||||||
|
import { FaceDirection, IHighSealedItem } from "../UI/Store/BoardInterface";
|
||||||
|
|
||||||
|
/**板件轮廓数据 */
|
||||||
|
export interface IContourData
|
||||||
|
{
|
||||||
|
pts: Vec2[];
|
||||||
|
buls: number[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ISealingData extends IHighSealedItem
|
||||||
|
{
|
||||||
|
length: number;
|
||||||
|
type?: string;
|
||||||
|
shop?: string;
|
||||||
|
}
|
||||||
|
interface IModelingData
|
||||||
|
{
|
||||||
|
curve: IContourData;
|
||||||
|
feeding: IContourData[];
|
||||||
|
thickness: number;
|
||||||
|
dir: FaceDirection;
|
||||||
|
knifeRadius: number;
|
||||||
|
addLen: number;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IDrillingOption
|
||||||
|
{
|
||||||
|
position: Vector3;
|
||||||
|
rad: number;
|
||||||
|
type: GangDrillType;
|
||||||
|
depth: number;
|
||||||
|
face: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IBoardHoleInfo
|
||||||
|
{
|
||||||
|
frontBackHoles: IDrillingOption[];
|
||||||
|
sideHoles: IDrillingOption[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IBoardProdInfo
|
||||||
|
{
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
[EBoardKeyList.RoomName]: string;
|
||||||
|
[EBoardKeyList.CabinetName]: string;
|
||||||
|
[EBoardKeyList.Mat]: string;
|
||||||
|
[EBoardKeyList.BrMat]: string;
|
||||||
|
[EBoardKeyList.Color]: string;
|
||||||
|
[EBoardKeyList.Lines]: number;
|
||||||
|
[EBoardKeyList.DrillType]: string;
|
||||||
|
spliteHeight: string;
|
||||||
|
spliteThickness: string;
|
||||||
|
spliteWidth: string;
|
||||||
|
|
||||||
|
isRect: boolean;
|
||||||
|
reamarks: any[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**拆单数据 */
|
||||||
|
interface ISpliteOrderData
|
||||||
|
{
|
||||||
|
info: IBoardProdInfo; //板件基本信息
|
||||||
|
outline: IContourData; //轮廓信息
|
||||||
|
sealing: ISealingData[]; //封边信息
|
||||||
|
modeling: IModelingData[]; //造型信息
|
||||||
|
holes: IBoardHoleInfo; //孔信息
|
||||||
|
sideModeling: IModelingData[]; //侧面造型信息
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace Production
|
||||||
|
{
|
||||||
|
/**获取板件拆单数据 */
|
||||||
|
export function GetBoardSplitOrderData(br: Board): ISpliteOrderData
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
info: GetBoardInfo(br),
|
||||||
|
outline: getBoardContour(br),
|
||||||
|
sealing: GetBoardSealingData(br),
|
||||||
|
modeling: GetBoardModelingData(br),
|
||||||
|
holes: GetBoardHolesData(br),
|
||||||
|
sideModeling: [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export function GetBoardInfo(br: Board): IBoardProdInfo
|
||||||
|
{
|
||||||
|
let data = br.BoardProcessOption;
|
||||||
|
return {
|
||||||
|
id: br.Id.Index,
|
||||||
|
name: br.Name,
|
||||||
|
[EBoardKeyList.RoomName]: data[EBoardKeyList.RoomName],
|
||||||
|
[EBoardKeyList.CabinetName]: data[EBoardKeyList.CabinetName],
|
||||||
|
[EBoardKeyList.Mat]: data[EBoardKeyList.Mat],
|
||||||
|
[EBoardKeyList.BrMat]: data[EBoardKeyList.BrMat],
|
||||||
|
[EBoardKeyList.Color]: data[EBoardKeyList.Color],
|
||||||
|
[EBoardKeyList.Lines]: data[EBoardKeyList.Lines],
|
||||||
|
[EBoardKeyList.DrillType]: data[EBoardKeyList.DrillType],
|
||||||
|
spliteHeight: data.spliteHeight,
|
||||||
|
spliteThickness: data.spliteThickness,
|
||||||
|
spliteWidth: data.spliteWidth,
|
||||||
|
isRect: !br.IsSpecialShape,
|
||||||
|
reamarks: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getBoardContour(br: Board): IContourData
|
||||||
|
{
|
||||||
|
let curve = getSealedBoardContour(br);
|
||||||
|
return curve ? ConverToPolylineAndSplitArc(curve) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换成多段线并且将圆弧打断(大于1/4的话)
|
||||||
|
*/
|
||||||
|
function ConverToPolylineAndSplitArc(cu: Polyline | Circle): IContourData
|
||||||
|
{
|
||||||
|
let ptsBuls: { pts: Vector2[]; buls: number[]; };
|
||||||
|
if (cu instanceof Circle)
|
||||||
|
{
|
||||||
|
let pl = ConverCircleToPolyline(cu);
|
||||||
|
ptsBuls = pl.PtsBuls;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptsBuls = SplitePolylineAtArc(cu);
|
||||||
|
let ocs = cu.OCS;
|
||||||
|
if (!equaln(ocs.elements[0], 1)
|
||||||
|
|| !equaln(ocs.elements[9], 0)
|
||||||
|
|| !equaln(ocs.elements[10], 0)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (let p of ptsBuls.pts)
|
||||||
|
Vector2ApplyMatrix4(ocs, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ptsBuls;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ConverCircleToPolyline(cir: Circle): Polyline
|
||||||
|
{
|
||||||
|
let arcs = cir.GetSplitCurves([0, 0.25, 0.5, 0.75]);
|
||||||
|
let pl = new Polyline();
|
||||||
|
for (let arc of arcs)
|
||||||
|
pl.Join(arc);
|
||||||
|
return pl;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SPLITBUL = Math.tan(Math.PI / 8);
|
||||||
|
|
||||||
|
/** 打断多段线超过1/4圆的圆弧*/
|
||||||
|
export function SplitePolylineAtArc(cu: Polyline): { pts: Vector2[], buls: number[] }
|
||||||
|
{
|
||||||
|
let ptsBuls = cu.PtsBuls;
|
||||||
|
let ocsInv = cu.OCSInv;
|
||||||
|
|
||||||
|
let result: { pts: Vector2[], buls: number[] } = { pts: [], buls: [] };
|
||||||
|
|
||||||
|
for (let i = 0; i < ptsBuls.buls.length; i++)
|
||||||
|
{
|
||||||
|
let bul = ptsBuls.buls[i];
|
||||||
|
if (Math.abs(bul) > SPLITBUL)
|
||||||
|
{
|
||||||
|
let allAngle = Math.atan(bul) * 4;
|
||||||
|
let splitCount = Math.floor(allAngle / (Math.PI / 2)) + 1;
|
||||||
|
let arc = cu.GetCurveAtIndex(i) as Arc;
|
||||||
|
let paramDiv = 1 / splitCount;
|
||||||
|
let newBul = Math.tan((allAngle / splitCount) / 4);
|
||||||
|
for (let i = 0; i < splitCount; i++)
|
||||||
|
{
|
||||||
|
let param = i * paramDiv;
|
||||||
|
let p = arc.GetPointAtParam(param).applyMatrix4(ocsInv);
|
||||||
|
result.pts.push(Vec3DTo2D(p));
|
||||||
|
result.buls.push(newBul);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.pts.push(ptsBuls.pts[i]);
|
||||||
|
result.buls.push(ptsBuls.buls[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**获取封边数据 */
|
||||||
|
export function GetBoardSealingData(br: Board): ISealingData[]
|
||||||
|
{
|
||||||
|
let highSeal = getBoardHighSeal(br);
|
||||||
|
let cus = getBoardSealingCurves(br);
|
||||||
|
if (highSeal.length === cus.length)
|
||||||
|
return highSeal.map((data, i) => Object.assign(data, { length: cus[i].Length }));
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function GetBoardModelingData(br: Board): IModelingData[]
|
||||||
|
{
|
||||||
|
const tool = FeedingToolPath.GetInstance() as FeedingToolPath;
|
||||||
|
const thickness = br.Thickness;
|
||||||
|
let data: IModelingData[] = br.BoardModeling.map(m =>
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
curve: ConverToPolylineAndSplitArc(m.shape.Outline.Curve),
|
||||||
|
feeding: tool.GetModelFeedPath(thickness, m).map(ConverToPolylineAndSplitArc),
|
||||||
|
thickness: m.thickness,
|
||||||
|
dir: m.dir,
|
||||||
|
knifeRadius: m.knifeRadius,
|
||||||
|
addLen: m.knifeRadius,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function GetBoardHolesData(br: Board): IBoardHoleInfo
|
||||||
|
{
|
||||||
|
let drillList = br.DrillList;
|
||||||
|
let processData = br.BoardProcessOption;
|
||||||
|
let data: IBoardHoleInfo = {
|
||||||
|
frontBackHoles: [],
|
||||||
|
sideHoles: []
|
||||||
|
};
|
||||||
|
let brNormal = br.Normal;
|
||||||
|
let outline = br.ContourCurve;
|
||||||
|
|
||||||
|
let sealedOutlin = getSealedBoardContour(br);
|
||||||
|
let moveVec = sealedOutlin ? sealedOutlin.BoundingBox.min.negate() : new Vector3();
|
||||||
|
|
||||||
|
let roMat = new Matrix4().extractRotation(br.OCSInv);
|
||||||
|
for (let [, driss] of drillList)
|
||||||
|
{
|
||||||
|
for (let dris of driss)
|
||||||
|
{
|
||||||
|
for (let dId of dris)
|
||||||
|
{
|
||||||
|
if (!dId || dId.IsErase)
|
||||||
|
continue;
|
||||||
|
let d = dId.Object as GangDrill;
|
||||||
|
let position = d.Position.applyMatrix4(br.OCSInv);
|
||||||
|
let holes = data.frontBackHoles;
|
||||||
|
let face: number;
|
||||||
|
let isPush = false;
|
||||||
|
if (d.Type === GangDrillType.Pxl)
|
||||||
|
{
|
||||||
|
if (isParallelTo(d.Normal, brNormal))
|
||||||
|
{
|
||||||
|
face = processData[EBoardKeyList.BigHole];
|
||||||
|
isPush = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (d.Type === GangDrillType.Ljg)
|
||||||
|
{
|
||||||
|
if (!isParallelTo(d.Normal, brNormal))
|
||||||
|
{
|
||||||
|
position.add(d.Normal.multiplyScalar(d.Height).applyMatrix4(roMat));
|
||||||
|
holes = data.sideHoles;
|
||||||
|
face = Math.floor(outline.GetParamAtPoint(position.clone().setZ(0)));
|
||||||
|
isPush = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isParallelTo(d.Normal, br.Normal))
|
||||||
|
{
|
||||||
|
holes = data.frontBackHoles;
|
||||||
|
face = !equalv3(d.Normal, brNormal) ? 0 : 1;
|
||||||
|
isPush = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isPush && holes.push({
|
||||||
|
type: d.Type,
|
||||||
|
position: position.add(moveVec),
|
||||||
|
rad: d.Radian,
|
||||||
|
depth: d.Height,
|
||||||
|
face,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let nid of br.LayerNails)
|
||||||
|
{
|
||||||
|
if (!nid || !nid.Object || nid.IsErase)
|
||||||
|
continue;
|
||||||
|
let nail = nid.Object as GangDrill;
|
||||||
|
if (isParallelTo(nail.Normal, brNormal))
|
||||||
|
{
|
||||||
|
let nailPosition = nail.Position.applyMatrix4(br.OCSInv);
|
||||||
|
let face = equalv3(nail.Normal, brNormal) ? 0 : 1;
|
||||||
|
let depth = face === 1 ? nailPosition.z : br.Thickness - nailPosition.z;
|
||||||
|
|
||||||
|
data.frontBackHoles.push({
|
||||||
|
type: nail.Type,
|
||||||
|
position: nailPosition.setZ(0),
|
||||||
|
rad: nail.Radian,
|
||||||
|
depth,
|
||||||
|
face,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in new issue