import { isTargetCurInOrOnSourceCur } from 'cadapi' import type { Polyline } from 'cadapi' import { PolylineHelper } from '../../common/LayoutEngine/PolylineHelper.js' import { PlaceBlock,PlaceBoard,PlaceMaterial } from '../../confClass.js' import { BlockPlus } from './BlockPlus.js' // 小板干涉判断等算法 /** 判断小板干涉情况 */ export function checkOverlapInBoard(pm: PlaceMaterial, pb: PlaceBoard,config:any) { if (pb.blockList.length == 0) return const blocks = pb.blockList.slice(0).sort((a, b) => a.cutOrder - b.cutOrder) let { overlapGap= 0.05 } = config // 初始化 for (const t of blocks) { t.isOverlap = false t.isOutBoard = false t.pl_border = null // 开料后轮廓(待预铣,同刀辅助 ,不含刀半径) ,内缩一个干涉容差/2 t.pl_cutBorder = null // 走刀轮廓 t.pl_modelSpaces = null t.pl_modelsOut = null } const r = pm.diameter / 2 // 干涉容差 let _overlapGap = overlapGap + 0.002 if (_overlapGap < 0) _overlapGap = 0 const borderOff = pm.cutBorder - _overlapGap / 2 - 0.001 // console.log('大板的尺寸 -- borderOff', pm.cutBorder, overlapGap / 2 - 0.001) const minx = borderOff const maxX = pb.width - borderOff const miny = borderOff const maxY = pb.length - borderOff // 余料异形大板 的轮廓 let boardBorders if (pb.isAdnormal()) { if (pb.polyline == null) { pb.polyline = PolylineHelper.create(pb.points, true) } if (_overlapGap > 0) // 有干涉容差, 变大 { boardBorders = pb.polyline.GetOffsetCurves(_overlapGap)[0] } else { boardBorders = pb.polyline } } for (let i = 0; i < blocks.length; i++) { const block1 = blocks[i] // 1.是否超出大板外 if (checkOutOfBoard(block1, boardBorders, minx, maxX, miny, maxY, _overlapGap)) { console.log('超出大板外', block1.blockNo) block1.isOverlap = true } // 2.检查板 铣刀路径,是否与前面板的铣刀路径 相干涉 for (let p = 0; p < i; p++) { const block2 = blocks[p] const isOverlap = isOverlap_block(block1, block2, r, _overlapGap) if (isOverlap) { console.log('铣刀路径问题 检查板 铣刀路径,与前面板的铣刀路径 相干涉', block1.blockNo, block1.blockId, block2.blockNo, block2.blockId) block1.isOverlap = true block2.isOverlap = true } } } // 初始化 for (const t of blocks) { t.pl_border = null // 开料后轮廓(待预铣,同刀辅助 ,不含刀半径) ,内缩一个干涉容差/2 t.pl_cutBorder = null // 走刀轮廓 t.pl_modelSpaces = null // 内部轮廓 t.pl_modelsOut = null // 造型外扩 轮廓 } } /** 判断板是否超出大板外 p0:大板可用最低点,p1:大板可用最高点 */ function checkOutOfBoard(b: PlaceBlock, pl_board: Polyline, minx, maxx, miny, maxy, overlapGap): boolean { // 判断小板的开料轮廓 const pl_block = getBorder(b, overlapGap) // 异形的余料大板 if (pl_board) { // 小板面积比大板大 , 干涉 if (pl_board.Area < pl_block.Area) { console.log('小板面积比大板大 , 干涉') return true } // 盒子 不干涉,小板在外面 if (pl_board.BoundingBox.intersectsBox(pl_block.BoundingBox) == false) { console.log('盒子 不干涉,小板在外面') return true } // 大盒子,没有包含 小盒子, 肯定在大板外 , if (pl_board.BoundingBox.containsBox(pl_block.BoundingBox) == false) { console.log('大盒子,没有包含 小盒子, 肯定在大板外 ,') return true } // 轮廓有干涉 if (pl_block.IntersectWith(pl_board, 0).length > 0) { console.log('轮廓有干涉') return true } // 大轮廓 包含 小轮廓 , if (isTargetCurInOrOnSourceCur(pl_board, pl_block) == false) { console.log('大轮廓 包含 小轮廓 ') return true } return false } else // 矩形板 { // console.log('打印所有的矩形板=>', b.blockNo, pl_block) if (pl_block.BoundingBox.min.x < minx) { console.log('矩形板 小板最小X 小于限定的 minx ') return true } if (pl_block.BoundingBox.min.y < miny) { console.log('矩形板 小板最小y 小于限定的 miny ', b.blockNo, pl_block.BoundingBox.min.y, miny) return true } if (pl_block.BoundingBox.max.x > maxx) { console.log('矩形板 小板最大x 小于限定的 maxx ') return true } if (pl_block.BoundingBox.max.y > maxy) { console.log('矩形板 小板最大y 大于限定的 maxy ') return true } return false } } /** 判断两板是否重叠 */ function isOverlap_block(block1: PlaceBlock, block2: PlaceBlock, r: number, overlapGap: number): boolean { if (block1.boardId != block2.boardId) { console.log('板材都不一样',block1.boardId ,block2.boardId); return false // 两板不在同一个大板上 } // 判断 b1,b2 开料是否干涉, <包括 造型洞内> if (isOverLap_border(block1, block2, r, overlapGap)) { return true } // 判断b1造型走刀 干涉到 b2。 if (isOverlap_model(block1, block2, r, overlapGap)) { return true } // 判断b2造型走刀 干涉到 b1。 if (isOverlap_model(block2, block1, r, overlapGap)) { return true } return false } /** 开料轮廓是否干涉 */ function isOverLap_border(block1: PlaceBlock, block2: PlaceBlock, r: number, overlapGap: number): boolean { let b1 = block1 let b2 = block2 let pl_b1 = getCutBorder(b1, r, overlapGap) let pl_b2 = getCutBorder(b2, r, overlapGap) // 盒子没有交集 ,不干涉 if (pl_b1.BoundingBox.intersectsBox(pl_b2.BoundingBox) == false) return false // 盒子有交集 ,有可能干涉 // 走刀轮廓有干涉点 , 肯定干涉了 if (pl_b1.IntersectWith(pl_b2, 0).length > 0) { // console.log('走刀轮廓有干涉点 , 肯定干涉了') return true } // 强制 b1 比 b2 大 if (pl_b1.Area < pl_b2.Area) { [b1, b2] = [b2, b1]; [pl_b1, pl_b2] = [pl_b2, pl_b1] } // b1 ,包含 b2 if (isTargetCurInOrOnSourceCur(pl_b1, pl_b2)) { // b1 的挖穿空间 const pls_inner1 = getModelSpaces(b1, r, overlapGap) // b2 的开料轮廓 const pl_border2 = getBorder(b2, overlapGap) for (const pl_1 of pls_inner1) { // 挖穿造型 包含 b2 , 则不干涉 if (pl_1.Area > pl_border2.Area && isTargetCurInOrOnSourceCur(pl_1, pl_border2)) return false } return true } return false } /** 判断block1 的造型走刀 是否干涉到 block2 */ function isOverlap_model(block1: PlaceBlock, block2: PlaceBlock, r: number, overlapGap: number): boolean { // 外扩造型线 const pls_1 = getModelsOuter(block1, r, overlapGap) const pl_2 = getCutBorder(block2, r, overlapGap) for (const pl of pls_1) { if (pl.IntersectWith(pl_2, 0).length > 0) return true } return false } /** 开料轮廓(待预铣,同刀辅助 ,不含刀半径) ,内缩一个干涉容差/2 */ function getBorder(b: PlaceBlock, overlapGap: number): Polyline { let pl_border = b.pl_border // if (pl_border == null) { const borders = BlockPlus.getBorder_sameKnife(b) let pl = BlockPlus.borderToPolyline(borders) pl = pl.GetOffsetCurves(-overlapGap / 2)[0] pl_border = PolylineHelper.moveTo(pl, b.placeX, b.placeY) // b.pl_border = pl_border // } return pl_border } /** 走刀轮廓(待预铣,同刀辅助 , 刀半径) ,内缩一个干涉容差/2 */ function getCutBorder(b: PlaceBlock, r: number, overlapGap: number): Polyline { let pl_cutBorder = b.pl_cutBorder if (pl_cutBorder == null) { const border = BlockPlus.getCutLines_sameKnife(b) pl_cutBorder = BlockPlus.borderToPolyline(border) pl_cutBorder = pl_cutBorder.GetOffsetCurves(-overlapGap / 2)[0] pl_cutBorder = PolylineHelper.moveTo(pl_cutBorder, b.placeX, b.placeY) b.pl_cutBorder = pl_cutBorder } return pl_cutBorder } /** 挖穿造型空间<扣除:刀直径 - 容差/2> */ function getModelSpaces(b: PlaceBlock, r: number, overlapGap: number): Polyline[] { let pl_models = b.pl_modelSpaces if (pl_models == null) { let spaces = BlockPlus.getBorders_inner(b) let rs = BlockPlus.getBorders_inner_r(b) pl_models = [] if (spaces.length > 0 && spaces.length == rs.length) { for (let i = 0; i < spaces.length; i++) { let pl = BlockPlus.borderToPolyline(spaces[i]) // 内侧 刀直径 < 造型刀,开料刀 最大值 > const off = Math.max(r, rs[i]) * 2 - overlapGap / 2 pl = pl.GetOffsetCurves(-off)[0] if (pl == null) continue pl = PolylineHelper.moveTo(pl, b.placeX, b.placeY) pl_models.push(pl) } } b.pl_modelSpaces = pl_models } return pl_models } /** 外扩造型 多段线 */ function getModelsOuter(b: PlaceBlock, r: number, overlapGap: number): Polyline[] { let pl_models = b.pl_modelsOut if (pl_models == null) { pl_models = [] const pls_org = BlockPlus.getOutModelBorders(b) for (const pl of pls_org) { const npl = PolylineHelper.moveTo(pl, b.placeX, b.placeY) pl_models.push(npl) } b.pl_modelsOut = pl_models } return pl_models }