|
|
|
@ -16,119 +16,128 @@ import { IHighSealedItem, ISealingData } from "../UI/Store/BoardInterface";
|
|
|
|
|
import { IntersectOption } from "./IntersectWith";
|
|
|
|
|
import { ParseEdgeSealDir } from "./ParseEdgeSealDir";
|
|
|
|
|
|
|
|
|
|
type CurveGroups = (Curve[])[];
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*曲线列表分段
|
|
|
|
|
* 将曲线分段(根据高级封边的特性 (因为圆弧无法单独使用封边,所以和圆弧在一起的曲线必须和圆弧一样的封边,否则偏移失败))
|
|
|
|
|
* @l-arc-l,l-arc-arc-l,l-arc-l-arc-l....
|
|
|
|
|
* @param in_out_curves 曲线组( 函数结束后 这个数组被改变 )
|
|
|
|
|
* @returns 返回编组 curveGroups
|
|
|
|
|
*/
|
|
|
|
|
export function ParagraphCulist(cus: Curve[])
|
|
|
|
|
export function SubsectionCurvesOfHightSeal(in_out_curves: Curve[]): CurveGroups
|
|
|
|
|
{
|
|
|
|
|
let newCulist: (Curve[])[] = [];
|
|
|
|
|
let curveGroups: CurveGroups = [];
|
|
|
|
|
let usedCu: WeakSet<Curve> = new WeakSet();
|
|
|
|
|
|
|
|
|
|
//归类曲线,返回归类是否成功
|
|
|
|
|
const paragraph = (cu: Curve, originCu: Curve, cuList: Curve[], isBack: boolean) =>
|
|
|
|
|
const paragraph = (nextCurve: Curve, curCurve: Curve, curvesGroup: Curve[], isBack: boolean) =>
|
|
|
|
|
{
|
|
|
|
|
const cuIsLine = cu instanceof Line;
|
|
|
|
|
const originCuIsLine = originCu instanceof Line;
|
|
|
|
|
const curIsLine = curCurve instanceof Line;
|
|
|
|
|
const nextIsLine = nextCurve instanceof Line;
|
|
|
|
|
|
|
|
|
|
if (usedCu.has(cu))
|
|
|
|
|
if (usedCu.has(nextCurve))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (originCuIsLine !== cuIsLine)
|
|
|
|
|
if (curIsLine !== nextIsLine)//直线和圆弧
|
|
|
|
|
{
|
|
|
|
|
if (originCuIsLine)
|
|
|
|
|
if (curIsLine)
|
|
|
|
|
{
|
|
|
|
|
if (isBack)
|
|
|
|
|
{
|
|
|
|
|
if (!isParallelTo(originCu.GetFistDeriv(0), cu.GetFistDeriv(0)))
|
|
|
|
|
if (!isParallelTo(curCurve.GetFistDeriv(0), nextCurve.GetFistDeriv(0)))
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (!isParallelTo(originCu.GetFistDeriv(0), cu.GetFistDeriv(1)))
|
|
|
|
|
if (!isParallelTo(curCurve.GetFistDeriv(0), nextCurve.GetFistDeriv(1)))
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cuIsLine)
|
|
|
|
|
if (nextIsLine)
|
|
|
|
|
{
|
|
|
|
|
if (isBack)
|
|
|
|
|
{
|
|
|
|
|
if (!isParallelTo(originCu.GetFistDeriv(1), cu.GetFistDeriv(0)))
|
|
|
|
|
if (!isParallelTo(curCurve.GetFistDeriv(1), nextCurve.GetFistDeriv(0)))
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (!isParallelTo(originCu.GetFistDeriv(0), cu.GetFistDeriv(0)))
|
|
|
|
|
if (!isParallelTo(curCurve.GetFistDeriv(0), nextCurve.GetFistDeriv(0)))
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (cuIsLine)
|
|
|
|
|
else if (nextIsLine)//都是直线
|
|
|
|
|
{
|
|
|
|
|
//共线且相连的直线分为一组 #I11T1Z
|
|
|
|
|
if (!isParallelTo(cu.GetFistDeriv(0).normalize(), originCu.GetFistDeriv(0).normalize()))
|
|
|
|
|
if (!isParallelTo(nextCurve.GetFistDeriv(0).normalize(), curCurve.GetFistDeriv(0).normalize()))
|
|
|
|
|
return false;
|
|
|
|
|
let pts = [originCu.StartPoint, originCu.EndPoint];
|
|
|
|
|
let pts2 = [cu.StartPoint, cu.EndPoint];
|
|
|
|
|
if (pts.every(p => pts2.every(p2 => !equalv3(p, p2, 1e-6))))
|
|
|
|
|
|
|
|
|
|
let pts = [curCurve.StartPoint, curCurve.EndPoint];
|
|
|
|
|
let pts2 = [nextCurve.StartPoint, nextCurve.EndPoint];
|
|
|
|
|
if (pts.every(p => pts2.every(p2 => !equalv3(p, p2, 1e-6))))//2条线完全分离 没有共同点
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
//else 都是圆弧 必然成组
|
|
|
|
|
|
|
|
|
|
if (isBack)
|
|
|
|
|
cuList.push(cu);
|
|
|
|
|
curvesGroup.push(nextCurve);
|
|
|
|
|
else
|
|
|
|
|
cuList.unshift(cu);
|
|
|
|
|
usedCu.add(cu);
|
|
|
|
|
curvesGroup.unshift(nextCurve);
|
|
|
|
|
|
|
|
|
|
usedCu.add(nextCurve);
|
|
|
|
|
return true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let caclCus = cus.filter(c => !equaln(c.Length, 0));
|
|
|
|
|
let caclCus = in_out_curves.filter(c => !equaln(c.Length, 0));
|
|
|
|
|
|
|
|
|
|
while (caclCus.length > 0)
|
|
|
|
|
{
|
|
|
|
|
let originCu = caclCus.shift();
|
|
|
|
|
if (usedCu.has(originCu))
|
|
|
|
|
let curCurve = caclCus.shift();
|
|
|
|
|
if (usedCu.has(curCurve))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
let originCus = [originCu];
|
|
|
|
|
usedCu.add(originCu);
|
|
|
|
|
let curvesGroup = [curCurve];//编组
|
|
|
|
|
usedCu.add(curCurve);
|
|
|
|
|
//往后搜索
|
|
|
|
|
for (let i = 0; i < caclCus.length; i++)
|
|
|
|
|
{
|
|
|
|
|
if (!paragraph(caclCus[i], originCu, originCus, true))
|
|
|
|
|
if (!paragraph(caclCus[i], curCurve, curvesGroup, true))
|
|
|
|
|
break;
|
|
|
|
|
originCu = caclCus[i];
|
|
|
|
|
curCurve = caclCus[i];
|
|
|
|
|
}
|
|
|
|
|
//只有第一条才需要往前搜索
|
|
|
|
|
if (caclCus.length === cus.length - 1)
|
|
|
|
|
if (caclCus.length === in_out_curves.length - 1)
|
|
|
|
|
{
|
|
|
|
|
originCu = originCus[0];
|
|
|
|
|
curCurve = curvesGroup[0];
|
|
|
|
|
//往前搜索
|
|
|
|
|
for (let i = caclCus.length - 1; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
if (!paragraph(caclCus[i], originCu, originCus, false))
|
|
|
|
|
if (!paragraph(caclCus[i], curCurve, curvesGroup, false))
|
|
|
|
|
break;
|
|
|
|
|
originCu = caclCus[i];
|
|
|
|
|
curCurve = caclCus[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
newCulist.push(originCus);
|
|
|
|
|
curveGroups.push(curvesGroup);
|
|
|
|
|
}
|
|
|
|
|
cus.length = 0;
|
|
|
|
|
|
|
|
|
|
in_out_curves.length = 0;
|
|
|
|
|
//同组多条曲线连接为多段线
|
|
|
|
|
for (let g of newCulist)
|
|
|
|
|
for (let g of curveGroups)
|
|
|
|
|
{
|
|
|
|
|
if (g.length === 1)
|
|
|
|
|
cus.push(g[0]);
|
|
|
|
|
in_out_curves.push(g[0]);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
let pl = new Polyline();
|
|
|
|
|
for (let c of g)
|
|
|
|
|
{
|
|
|
|
|
pl.Join(c);
|
|
|
|
|
}
|
|
|
|
|
cus.push(pl);
|
|
|
|
|
in_out_curves.push(pl);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return curveGroups;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -351,13 +360,14 @@ export function GetBoardSealingCurves(br: Board, isOffset = false): Curve[]
|
|
|
|
|
{
|
|
|
|
|
cus = cu.Explode() as Curve[];
|
|
|
|
|
if (br.IsSpecialShape)
|
|
|
|
|
ParagraphCulist(cus);
|
|
|
|
|
SubsectionCurvesOfHightSeal(cus);
|
|
|
|
|
return cus;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const SEAL_VALUE_KEY = "__highSeals__";
|
|
|
|
|
//曲线的每段封边值
|
|
|
|
|
const __CURVE_EACH_SEAL_VALUE_KEY__ = "__CURVE_EACH_SEAL_VALUE__";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -477,7 +487,7 @@ export function GetSealedBoardContour(br: Board, hasSealing: boolean, isParseSea
|
|
|
|
|
{
|
|
|
|
|
let cir = offsetCus[0];
|
|
|
|
|
|
|
|
|
|
if (highSealsExpd) cir[SEAL_VALUE_KEY] = highSealsExpd;
|
|
|
|
|
if (highSealsExpd) cir[__CURVE_EACH_SEAL_VALUE_KEY__] = highSealsExpd;
|
|
|
|
|
|
|
|
|
|
return cir;
|
|
|
|
|
}
|
|
|
|
@ -490,14 +500,14 @@ export function GetSealedBoardContour(br: Board, hasSealing: boolean, isParseSea
|
|
|
|
|
highSealsExpd?.reverse();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (highSealsExpd) pl[SEAL_VALUE_KEY] = highSealsExpd;
|
|
|
|
|
if (highSealsExpd) pl[__CURVE_EACH_SEAL_VALUE_KEY__] = highSealsExpd;
|
|
|
|
|
|
|
|
|
|
return pl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function GetBoardSealingData(curve: Polyline | Circle)
|
|
|
|
|
{
|
|
|
|
|
let sealData = curve[SEAL_VALUE_KEY] as ISealingData[];
|
|
|
|
|
let sealData = curve[__CURVE_EACH_SEAL_VALUE_KEY__] as ISealingData[];
|
|
|
|
|
if (curve instanceof Circle)
|
|
|
|
|
{
|
|
|
|
|
sealData[0].length *= 0.5;
|
|
|
|
@ -507,90 +517,28 @@ export function GetBoardSealingData(curve: Polyline | Circle)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function ParagraphSealinglist(hightSeal: IHighSealedItem[], cus: Curve[])
|
|
|
|
|
/**
|
|
|
|
|
* 将11对应的封边数值改成WebCAD的高级封边
|
|
|
|
|
* @param seals 每段曲线的封边
|
|
|
|
|
* @param curves 曲线表
|
|
|
|
|
* @returns 转换成高级封边后的封边值 (圆弧会编组)
|
|
|
|
|
*/
|
|
|
|
|
export function ConverEachSeal2HightSealData(seals: IHighSealedItem[], curves: Curve[]): IHighSealedItem[]
|
|
|
|
|
{
|
|
|
|
|
if (hightSeal.length !== cus.length) return hightSeal;
|
|
|
|
|
|
|
|
|
|
let usedCu: WeakSet<Curve> = new WeakSet();
|
|
|
|
|
let newHighSeal: IHighSealedItem[] = [];
|
|
|
|
|
|
|
|
|
|
//归类曲线,返回归类是否成功
|
|
|
|
|
const paragraph = (cu: Curve, originCu: Curve, isBack: boolean) =>
|
|
|
|
|
{
|
|
|
|
|
const cuIsLine = cu instanceof Line;
|
|
|
|
|
const originCuIsLine = originCu instanceof Line;
|
|
|
|
|
curves = curves.concat();
|
|
|
|
|
seals = seals.concat();
|
|
|
|
|
let s = seals[seals.length - 1];
|
|
|
|
|
for (let i = seals.length; i < curves.length; i++)
|
|
|
|
|
seals.push(s);
|
|
|
|
|
|
|
|
|
|
if (usedCu.has(cu))
|
|
|
|
|
return false;
|
|
|
|
|
const KEY = "__CURVE_SEAL_DATA__";
|
|
|
|
|
|
|
|
|
|
if (originCuIsLine !== cuIsLine)
|
|
|
|
|
{
|
|
|
|
|
if (originCuIsLine &&
|
|
|
|
|
!isParallelTo(originCu.GetFistDeriv(0), cu.GetFistDeriv(0))
|
|
|
|
|
&& !isParallelTo(originCu.GetFistDeriv(0), cu.GetFistDeriv(1))
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cuIsLine
|
|
|
|
|
&& !isParallelTo(originCu.GetFistDeriv(1), cu.GetFistDeriv(0))
|
|
|
|
|
&& !isParallelTo(originCu.GetFistDeriv(0), cu.GetFistDeriv(0)
|
|
|
|
|
))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (cuIsLine)
|
|
|
|
|
{
|
|
|
|
|
//共线且相连的直线分为一组 #I11T1Z
|
|
|
|
|
if (!isParallelTo(cu.GetFistDeriv(0).normalize(), originCu.GetFistDeriv(0).normalize()))
|
|
|
|
|
return false;
|
|
|
|
|
let pts = [originCu.StartPoint, originCu.EndPoint];
|
|
|
|
|
let pts2 = [cu.StartPoint, cu.EndPoint];
|
|
|
|
|
if (pts.every(p => pts2.every(p2 => !equalv3(p, p2, 1e-6))))
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (isBack)
|
|
|
|
|
hightSeal.shift();
|
|
|
|
|
else
|
|
|
|
|
hightSeal.pop();
|
|
|
|
|
usedCu.add(cu);
|
|
|
|
|
return true;
|
|
|
|
|
};
|
|
|
|
|
let caclCus = cus.slice();
|
|
|
|
|
for (let i = 0; i < curves.length; i++)
|
|
|
|
|
curves[i][KEY] = seals[i];
|
|
|
|
|
|
|
|
|
|
while (caclCus.length > 0)
|
|
|
|
|
{
|
|
|
|
|
let originCu = caclCus.shift();
|
|
|
|
|
if (usedCu.has(originCu))
|
|
|
|
|
continue;
|
|
|
|
|
let oldCu = originCu;
|
|
|
|
|
let originSeal = hightSeal.shift();
|
|
|
|
|
newHighSeal.push(originSeal);
|
|
|
|
|
usedCu.add(originCu);
|
|
|
|
|
//往后搜索
|
|
|
|
|
for (let i = 0; i < caclCus.length; i++)
|
|
|
|
|
{
|
|
|
|
|
if (!paragraph(caclCus[i], originCu, true))
|
|
|
|
|
break;
|
|
|
|
|
originCu = caclCus[i];
|
|
|
|
|
}
|
|
|
|
|
//只有第一条才需要往前搜索
|
|
|
|
|
if (caclCus.length === cus.length - 1)
|
|
|
|
|
{
|
|
|
|
|
originCu = oldCu;
|
|
|
|
|
//往前搜索
|
|
|
|
|
for (let i = caclCus.length - 1; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
if (!paragraph(caclCus[i], originCu, false))
|
|
|
|
|
break;
|
|
|
|
|
originCu = caclCus[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
let groups = SubsectionCurvesOfHightSeal(curves);
|
|
|
|
|
|
|
|
|
|
return newHighSeal;
|
|
|
|
|
return groups.map(g => g[0][KEY]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 设置板的上下左右封边 */
|
|
|
|
|