!321 获取拆单数据

Merge pull request !321 from ZoeLeeFZ/productData2
pull/321/MERGE
ZoeLeeFZ 5 years ago committed by ChenX
parent 090e3d0c9f
commit dee1988364

@ -9,7 +9,7 @@ function testPathCount(br: Board, count?: number)
{ {
holeCount += model.shape.Holes.length; holeCount += model.shape.Holes.length;
} }
let cus = feedUtil.CalcPath(br); let cus = feedUtil.TestCalcPath(br);
if (count !== undefined) if (count !== undefined)
expect(cus.length).toBe(count); expect(cus.length).toBe(count);
else else

@ -92,7 +92,9 @@ export class BoardFindModify implements Command
{ {
if (en instanceof GangDrill) if (en instanceof GangDrill)
{ {
return (en.Type === GangDrillType.Drill && option.condition.useDrill) return ((en.Type === GangDrillType.Pxl
|| en.Type === GangDrillType.Ymj
|| en.Type === GangDrillType.Ljg) && option.condition.useDrill)
|| (en.Type === GangDrillType.Nail && option.condition.useNail); || (en.Type === GangDrillType.Nail && option.condition.useNail);
} }
else if (en instanceof Board) else if (en instanceof Board)

@ -27,7 +27,7 @@ export class FeedingCommand implements Command
{ {
let feedingTool = FeedingToolPath.GetInstance() as FeedingToolPath; let feedingTool = FeedingToolPath.GetInstance() as FeedingToolPath;
let retCus = brs.map(br => feedingTool.CalcPath(br)); let retCus = brs.map(br => feedingTool.TestCalcPath(br));
let ptRes = await app.m_Editor.GetPoint({ Msg: "点取位置" }); let ptRes = await app.m_Editor.GetPoint({ Msg: "点取位置" });

@ -47,10 +47,7 @@ export class DrawLayerBoard extends DrawBoardTool
let type = opt.boardRelative; let type = opt.boardRelative;
let spaceSize = opt.spaceSize; let spaceSize = opt.spaceSize;
let frontShrink = opt.frontShrink; let frontShrink = opt.frontShrink;
if (opt.isTotalLength) width -= frontShrink;
{
width -= frontShrink;
}
let leftShrink = opt.leftShrink; let leftShrink = opt.leftShrink;
let rightShrink = opt.rightShrink; let rightShrink = opt.rightShrink;
let thickness = opt.thickness; let thickness = opt.thickness;
@ -115,8 +112,7 @@ export class DrawLayerBoard extends DrawBoardTool
if (this.leftBoard) if (this.leftBoard)
{ {
let lNail = GangDrill.CreateCylDrill(rad, nailOpt.length); let lNail = GangDrill.CreateCylDrill(rad, nailOpt.length, GangDrillType.Nail);
lNail.Type = GangDrillType.Nail;
lNail.ApplyMatrix(new Matrix4().makeRotationX(Math.PI / 2)) lNail.ApplyMatrix(new Matrix4().makeRotationX(Math.PI / 2))
.ApplyMatrix(MoveMatrix(new Vector3(frontDist, br.Height + depth + leftShrink, -rad))); .ApplyMatrix(MoveMatrix(new Vector3(frontDist, br.Height + depth + leftShrink, -rad)));
initNails.push({ initNails.push({
@ -127,8 +123,7 @@ export class DrawLayerBoard extends DrawBoardTool
if (this.rightBoard) if (this.rightBoard)
{ {
let rNail = GangDrill.CreateCylDrill(rad, nailOpt.length); let rNail = GangDrill.CreateCylDrill(rad, nailOpt.length, GangDrillType.Nail);
rNail.Type = GangDrillType.Nail;
rNail.ApplyMatrix(new Matrix4().makeRotationX(-Math.PI / 2)) rNail.ApplyMatrix(new Matrix4().makeRotationX(-Math.PI / 2))
.ApplyMatrix(MoveMatrix(new Vector3(frontDist, -depth - rightShrink, -rad))); .ApplyMatrix(MoveMatrix(new Vector3(frontDist, -depth - rightShrink, -rad)));
initNails.push({ initNails.push({
@ -140,10 +135,11 @@ export class DrawLayerBoard extends DrawBoardTool
if (this.backBoard) if (this.backBoard)
{ {
let bNail = GangDrill.CreateCylDrill(rad, nailOpt.length); let backShrink = (this.space.Size.y - layerOpt.frontShrink) - br.Width;
bNail.Type = GangDrillType.Nail;
let bNail = GangDrill.CreateCylDrill(rad, nailOpt.length, GangDrillType.Nail);
bNail.ApplyMatrix(new Matrix4().makeRotationY(-Math.PI / 2)) bNail.ApplyMatrix(new Matrix4().makeRotationY(-Math.PI / 2))
.ApplyMatrix(MoveMatrix(new Vector3(br.Width + depth, frontDist, -rad))); .ApplyMatrix(MoveMatrix(new Vector3(br.Width + depth + backShrink, frontDist, -rad)));
initNails.push({ initNails.push({
pos: NailPos.Back, pos: NailPos.Back,
nail: bNail nail: bNail

@ -3,7 +3,7 @@ import { app } from "../../ApplicationServices/Application";
import { arrayLast } from "../../Common/ArrayExt"; import { arrayLast } from "../../Common/ArrayExt";
import { Singleton } from "../../Common/Singleton"; import { Singleton } from "../../Common/Singleton";
import { operationExpReg } from "../../Common/Utils"; import { operationExpReg } from "../../Common/Utils";
import { GangDrill } from "../../DatabaseServices/3DSolid/GangDrill"; import { GangDrill, GangDrillType } from "../../DatabaseServices/3DSolid/GangDrill";
import { Board } from "../../DatabaseServices/Board"; import { Board } from "../../DatabaseServices/Board";
import { Circle } from "../../DatabaseServices/Circle"; import { Circle } from "../../DatabaseServices/Circle";
import { ObjectId } from "../../DatabaseServices/ObjectId"; import { ObjectId } from "../../DatabaseServices/ObjectId";
@ -54,19 +54,19 @@ export class DrawDrillingTool extends Singleton
let ljgRad = this.m_Option.ljgRad; let ljgRad = this.m_Option.ljgRad;
let ljgLength = this.m_Option.ljgLength; let ljgLength = this.m_Option.ljgLength;
let pxlEnt = GangDrill.CreateCylDrill(this.m_Option.pxlRad, pxlDepth); let pxlEnt = GangDrill.CreateCylDrill(this.m_Option.pxlRad, pxlDepth, GangDrillType.Pxl);
this.drillEnts.push(pxlEnt); this.drillEnts.push(pxlEnt);
//将三个实体移动到相应的位置 //将三个实体移动到相应的位置
pxlEnt.ApplyMatrix(new Matrix4().makeRotationX(Math.PI / 2)); pxlEnt.ApplyMatrix(new Matrix4().makeRotationX(Math.PI / 2));
let ljgEnt = GangDrill.CreateCylDrill(ljgRad, ljgLength); let ljgEnt = GangDrill.CreateCylDrill(ljgRad, ljgLength, GangDrillType.Ljg);
this.drillEnts.push(ljgEnt); this.drillEnts.push(ljgEnt);
//如果都是侧面,不要预埋件 //如果都是侧面,不要预埋件
if (!this.m_Face.isEqualType) if (!this.m_Face.isEqualType)
{ {
let ymjEnt = GangDrill.CreateCylDrill(this.m_Option.ymjRad, this.m_Option.ymjDepth); let ymjEnt = GangDrill.CreateCylDrill(this.m_Option.ymjRad, this.m_Option.ymjDepth, GangDrillType.Ymj);
ymjEnt.ApplyMatrix(new Matrix4().setPosition(new Vector3(0, 0, ljgLength))); ymjEnt.ApplyMatrix(new Matrix4().setPosition(new Vector3(0, 0, ljgLength)));
this.drillEnts.push(ymjEnt); this.drillEnts.push(ymjEnt);
} }

@ -1,12 +1,10 @@
import { Vector3 } from "three"; import { Vector3 } from "three";
import { app } from "../ApplicationServices/Application"; import { app } from "../ApplicationServices/Application";
import { EBoardKeyList } from "../Common/BoardKeyList";
import { Board } from "../DatabaseServices/Board"; import { Board } from "../DatabaseServices/Board";
import { Curve } from "../DatabaseServices/Curve"; import { Curve } from "../DatabaseServices/Curve";
import { Polyline } from "../DatabaseServices/Polyline";
import { Command } from "../Editor/CommandMachine"; import { Command } from "../Editor/CommandMachine";
import { PromptStatus } from "../Editor/PromptResult"; import { PromptStatus } from "../Editor/PromptResult";
import { calcEdgeSealing, paragraphCulist } from "../GraphicsSystem/CalcEdgeSealing"; import { getSealedBoardContour } from "../GraphicsSystem/CalcEdgeSealing";
export class TestFb implements Command export class TestFb implements Command
{ {
@ -14,10 +12,9 @@ export class TestFb implements Command
{ {
let brRes = await app.m_Editor.GetSelection({ let brRes = await app.m_Editor.GetSelection({
Msg: "选择板件", Msg: "选择板件",
Filter: { UseSelect: true,
filterTypes: [Board] Filter: { filterTypes: [Board] }
} });
})
if (brRes.Status === PromptStatus.Cancel) if (brRes.Status === PromptStatus.Cancel)
return; return;
@ -27,46 +24,20 @@ export class TestFb implements Command
for (let br of brs) for (let br of brs)
{ {
let offsetCus: Curve[] = []; let pl = getSealedBoardContour(br);
let highSeals = br.BoardProcessOption.highSealed; if (pl)
let cus = br.ContourCurve.Explode() as Curve[];
if (!br.IsSpecialShape)
{ {
highSeals.length = 0; pl.ColorIndex = 1;
let sealDown = parseFloat(br.BoardProcessOption[EBoardKeyList.DownSealed]); showCus.push(br.ContourCurve.Clone(), pl);
let sealUp = parseFloat(br.BoardProcessOption[EBoardKeyList.UpSealed]);
let sealLeft = parseFloat(br.BoardProcessOption[EBoardKeyList.LeftSealed]);
let sealRight = parseFloat(br.BoardProcessOption[EBoardKeyList.RightSealed]);
let seals = [...new Set([sealDown, sealRight, sealUp, sealLeft])];
[sealDown, sealRight, sealUp, sealLeft].forEach(size => highSeals.push({ size, color: seals.indexOf(size) + 1 }));
} }
else else
paragraphCulist(cus);
if (highSeals.length > 0 && cus.length === highSeals.length)
{ {
for (let i = 0; i < cus.length; i++) app.m_Editor.Prompt("警告:该板件无法得到模拟封边结果!");
{
let cs = cus[i].GetOffsetCurves(-highSeals[i].size);
for (let c of cs)
{
if (c instanceof Polyline)
offsetCus.push(...c.Explode());
else
offsetCus.push(c);
}
}
calcEdgeSealing(offsetCus);
let pl = new Polyline();
pl.ColorIndex = 1;
for (let c of offsetCus)
{
pl.Join(c);
}
showCus.push(br.ContourCurve.Clone(), pl);
} }
} }
if (showCus.length === 0)
return;
let ptRes = await app.m_Editor.GetPoint({ let ptRes = await app.m_Editor.GetPoint({
Msg: "选择放置位置" Msg: "选择放置位置"

@ -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));
}
} }
} }

@ -1,19 +1,19 @@
import { Matrix3, Vector2, Vector3, Line3 } from 'three'; import { Box3, Line3, Matrix3, Matrix4, Vector2, Vector3 } from 'three';
import { Arc } from '../DatabaseServices/Arc'; import { Arc } from '../DatabaseServices/Arc';
import { Circle } from '../DatabaseServices/Circle'; import { Circle } from '../DatabaseServices/Circle';
import { Curve } from '../DatabaseServices/Curve'; import { Curve } from '../DatabaseServices/Curve';
import { Ellipse } from '../DatabaseServices/Ellipse';
import { Line } from '../DatabaseServices/Line'; import { Line } from '../DatabaseServices/Line';
import { IsPointInBowArc } from '../DatabaseServices/PointInPolyline'; import { IsPointInBowArc } from '../DatabaseServices/PointInPolyline';
import { Polyline } from '../DatabaseServices/Polyline'; import { Polyline } from '../DatabaseServices/Polyline';
import { Count } from '../Geometry/Count'; import { Count } from '../Geometry/Count';
import { CurveMap } from '../Geometry/CurveMap'; import { CurveMap } from '../Geometry/CurveMap';
import { equaln, equalv2, equalv3, isParallelTo } from '../Geometry/GeUtils'; import { cZeroVec, equaln, equalv2, equalv3, isParallelTo } from '../Geometry/GeUtils';
import { Stand } from '../Geometry/RegionParse';
import { FixIndex } from './Utils';
import { PlaneExt } from '../Geometry/Plane'; import { PlaneExt } from '../Geometry/Plane';
import { Stand } from '../Geometry/RegionParse';
import { IntersectOption } from '../GraphicsSystem/IntersectWith'; import { IntersectOption } from '../GraphicsSystem/IntersectWith';
import { arrayLast, changeArrayStartIndex, equalArray } from './ArrayExt'; import { arrayLast, changeArrayStartIndex, equalArray } from './ArrayExt';
import { Ellipse } from '../DatabaseServices/Ellipse'; import { FixIndex } from './Utils';
//3点获取圆心 //3点获取圆心
export function getCircleCenter(pt1: Vector3, pt2: Vector3, pt3: Vector3) export function getCircleCenter(pt1: Vector3, pt2: Vector3, pt3: Vector3)
@ -364,47 +364,6 @@ function PointInPolylineArc(pl: Polyline, index: number, pt: Vector3): number
return 0; return 0;
} }
/**
* 线,.
* ,0.5
*
* @export
* @param {Polyline} pl
* @returns {Polyline} 线
*/
export function BreakPolylineAtArc(pl: Polyline): Polyline
{
let { pts, buls } = pl.PtsBuls;
let npl = new Polyline();
for (let i = 0; i < pts.length; i++)
{
let bul = buls[i];
npl.AddVertexAt(npl.NumberOfVertices, pts[i]);
if (i !== pts.length - 1 && Math.abs(bul) > 0.5)
{
let divCount = Math.floor(Math.abs(bul) / 0.5) + 1;
let arc = new Arc().ParseFromBul(pts[i], pts[i + 1], bul);
let bulDiv = Math.tan(Math.atan(bul) / divCount);
npl.SetBulgeAt(npl.NumberOfVertices - 1, bulDiv);
for (let i = 0; i < divCount - 1; i++)
{
npl.AddVertexAt(npl.NumberOfVertices, Vec3DTo2D(arc.GetPointAtParam((i + 1) / divCount)));
npl.SetBulgeAt(npl.NumberOfVertices - 1, bulDiv);
}
}
else
{
npl.SetBulgeAt(npl.NumberOfVertices - 1, 0);
}
}
return npl;
}
export function ConverCircleToPolyline(cir: Circle): Polyline export function ConverCircleToPolyline(cir: Circle): Polyline
{ {
//该写法不支持三维坐标系 //该写法不支持三维坐标系
@ -592,3 +551,49 @@ export function getTanPtsOnEllipse(cu: Ellipse, lastPoint: Vector3)
{ {
return []; return [];
} }
export function isRect(cu: Curve): { isRect: boolean, size?: Vector3, box?: Box3, OCS?: Matrix4 }
{
if (cu instanceof Polyline)
{
if (!cu.IsClose) return { isRect: false };
let pts = cu.GetStretchPoints();
if (pts.length < 4) return { isRect: false };
let xVec: Vector3;
let p1 = pts[0];
for (let i = 1; i < pts.length; i++)
{
xVec = pts[i].clone().sub(p1).normalize();
if (!equalv3(xVec, cZeroVec))
break;
}
if (!xVec) return { isRect: false };
let zVec = cu.Normal;
let yVec = zVec.clone().cross(xVec).normalize();
let rectOCS = new Matrix4().makeBasis(xVec, yVec, zVec);
let rectOCSInv = new Matrix4().getInverse(rectOCS);
for (let p of pts)
p.applyMatrix4(rectOCSInv);
let box = new Box3().setFromPoints(pts);
let size = box.getSize(new Vector3);
if (equaln(size.x * size.y, cu.Area, 0.1))
{
return {
isRect: true,
size,
box,
OCS: rectOCS,
};
}
}
return { isRect: false };
}

@ -1,5 +1,5 @@
import * as THREE from 'three'; import * as THREE from 'three';
import { BufferGeometry, ExtrudeGeometry, Group, LineSegments, MeshNormalMaterial, Object3D, Vector3 } from "three"; import { BufferGeometry, ExtrudeGeometry, Group, LineSegments, Object3D, Vector3 } from "three";
import { ColorMaterial } from '../../Common/ColorPalette'; import { ColorMaterial } from '../../Common/ColorPalette';
import { DisposeThreeObj } from '../../Common/Dispose'; import { DisposeThreeObj } from '../../Common/Dispose';
import { FastDrillingEdgeGeometry } from '../../Geometry/CreateWireframe'; import { FastDrillingEdgeGeometry } from '../../Geometry/CreateWireframe';
@ -13,9 +13,15 @@ import { Solid3D } from "./Solid3D";
export enum GangDrillType export enum GangDrillType
{ {
Drill = 0, /**偏心轮 */
Nail = 1, Pxl = 0,
Wood = 2, /**连接杆 */
Ljg = 1,
/**预埋件 */
Ymj = 2,
/**层板钉 */
Nail = 3,
Wood = 4,
} }
@Factory @Factory
@ -24,16 +30,17 @@ export class GangDrill extends Solid3D
ColorIndex = 1; ColorIndex = 1;
private m_Shape: Shape; private m_Shape: Shape;
private m_Height: number; private m_Height: number;
private type: GangDrillType = GangDrillType.Drill; private type: GangDrillType = GangDrillType.Pxl;
constructor() constructor()
{ {
super(); super();
} }
static CreateCylDrill(rad: number, height: number) static CreateCylDrill(rad: number, height: number, type: GangDrillType)
{ {
let drill = new GangDrill(); let drill = new GangDrill();
drill.m_Height = height; drill.m_Height = height;
drill.m_Shape = new Shape(Contour.CreateContour([new Circle(new Vector3(), rad)])); drill.m_Shape = new Shape(Contour.CreateContour([new Circle(new Vector3(), rad)]));
drill.type = type;
return drill; return drill;
} }
get Type() get Type()
@ -127,7 +134,7 @@ export class GangDrill extends Solid3D
if (ver > 1) if (ver > 1)
this.type = file.Read(); this.type = file.Read();
else else
this.type = GangDrillType.Drill; this.type = GangDrillType.Pxl;
} }
WriteFile(file: CADFiler) WriteFile(file: CADFiler)
{ {

@ -362,6 +362,9 @@ export class Contour
arrayRemoveDuplicateBySort(gclone, (cu1: Curve, cu2: Curve) => cu1.Join(cu2) === Status.True); arrayRemoveDuplicateBySort(gclone, (cu1: Curve, cu2: Curve) => cu1.Join(cu2) === Status.True);
if (gclone[0].Join(arrayLast(gclone)))
gclone.pop();
for (let cu of gclone) for (let cu of gclone)
pl.Join(cu, false, tolerance); pl.Join(cu, false, tolerance);

@ -4,7 +4,7 @@ import { matrixIsCoplane } from "../../Common/Matrix4Utils";
import { Board } from "../../DatabaseServices/Board"; import { Board } from "../../DatabaseServices/Board";
import { Curve } from "../../DatabaseServices/Curve"; import { Curve } from "../../DatabaseServices/Curve";
import { Region } from "../../DatabaseServices/Region"; import { Region } from "../../DatabaseServices/Region";
import { cZAxis, equalv3, rotatePoint } from "../GeUtils"; import { cZAxis, equalv3, rotatePoint, equaln } from "../GeUtils";
import { Face } from "./Face"; import { Face } from "./Face";
import { DrillType } from "../../UI/Store/BoardInterface"; import { DrillType } from "../../UI/Store/BoardInterface";
import { Arc } from "../../DatabaseServices/Arc"; import { Arc } from "../../DatabaseServices/Arc";
@ -86,7 +86,9 @@ export class BoardGetFace
for (let i = 0; i < cus.length; i++) for (let i = 0; i < cus.length; i++)
{ {
let cu = cus[i]; let cu = cus[i];
if ((highDrill.length > 0 && highDrill[i] === DrillType.None) || cu instanceof Arc) if ((highDrill.length > 0 && highDrill[i] === DrillType.None)
|| equaln(cu.Length, 0)
|| cu instanceof Arc)
continue; continue;
let derv = cu.GetFistDeriv(0).normalize(); let derv = cu.GetFistDeriv(0).normalize();
let len = cu.Length; let len = cu.Length;

@ -1,10 +1,13 @@
import { EBoardKeyList } from "../Common/BoardKeyList";
import { FixIndex } from "../Common/Utils"; import { FixIndex } from "../Common/Utils";
import { Board } from "../DatabaseServices/Board";
import { Curve } from "../DatabaseServices/Curve"; import { Curve } from "../DatabaseServices/Curve";
import { Line } from "../DatabaseServices/Line"; import { Line } from "../DatabaseServices/Line";
import { Polyline } from "../DatabaseServices/Polyline"; import { Polyline } from "../DatabaseServices/Polyline";
import { equaln, equalv3, isParallelTo } from "../Geometry/GeUtils"; import { equaln, equalv3, isParallelTo } from "../Geometry/GeUtils";
import { IntersectOption } from "./IntersectWith"; import { IntersectOption } from "./IntersectWith";
import { PolyOffsetUtil } from "./OffsetPolyline"; import { PolyOffsetUtil } from "./OffsetPolyline";
import { Vector3 } from "three";
/** /**
*线 *线
@ -124,3 +127,72 @@ export function calcEdgeSealing(cus: Curve[])
laterLine.StartPoint = iPt; laterLine.StartPoint = iPt;
} }
} }
export function getBoardSealingData(br: Board)
{
let highSeals = br.BoardProcessOption.highSealed.slice();
if (!br.IsSpecialShape)
{
highSeals.length = 0;
let sealDown = parseFloat(br.BoardProcessOption[EBoardKeyList.DownSealed]);
let sealUp = parseFloat(br.BoardProcessOption[EBoardKeyList.UpSealed]);
let sealLeft = parseFloat(br.BoardProcessOption[EBoardKeyList.LeftSealed]);
let sealRight = parseFloat(br.BoardProcessOption[EBoardKeyList.RightSealed]);
let seals = [...new Set([sealDown, sealRight, sealUp, sealLeft])]; //color看上去毫无意义
[sealDown, sealRight, sealUp, sealLeft].forEach(size => highSeals.push({ size, color: seals.indexOf(size) + 1 }));
}
return highSeals;
}
/**获取板件封边轮廓曲线 */
export function getBoardSealingCurves(br: Board)
{
let cus: Curve[] = [];
if (br.IsSpecialShape)
{
cus = br.ContourCurve.Explode() as Curve[];
paragraphCulist(br.ContourCurve.Explode() as Curve[]);
}
else
{
let cu = br.ContourCurve as Polyline;
let index = cu.GetParamAtPoint(new Vector3());
while (cus.length < 4)
{
cus.push(cu.GetCurveAtIndex(index));
index = FixIndex(++index, cu.EndParam);
}
}
return cus;
}
export function getSealedBoardContour(br: Board)
{
let offsetCus: Curve[] = [];
let highSeals = getBoardSealingData(br);
let cus = getBoardSealingCurves(br);
let dir = Math.sign(br.ContourCurve.Area2);
if (cus.length !== highSeals.length)
{
console.warn("请设置高级封边");
return;
}
for (let i = 0; i < cus.length; i++)
{
let cs = cus[i].GetOffsetCurves(-highSeals[i].size * dir);
for (let c of cs)
{
if (c instanceof Polyline)
offsetCus.push(...c.Explode());
else
offsetCus.push(c);
}
}
calcEdgeSealing(offsetCus);
let pl = new Polyline();
for (let c of offsetCus)
pl.Join(c);
return pl;
}

@ -1,5 +1,5 @@
import { Singleton } from "../../Common/Singleton"; import { Singleton } from "../../Common/Singleton";
import { Board } from "../../DatabaseServices/Board"; import { Board, IModeling } from "../../DatabaseServices/Board";
import { Circle } from "../../DatabaseServices/Circle"; import { Circle } from "../../DatabaseServices/Circle";
import { Contour } from "../../DatabaseServices/Contour"; import { Contour } from "../../DatabaseServices/Contour";
import { Curve } from "../../DatabaseServices/Curve"; import { Curve } from "../../DatabaseServices/Curve";
@ -8,7 +8,8 @@ import { Shape } from "../../DatabaseServices/Shape";
import { ShapeManager } from "../../DatabaseServices/ShapeManager"; import { ShapeManager } from "../../DatabaseServices/ShapeManager";
import { BoolOpeartionType } from "../BoolOperateUtils"; import { BoolOpeartionType } from "../BoolOperateUtils";
import { OptimizeToolPath } from "./OptimizeToolPath"; import { OptimizeToolPath } from "./OptimizeToolPath";
import { equalCurve } from "../../Common/CurveUtils"; import { equalCurve, isRect } from "../../Common/CurveUtils";
import { Vector3 } from "three";
/** /**
* *
@ -28,7 +29,6 @@ export class FeedingToolPath extends Singleton
let dir = this.GetCurveToInDir(outline); let dir = this.GetCurveToInDir(outline);
let offsetCus: Curve[] = [outline]; let offsetCus: Curve[] = [outline];
//获得形状外孔轮廓 //获得形状外孔轮廓
let holes = shape.Holes.map(h => let holes = shape.Holes.map(h =>
{ {
@ -130,39 +130,105 @@ export class FeedingToolPath extends Singleton
dir = -1; dir = -1;
return dir; return dir;
} }
/**用于测试走刀路径 */
TestCalcPath(br: Board)
{
let cus = this.CalcPath(br);
//加入板件轮廓
cus.push(br.ContourCurve.Clone());
if (cus.length === 1)
return cus;
//加入造型外轮廓和洞
for (let { shape, thickness } of br.BoardModeling)
{
let outline = shape.Outline.Curve.Clone();
outline.Position = outline.Position.setZ(0);
outline.ColorIndex++;
cus.push(outline);
if (thickness < br.Thickness)
{
cus.push(...shape.Holes.map(h =>
{
let c = h.Curve.Clone();
c.Position = c.Position.setZ(0);
c.ColorIndex += 1;
return c;
}));
}
}
return cus;
}
/** /**
* *
* TODO:===ys * TODO:===ys
*/ */
CalcPath(br: Board): Curve[] CalcPath(br: Board): Curve[]
{ {
let cus: Curve[] = [br.ContourCurve.Clone()]; let cus: Curve[] = [];
let modelings = br.BoardModeling; let modelings = br.BoardModeling;
for (let { shape, thickness, knifeRadius } of modelings) for (let m of modelings)
{ {
if (!knifeRadius) knifeRadius = 3; cus.push(...this.GetModelFeedPath(br.Thickness, m));
if (thickness >= br.Thickness) }
{ return cus;
//通孔只切一刀 }
let outline = shape.Outline.Curve; GetModelFeedPath(brThickness: number, m: IModeling): Curve[]
let dir = this.GetCurveToInDir(outline); {
let paths: Curve[]; let cus: Curve[] = [];
if (outline instanceof Circle) let { shape, thickness, knifeRadius, addLen } = m;
paths = outline.GetOffsetCurves(dir * knifeRadius); if (!knifeRadius) knifeRadius = 3;
else
paths = outline.GetFeedingToolPath(dir * knifeRadius); shape = shape.Clone();
paths.forEach(p => p.ColorIndex = outline.ColorIndex);
outline.ColorIndex++; this.GrooveAddLen(shape, addLen);
cus.push(outline, ...paths);
} if (thickness >= brThickness)
{
//通孔只切一刀
let outline = shape.Outline.Curve;
let dir = this.GetCurveToInDir(outline);
let paths: Curve[];
if (outline instanceof Circle)
paths = outline.GetOffsetCurves(dir * knifeRadius);
else else
paths = outline.GetFeedingToolPath(dir * knifeRadius);
paths.forEach(p => p.ColorIndex = outline.ColorIndex);
outline.ColorIndex++;
cus.push(...paths);
}
else
{
let offsetCus = this.HandleShape(shape, knifeRadius);
if (offsetCus.length > 1)
cus.push(...OptimizeToolPath(offsetCus, shape, knifeRadius));
}
return cus;
}
private GrooveAddLen(shape: Shape, addLen: number)
{
shape.Outline.Curve.Position = shape.Outline.Curve.Position.setZ(0);
//若是矩形,应用槽加长
if (addLen > 0)
{
let curveData = isRect(shape.Outline.Curve);
if (curveData.isRect)
{ {
let offsetCus = this.HandleShape(shape, knifeRadius); let box = curveData.box;
if (offsetCus.length > 1) let size = curveData.size;
cus.push(...OptimizeToolPath(offsetCus, shape, knifeRadius)); if (size.x > size.y)
{
box.max.add(new Vector3(addLen / 2));
box.min.add(new Vector3(-addLen / 2));
}
else
{
box.max.add(new Vector3(0, addLen / 2));
box.min.add(new Vector3(0, -addLen / 2));
}
let pl = new Polyline().Create2Pt(box.min, box.max).ApplyMatrix(curveData.OCS);
pl.ColorIndex = shape.Outline.Curve.ColorIndex;
shape.Outline = Contour.CreateContour(pl);
} }
} }
return cus;
} }
} }

@ -15,18 +15,10 @@ import { arrayLast } from "../../Common/ArrayExt";
* @param rad * @param rad
* @returns tool path * @returns tool path
*/ */
export function OptimizeToolPath(offsetCus: Curve[], originShape: Shape, rad: number): Curve[] export function OptimizeToolPath(offsetCus: Curve[], originShape: Shape, rad: number, isTest = false): Curve[]
{ {
// 去掉最外轮廓 // 去掉最外轮廓
let outline = offsetCus.shift(); let outline = offsetCus.shift();
outline.ColorIndex += 1;
//洞轮廓
let holesCurve = originShape.Holes.map(h =>
{
let c = h.Curve.Clone();
c.ColorIndex += 1;
return c;
});
let plList: Polyline[] = []; let plList: Polyline[] = [];
let noCloseCus: Curve[] = []; let noCloseCus: Curve[] = [];
@ -119,7 +111,7 @@ export function OptimizeToolPath(offsetCus: Curve[], originShape: Shape, rad: nu
} }
} }
} }
result.push(firstPl, outline, ...holesCurve); result.push(firstPl);
return result; return result;
} }

@ -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;
}
}

@ -135,7 +135,8 @@ export class BoardConfigModal extends React.Component<BoardConfigProps, {}>{
let groove = new ExtureSolid(); let groove = new ExtureSolid();
groove.Thickness = cd.height; groove.Thickness = cd.height;
groove.ContourCurve = shape.Outline.Curve; groove.ContourCurve = shape.Outline.Curve;
groove.KnifeRadius = cd.knifeRad;
groove.GroovesAddLength = cd.addLen;
for (let hole of shape.Holes) for (let hole of shape.Holes)
{ {
let holeSolid = new ExtureSolid(); let holeSolid = new ExtureSolid();
@ -195,18 +196,18 @@ export class BoardConfigModal extends React.Component<BoardConfigProps, {}>{
store.InitModelingItems(); store.InitModelingItems();
let colorIndex = 1; let colorIndex = 1;
let thickMap = new Map<string, number>(); let dataMap = new Map<string, number>();
for (let data of br.BoardModeling) for (let data of br.BoardModeling)
{ {
let thickStr = data.thickness.toString(3); let str = [data.thickness, data.dir, data.knifeRadius, data.addLen].join("-");
let color: number; let color: number;
if (thickMap.has(thickStr)) if (dataMap.has(str))
color = thickMap.get(thickStr); color = dataMap.get(str);
else else
{ {
color = colorIndex; color = colorIndex;
thickMap.set(thickStr, color); dataMap.set(str, color);
colorIndex++; colorIndex++;
store.ChangeModelingValue(color - 1, data); store.ChangeModelingValue(color - 1, data);

@ -39,6 +39,9 @@ export const LayerBoardModal =
uiOption['rightShrink'] = "1"; uiOption['rightShrink'] = "1";
brOpt.leftShrink = 1; brOpt.leftShrink = 1;
brOpt.rightShrink = 1; brOpt.rightShrink = 1;
brOpt.isTotalLength = false;
uiOption['calcHeight'] = "L-1";
brOpt.calcHeight = "L-1";
} }
else else
{ {

@ -12,8 +12,8 @@ export interface IModelingItem
readonly color: number; readonly color: number;
height: number; height: number;
dir: FaceDirection; dir: FaceDirection;
rad: number; knifeRad: number;
length: number; addLen: number;
} }
@inject("store") @inject("store")

@ -85,7 +85,7 @@ export interface BoardProcessOption extends BoardOption
[EBoardKeyList.BigHole]?: FaceDirection;//大孔面 [EBoardKeyList.BigHole]?: FaceDirection;//大孔面
[EBoardKeyList.DrillType]?: string;//排钻类型 [EBoardKeyList.DrillType]?: string;//排钻类型
[EBoardKeyList.ComposingFace]?: ComposingType;//排版面 [EBoardKeyList.ComposingFace]?: ComposingType;//排版面
[EBoardKeyList.HighSealed]?: IHighSealedItem[]; [EBoardKeyList.HighSealed]?: IHighSealedItem[];//封边数据
[EBoardKeyList.UpSealed]?: string;//封边上下左右 [EBoardKeyList.UpSealed]?: string;//封边上下左右
[EBoardKeyList.DownSealed]?: string; [EBoardKeyList.DownSealed]?: string;
[EBoardKeyList.LeftSealed]?: string; [EBoardKeyList.LeftSealed]?: string;

@ -18,6 +18,7 @@ import { AppToaster } from "../Components/Toaster";
import { DrillType, FaceDirection, IHighSealedItem } from "./BoardInterface"; import { DrillType, FaceDirection, IHighSealedItem } from "./BoardInterface";
import { IConfigStore } from "./BoardStore"; import { IConfigStore } from "./BoardStore";
import { LightStore } from "./LightStore"; import { LightStore } from "./LightStore";
import { Modify } from "../../Common/TypeOperator";
export function toggleObject3DVisible(visible = false) export function toggleObject3DVisible(visible = false)
{ {
@ -34,13 +35,20 @@ export function changeView(en: Entity)
app.m_Editor.UpdateScreen(); app.m_Editor.UpdateScreen();
} }
type IUIModeiling = Modify<IModelingItem, {
color: string;
height: string;
knifeRad: string;
addLen: string;
}>;
export class RightPanelStore extends Singleton implements IConfigStore export class RightPanelStore extends Singleton implements IConfigStore
{ {
@observable m_TabId: TabId = RightTabId.Model; @observable m_TabId: TabId = RightTabId.Model;
@observable m_BoardTemplateTabId: TabId = "cabinet"; @observable m_BoardTemplateTabId: TabId = "cabinet";
@observable m_IsShow = false; @observable m_IsShow = false;
@observable modelingItems: IModelingItem[] = []; @observable modelingItems: IModelingItem[] = [];
@observable UIModelingItems = []; @observable UIModelingItems: IUIModeiling[] = [];
lightStore = new LightStore(); lightStore = new LightStore();
currentBoard: Board; currentBoard: Board;
@observable cuList: Curve[] = []; @observable cuList: Curve[] = [];
@ -64,15 +72,15 @@ export class RightPanelStore extends Singleton implements IConfigStore
color: (i + 1).toString(), color: (i + 1).toString(),
height: "0", height: "0",
dir: FaceDirection.Front, dir: FaceDirection.Front,
rad: "3", knifeRad: "3",
length: "0" addLen: "0"
}) })
this.modelingItems.push({ this.modelingItems.push({
color: i + 1, color: i + 1,
height: 0, height: 0,
dir: FaceDirection.Front, dir: FaceDirection.Front,
rad: 3, knifeRad: 3,
length: 0 addLen: 0
}) })
} }
} }
@ -82,6 +90,10 @@ export class RightPanelStore extends Singleton implements IConfigStore
this.UIModelingItems[index]["height"] = data.thickness.toString(); this.UIModelingItems[index]["height"] = data.thickness.toString();
this.modelingItems[index].dir = data.dir; this.modelingItems[index].dir = data.dir;
this.UIModelingItems[index]["dir"] = data.dir; this.UIModelingItems[index]["dir"] = data.dir;
this.modelingItems[index].knifeRad = data.knifeRadius;
this.UIModelingItems[index]["knifeRad"] = data.knifeRadius.toString();
this.modelingItems[index].addLen = data.addLen;
this.UIModelingItems[index]["addLen"] = data.addLen.toString();
} }
ShowCurve() ShowCurve()
@ -268,8 +280,8 @@ export class RightPanelStore extends Singleton implements IConfigStore
for (let i = 0; i < this.modelingItems.length; i++) for (let i = 0; i < this.modelingItems.length; i++)
{ {
this.UIModelingItems[i].height = this.modelingItems[i].height.toString(); this.UIModelingItems[i].height = this.modelingItems[i].height.toString();
this.UIModelingItems[i].rad = this.modelingItems[i].rad.toString(); this.UIModelingItems[i].knifeRad = this.modelingItems[i].knifeRad.toString();
this.UIModelingItems[i].length = this.modelingItems[i].length.toString(); this.UIModelingItems[i].addLen = this.modelingItems[i].addLen.toString();
} }
} }
} }

Loading…
Cancel
Save