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

301 lines
9.2 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 { 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
}