Files
cut-abstractions/tests/dev1/dataHandle/common/LayoutEngine/BlockSizePlus.ts
2025-07-22 18:22:31 +08:00

474 lines
17 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { Line2d } from '../../common/base/CAD.js'
import { PlaceStyle,PlaceBlock } from '../../confClass.js'
/** 有造型需要板外下刀, 特别计算要外偏的偏移值, 在排版的时候要算进开料尺寸 */
export class BlockSizePlus
{
/** 分析板外尺寸偏移:1 预洗, 同刀辅助开料,出板造型刀, 2V刀路 */
static analySizeOff(block: PlaceBlock, sysConfig: any)
{
// //1.预铣 预铣值先设置=1
// this.analyePreCut(block,sysConfig);
// //2.同刀辅助
// this.analyeSameKnifeToHelpCut(block, sysConfig);
// //3.造型刀超出板外
// this.analyeModelKnifeR(block);
// //3.二维刀路 板外下刀
// this.analye2VModels(block);
}
/** 分析1: 预铣尺寸扩展, 分析每条异形边预铣标识 */
static analyePreCut(block: PlaceBlock, sysConfig: any)
{
// 先默认 预洗值为1 ,真正使用时 * 真正的预洗值
// let bd = block.SaleBlockDetail;
// if (bd.preCutSizeOutOff) return;
// if(sysConfig.PreCutValue <= 0) //没有启动预铣
// {
// bd.preCutSizeOutOff = new SizeOutOff();
// return ;
// }
// let width = block.Width;
// let length = block.Length;
// let zp = 0;
// let yp = 0;
// let sp = 0;
// let xp = 0;
// if (block.IsUnRegular == false) //矩形板
// {
// if (block.BorderLeft > 0.001) zp = 1;
// if (block.BorderRight > 0.001) yp = 1;
// if (block.BorderUpper > 0.001) sp = 1;
// if (block.BorderUnder > 0.001) xp = 1;
// }
// else //异形板
// {
// //1 判断异形边 预洗
// for (let i = 0; i < bd.OrgPoints.length; i++)
// {
// let s = i - 1;
// let j = i + 1;
// if (s == -1) s = bd.OrgPoints.length - 1;
// if (j == bd.OrgPoints.length) j = 0;
// let p0 = bd.OrgPoints[s];
// let p1 = bd.OrgPoints[i];
// let p2 = bd.OrgPoints[j];
// p1.needPreCut = checkYX(p0,p1,p2);
// setFX(p1,p2);
// }
// //2 如果是同一水平线,或垂直线的, 有一条不能预铣,所有都不能预铣
// // //底
// // let pts = bd.OrgPoints.filter(t=>t['fx']==0 && equal(t.PointY,0));
// // let noPreCut = pts.some(t=>!t.needPreCut);
// // if(noPreCut) pts.forEach(t=>t.needPreCut = false);
// // xp = pts.some(t=>t.needPreCut) ? 1:0;
// // //右
// // pts = bd.OrgPoints.filter(t=>t['fx']==1 && equal(t.PointX,width));
// // noPreCut = pts.some(t=>!t.needPreCut);
// // if(noPreCut) pts.forEach(t=>t.needPreCut = false);
// // yp = pts.some(t=>t.needPreCut) ? 1:0;
// // //上
// // pts = bd.OrgPoints.filter(t=>t['fx']==2 && equal(t.PointY,length));
// // noPreCut = pts.some(t=>!t.needPreCut);
// // if(noPreCut) pts.forEach(t=>t.needPreCut = false);
// // sp = pts.some(t=>t.needPreCut) ? 1:0;
// // //左
// // pts = bd.OrgPoints.filter(t=>t['fx']==3 && equal(t.PointX,0));
// // noPreCut = pts.some(t=>!t.needPreCut);
// // if(noPreCut) pts.forEach(t=>t.needPreCut = false);
// // zp = pts.some(t=>t.needPreCut) ? 1:0;
// //3 .内部有缺角的边 ,不能预铣
// //底
// let pts = bd.OrgPoints.filter(t=>t['fx']==0 && equal(t.PointY,0));
// if(pts.length > 1) pts.forEach(t=>t.needPreCut = false); //底的边,有多条线段,表示内部有缺角,全部不能预铣
// xp = pts.some(t=>t.needPreCut) ? 1:0;
// //右
// pts = bd.OrgPoints.filter(t=>t['fx']==1 && equal(t.PointX,width));
// if(pts.length > 1) pts.forEach(t=>t.needPreCut = false);
// yp = pts.some(t=>t.needPreCut) ? 1:0;
// //上
// pts = bd.OrgPoints.filter(t=>t['fx']==2 && equal(t.PointY,length));
// if(pts.length > 1) pts.forEach(t=>t.needPreCut = false);
// sp = pts.some(t=>t.needPreCut) ? 1:0;
// //左
// pts = bd.OrgPoints.filter(t=>t['fx']==3 && equal(t.PointX,0));
// if(pts.length > 1) pts.forEach(t=>t.needPreCut = false);
// zp = pts.some(t=>t.needPreCut) ? 1:0;
// //如果斜边 会影响
// //3 再计算 扩展 有预铣边的斜线 起点或终点 在这边上的,这边就要扩展
// for(let i = 0 ; i < bd.OrgPoints.length ;i++)
// {
// let j = i + 1;
// if (j == bd.OrgPoints.length) j = 0;
// let p1 = bd.OrgPoints[i];
// let p2 = bd.OrgPoints[j];
// if(p1.needPreCut == false) continue;
// //判断 起点
// if(p1['fx']==4 && xp == 0 && equal(p1.PointY,0)) xp = 1
// if(p1['fx']==5 && yp == 0 && equal(p1.PointX,width)) yp = 1
// if(p1['fx']==6 && sp == 0 && equal(p1.PointY,length)) sp = 1
// if(p1['fx']==7 && zp == 0 && equal(p1.PointX,0)) zp = 1
// //判断终点
// if(p1['fx']==4 && yp == 0 && equal(p2.PointX,width)) yp = 1
// if(p1['fx']==5 && sp == 0 && equal(p2.PointY,length)) sp = 1
// if(p1['fx']==6 && zp == 0 && equal(p2.PointX,0)) zp = 1
// if(p1['fx']==7 && xp == 0 && equal(p2.PointY,0)) xp = 1
// }
// }
// let sizePlus = new SizeOutOff();
// sizePlus.left = zp;
// sizePlus.right = yp;
// sizePlus.bottom = xp;
// sizePlus.top = sp;
// sizePlus.width = zp + yp;
// sizePlus.length = sp + xp;
// bd.preCutSizeOutOff = sizePlus;
// function checkYX(p0,p1,p2) //判断p1是否需要预铣
// {
// if (p1.Curve != 0) return false; //本身是圆弧
// if (p1.SealSize < 0.001) return false;// 本身不封边
// if (p0.Curve != 0) return false; //前一段是圆弧
// if (p2.Curve != 0) return false;//后一段是圆弧
// //p1.p2 只要有一点在板内,就不行
// let isIn1 = (p1.PointX > 0.001 && p1.PointX < width - 0.001 && p1.PointY > 0.001 && p1.PointY < length - 0.001);
// if (isIn1) return false;
// let isIn2 = (p2.PointX > 0.001 && p2.PointX < width - 0.001 && p2.PointY > 0.001 && p2.PointY < length - 0.001);
// if (isIn2) return false;
// return true; //需要预洗
// }
// function setFX(p1,p2) //设置p1的方向
// {
// let fx = -1; //向右 0,向上 1向左 2向下 3 ,右上 4,左上5,左下6右下 7
// if(p2.PointX > p1.PointX && equal(p2.PointY,p1.PointY))
// {
// fx = 0;
// }
// else if(p2.PointX < p1.PointX && equal(p2.PointY,p1.PointY))
// {
// fx = 2;
// }
// else if(p2.PointY > p1.PointY && equal(p2.PointX,p1.PointX))
// {
// fx = 1;
// }
// else if(p2.PointY < p1.PointY && equal(p2.PointX,p1.PointX))
// {
// fx = 3;
// }
// else if(p2.PointX > p1.PointX && p2.PointY > p1.PointY)
// {
// fx = 4;
// }
// else if(p2.PointX < p1.PointX && p2.PointY > p1.PointY)
// {
// fx = 5;
// }
// else if(p2.PointX < p1.PointX && p2.PointY < p1.PointY)
// {
// fx = 6;
// }
// else if(p2.PointX > p1.PointX && p2.PointY < p1.PointY)
// {
// fx = 7;
// }
// p1['fx'] = fx;
// }
}
// 分析2 同刀辅助
static analyeSameKnifeToHelpCut(block: PlaceBlock, sysconfig: any)
{
// let bDetail = block.SaleBlockDetail;
// let isSameKnifeToCut = sysconfig.UseSameKnifeToHelpCut && sysconfig.UseSameKnifeToHelpCutGap > 0;
// //未启动同刀辅助, 或 该小板 不需要同刀辅助
// if (isSameKnifeToCut == false || bDetail.isNeedHelpCut == false)
// {
// bDetail.sameKnifeToHelpCutGap = 0;
// bDetail.sameKnfieHelpOutOff = new SizeOutOff();
// }
// else
// {
// let gap = sysconfig.UseSameKnifeToHelpCutGap;
// bDetail.sameKnifeToHelpCutGap = gap;
// bDetail.sameKnfieHelpOutOff = new SizeOutOff({ left: gap, right: gap, under: gap, upper: gap });
// }
}
// 分析3 造型刀 超出板外
static analyeModelKnifeR(block: PlaceBlock)
{
// let bDetail = block.SaleBlockDetail;
// if (bDetail.modelKnifeOutOff) return;
// let outValue = (block.PlaceMetrial.CutDia + block.PlaceMetrial.CutGap) /2;
// let minX = -outValue;
// let maxX = bDetail.CuttingWidth + outValue;
// let minY = -outValue;
// let maxY = bDetail.CuttingLength + outValue;
// //求 造型点 最偏 值
// for (let model of bDetail.Models)
// {
// if(model.isVKnifeModel) continue;
// if(model.IsDo==false) continue;
// if(model.Depth > block.Thickness - 0.001) continue;
// let r = model.KnifeRadius;
// for (let mp of model.PointList)
// {
// if (mp.PointX - r < minX) minX = mp.PointX - r;
// if (mp.PointX + r > maxX) maxX = mp.PointX + r;
// if (mp.PointY - r < minY) minY = mp.PointY - r;
// if (mp.PointY + r > maxY) maxY = mp.PointY + r;
// }
// }
// let off = {left:0,right :0,upper:0,under:0};
// /**暂时屏蔽 造型外扩 */
// // if (minX < - outValue) off.left = (-minX) - outValue;
// // if (maxX > bDetail.CuttingWidth + outValue) off.right = maxX - bDetail.CuttingWidth - outValue;
// // if (minY < - outValue) off.bottom = (-minY) - outValue;
// // if (maxY > bDetail.CuttingLength + outValue) off.top = maxY - bDetail.CuttingLength - outValue;
// bDetail.modelKnifeOutOff = new SizeOutOff(off);
}
// 分析4 板外下刀 2v刀路
static analye2VModels(block: PlaceBlock)
{
// let blockDetail = block.SaleBlockDetail;
// if (blockDetail.vKnifeModelSizeOutOff) return;//已存在, 不用重复分析
// let sizePlus = new SizeOutOff();
// let cutR = block.PlaceMetrial.CutDia /2;
// let minX = - cutR;
// let maxX = block.CuttingWidth + cutR ;
// let minY = - cutR;
// let maxY = block.CuttingLength + cutR;
// for(let model of blockDetail.Models)
// {
// if(!model.IsDo || model.isVKnifeModel ==false ) continue;
// if(!model.VLines) continue;
// if(model.VLines.length == 0) continue;
// for(let vm of model.VLines)
// {
// let knifeR = vm.knifeRadius;
// let points = vm.points.map((t) =>
// {
// return {
// PointX: t.x,
// PointY: t.y,
// Radius: t.r,
// Depth: vm.depth - t.z,
// Curve: t.bul,
// };
// });
// let isOut = vm.points.some(t=>t.x - knifeR < -cutR)
// || vm.points.some(t=>t.x + knifeR > block.CuttingWidth + cutR)
// || vm.points.some(t=>t.y - knifeR < -cutR)
// || vm.points.some(t=>t.y + knifeR > block.CuttingLength + cutR);
// if(isOut ) //超出板外
// {
// vm['isOut'] = true;
// for (let mp of points)
// {
// if (mp.PointX - knifeR < minX) minX = mp.PointX - knifeR;
// if (mp.PointX + knifeR > maxX) maxX = mp.PointX + knifeR;
// if (mp.PointY - knifeR < minY) minY = mp.PointY - knifeR;
// if (mp.PointY + knifeR > maxY) maxY = mp.PointY + knifeR;
// }
// }
// }
// }
// if (minX < -cutR) sizePlus.left = -minX;
// if (maxX > block.CuttingWidth + cutR) sizePlus.right = maxX - block.CuttingWidth;
// if (minY < -cutR) sizePlus.bottom = - minY;
// if (maxY > block.CuttingLength + cutR) sizePlus.top = maxY - block.CuttingLength;
// sizePlus.width = sizePlus.left + sizePlus.right;
// sizePlus.length = sizePlus.bottom + sizePlus.top;
// sizePlus.hasDone = true;
// //blockDetail.vKnifeModelSizeOutOff = sizePlus;
// blockDetail.vKnifeModelSizeOutOff = new SizeOutOff();
}
/** 获得板件偏移值 */
static getOffDis(block: PlaceBlock, placeStyle?: PlaceStyle): any
{
// console.log('获得板件偏移值')
if (placeStyle == null || placeStyle == undefined)
{
placeStyle = block.placeStyle
}
let expandSize :any = block.sizeExpand()
let posOff = { x: 0, y: 0, left: 0, right: 0, top: 0, bottom: 0 }
if(expandSize){
switch (placeStyle)
{
case PlaceStyle.FRONT: // 正面
posOff.x = expandSize.left
posOff.y = expandSize.bottom
posOff.left = expandSize.left
posOff.right = expandSize.right
posOff.bottom = expandSize.bottom
posOff.top = expandSize.top
break
case PlaceStyle.FRONT_TURN_RIGHT: // 正面右转
posOff.x = expandSize.bottom
posOff.y = expandSize.right
posOff.left = expandSize.bottom
posOff.right = expandSize.top
posOff.bottom = expandSize.right
posOff.top = expandSize.left
break
case PlaceStyle.FRONT_TURN_BACK: // 正面后转
posOff.x = expandSize.right
posOff.y = expandSize.top
posOff.left = expandSize.right
posOff.right = expandSize.left
posOff.bottom = expandSize.top
posOff.top = expandSize.bottom
break
case PlaceStyle.FRONT_TURN_LEFT: // 正面左转
posOff.x = expandSize.top
posOff.y = expandSize.left
posOff.left = expandSize.top
posOff.right = expandSize.bottom
posOff.bottom = expandSize.left
posOff.top = expandSize.right
break
case PlaceStyle.BACK: // 反面
posOff.x = expandSize.right
posOff.y = expandSize.bottom
posOff.left = expandSize.right
posOff.right = expandSize.left
posOff.bottom = expandSize.bottom
posOff.top = expandSize.top
break
case PlaceStyle.BACK_TURN_RIGHT: // 反面右转
posOff.x = expandSize.bottom
posOff.y = expandSize.left
posOff.left = expandSize.bottom
posOff.right = expandSize.top
posOff.bottom = expandSize.left
posOff.top = expandSize.right
break
case PlaceStyle.BACK_TURN_BACK: // 反面后转
posOff.x = expandSize.left
posOff.y = expandSize.top
posOff.left = expandSize.left
posOff.right = expandSize.right
posOff.bottom = expandSize.top
posOff.top = expandSize.bottom
break
case PlaceStyle.BACK_TURN_LEFT: // 反面左转
posOff.x = expandSize.top
posOff.y = expandSize.right
posOff.left = expandSize.bottom
posOff.right = expandSize.bottom
posOff.bottom = expandSize.right
posOff.top = expandSize.left
break
default:
break
}
}
return posOff
}
// 设置板件的位置
static resetNewPlace(block: PlaceBlock)
{
let posOff = this.getOffDis(block)
block.placeOffX = posOff.x
block.placeOffY = posOff.y
block.placeX = block.placeX + block.placeOffX
block.placeY = block.placeY + block.placeOffY
}
static checkPreBorder(block: PlaceBlock, line: Line2d): boolean // 判断 开料刀路中的一条 line 是否需要预洗
{
let x1 = line.StartPoint.m_X
let y1 = line.StartPoint.m_Y
let x2 = line.EndPoint.m_X
let y2 = line.EndPoint.m_Y
if (block.isUnRegular == false) // 矩形
{
if (this.eqaul(x1, 0, 0.01) && this.eqaul(x1, x2))
return block.sealLeft > 0
if (this.eqaul(x1, block.cutWidth, 0.01) && this.eqaul(x1, x2))
return block.sealRight > 0
if (this.eqaul(y1, 0, 0.01) && this.eqaul(y1, y2))
return block.sealBottom > 0
if (this.eqaul(y1, block.cutLength, 0.01) && this.eqaul(y1, y2))
return block.sealTop > 0
return false
}
else // 异形
{
// 找出原始轮廓中 对应的边 , 是否有 预洗信息
for (let i = 0; i < block.orgPoints.length; i++)
{
let j = i + 1
if (j == block.orgPoints.length)
j = 0
if (block.orgPoints[i].curve != 0)
continue
let dis = block.orgPoints[i].sealSize
let w1 = block.orgPoints[i].pointX - (block.blockDetail?.offsetX || 0)
let v1 = block.orgPoints[i].pointY - (block.blockDetail?.offsetY || 0)
let w2 = block.orgPoints[j].pointX - (block.blockDetail?.offsetX || 0)
let v2 = block.orgPoints[j].pointY - (block.blockDetail?.offsetY || 0)
let dis1 = Math.sqrt((x1 - w1) * (x1 - w1) + (y1 - v1) * (y1 - v1))
if (dis1 > dis * 2)
continue
let dis2 = Math.sqrt((x2 - w2) * (x2 - w2) + (y2 - v2) * (y2 - v2))
if (dis2 < dis * 2)
return block.orgPoints[i].isPreCutRequired
}
return false
}
}
static equal2Point(p1, p2, dis = 0.001)
{
let x1 = p1.m_X
let y1 = p1.m_Y
let x2 = p2.m_X
let y2 = p2.m_Y
let len1 = (x1 - x2) * (x1 - x2)
let len2 = (y1 - y2) * (y1 - y2)
let len = Math.sqrt(len2 + len1)
return len < dis
}
static eqaul(a, b, dis = 0.001)
{
return Math.abs(a - b) < 0.001
}
}