262 lines
8.3 KiB
TypeScript
262 lines
8.3 KiB
TypeScript
import { ProcessorModule } from "../../src/device";
|
||
import { confItem, PlaceBlock, PlaceBlockDetail, PlaceMaterial } from "../confClass";
|
||
import { Big_bang, ComposingType, LineType, WorkerItemType, xbang } from "../handleAbility/RectOptimizeWorker/bang";
|
||
import resData from './res1.json'
|
||
import {Worker} from 'worker_threads'
|
||
|
||
/** 模块 新优化
|
||
*
|
||
* input 入参
|
||
*
|
||
* ProcessorModule<any, any>这里的any 可以自定义 根据组件需求
|
||
*/
|
||
|
||
|
||
export const RectOptimizeMachineModule: ProcessorModule<any, any> = {
|
||
moduleName: "RectOptimizeMachine",
|
||
config: {
|
||
workerList: [],
|
||
placeStyle: 1,
|
||
},
|
||
|
||
setConfig(config) {
|
||
this.config = { ...this.config, ...config };
|
||
},
|
||
|
||
before(input) {
|
||
// console.log(`优化前要做的事情`, input);
|
||
},
|
||
|
||
process(input, next, context) {
|
||
let { blockList, materialList } = input
|
||
let bList: any = []
|
||
let pm = materialList[0]
|
||
blockList.map(e => {
|
||
if (e.goodsId == pm.goodsId) {
|
||
bList[e.blockNo] = e
|
||
// let detail = blockDetailList.find(x => x.blockId == e.blockId)
|
||
// // 处理可能出现的异常 --没有板明细
|
||
// if (!Reflect.has(bList[e.blockNo], 'blockDetail')) {
|
||
// bList[e.blockNo].blockDetail = new PlaceBlockDetail(detail)
|
||
// }
|
||
// bList[e.blockNo].isTurnFaceToPlace = !this.getDoFace(bList[e.blockNo], this.processMode())
|
||
// 是否翻面后续处理
|
||
bList[e.blockNo].isTurnFaceToPlace = true
|
||
if (Array.isArray(pm.blockList)) {
|
||
|
||
pm.blockList.push(e)
|
||
} else {
|
||
pm.blockList = [e]
|
||
}
|
||
}
|
||
})
|
||
pm.cutBorder = this.cutBoardBorder
|
||
pm.cutKnifeGap = this.blockKnifeLineSpacing
|
||
|
||
/** 小板 */
|
||
let bans: xbang[] = []
|
||
|
||
// 实际开料大板的列表
|
||
let big_Bang: Big_bang[] = []
|
||
let big_BangSL: number[] = []
|
||
|
||
|
||
let border = this.cutBoardBorder
|
||
let borderOff = (pm.diameter + pm.cutKnifeGap) / 2
|
||
|
||
// 余料板 以及实际开料大板
|
||
for (const cuttingBoard of pm.remainBoardList) {
|
||
big_Bang.push({ w: cuttingBoard.width - border * 2 + borderOff * 2, l: cuttingBoard.length - border * 2 + borderOff * 2, x: border - borderOff, y: border - borderOff })
|
||
big_BangSL.push(cuttingBoard.count || 999)
|
||
}
|
||
// big_Bang = []
|
||
// big_BangSL = []
|
||
// 母板 兜底的
|
||
big_Bang.push({ w: pm.width - border * 2 + borderOff * 2, l: pm.length - border * 2 + borderOff * 2, x: border - borderOff, y: border - borderOff })
|
||
// 生成小板
|
||
for (let key in bList) {
|
||
let b = bList[key]
|
||
|
||
let bid = b.blockNo
|
||
|
||
let width = b.placeFullWidth
|
||
let length = b.placeFullLength
|
||
let line = toLine(b.texture)
|
||
|
||
bans.push({
|
||
l: length,
|
||
w: width,
|
||
line,
|
||
face: toface(b),
|
||
id: bid,
|
||
bno: b.blockNo,
|
||
holeFaceCount: 3,
|
||
isRect: !b.isUnRegular,
|
||
hasHole: false,
|
||
isdtwosided: true,
|
||
})
|
||
}
|
||
|
||
let bestCount = 0
|
||
if (bans.length == 0) // 没有板了
|
||
{
|
||
|
||
if (context.CallBack) {
|
||
let best = []
|
||
let yl: Big_bang[] = []
|
||
let fit = 0
|
||
let resObj = {
|
||
data: { bList, best, yl, fit, bans, width: pm.width, length: pm.length, bestCount: bestCount++, pm },
|
||
info: {
|
||
times: -1,
|
||
type: 'noBan'
|
||
}
|
||
}
|
||
context.CallBack(resObj)
|
||
}
|
||
|
||
return
|
||
}
|
||
let xyhcs = 50
|
||
if (bans.length > 1000) { xyhcs = 40 }
|
||
else if (bans.length > 1500) { xyhcs = 30 }
|
||
else if (bans.length > 2000) { xyhcs = 25 }
|
||
else if (bans.length > 4000) { xyhcs = 20 }
|
||
else if (bans.length > 6000) { xyhcs = 15 }
|
||
else if (bans.length > 10000) { xyhcs = 10 }
|
||
else if (bans.length > 15000) { xyhcs = 5 }
|
||
else if (bans.length > 20000) { xyhcs = 1 }
|
||
let isDoubleFaceBlockFirst = this.isDoubleFaceBlockFirst // 双面加工排前面
|
||
let gap = this.blockKnifeLineSpacing
|
||
// this.bestfit = 0
|
||
|
||
/** 这里要做个多线程 测试环境下 这部分有问题 暂时略过 */
|
||
for (let j = 0; j < 1; j++) {
|
||
|
||
// let w = new Worker(new URL('../handleAbility/RectOptimizeWorker/RectOptimizeWorker.worker', import.meta.url), { type: 'module' })
|
||
let w= new Worker('../handleAbility/RectOptimizeWorker/RectOptimizeWorker.worker')
|
||
const data = {
|
||
type: 'start',
|
||
data: [bans, big_Bang, big_BangSL, xyhcs, isDoubleFaceBlockFirst, gap, this.isRectPlace, this.isDoubleFaceBlockInRemain],
|
||
}
|
||
let item: WorkerItemType = {
|
||
w: w,
|
||
goodsId: pm.goodsId,
|
||
pm,
|
||
status: 'start'
|
||
}
|
||
if (this.config.workerList.findIndex(e => e.goodsId == item.goodsId) == -1) {
|
||
this.config.workerList.push(item)
|
||
}
|
||
|
||
|
||
let workItem = this.config.workerList.find(e => e.goodsId == pm.goodsId)
|
||
if (workItem && workItem != undefined) {
|
||
workItem.w?.postMessage(data)
|
||
|
||
workItem.w.onmessage = async (d) => {
|
||
let [best, yl, fit, info] = d.data as [any[], Big_bang[], number, any]
|
||
|
||
switch (info.type) {
|
||
case 'loop':
|
||
let resObj = {
|
||
data: { bList, best, yl, fit, bans, width: pm.width, length: pm.length, bestCount: bestCount++, pm },
|
||
info
|
||
}
|
||
if (context.CallBack) {
|
||
context.CallBack(resObj)
|
||
}
|
||
|
||
break;
|
||
case 'stop':
|
||
console.error('stop =》dataHandleBase', info, this.config.workerList)
|
||
this.terminateWorker({ goodsId: pm.goodsId })
|
||
break;
|
||
case 'isStop':
|
||
// console.error('isStop', info)
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
if (context.CallBack) {
|
||
context.CallBack(resData)
|
||
}
|
||
|
||
return next ? next(input) : input;
|
||
},
|
||
|
||
after(result) {
|
||
console.log(`优化后要做的事情`,);
|
||
},
|
||
|
||
onError(error) {
|
||
console.log('出错了哦', error);
|
||
}
|
||
};
|
||
|
||
|
||
function toLine(texture): LineType {
|
||
if (texture == 0)
|
||
return LineType.Positive
|
||
if (texture == 1)
|
||
return LineType.CanReversal
|
||
return LineType.Reverse
|
||
}
|
||
/** 小板加工面:Positive=0正面 Reverse=1反面 Arbitrary=2任意 */
|
||
function toface(block: PlaceBlock): ComposingType {
|
||
let turnF = block.isTurnFaceToPlace
|
||
// if (this.isTurnFaceToPlace)
|
||
if (true)
|
||
turnF = !turnF
|
||
if (!turnF)
|
||
return ComposingType.Positive
|
||
return ComposingType.Reverse
|
||
}
|
||
/** 配置列表 */
|
||
export const confList: confItem[] = [
|
||
{
|
||
key: 'isCutProcess',
|
||
label: '开料机(雕刻机)加工',
|
||
value: true
|
||
},
|
||
{
|
||
key: 'isCutAndCNCProcess',
|
||
label: '开料机CNC组合',
|
||
value: false
|
||
},
|
||
{
|
||
key: 'isCustomized',
|
||
label: '定制加工',
|
||
value: false
|
||
},
|
||
{
|
||
key: 'cutBoardBorder',
|
||
label: '总修边宽度',
|
||
value: 3
|
||
},
|
||
{
|
||
key: 'blockKnifeLineSpacing',
|
||
label: '刀路间距',
|
||
value: 0
|
||
},
|
||
{
|
||
key: 'isDoubleFaceBlockFirst',
|
||
label: '双面开料优先排版',
|
||
value: true
|
||
},
|
||
{
|
||
key: 'isRectPlace',
|
||
label: '新优化规则排版',
|
||
value: false
|
||
},
|
||
{
|
||
// yuLiaoBoardDo2FaceBlock
|
||
key: 'isDoubleFaceBlockInRemain',
|
||
label: '余料板允许排入双面加工的小板',
|
||
value: true
|
||
},
|
||
] |