Files
cut-abstractions/tests/dev1/dataHandle/common/LayoutEngine/BlockOverlap.ts

301 lines
9.2 KiB
TypeScript
Raw Normal View History

2025-07-22 18:22:31 +08:00
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
}