import { Production } from 'cadapi' import { PolylineHelper } from '../../common/LayoutEngine/PolylineHelper.js' import { ArrayExt } from '../../common/base/ArrayExt.js' import { CADExt } from '../../common/base/CAD.js' import { equal } from '../../common/base/MathComm.js' import { getDis_PointLine, getDis2 } from '@/imes/common/base/MathComm.js' // import { SideModel } from '../model/SideModel.js' import { BlockHelper } from './BlockHelper.js' import { SideModel, PlaceBlock, PlaceBlockDetail, FaceType, HoleType, BlockHole, BlockModelPoint, BlockSideModelPoint, SideFaceType, HoleArrange } from '../../confClass.js' import { getDoFace } from './BlockDoFace.js' import { ToolsHelper } from '../../tools/tool.js' /** * 小板原始数据的修改|计算 * 造型点阵,屏蔽一些不合理数据等 * 造型换刀铣 * 计算侧孔方向 * 计算异形板的封边 */ /** 强制造型内往外铣 */ export function reverseModelPoints(bd: PlaceBlockDetail) { // 默认:正面造型,外->内铣;反面造型,内->外铣;因此修改正面造型的点阵顺序 for (let model of bd.models) { if (model.offsetList.length > 0) continue // 2维刀路 不处理 if (model.depth > bd.thickness - 0.001) continue // 挖穿的造型不算 if (model.pointList.length < 3) continue if (model.face != FaceType.FRONT) continue // 正面 // 找出最外圈 let p0 = model.pointList[0] let index = -1 for (let i = 1; i < model.pointList.length; i++) { if (model.pointList[i].pointX == p0.pointX && model.pointList[i].pointY == p0.pointY) { index = i break } } if (index == model.pointList.length - 1) continue if (index == -1) continue // 找不到 // 最外圈 let ps_0 = model.pointList.splice(0, index + 1) // 剩下倒序 model.pointList.reverse() // 换 bul for (let i = 0; i < model.pointList.length; i++) { let j = i + 1 if (j < model.pointList.length) { model.pointList[i].curve = -model.pointList[j].curve model.pointList[i].radius = model.pointList[j].radius } else { model.pointList[i].curve = 0 model.pointList[i].radius = 0 } } model.pointList = model.pointList.concat(ps_0) // 最开始添加一点,避免cnc 当做槽处理 let pf = model.pointList[0].copy() model.pointList.splice(0, 0, pf) } } // /** 排钻转造型 */ // export function Hole2Model(bds: PlaceBlockDetail[], sysConfig: SysConfig) // { // let knifes = sysConfig.HoleToModelKnifes; // knifes = knifes.filter(t => t.isUse && t.knifeId > 0); // for (let knife of knifes) // { // let k = sysConfig.getKnifeById(knife.knifeId); // if (k == null) continue; // knife.knifeR = -1; // if (k.AllowCut || k.AllowModel) // { // knife.knifeR = k.diameter / 2; // } // } // knifes = knifes.filter(t => t.knifeR > 0); // for (let bd of bds) // { // for (let i = bd.holes.length - 1; i >= 0; i--) // { // let hole = bd.holes[i]; // let k = knifes.find(t => t.minR <= hole.radius + 0.00001 && t.maxR > hole.radius + 0.0000001); // if (k == null) continue; // let model = toModel(bd.thickness, hole, k.knifeR); // if (model == null) continue; // bd.models.push(model); // bd.holes.splice(i, 1); // } // } // function toModel(t: number, hole: BlockHole, r: number) // { // let depth = hole.depth; // let hR = hole.radius; // if (hR < r + 0.001) return null; // let model = new BlockModel(); // model.face = hole.face; // model.knifeRadius = r; // model.knifeName = ''; // model.realKnifeRadius = r; // model.depth = hole.depth; // model.canSpace = false; // model.pointList = []; // model.realPointList = model.pointList; // let cx = hole.pointX; // let cy = hole.pointY; // let r0 = hR - r; // if (r0 < 0) r0 = 0; // //最外层先走一圈,顺时针 // //左,上,右,下 // model.pointList.push( new BlockModelPoint({ pointX: cx - r0, pointY: cy, radius: r0, curve: -0.41421356237309503, depth: depth }) ); // model.pointList.push( new BlockModelPoint({ pointX: cx, pointY: cy + r0, radius: r0, curve: -0.41421356237309503, depth: depth }) ); // model.pointList.push( new BlockModelPoint({ pointX: cx + r0, pointY: cy, radius: r0, curve: -0.41421356237309503, depth: depth }) ); // model.pointList.push( new BlockModelPoint({ pointX: cx, pointY: cy - r0, radius: r0, curve: -0.41421356237309503, depth: depth }) ); // model.pointList.push( new BlockModelPoint({ pointX: cx - r0, pointY: cy, radius: 0, curve: 0, depth: depth }) ); // //挖穿 // if (depth >= t - 0.001) return model; // //非挖穿的 // r0 = r0 - r; // while (r0 > 0) // { // //左 ,下,右,上 逆时针 // model.pointList.push( new BlockModelPoint({ pointX: cx - r0, pointY: cy, radius: r0, curve: 0.41421356237309503, depth: depth }) ); // model.pointList.push( new BlockModelPoint({ pointX: cx, pointY: cy - r0, radius: r0, curve: 0.41421356237309503, depth: depth }) ); // model.pointList.push( new BlockModelPoint({ pointX: cx + r0, pointY: cy, radius: r0, curve: 0.41421356237309503, depth: depth }) ); // model.pointList.push( new BlockModelPoint({ pointX: cx, pointY: cy + r0, radius: r0, curve: 0.41421356237309503, depth: depth }) ); // model.pointList.push( new BlockModelPoint({ pointX: cx - r0, pointY: cy, radius: 0, curve: 0, depth: depth }) ); // r0 = r0 - r; // } // //圆心 // model.pointList.push( new BlockModelPoint({ pointX: cx, pointY: cy, radius: 0, curve: 0, depth: depth }) ); // return model; // } // } /** 移除无效的面孔:孔不在板内/孔径太小/孔深不够/圆心在外面的孔 */ export function removeInvalidHoles(block: PlaceBlockDetail, minHoleRadius: number, minHoleDepth: number) { let count = block.holes.length for (let i = count - 1; i >= 0; i--) { let hole = block.holes[i] // 是否无效, 板外,孔径太小,孔深度太浅 let invalid = isInvalidHole(block, hole, 1) if (invalid) { block.holes.splice(i, 1) continue } if (hole.face != FaceType.SIDE && hole.depth > block.thickness) { hole.depth = block.thickness } } function isInvalidHole(blockDetail: PlaceBlockDetail, hole: BlockHole, offset: number): boolean { if (hole.radius < minHoleRadius) return true // 孔径太小 if (hole.depth < minHoleDepth) return true // 孔深度太浅 // 圆心不在板内 if (hole.pointX < -offset) return true // if (hole.PointX > block.KaiLiaoWidth) return true; if (hole.pointY < -offset) return true // if (hole.PointY > block.KaiLiaoLength + offset) return true; return false } } /** 移除二合一的面孔 */ export function remove2in1Hole(block: PlaceBlockDetail, gap: number) { /** 二合一侧孔离边距离 */ let removeSideHoles = new Array() let count = block.holes.length for (let i = count - 1; i >= 0; i--) { let hole = block.holes[i] if (hole.face != FaceType.SIDE) { let sideHolesL = block.holes.filter(t => t.face == FaceType.SIDE && t.pointY == hole.pointY && t.pointX < hole.pointX && t.pointX >= hole.pointX - hole.radius - gap) let sideHolesR = block.holes.filter(t => t.face == FaceType.SIDE && t.pointY == hole.pointY && t.pointX > hole.pointX && t.pointX <= hole.pointX + hole.radius + gap) let sideHolesS = block.holes.filter(t => t.face == FaceType.SIDE && t.pointX == hole.pointX && t.pointY > hole.pointY && t.pointY < hole.pointY + hole.radius + gap) let sideHolesX = block.holes.filter(t => t.face == FaceType.SIDE && t.pointX == hole.pointX && t.pointY < hole.pointY && t.pointY > hole.pointY - hole.radius - gap) removeSideHoles = removeSideHoles.concat(sideHolesL, sideHolesR, sideHolesS, sideHolesX) } } for (let removeHole of removeSideHoles) { let index = block.holes.indexOf(removeHole) if (index >= 0) { block.holes.splice(index, 1) } } } /** 穿孔或打穿造型通孔一刀加工 */ /** * * @param bd * @param config config * throughHoleOneTime 通孔穿孔一刀加工 * * throughHoleProcessMode 穿孔对面加工方式: ** 0随意面,根据排版尽量正面加工(少翻板); ** 1孔面,按碰撞面排孔所在面加工; ** 2孔对面,按碰撞面排孔所在面的对面打孔 */ export function resetThroughHoleModes(bd: PlaceBlockDetail, config: any) { if (!bd.points) bd.points = [] if (!bd.holes) bd.holes = [] if (!bd.models) bd.models = [] const { throughHoleOneTime = false, throughHoleProcessMode = 0, } = config if (throughHoleOneTime) // 通孔穿孔一刀加工 { // 判断正反面匹配的 bd.holeListThrough = bd.holes.filter(t => t.depth >= bd.thickness - 0.001) // 穿孔 bd.holeListFaceA = bd.holes.filter(t => t.face == FaceType.FRONT && t.depth < bd.thickness - 0.001) bd.holeListFaceB = bd.holes.filter(t => t.face == FaceType.BACK && t.depth < bd.thickness - 0.001) // 通孔判断 for (let i = bd.holeListFaceA.length - 1; i >= 0; i--) { let hole1 = bd.holeListFaceA[i] let isThrough = false for (let j = bd.holeListFaceB.length - 1; j >= 0; j--) { let hole2 = bd.holeListFaceB[j] if (isThroughHole(hole1, hole2)) { bd.holeListFaceB.splice(j, 1) isThrough = true } } if (isThrough) { bd.holeListFaceA.splice(i, 1) hole1.depth = bd.thickness bd.holeListThrough.push(hole1) } } } else { if (throughHoleProcessMode == 2) // 通孔对面加工 { for (let hole of bd.holes) { if (hole.holeType == HoleType.THROUGH_HOLE || hole.depth >= bd.thickness - 0.01) { let oldFace = hole.face if (oldFace == FaceType.FRONT) { hole.face = FaceType.BACK } else if (oldFace == FaceType.BACK) { hole.face = FaceType.FRONT } } } } bd.holeListFaceA = bd.holes.filter(t => t.face == FaceType.FRONT) bd.holeListFaceB = bd.holes.filter(t => t.face == FaceType.BACK) bd.holeListThrough = [] } bd.modelListFaceA = bd.models.filter(t => t.face == FaceType.FRONT && (t.depth < bd.thickness - 0.01 || t.isVKnifeModel())) bd.modelListFaceB = bd.models.filter(t => t.face == FaceType.BACK && (t.depth < bd.thickness - 0.01 || t.isVKnifeModel())) bd.modelListThrough = bd.models.filter(t => t.depth >= bd.thickness - 0.01 && t.isVKnifeModel() == false) bd.holeCountFront = bd.holeListFaceA.length bd.holeCountBack = bd.holeListFaceB.length bd.holeCountThrough = bd.holeListThrough.length bd.holeCountSide = bd.holeListSide.length bd.modelCountFront = bd.modelListFaceA.length bd.modelCountBack = bd.modelListFaceB.length bd.modelCountThrough = bd.modelListThrough.length bd.hasModelThrogh = bd.modelListThrough.length > 0 bd.bigHoleInFaceA = bd.holeListFaceA.some(t => t.holeType == HoleType.BIG_HOLE) bd.isTwoFaceProcess = bd.holeCountFront + bd.modelCountFront > 0 && bd.holeCountBack + bd.modelCountBack > 0 /** 判断两孔是否是通孔 */ function isThroughHole(hole1, hole2) { // 孔半径一样,位置一样,深度和大于板厚 return equal(hole1.radius, hole2.radius) && equal(hole1.pointX, hole2.pointX) && equal(hole1.pointY, hole2.pointY) && hole1.depth + hole2.depth >= bd.thickness - 0.01 } } /** 设置侧孔的方向 */ export function setSideHoleFace(block: PlaceBlockDetail) { // 矩形板的侧孔face原始数据无法保证正确,所有都当做起点,终点来计算侧孔的面与方向 for (const hole of block.holeListSide) { if (Math.abs(hole.pointX - hole.pointX2) < 1 && hole.pointY2 > hole.pointY) { hole.direct = 0 // 下侧边,向上 hole.sideFace = SideFaceType.BOTTOM_SIDE } else if (Math.abs(hole.pointX - hole.pointX2) < 1 && hole.pointY2 < hole.pointY) { hole.direct = 2 // 上侧边 向下 hole.sideFace = SideFaceType.TOP_SIDE } else if (Math.abs(hole.pointY - hole.pointY2) < 1 && hole.pointX2 > hole.pointX) { hole.direct = 3 // 在左侧板 向右 hole.sideFace = SideFaceType.LEFT_SIDE } else if (Math.abs(hole.pointY - hole.pointY2) < 1 && hole.pointX2 < hole.pointX) { hole.direct = 1 // 右侧边, 向左 hole.sideFace = SideFaceType.RIGHT_SIDE } else // 斜边 { hole.direct = -1 hole.sideFace = SideFaceType.SPECIAL_SHAPED_SIDE } } block.holeCountLeft = ArrayExt.count(block.holeListSide, t => t.faceId == 3) block.holeCountRight = ArrayExt.count(block.holeListSide, t => t.faceId == 1) block.holeCountTop = ArrayExt.count(block.holeListSide, t => t.faceId == 2) block.holeCountBottom = ArrayExt.count(block.holeListSide, t => t.faceId == 0) block.holeCountBevelled = ArrayExt.count(block.holeListSide, t => ![0, 1, 2, 3].includes(t.faceId)) } /** 初始化 侧面造型 * * * 侧面造型的点阵判断逻辑 * * 提要: * 1、 face 为 该造型在该板件的第几条边上 * 2、 originModeling 内的造型轮廓点阵的 X Y轴 为 : * 以该造型为正面 且小板板面朝上 造型为正面的左下角为原点 板厚 为 Y 横象为X * 注:最终使用的时候 要得到该造型 对应机台的 轮廓数据和刀路数据 * * 平行判断 参考 checkIsTilt 修改一个新的方法 * 是否在板内 可使用 isPointInBlock * * 要求:要得到 * * 转换逻辑 * 1、通过face 获取 该造型所在的边 * 2、将这条边 与 板件的坐标轴做比较 判断平行 * 情况1:与板件的X轴 平行 则造型 可能为 上 || 下 ,使用 isPointInBlock 判断 具体是上 还是下 * 情况2:与板件的Y轴 平行 则造型 可能为 左 || 右 , 使用 isPointInBlock 判断 具体是左 还是右 * 情况3:都不平行 则 朝向的值为斜边 * 最终得到造型的朝向 * 3、依据边的坐标和造型的朝向 可以 根据造型的轮廓数据转为 对应机台的轮廓数据 和刀路数据 * * * 注:这里解析出的是设计端的数据 */ export async function initSideModel(block: PlaceBlock) { if (!block.blockDetail) { console.error('initSideModel: blockDetail is undefind') return } let detail = block.blockDetail if (detail.modelListSide.length > 0) { // 判断时侧面造型 还是 侧面槽 以及计算槽的相关信息 for (const sideModel of detail.modelListSide) { let min = 0; // 宽 let max = 0; // 长 // let temp: any = [] let isRect = true // 是否矩形 let lines: Array = [] for (let index = 0; index < sideModel.originModeling.outline.length; index++) { const baseStartPoint = sideModel.originModeling.outline[index]; const baseEndPoint = sideModel.originModeling.outline[index + 1]; if (!baseEndPoint) { break } const startPoint = sideModel.originModeling.outline[index].pts; const endPoint = sideModel.originModeling.outline[index + 1].pts; if (baseStartPoint.buls != 0 || baseEndPoint.buls != 0) { isRect = false break } let centerPoint = { x: (startPoint.x + endPoint.x) / 2, y: (startPoint.y + endPoint.y) / 2, curve: baseStartPoint.buls, depth: sideModel.depth, radius: 0 } let lineLength = getDis2(startPoint, endPoint) // parseFloat(parseFloat(getDis2(startPoint, endPoint)).toFixed(3)) if (min == 0) { min = lineLength } if (max == 0) { max = lineLength } min = Math.min(min, lineLength) max = Math.max(max, lineLength) let temp = { startPoint, endPoint, centerPoint, lineLength } lines.push(temp); if (index + 1 == sideModel.originModeling.outline.length) { break } } let startAndEndLines = lines.filter(e => isInRange(min, e.lineLength - 0.001, e.lineLength + 0.001)); // 槽的起点 和终点 if (startAndEndLines.length == 2) { sideModel.modelStartPoint = startAndEndLines[0].centerPoint sideModel.modelEndPoint = startAndEndLines[1].centerPoint } isRect = (lines.length == 4 || lines.length == 1) && sideModel.offsetList.length == 0 // console.log('情况123', lines, model,isRect) sideModel.modelLength = max sideModel.modelWidth = min sideModel.isRect = isRect if (isRect) { sideModel.isTilt = checkIsTilt(lines) } let directionRes = getModelDirection(block, sideModel) sideModel.direction = directionRes.direction; // console.log('direction', directionRes.direction, sideModel.isRect, sideModel.isTilt); if (!detail.borderContour) { console.error('initSideModel: borderContour is undefind') return } const borders = detail?.borderContour?.borderFinal const border = borders[sideModel.face] // 依据 造型的朝向 和 造型的轮廓数据 和 所在边的坐标 生成 轮廓数据 还有刀路数据 if (isRect && sideModel.isTilt == false) { detail.borderContour.borderFinal sideModel.modelStartPoint = transformSideModelPoint(sideModel.modelStartPoint, directionRes, border, sideModel, 'modelStartPoint') sideModel.modelEndPoint = transformSideModelPoint(sideModel.modelEndPoint, directionRes, border, sideModel, 'modelStartPoint') } let newPointList: any = [] if (Array.isArray(sideModel.originModeling.outline)) { for (const linePoint of sideModel.originModeling.outline) { let tempPoint = { curve: linePoint.buls, depth: sideModel.depth, radius: 1 / linePoint.buls, x: linePoint.pts.x, y: linePoint.pts.y, z: linePoint.pts.z, } let temp = transformSideModelPoint(tempPoint, directionRes, border, sideModel, 'linePoint') let sideModelPoint = new BlockSideModelPoint(temp) newPointList.push(sideModelPoint) } } else { for (const i in sideModel.originModeling.outline.pts) { let pts = sideModel.originModeling.outline.pts[i] let bul = sideModel.originModeling.outline.buls[i] let tempPoint = { curve: bul, depth: sideModel.depth, radius: 1 / bul, x: pts.x, y: pts.y, z: pts.z, } let temp = transformSideModelPoint(tempPoint, directionRes, border, sideModel, 'linePoint') let sideModelPoint = new BlockSideModelPoint(temp) newPointList.push(sideModelPoint) } } sideModel.pointList = newPointList } } } /**侧面造型数据转换 从设计端 转为生产数据 * config: * placeStyle 小板放置方式 */ export function transFormSideModelDataToProductData(block: PlaceBlock, config) { if(!block.blockDetail){ console.error('transFormSideModelDataToProductData: blockDetail is undefind') return } const { placeStyle= 1 } = config if (block.blockDetail.modelListSide.length > 0) { for (const sideModel of block.blockDetail.modelListSide) { if (sideModel.isRect == true && sideModel.isTilt == false) { // 矩形槽 要转换下起始点 let p_start = BlockHelper.getPlacedPostionInBlock(placeStyle, block.placeWidth, block.placeLength, sideModel.modelStartPoint.x, sideModel.modelStartPoint.y, false) let p_end = BlockHelper.getPlacedPostionInBlock(placeStyle, block.placeWidth, block.placeLength, sideModel.modelEndPoint.x, sideModel.modelEndPoint.y, false) sideModel.modelStartPoint.x = p_start.x sideModel.modelStartPoint.y = p_start.y sideModel.modelEndPoint.x = p_end.x sideModel.modelEndPoint.y = p_end.y } // 转换造型 轮廓点阵 for (const point of sideModel.pointList) { let p = BlockHelper.getPlacedPostionInBlock(placeStyle, block.placeWidth, block.placeLength, point.pointX, point.pointY, false) point.pointX = p.x point.pointY = p.y } } } } /** * 值 是否在范围内 * @param value 目标值 * @param min 最小值 比较值 * @param max 最大值 比较值 * @returns */ function isInRange(value, min, max) { return value >= min && value <= max; } /** * * @param lines * 注:假定2条在坐标轴上的线 与矩形造型的4条线判断是否是平行 * * 线的起始点 与 坐标轴 X Y 比较 判断是否倾斜 (倾斜的矩形 或者 平行四边形) */ // 判断是否是倾斜的 function checkIsTilt(lines) { // 假定的坐标轴 定义坐标点 let p1 = { x: 0, y: 0 } let p2 = { x: 0, y: 100 } let p3 = { x: 100, y: 0 } // 假定2条在坐标轴上的线 // let tempAxiosXLine = [p1,p3] // let tempAxiosYLine = [p1,p2] lines.forEach(line => { // flag 是否平行的标识 true 平行 false 不平行 let flagX = false let flagY = false let startX = line.startPoint.pointX || line.startPoint.x let startY = line.startPoint.pointY || line.startPoint.y let endX = line.endPoint.pointX || line.endPoint.x let endY = line.endPoint.pointY || line.endPoint.y // 距离X轴的距离是否相等 // 线段的起点 距离X轴的距离 let len1 = getDis_PointLine(p1.x, p1.y, p3.x, p3.y, startX, startY) // 线段的终点 距离X轴的距离 let len2 = getDis_PointLine(p1.x, p1.y, p3.x, p3.y, endX, endY) // 实际数据是有误差的 误差 的容差为 0.001 if (isInRange(len1, len2 - 0.001, len2 + 0.001) || isInRange(len2, len1 - 0.001, len1 + 0.001)) { flagX = true } // 距离Y轴的距离是否相等 // 线段起点距离Y轴的距离 let len3 = getDis_PointLine(p1.x, p1.y, p2.x, p2.y, startX, startY) // 线段终点距离Y轴的距离 let len4 = getDis_PointLine(p1.x, p1.y, p2.x, p2.y, endX, endY) if (isInRange(len3, len4 - 0.001, len4 + 0.001) || isInRange(len4, len3 - 0.001, len3 + 0.001)) { flagX = true } // 只要和 X || Y 轴 平行 就不是倾斜的 if (flagX || flagY) { line.isTilt = false } else { line.isTilt = true } }); // 查找有没有 倾斜的边 const res = lines.filter(e => e.isTilt == true).length > 0 //.findIndex(e => e.isTilt == true) == -1 return res } /** 转换 侧面造型的坐标点 */ export function transformSideModelPoint(point, directionRes, border, sideModel: SideModel, flag?: string) { const { direction, preFlag, nextFlag } = directionRes let newPoint: any = { x: 0, y: 0, z: 0, buls: 0, depth: 0 } if (point == null) { newPoint = null // { x: -1, y: -1, z: -1, buls: 0, depth: 0 } } else { /** * * 侧面造型的点坐标使用 等比三角形 解决坐标问题 * */ // 斜边比例 let rate = point.x / border.m_Length switch (direction) { case 0: /**坐标转换逻辑 下造型 * * point 里面的 * x 对应 实际的 X * y 对应 实际的 Z * 实际的y 为 border 对应的 y */ // console.log('下造型',sideModel.modelId) newPoint.x = point.x newPoint.y = border.StartPoint.m_Y newPoint.z = point.y newPoint.buls = point.curve newPoint.depth = sideModel.depth break case 1: // console.log('右造型',sideModel.modelId) newPoint.x = border.StartPoint.m_X newPoint.y = point.x newPoint.z = point.y newPoint.buls = point.curve newPoint.depth = sideModel.depth break case 2: // console.log('上造型',sideModel.modelId) newPoint.x = border.StartPoint.m_X - point.x newPoint.y = border.StartPoint.m_Y newPoint.z = point.y newPoint.buls = point.curve newPoint.depth = sideModel.depth break case 3: // console.log('左造型',sideModel.modelId) newPoint.x = border.StartPoint.m_X newPoint.y = border.StartPoint.m_Y - point.x newPoint.z = point.y newPoint.buls = point.curve newPoint.depth = sideModel.depth break case 10: // console.log('左下造型',sideModel.modelId) // 底边 var x = Math.abs(border.StartPoint.m_X) - Math.abs(border.EndPoint.m_X) // 竖边 var y = Math.abs(border.StartPoint.m_Y) - Math.abs(border.EndPoint.m_Y) // 实际点坐标的 偏移值 var p_x = Math.abs(x * rate) var p_y = Math.abs(y * rate) var fakeStartPoint: any = null // 二次计算的原点坐标 /** * 根据 造型的坐标系的定位点 进行偏移 (边框的起点 或者终点) * 根据preFlag (小板的轮廓的上一条边的朝向 判断 定位点事 起点还是终点) */ if (preFlag == 'toDown') { fakeStartPoint = { x: border.StartPoint.m_X, y: border.StartPoint.m_Y } } else if (preFlag == 'toLeft') { fakeStartPoint = { x: border.EndPoint.m_X, y: border.EndPoint.m_Y } } else { console.log('理论上有异常 排查') } newPoint.x = fakeStartPoint.x + p_x newPoint.y = fakeStartPoint.y - p_y newPoint.z = point.y newPoint.buls = point.curve newPoint.depth = sideModel.depth break case 11: // console.log('右下造型',sideModel.modelId) // 底边 var x = Math.abs(border.StartPoint.m_X) - Math.abs(border.EndPoint.m_X) // 竖边 var y = Math.abs(border.StartPoint.m_Y) - Math.abs(border.EndPoint.m_Y) // 实际点坐标的 偏移值 var p_x = Math.abs(x * rate) var p_y = Math.abs(y * rate) var fakeStartPoint: any = null // 二次计算的原点坐标 /** * 根据 造型的坐标系的定位点 进行偏移 (边框的起点 或者终点) * 根据preFlag (小板的轮廓的上一条边的朝向 判断 定位点事 起点还是终点) */ if (preFlag == 'toRight') { fakeStartPoint = { x: border.StartPoint.m_X, y: border.StartPoint.m_Y } } else if (preFlag == 'toDown') { fakeStartPoint = { x: border.EndPoint.m_X, y: border.EndPoint.m_Y } } else { console.log('理论上有异常 排查') } newPoint.x = fakeStartPoint.x + p_x newPoint.y = fakeStartPoint.y + p_y newPoint.z = point.y newPoint.buls = point.curve newPoint.depth = sideModel.depth break case 12: // console.log('右上造型',sideModel.modelId) // 底边 var x = Math.abs(border.StartPoint.m_X) - Math.abs(border.EndPoint.m_X) // 竖边 var y = Math.abs(border.StartPoint.m_Y) - Math.abs(border.EndPoint.m_Y) // 实际点坐标的 偏移值 var p_x = Math.abs(x * rate) var p_y = Math.abs(y * rate) var fakeStartPoint: any = null // 二次计算的原点坐标 /** * 根据 造型的坐标系的定位点 进行偏移 (边框的起点 或者终点) * 根据preFlag (小板的轮廓的上一条边的朝向 判断 定位点事 起点还是终点) */ if (preFlag == 'toUp') { fakeStartPoint = { x: border.StartPoint.m_X, y: border.StartPoint.m_Y } } else if (preFlag == 'toRight') { fakeStartPoint = { x: border.EndPoint.m_X, y: border.EndPoint.m_Y } } else { console.log('理论上有异常 排查') } newPoint.x = fakeStartPoint.x - p_x newPoint.y = fakeStartPoint.y - p_y newPoint.z = point.y newPoint.buls = point.curve newPoint.depth = sideModel.depth break case 13: // console.log('左上造型',sideModel.modelId) // 底边 var x = Math.abs(border.StartPoint.m_X) - Math.abs(border.EndPoint.m_X) // 竖边 var y = Math.abs(border.StartPoint.m_Y) - Math.abs(border.EndPoint.m_Y) // 实际点坐标的 偏移值 var p_x = Math.abs(x * rate) var p_y = Math.abs(y * rate) var fakeStartPoint: any = null // 二次计算的原点坐标 /** * 根据 造型的坐标系的定位点 进行偏移 (边框的起点 或者终点) * 根据preFlag (小板的轮廓的上一条边的朝向 判断 定位点事 起点还是终点) */ if (preFlag == 'toLeft') { fakeStartPoint = { x: border.StartPoint.m_X, y: border.StartPoint.m_Y } } else if (preFlag == 'toUp') { fakeStartPoint = { x: border.EndPoint.m_X, y: border.EndPoint.m_Y } } else { console.log('理论上有异常 排查') } newPoint.x = fakeStartPoint.x - p_x newPoint.y = fakeStartPoint.y - p_y newPoint.z = point.y newPoint.buls = point.curve newPoint.depth = sideModel.depth break default: break; } } return newPoint; } // 获取侧面造型的朝向 export function getModelDirection(block: PlaceBlock, sideModel) { console.log('getModelDirection', block); let detail = block.blockDetail const borders = detail?.borderContour?.borderFinal // if(borders==undefined){ // return // } const border = borders[sideModel.face] let polygon: any = [] borders.forEach(br => { let temp = { x: br.StartPoint.m_X, y: br.StartPoint.m_Y } polygon.push(temp) }); // 假定的坐标轴 定义坐标点 let p1 = { x: 0, y: 0 } let p2 = { x: 0, y: 100 } let p3 = { x: 100, y: 0 } // 朝向 let direction = -2; // 注: 根据上一条边和下一条的朝向判断 造型的 朝向 // 板件轮廓 上一条边的朝向 let preFlag = ''; // 板件轮廓 下一条边的朝向 let nextFlag = ''; let flagX = false let flagY = false // 线段的起点 距离X轴的距离 let len1 = getDis_PointLine(p1.x, p1.y, p3.x, p3.y, border.StartPoint.m_X, border.StartPoint.m_Y) // 线段的终点 距离X轴的距离 let len2 = getDis_PointLine(p1.x, p1.y, p3.x, p3.y, border.EndPoint.m_X, border.EndPoint.m_Y) if (len1 == len2) { flagX = true } // 距离Y轴的距离是否相等 // 线段起点距离Y轴的距离 let len3 = getDis_PointLine(p1.x, p1.y, p2.x, p2.y, border.StartPoint.m_X, border.StartPoint.m_Y) // 线段终点距离Y轴的距离 let len4 = getDis_PointLine(p1.x, p1.y, p2.x, p2.y, border.EndPoint.m_X, border.EndPoint.m_Y) if (len3 == len4) { flagY = true } let xx = (border.StartPoint.m_X + border.EndPoint.m_X) / 2 let yy = (border.StartPoint.m_Y + border.EndPoint.m_Y) / 2 if (flagY == false && flagX == false) { // 斜的 direction = -1 // 获取 上一条边 和下一条边 (忽略弧形 弧线也按照线段处理 不会影响方向的判断) let preborderId = sideModel.face - 1 let nextBorderId = sideModel.face + 1 if (preborderId < 0) { preborderId = borders.length - 1 } if (nextBorderId > borders.length - 1) { nextBorderId = 0 } let preborder = borders[preborderId] let nextborder = borders[nextBorderId] let preX = preborder.StartPoint.m_X - preborder.EndPoint.m_X let preY = preborder.StartPoint.m_Y - preborder.EndPoint.m_Y let nextX = nextborder.StartPoint.m_X - nextborder.EndPoint.m_X let nextY = nextborder.StartPoint.m_Y - nextborder.EndPoint.m_Y if (preX == 0) { // 上下 if (preY > 0) { // 向下 preFlag = 'toDown' } else if (preY < 0) { // 向上 preFlag = 'toUp' } } if (preY == 0) { // 左右 if (preX > 0) { // 向左 preFlag = 'toLeft' } else if (preX < 0) { // 向右 preFlag = 'toRight' } } if (nextX == 0) { // 上下 if (nextY > 0) { // 向下 nextFlag = 'toDown' } else if (nextY < 0) { // 向上 nextFlag = 'toUp' } } if (nextY == 0) { // 左右 if (nextX > 0) { // 向左 nextFlag = 'toLeft' } else if (nextX < 0) { // 向右 nextFlag = 'toRight' } } // 理论只有下面的情况 不符合的都是异常情况 或者不存在的情况 switch (preFlag) { case 'toDown': if (nextFlag == 'toLeft') { // 造型在 右下斜面 direction = 11 } else if (nextFlag == 'toRight') { // 造型在 左下斜面 direction = 10 } break; case 'toRight': if (nextFlag == 'toUp') { // 造型在 右下斜面 direction = 11 } else if (nextFlag == 'toDown') { // 造型在 右上斜面 direction = 12 } break; case 'toUp': if (nextFlag == 'toLeft') { // 造型在 右上斜面 direction = 12 } else if (nextFlag == 'toRight') { // 造型在 左上斜面 direction = 13 } break; case 'toLeft': if (nextFlag == 'toUp') { // 造型在 左下斜面 direction = 10 } else if (nextFlag == 'toDown') { // 造型在 左上斜面 direction = 13 } break; default: break; } } else if (flagX == true) { // 上下 const p1 = { x: xx, y: yy - 1 } const p2 = { x: xx, y: yy + 1 } const isTop = isPointInPolygon(p1, polygon) if (isTop) { direction = 2 } else { const isBottom = isPointInPolygon(p2, polygon) if (isBottom) { direction = 0 } if (direction == -2) { } } } else if (flagY == true) { // 左右 const p3 = { x: xx - 1, y: yy } const p4 = { x: xx + 1, y: yy } const isRight = isPointInPolygon(p3, polygon) if (isRight) { direction = 1 } else { const isLeft = isPointInPolygon(p4, polygon) if (isLeft) { direction = 3 } if (direction == -2) { } } } const directionRes = { direction, preFlag, nextFlag } return directionRes } /** 判断 点 是否在轮廓内 射线法 */ export function isPointInPolygon(point, polygon) { const x = point.x; const y = point.y; let inside = false; for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) { const xi = polygon[i].x; const yi = polygon[i].y; const xj = polygon[j].x; const yj = polygon[j].y; // 检查点是否位于当前边的水平线上 const intersect = ((yi > y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi); if (intersect) inside = !inside; } return inside; } export function createSideModelRealKnifePoints(block: PlaceBlock, sideModel: SideModel) { let directionRes = getModelDirection(block, sideModel) // 确定 轮廓的中点 let x = { min: 0, max: 0 } let y = { min: 0, max: 0 } let z = { min: 0, max: 0 } sideModel.pointList.forEach((p, i) => { if (i == 0) { x.min = p.pointX x.max = p.pointX y.min = p.pointY y.max = p.pointY z.min = p.pointZ z.max = p.pointZ } else { x.min = Math.min(x.min, p.pointX) x.max = Math.max(x.max, p.pointX) y.min = Math.min(y.min, p.pointY) y.max = Math.max(y.max, p.pointY) z.min = Math.min(z.min, p.pointZ) z.max = Math.max(z.max, p.pointZ) } }); let centerPoint = { x: (x.min + x.max) / 2, y: (y.min + y.max) / 2, z: (z.min + z.max) / 2 } if (equal(sideModel.realKnifeRadius, sideModel.knifeRadius)) { let realPointList: any = []; if (directionRes.direction == 0 || directionRes.direction == 2) { let tempPoints: any = [] sideModel.pointList.forEach((p) => { tempPoints.push({ x: p.pointY, y: p.pointZ }) }) var newPointList = shrinkRectangle(tempPoints, centerPoint.y, centerPoint.z, sideModel.realKnifeRadius) realPointList = sideModel.pointList.map((point, i) => { let temp = JSON.parse(JSON.stringify(point)) temp.pointY = newPointList[i].x temp.pointZ = newPointList[i].y return temp }) } else if (directionRes.direction == 1 || directionRes.direction == 3) { let tempPoints: any = [] sideModel.pointList.forEach(p => { tempPoints.push({ x: p.pointX, y: p.pointZ }) }) var newPointList = shrinkRectangle(tempPoints, centerPoint.x, centerPoint.z, sideModel.realKnifeRadius) realPointList = sideModel.pointList.map((point, i) => { let temp = JSON.parse(JSON.stringify(point)) temp.pointX = newPointList[i].x temp.pointZ = newPointList[i].y return temp }) } } } // 刀路 向内铣 /** * 得到 点阵 向内缩小的 新的点阵 * @param points 点阵 * @param centerX 造型的中心点x * @param centerY 造型的中心点y * @param shrinkAmount 向内的偏移量 * @returns */ function shrinkRectangle(points, centerX, centerY, shrinkAmount) { return points.map(point => { // 计算到中心点的偏移量 const dx = point.x - centerX; const dy = point.y - centerY; // 为了避免除以0的错误和保持简单性,我们可以使用下面的方法: // 如果dx或dy的绝对值小于shrinkAmount的一半,则将其设置为0(即该点保持在中心点上或非常接近)。 // 否则,我们按照比例减少dx和dy。 const absDx = Math.abs(dx); const absDy = Math.abs(dy); const halfShrink = shrinkAmount; const newDx = (absDx > halfShrink) ? dx - (Math.sign(dx) * halfShrink) : 0; const newDy = (absDy > halfShrink) ? dy - (Math.sign(dy) * halfShrink) : 0; return { x: centerX + newDx, y: centerY + newDy }; }); } // 刀路 向外铣 /** * 得到 点阵 向外放大的 新的点阵 * @param points 点坐标 * @param centerX 造型的中心点x * @param centerY 造型的中心点y * @param expansionAmount 向外的偏移量 * @returns */ function expandRectangleCorrect(points, centerX, centerY, expansionAmount) { const halfExpansion = expansionAmount; // 在本例中,这将是0.5 return points.map(point => ({ // 只加一次halfExpansion,因为我们在两个方向上都会加。 x: centerX + (point.x - centerX) + halfExpansion, y: centerY + (point.y - centerY) + halfExpansion })); } /** 造型轮廓(含封边),扣除封边, 变成开料坐标 */ export function resetModelContour(bd: PlaceBlockDetail) { let ox = bd.offsetX let oy = bd.offsetY for (let m of bd.models) { if (m.hasContour()) { let ptsArr = m.originModeling.outline.map(e => e.pts) for (let pt of ptsArr) { // 23.8.5 发现矩形的挖穿轮廓坐标是不含封边的 pt.x -= ox pt.y -= oy } } } } export function resetModelKnife(block: PlaceBlock, toolsHelper:ToolsHelper, isUseOffset?: boolean) { let _isUseOffset = false if (isUseOffset) { _isUseOffset = isUseOffset } let processModelIdList: number[] = []; // console.log(block) for (let m_i = 0; m_i < block.blockDetail.models.length; m_i++) { let model = block.blockDetail.models[m_i] if (model.isVKnifeModel()) continue // 二维刀路 不处理 // if (model.realKnifeRadius != 0) // continue // 已处理 let knife = toolsHelper.getKnifeByParams({knifeName : model.knifeName}) //sysConfig.getModelKnife(model) if (knife == null) { model.realKnifeRadius = -1 } else { model.realKnifeRadius = knife.diameter / 2 model.realKnifeId = knife.knifeId // 修复问题 如果是弧线的情况下 出现 弧线生成异常 let checkIsOk = true for (const p of model.pointList) { if ((p.curve != 0 && p.radius == 0) || (p.radius != 0 && p.curve == 0)) { checkIsOk = false break } } if (equal(model.realKnifeRadius, model.knifeRadius) && checkIsOk) { model.realPointList = model.pointList } else { model.originModeling.knifeRadius = knife.diameter / 2 model.originModeling.thickness = model.depth model.originModeling.brThickness = block.thickness model.originModeling.boardContour = getOrgContour() let newData: any = null if (model.originModeling && Array.isArray(model.originModeling.outline)) { newData = JSON.parse(JSON.stringify(model.originModeling)) let newOutLine = { pts: newData.outline.map(e => e.pts), buls: newData.outline.map(e => e.buls) } let newHoles = newData?.holes?.map(x => { return { pts: x.map(e => e.pts), buls: x.map(e => e.buls) } }) newData.outline = newOutLine newData.holes = newHoles || [] } else { newData = model.originModeling } let custborders: any = [] try { if (model.originModeling.outline) { custborders = Production.GetChaiDanFeedingPath(newData, 0) } } catch (error) { console.error(error, block.blockNo, model.modelId, model); } let offx = _isUseOffset ? block.offsetX() : 0// block.OffsetX; let offy = _isUseOffset ? block.offsetY() : 0// block.OffsetY; let ps1: BlockModelPoint[] = [] if (custborders.length > 0) { let ct = custborders[0] if (processModelIdList.includes(model.modelId)) { ct = custborders[model.lineId - 1] } else { processModelIdList.push(model.modelId) } if (ct) { for (let i = 0; i < ct.buls.length; i++) { var r = 0 if (ct.buls[i] != 0) { let j = i + 1 if (j == ct.buls.length) j = 0 r = CADExt.getR(ct.pts[i].x, ct.pts[i].y, ct.pts[j].x, ct.pts[j].y, ct.buls[i]) } ps1.push(new BlockModelPoint({ pointX: ct.pts[i].x - offx, pointY: ct.pts[i].y - offy, curve: ct.buls[i], radius: r, depth: model.depth })) } } } if (ps1.length > 0) { model.realPointList = ps1 } else { model.realKnifeId = -1 model.realKnifeRadius = -1 model.realPointList = [] } } } } /** 获取轮廓 */ function getOrgContour() { if (!block.blockDetail) { console.error('resetModelKnife=>getOrgContour: blockDetail is undefind') return } if (!block.blockDetail.orgContourData) { let pts: any = [] let buls: any = [] if (!block.isUnRegular) { pts.push({ x: 0, y: 0 }) pts.push({ x: block.cutWidth, y: 0 }) pts.push({ x: block.cutWidth, y: block.cutLength }) pts.push({ x: 0, y: block.cutLength }) buls.push(0) buls.push(0) buls.push(0) buls.push(0) } else // 矩形板 { for (let p of block.blockDetail.points) { pts.push({ x: p.pointX, y: p.pointY }) buls.push(p.curve) } } block.blockDetail.orgContourData = { pts, buls } } return block.blockDetail.orgContourData } } export async function resetSideModelKnife(block: PlaceBlock, tools: ToolsHelper) { if (!block.blockDetail) { console.error('resetModelKnife=>getOrgContour: blockDetail is undefind') return } for (let model of block.blockDetail.modelListSide) { let knife = model.knife || tools.getKnifeByParams({ knifeName: model.knifeName }) if (knife == null) { model.realKnifeRadius = -1 } else { model.knife = knife model.realKnifeRadius = knife.diameter / 2 model.realKnifeId = knife.knifeId // if(model.pointList.length ==0){ // await initSideModel(block) // } if (equal(model.realKnifeRadius, model.knifeRadius)) { model.realPointList = model.pointList } else { model.originModeling.knifeRadius = knife.diameter / 2 model.originModeling.thickness = model.depth model.originModeling.brThickness = block.thickness model.originModeling.boardContour = getOrgContour() console.log('侧面造型生成新刀路:', model.modelId, model) let newData: any = null if (model.originModeling && Array.isArray(model.originModeling.outline)) { newData = JSON.parse(JSON.stringify(model.originModeling)) let newOutLine = { pts: newData.outline.map(e => e.pts), buls: newData.outline.map(e => e.buls) } let newHoles = newData?.holes?.map(x => { return { pts: x.map(e => e.pts), buls: x.map(e => e.buls) } }) newData.outline = newOutLine newData.holes = newHoles || [] } else { newData = model.originModeling } let custborders = model.originModeling.outline ? Production.GetChaiDanFeedingPath(newData) : [] let offx = 0// block.OffsetX; let offy = 0// block.OffsetY; let ps1: BlockSideModelPoint[] = [] if (custborders.length > 0) { if (custborders.length == 1) { let ct = custborders[0] model.lineId = 1 for (let i = 0; i < ct.buls.length; i++) { let r = 0 if (ct.buls[i] != 0) { let j = i + 1 if (j == ct.buls.length) j = 0 r = CADExt.getR(ct.pts[i].x, ct.pts[i].y, ct.pts[j].x, ct.pts[j].y, ct.buls[i]) } ps1.push(new BlockSideModelPoint({ pointX: ct.pts[i].x - offx, pointY: ct.pts[i].y - offy, pointZ: 0, curve: ct.buls[i], radius: r, depth: model.depth })) } // 要处理下坐标 if (ps1.length > 0) { let directionRes = getModelDirection(block, model) const borders = block.blockDetail?.borderContour?.borderFinal if (!borders) { console.error('resetModelKnife=>getOrgContour: blockDetail is undefind') return } const border = borders[model.face] let newRealPointList: BlockSideModelPoint[] = [] for (const linePoint of ps1) { let tempPoint = { curve: linePoint.buls, depth: model.depth, radius: 1 / linePoint.buls, x: linePoint.pointX || 0, y: linePoint.pointY || 0, z: linePoint.pointZ || 0, } let temp = transformSideModelPoint(tempPoint, directionRes, border, model, 'linePoint') let sideModelPoint = new BlockSideModelPoint(temp) newRealPointList.push(sideModelPoint); } model.realPointList = newRealPointList } else { model.realKnifeId = -1 model.realKnifeRadius = -1 model.realPointList = [] } } else { for (const ct_key in custborders) { let tempModel = new SideModel(model) ps1 = [] let ct = custborders[ct_key] tempModel.lineId = parseFloat(ct_key) + 1 for (let i = 0; i < ct.buls.length; i++) { let r = 0 if (ct.buls[i] != 0) { let j = i + 1 if (j == ct.buls.length) j = 0 r = CADExt.getR(ct.pts[i].x, ct.pts[i].y, ct.pts[j].x, ct.pts[j].y, ct.buls[i]) } ps1.push(new BlockSideModelPoint({ pointX: ct.pts[i].x - offx, pointY: ct.pts[i].y - offy, pointZ: 0, curve: ct.buls[i], radius: r, depth: tempModel.depth })) } if (ps1.length > 0) { let directionRes = getModelDirection(block, tempModel) const borders = block.blockDetail?.borderContour?.borderFinal const border = borders[tempModel.face] let newRealPointList: BlockSideModelPoint[] = [] for (const linePoint of ps1) { let tempPoint = { curve: linePoint.buls, depth: tempModel.depth, radius: 1 / linePoint.buls, x: linePoint.pointX || 0, y: linePoint.pointY || 0, z: linePoint.pointZ || 0, } let temp = transformSideModelPoint(tempPoint, directionRes, border, tempModel, 'linePoint') let sideModelPoint = new BlockSideModelPoint(temp) newRealPointList.push(sideModelPoint); } tempModel.realPointList = newRealPointList } else { tempModel.realKnifeId = -1 tempModel.realKnifeRadius = -1 tempModel.realPointList = [] } // 避免拆分的刀路造型 重复插入 if (block.blockDetail.modelListSide.findIndex(e => e.modelId == tempModel.modelId && e.lineId == tempModel.lineId) == -1) { block.blockDetail.modelListSide.push(tempModel) } else { model = tempModel } } } } } } } /** 获取轮廓 */ function getOrgContour() { if (!block.blockDetail) { console.error('resetModelKnife=>getOrgContour: blockDetail is undefind') return } if (!block.blockDetail.orgContourData) { let pts: any = [] let buls: any = [] if (!block.isUnRegular) { pts.push({ x: 0, y: 0 }) pts.push({ x: block.cutWidth, y: 0 }) pts.push({ x: block.cutWidth, y: block.cutLength }) pts.push({ x: 0, y: block.cutLength }) buls.push(0) buls.push(0) buls.push(0) buls.push(0) } else // 矩形板 { for (let p of block.blockDetail.points) { pts.push({ x: p.pointX, y: p.pointY }) buls.push(p.curve) } } block.blockDetail.orgContourData = { pts, buls } } return block.blockDetail.orgContourData } } /** 二维刀路初始化 */ export function init2VModel(blockDetail: PlaceBlockDetail, tools: ToolsHelper, isCNC = false) { for (let model of blockDetail.models) { if (!model.isVKnifeModel()) continue let vModels: any[] = [] model.VLines = vModels let isFaceB = model.face == FaceType.BACK if (model.pointList.length < 1) continue let ps = model.pointList.map((t) => { return { x: t.pointX, y: t.pointY, bul: t.curve } }) let pl = PolylineHelper.create(ps) if (model.VLines?.length > 0) return // 已经分析了 model.VLines = [] for (let os of model.offsetList) { // 根据刀名称找刀 let knife1 = isCNC ? null : tools.getKnifeByParams({ knifeName: os.name }) let knifeR = os.radius let knifeId = knife1 ? knife1.knifeId : -1 try { let vps_1 = PolylineHelper.getVModelPoints_offset(pl, os.offset, os.depth, os.angle) let vLine = { isFaceB, name: os.name, value: os.offset, knife: knife1, knifeId, knifeRadius: knifeR, depth: os.depth, points: vps_1, offset: os } vModels.push(vLine) // 偏移路径 model.VLines.push(vLine) } catch (err) { console.log('v型刀走刀路径算法出错。' + err) } } model.VLines = vModels } } /** 异形板 封边值 */ export function resetBorderValue(block: PlaceBlock) { if (!block.blockDetail) { console.error('resetBorderValue: blockDetail is undefind') return } if (block.isUnRegular) { block.cutWidth = block.blockDetail.cutWidth block.cutLength = block.blockDetail.cutLength } block.blockDetail.cutWidth = block.cutWidth block.blockDetail.cutLength = block.cutLength if (block.isUnRegular == false) return // 计算异形板 的上下左右 封边值 block.sealLeft = getSealEdge('LEFT') block.sealRight = getSealEdge('RIGHT') block.sealTop = getSealEdge('TOP') block.sealBottom = getSealEdge('BOTTOM') function getSealEdge(sealEdge) { let closetP let dis = 1000000 for (let i = 0; i < block.orgPoints.length; i++) { let p0 = block.orgPoints[i] let p1 = i == block.orgPoints.length - 1 ? block.orgPoints[0] : block.orgPoints[i + 1] if (sealEdge == 'LEFT') { if (equal(p0.pointX, 0) && equal(p1.pointX, 0)) return p0.sealSize let dis_t = (p0.pointX + p1.pointX) * 0.5 if (dis_t < dis) { closetP = p0 dis = dis_t } } if (sealEdge == 'RIGHT') { if (equal(p0.pointX, block.width) && equal(p1.pointX, block.width)) return p0.sealSize let dis_t = (p0.pointX + p1.pointX) * 0.5 if (block.width - dis_t < dis) { closetP = p0 dis = block.width - dis_t } } if (sealEdge == 'TOP') { if (equal(p0.pointY, block.length) && equal(p1.pointY, block.length)) return p0.sealSize let dis_t = (p0.pointY + p1.pointY) * 0.5 if (block.length - dis_t < dis) { closetP = p0 dis = dis_t } } if (sealEdge == 'BOTTOM') { if (equal(p0.pointY, 0) && equal(p1.pointY, 0)) return p0.sealSize let dis_t = (p0.pointY + p1.pointY) * 0.5 if (dis_t < dis) { closetP = p0 dis = dis_t } } } // 找最接近边的点 return closetP ? closetP.sealSize : 0 } } /** * 设置小板是否反面排版优化 * @param block 小板 * @param processMode 加工模式(0开料机(雕刻机)加工 1开料机CNC组合 2定制加工) */ export function setFaceToPlace(block: PlaceBlock, config) { // let processMode = 0; // if(sys.isCutProcess) processMode = 0; // if(sys.isCutAndCNCProcess) processMode = 1; // if(sys.isCustomized) processMode = 2; const { processMode = 0 } = config block.isTurnFaceToPlace = !getDoFace(block, processMode) }