Files
cut-abstractions/tests/dev1/index3.vue
2025-07-23 10:12:11 +08:00

1270 lines
38 KiB
Vue
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.

<script lang="ts" setup>
import { ref, onMounted, computed } from 'vue'
import { nextTick } from 'vue'
import BoardView from '@/components/borderView/BoardView.vue'
import {
Select, SelectOption, Pagination, TreeSelect, Form, FormItem,
Input, Button, Table, Modal, Textarea, Tooltip, Switch,
InputNumber, Checkbox
} from 'ant-design-vue'
import { Knife, SysConfig } from '@/imes/biz/SysConfig'
import { ParserMain } from '@/imes/processParser/parseMain'
import { PlusOutlined } from '@ant-design/icons-vue'
import { getListAllSimple, getOrderSource } from '@/api/production/productManagerList'
import { BoardShowType } from '@/imes/vo/enums/BoardShowType'
import { BlockBorderPoint } from '@/imes/vo/point/BlockBorderPoint'
import { BoardEditor } from '@/imes/biz/RenderNewBoard'
import { BasicTable, TableAction, useTable } from '@/components/Table'
import { optimizeColumns1 } from '../production/productManagerList/productManagerList.data'
import { DataHandleServe } from '@/imes/dataHandle/DataHandleServe'
import { convertData } from '@/imes/common/transform'
import { blockborderClass } from '@/imes/dataClass/blockborderClass'
import { Arc2d, Curve2d } from '@/imes/common/base/CAD'
import { ProcessorContext } from './dataHandle/base'
import { OptimizeLayoutProcessor } from './dataHandle/optimizeLayout/optimizeLayout'
import { ToolsHelper } from './dataHandle/tools/tool'
import {
BlockPlaceResult, BoardPlaceResult, BoardPosition, MaterialPlaceResult, PlaceBoard, PlaceStyle,
PlaceBlock, PlaceBlockDetail,
PlaceMaterial, RemainBlock,
PlacePositionClass,
CodeParams,
BlockHole,
BlockModel,
BlockModelPoint
} from './dataHandle/confClass'
import { BlockSizePlus } from './dataHandle/common/LayoutEngine/BlockSizePlus'
import { Point } from './dataHandle/common/Vector2'
import { PlacePositionHelper } from './dataHandle/common/PlacePostionHelper'
import { DisPoseModelInBoardBorder } from './dataHandle/common/LayoutEngine/DisposeModelInBoardBorder'
import { getMaterialSealEdge } from './dataHandle/common/BlockSealEdge'
import { ArrayExt } from './dataHandle/ArrayExt'
import { CutOrder } from './dataHandle/common/cutorder/CutOrder'
import { CutPointHelper } from './dataHandle/common/cutorder/CutPointHelper'
import { CodeParamsList, CodeParamsObj } from '@/imes/processParser/confClass'
import { BlockHelper } from './dataHandle/common/LayoutEngine/BlockHelper'
const selectedMachineID = ref() // 机台选中
const machineList = ref<any>([]) // 机台列表
// 1920321997498220544 1907276351086264320 1920401449485860864 1920739893772812288
const orderNo = ref('1920401449485860864')
const canvasWidth = ref(1200)
const canvasHeight = ref(650)
const paginationCurrent = ref<any>(1)
const paginationCurrentAll = ref<any>(1)
const boardEditor = ref<BoardEditor>()
const canvasMain = ref()
const canvas = ref()
const isOptimizeing = ref(false)
const _handleServe = ref<OptimizeLayoutProcessor | null>(null)
const selectVal = ref<any>()
const plateSelectOptions = ref<any>([])
const parserMain = ref<ParserMain>(new ParserMain())
const testData1 = ref('')
const dataBase = ref<any>(null)
// 添加显示标志位数组,用于记录当前需要绘制的内容
const displayFlags = ref({
isLockd: false, // 是否锁定
showBlocks: false, // 是否显示小板
showCutPoints: false, // 是否显示下刀点
showCutOrders: false, // 是否显示开料顺序
showCutNo: false, // 是否显示板号
showCutArrow: false, // 是否显示开料方向箭头
showManualPlace: false, // 是否显示手动排版
showHoles: false, // 是否显示孔洞
showModels: false, // 是否显示造型
});
// 初始化解析器
parserMain.value.setDeviceByKey('device1')
// 画布控制器
const canvasController = ref({
showType: BoardShowType.NORMAL,
showHelpCut: false,
isDragingBlock: false,
clickedBlock: new PlaceBlock(),
clickedScrapBlock: new RemainBlock(1, 1, 100, 100),
dragedDistance: Point,
beginDragPosition: Point,
mousePostion: Point,
dragingBlockPoint: BlockBorderPoint,
closestBlockPoint: BlockBorderPoint
})
const currentMaterial = computed(() => {
if (!dataBase.value?.materialList) return null;
const mIndex = dataBase.value.materialList.findIndex(e => e.goodsId === selectVal.value);
return mIndex >= 0 ? dataBase.value.materialList[mIndex] : null;
});
const currentBoard = computed(() => {
if (!currentMaterial.value?.boardList) return null;
const pIndex = paginationCurrent.value - 1;
return pIndex >= 0 && pIndex < currentMaterial.value.boardList.length
? currentMaterial.value.boardList[pIndex]
: null;
});
onMounted(() => {
getOptions();
})
const [registerTable, { setTableData, updateTableData, getDataSource }] = useTable({
title: '',
columns: optimizeColumns1,
useSearchForm: false,
rowKey: 'id',
pagination: false,
canResize: true,
maxHeight: 100,
showTableSetting: false,
actionColumn: {}
})
/**
* 获取弹出容器
*/
function getPopupContainer(node?: HTMLElement): HTMLElement {
return (node?.parentNode as HTMLElement) ?? document.body
}
/**
* 获取机台列表
*/
async function getOptions() {
const res = await getListAllSimple({ type: 1 });
if (res) {
machineList.value = res;
selectedMachineID.value = res[0].id;
_getPlaceOrderData();
}
}
/**
* 订单变化处理
*/
function orderNoChange() {
_getPlaceOrderData();
}
/**
* 机台变化处理
*/
function machineChange() {
// 机台变化逻辑
}
/**
* 获取排版订单数据
*/
async function _getPlaceOrderData() {
const params = {
// orderId: '1792854086534561792',
// machineId: '14193',
orderId: orderNo.value,
machineId: selectedMachineID.value,
};
const res = await getOrderSource(params);
if (!res) return;
let conf = JSON.parse(res.machineDTO.setting);
let tempData = { ...res, optimizeBoardModelDOS: [] };
let newGoodsList: any[] = [];
for (let material of tempData.goodsList) {
if (material.height == 0) material.height = 2440;
if (material.width == 0) material.width = 1220;
if (newGoodsList.findIndex(e => e.goodsId == material.goodsId) == -1) {
newGoodsList.push(material);
}
}
tempData.goodsList = newGoodsList;
let newTestData = convertData(tempData);
let goodsId = newTestData.materialList.map(e => e.goodsId)[0]
newTestData.blockList.forEach(block => {
block.goodsId = goodsId
});
dataBase.value = newTestData;
let sysConfig = new SysConfig(conf);
let _sysConfig = { ...sysConfig };
setTableData(newTestData.materialList);
selectVal.value = newTestData.materialList[0].goodsId;
plateSelectOptions.value = newTestData.materialList;
_sysConfig.boardBorder = _sysConfig.cutBoardBorder;
let eleCanvasMain = document.getElementsByClassName('contentMain')[0];
const { clientWidth, clientHeight } = eleCanvasMain;
canvasWidth.value = clientWidth - 10;
canvasHeight.value = clientHeight - 30;
await nextTick();
boardEditor.value = new BoardEditor(
canvas.value.canvasRef,
_sysConfig,
canvasController.value
);
boardEditor.value.boardWidth = sysConfig.boardWidth;
boardEditor.value.boardLength = sysConfig.boardLength;
boardEditor.value.drawBase();
boardEditor.value.setSysConfig(_sysConfig);
}
async function initHandleServe1() {
let newTestData = dataBase.value;
//#region 刀库
let toolsHelperClass = new ToolsHelper();
let contextKnife: ProcessorContext<Knife[], any, any> = {
input: newTestData.sysConfig.knifeList,
output: {},
params: newTestData.sysConfig
}
const toolsHelper = toolsHelperClass.exec(contextKnife)
//#endregion
//#region 优化排版
let input = {
materialList: newTestData.materialList,
blockList: newTestData.blockList,
blockDetailList: newTestData.blockDetailList,
toolsHelper: toolsHelper,
}
let params = newTestData.sysConfig
let context: ProcessorContext<any, Function, any> = {
input: input,
params: params,
output: optimizeLayoutProcessorCallBack
};
const optimizeLayoutProcessor = new OptimizeLayoutProcessor()
let res = optimizeLayoutProcessor.exec(context)
_handleServe.value = optimizeLayoutProcessor
//#endregion
}
/** 优化的处理器回调--这部分 不做到处理器 */
async function optimizeLayoutProcessorCallBack(context) {
console.log('optimizeLayoutProcessorCallBack', context);
const { data, info } = context;
if (['noBan', 'stop'].includes(info.type)) {
await _handleServe.value?.terminateWorker({ goodsId: context.data.pm.goodsId });
return;
}
// 优化算法拿到优化数据后 各部门根据情况 将数据加载到各自的数据结构中
let materialPlaceResult = await getMaterialPlaceResult(data);
if (materialPlaceResult) {
const { placeResult, pm } = materialPlaceResult;
const remain = placeResult.boards.filter(e => e.isRemainBoard == true);
for (const i in dataBase.value.materialList) {
let material = dataBase.value.materialList[i];
if (material.goodsId == pm.goodsId) {
// let hasResPm = _handleServe.value?.handlePlaceResult(placeResult, pm);
let _hasResPm = await handleTempPlaceResultToPlaceMaterial(placeResult, pm);
dataBase.value.materialList[i] = {
...material,
...pm,
..._hasResPm,
optimizingAvgUsageRateExcludeLastBoard: placeResult.avgUsageRateExcludeLastBoard.toFixed(3),
optimizingUsageRateLastBoard: placeResult.usageRateLastBoard.toFixed(3),
optimizingBoardCount: placeResult.boardCount,
optimizingRemainBoardCount: remain.length,
selectedBlockCount: pm.blockList.length,
};
}
}
setTableData(dataBase.value.materialList);
}
}
/** 数据处理 将优化数据转 为 MaterialPlaceResult */
function getMaterialPlaceResult(data) {
let {
bList, best, yl, pm, width, length
} = data
const config = dataBase.value.sysConfig
let blocks = bList
let retData = new MaterialPlaceResult()
let boardCount = 0
let remainCount = 0
let border = config.cutBoardBorder
let borderOff = (pm.diameter + pm.cutKnifeGap) / 2
// 所有大板上的小板面积
let size_all = 0
for (let i = 0; i < best.length; i++) {
let bd = best[i]
let isRemainBoard = false
boardCount = retData.boards.length + 1
if (i < yl.length) // 余料板
{
width = yl[i].w + border * 2 - borderOff * 2
length = yl[i].l + border * 2 - borderOff * 2
isRemainBoard = true
remainCount++
}
let boardResult = new BoardPlaceResult()
boardResult.boardId = boardCount
boardResult.width = width
boardResult.length = length
boardResult.isRemainBoard = isRemainBoard
let pid = 0
for (let b of bd) {
pid++
let block = blocks[b.bangid]
let placeStyle = PlaceStyle.FRONT
if (!block) {
return
}
let faceF = block.isTurnFaceToPlace || false
let isTurnFaceToPlace = config.placeOriginByBoardLocation && (
config.boardLocation == BoardPosition.RIGHT_BOTTOM || config.boardLocation == BoardPosition.LEFT_TOP)
if (isTurnFaceToPlace)
faceF = !faceF
if (faceF) // 翻面开料
{
if (block.texture == 0) {
placeStyle = PlaceStyle.BACK
}
else if (block.texture == 2) {
placeStyle = PlaceStyle.BACK_TURN_LEFT
}
else {
placeStyle = (b.pbg == block.placeFullLength ? PlaceStyle.BACK : PlaceStyle.BACK_TURN_LEFT)
}
}
else {
if (block.texture == 0) {
placeStyle = PlaceStyle.FRONT
}
else if (block.texture == 2) {
placeStyle = PlaceStyle.FRONT_TURN_RIGHT
}
else {
placeStyle = (b.pbg == block.placeFullLength ? PlaceStyle.FRONT : PlaceStyle.FRONT_TURN_RIGHT)
}
}
let br: any = null
br = new BlockPlaceResult(block.blockNo, boardCount, pid, b.x, b.y, b.pbk, b.pbg, placeStyle, block.area)
boardResult.blocks.push(br)
boardResult.area += block.area
}
retData.boards.push(boardResult)
size_all += boardResult.area
let val = (size_all - boardResult.area) / (retData.boards.length - 1)
retData.avgUsageRateAll = size_all / retData.boards.length
retData.avgUsageRateExcludeLastBoard = Number.isNaN(val) ? boardResult.area : val
retData.usageRateLastBoard = boardResult.area
retData.boardCount = retData.boards.length
}
retData.boardCount = retData.boards.length // 大板数
let remainBoardCount = retData.boards.filter(t => t.remainNo != '').length // 异形大板数
let remianCount = 0
if (Array.isArray(pm.remainBoardList)) {
pm.remainBoardList.forEach(e => {
if (e?.placeBoardJSON) {
let str = e?.placeBoardJSON
e.placeBoardList = JSON.parse(str)
remianCount += e.placeBoardList.length
}
})
}
retData.remainBoardCount = pm?.remainBoardList ? remianCount : yl.length + remainBoardCount
return { placeResult: retData, pm }
}
async function handleTempPlaceResultToPlaceMaterial(_placeResult: MaterialPlaceResult, _pm: PlaceMaterial) {
console.log('确认优化生效 affirmPlace')
let pm: PlaceMaterial = _pm
pm.tempBestPlaceResult = _placeResult
const config = dataBase.value.sysConfig
// 没发现优化结果
if (!pm.tempBestPlaceResult)
return
let placeResult = pm.tempBestPlaceResult
let orgBoardList = pm.boardList
let dic: any = [] // 存放当前 优化的小板
pm.boardList = []
let boardId1 = 1
// 第一次 false
if (pm.tempPlaceResultOnyUnlockedBoard) {
for (let pb of orgBoardList) {
if (pb.isLocked == false && pb.cutedType == 0) // 未锁定
{
pb.blockList.forEach(i => dic[i.blockNo] = i)
}
else // 锁定
{
if (pb.isAdnormal()) {
let sb = pm.remainBoardList.find(t => t.id == Number(pb.boardNo))
if (sb)
sb.isUsed = true
}
pb.boardId = boardId1
pm.boardList.push(pb)
boardId1++
}
}
}
else {
pm.blockList.forEach(i => dic[i.blockNo] = i)
}
// 0904 修复 需求改造后 导致 这里的dic 最终为空
if (Object.keys(dic).length == 0) {
pm.blockList.forEach(i => dic[i.blockNo] = i)
}
let locator = config.boardLocation
// 大板优化结果
let boardId = 0
for (let bpr of placeResult.boards) {
boardId++
// bpr.isRemainBoard false
let bW = bpr.isRemainBoard ? bpr.width : pm.width
let bL = bpr.isRemainBoard ? bpr.length : pm.length
let pb = new PlaceBoard(boardId, bW, bL, bpr.remainId, bpr.remainNo)
pb.isCreateRemainSpace = true
for (let bInfo of bpr.blocks) {
let block: PlaceBlock = dic[bInfo.blockId]
if (block) {
block.isPlaced = true
block.boardId = boardId
block.placeId = bInfo.placeId
block.placeX = bInfo.placeX
block.placeY = bInfo.placeY
// console.log('重置 开料面 开料信息 after', block.boardId, block.blockNo, block, block.placeStyle, bInfo.placeStyle)
/**
* 雕刻机(钻孔、拉槽、开料)优化排版,开料排版面(开料正面)选择顺序:排版面>>造型>>排钻>>设计正面
1. 排版面
小板设计排版面为正面或反面,设置对应面为开料排版面,
小板设计排版面为随意面,则继续;
2. 造型
小板只有单面造型,设置对应面为开料排版面,
小板双面无造型或双面有造型,则继续;
3. 排钻
小板有大孔(偏心轮锁孔),设置对应面为开料排版面,
小板无大孔(偏心轮锁孔),则设置孔多的面为开料排版面,
小板无孔,则继续;
4. 设计正面
默认设置设计正面为开料排版面。
*/
block.placeStyle = bInfo.placeStyle
let posOff = BlockSizePlus.getOffDis(block)// this.getOffDis(block)
block.placeOffX = posOff.x
block.placeOffY = posOff.y
block.placeX = bInfo.placeX + posOff.x
block.placeY = bInfo.placeY + posOff.y
if (bInfo.placeStyle == PlaceStyle.FRONT || bInfo.placeStyle == PlaceStyle.FRONT_TURN_BACK
|| bInfo.placeStyle == PlaceStyle.BACK || bInfo.placeStyle == PlaceStyle.BACK_TURN_BACK) {
block.placeWidth = block.cutWidth
block.placeLength = block.cutLength
}
else {
block.placeWidth = block.cutLength
block.placeLength = block.cutWidth
}
block.isAutoPlaced = true
block.isOverlap = false
block.cutOrder = 0
pb.blockList.push(block)
pb.blockCount++
pb.blockArea += block.area
delete dic[bInfo.blockId] // 移除block;
} else {
}
}
if (bpr.isScrap) {
// 设置前余料板的使用状态,将不需要的释放.
console.log('设置前余料板的使用状态,将不需要的释放.')
let sb = pm.remainBoardList.find(t => t.id == bpr.remainId)
if (sb) {
sb.isUsed = true
if (sb.placeStyle % 2 != 0) {
pb.width = sb.length
pb.length = sb.width
}
let pl = sb.placePolyline
pb.points = sb?.placePolyline?.LineData.map((t) => { return { x: t.pt.x, y: t.pt.y, bul: t.bul } }) || []
// pb.StoreNo = sb.StoreHouse;
}
}
pb.usageRate = Math.round(10000 * pb.blockArea / pb.area) / 100
pm.boardList.push(pb)
console.log('大板靠板翻转', pb.boardId, locator)
// 大板靠板翻转
PlacePositionHelper.turnPlacePosition(pb, locator, config)
for (let block of pb.blockList) {
// 重置 开料面 开料信息
// console.log('重置 开料面 开料信息', block.boardId, block.blockNo, block, block.placeStyle)
if (block.placeStyle == null || block.placeStyle == undefined) {
console.log('handleTempPlaceResultToPlaceMaterial error block.placeStyle is null or undefined')
} else {
PlacePositionClass.resetPlaceStyle(block, block.placeStyle)
}
}
}
// 大板长边两侧 width 范围内 避免出现造型 DisPoseModelInBoardBorderWidth > 0 生效
DisPoseModelInBoardBorder(
pm,
config.boardBorderModelRange,
config.boardBorderModelModeToFace,
config.boardBorderModelByMachine,
config.modelNearBoardBorder,
)
// for (let pb of pm.boardList) {
// // 重设大板汇总 重设 大板开料 顺序,下刀点
// this.resetPlaceBoard(pm, pb)
// // 检查干涉
// if (pb.isLocked == false && pb.cutedType == 0)
// this.checkOverlapInBoard(pm, pb)
// }
let rBoardCount = placeResult.boardCount
let rUseSize_avg = placeResult.avgUsageRateAll
let rUseSize_noLast = placeResult.avgUsageRateExcludeLastBoard
let rUseSize_last = placeResult.usageRateLastBoard
pm.avgUsageRateAll = rUseSize_avg
pm.avgUsageRateExcludeLastBoard = rUseSize_noLast
pm.usageRateLastBoard = rUseSize_last
pm.boardCount = pm.boardList.length
pm.remainBoardCount = placeResult.remainBoardCount
pm.minBoardId = 1
pm.maxBoardId = pm.boardCount
pm.edgeSealLengthList = getMaterialSealEdge(pm)
pm.boardCountFlipFace = ArrayExt.count(pm.boardList, t => t.isTwoFaceProcessing())
pm.isOptimized = true
pm.tempBestPlaceResult = null
pm.tempPlaceResultError = ''
let mesg = ''
let c = 0
for (let v in dic) {
mesg += `${v} `
c++
}
mesg = `${c}片小板未能排入大板,有可能是尖角导致优化失败.${mesg}`
if (c > 0) {
console.log(pm)
// createMessage.error(mesg)
throw new Error(mesg)
}
return pm
}
/**
* 绘制下刀点
*/
function drawCutPoint() {
if (!boardEditor.value || !dataBase.value || !_handleServe.value) return;
let mIndex = dataBase.value.materialList.findIndex(e => e.goodsId == selectVal.value);
let pIndex = paginationCurrent.value - 1;
if (mIndex >= 0 && dataBase.value.materialList[mIndex].boardList?.length > 0) {
const pm = dataBase.value.materialList[mIndex];
const pb = pm.boardList[pIndex];
// 计算开料顺序和下刀点
// _handleServe.value.autoCalcCutOrder(pm, pb);
CutPointHelper.autoFindCutPoint(pm, pb)
// 设置显示标志位,只显示小板和下刀点
displayFlags.value.showBlocks = true;
displayFlags.value.showCutPoints = !displayFlags.value.showCutPoints; // 切换下刀点显示状态
// 重新绘制
// reDrawCanvas();
} else {
alert('请先进行优化!');
}
}
/**
* 绘制开料顺序
*/
function drawSortingPlace() {
if (!boardEditor.value || !dataBase.value || !_handleServe.value) return;
let mIndex = dataBase.value.materialList.findIndex(e => e.goodsId == selectVal.value);
let pIndex = paginationCurrent.value - 1;
if (mIndex >= 0 && dataBase.value.materialList[mIndex].boardList?.length > 0) {
const pm = dataBase.value.materialList[mIndex];
const pb = pm.boardList[pIndex];
const config = dataBase.value.sysConfig
// 计算所有板材的 开料顺序
let newList = CutOrder.autoSetCutOrder(dataBase.value.materialList, config)
// 计算当前板材的开料顺序
// CutOrder.autoCalcCutOrder(pm,pb,false,config)
// 设置显示标志位,只显示小板和开料顺序
displayFlags.value.showBlocks = true;
displayFlags.value.showCutOrders = !displayFlags.value.showCutOrders; // 切换开料顺序显示状态
// 重新绘制
// reDrawCanvas();
} else {
alert('请先进行优化!');
}
}
/**
* 处理画布事件
*/
function boardViewEvent(name, e) {
if (!boardEditor.value) return;
if (name === 'CanvasEvent_MouseDown') {
// 处理鼠标按下事件
boardEditor.value.CanvasEvent_MouseDown(e);
} else if (name === 'CanvasEvent_MouseMove') {
// 使用节流函数处理鼠标移动事件,减少事件触发频率
throttledMouseMove(e);
} else if (name === 'CanvasEvent_Mouseup') {
boardEditor.value.CanvasEvent_Mouseup(e);
} else if (name === 'CanvasEvent_dblclick') {
// 双击事件处理
} else if (name === 'CanvasEvent_Wheel') {
// 滚轮事件处理
} else if (name === 'keyDown') {
boardEditor.value.keyDown(e);
}
}
const throttledMouseMove = throttle((e) => {
if (boardEditor.value) {
boardEditor.value.CanvasEvent_MouseMove(e);
}
}, 16);
/**
* 节流函数
*/
function throttle(fn, delay) {
let lastCall = 0;
return function (...args) {
const now = Date.now();
if (now - lastCall >= delay) {
lastCall = now;
fn.apply(this, args);
}
};
}
/**
* 开始排版
*/
function startPlace() {
// initHandleServe();
initHandleServe1();
// 设置显示标志位,显示所有内容
displayFlags.value.showBlocks = true;
displayFlags.value.showCutPoints = true;
displayFlags.value.showCutOrders = true;
displayFlags.value.showCutArrow = true;
displayFlags.value.showCutNo = true;
displayFlags.value.showHoles = true;
displayFlags.value.showModels = true;
}
/**
* 清空画布
*/
function clearCanvas() {
// 重置显示标志位
displayFlags.value.showBlocks = false;
displayFlags.value.showCutPoints = false;
displayFlags.value.showCutOrders = false;
displayFlags.value.showCutArrow = false;
displayFlags.value.showCutNo = false;
displayFlags.value.showHoles = false;
displayFlags.value.showModels = false;
// 清空画布
boardEditor.value?.clearCanvas();
}
/**
* 获取解析器参数
*/
function getParserParams() {
handleTemplateData();
}
/**
* 处理模板数据
*/
async function handleTemplateData() {
// 获取模板和范例
let templateData = parserMain.value._device.getTemplateData();
console.log(templateData, dataBase.value);
if (!currentMaterial.value || !currentBoard.value) {
alert('请先进行优化!');
return;
}
// 准备代码参数列表
let data: CodeParamsList = {
processList: [],
};
// 获取速度参数
let freeSpeed = _handleServe.value?.freeSpeed || 10000;
let workSpeed = _handleServe.value?.workSpeed || 8000;
let modelSpeed = _handleServe.value?.modelSpeed || 8000;
let holeSpeed = _handleServe.value?.holeSpeed || 8000;
/** 根据哪个加工面加工 */
let doBackFace = true
for (const template of templateData) {
// 必须要有指令和代码
if (!template.value || !template.orderStr) continue;
if (template.isLoop) {
// 处理循环节点(加工刀路数据)
let material = currentMaterial.value;
let board = currentBoard.value;
// 根据开料顺序做个排序
board.blockList = board.blockList.sort((a, b) => a.cutOrder - b.cutOrder)
//#region 排钻
/**
* 先对该大板内所有小板上的孔进行分析
*/
let allHoles: BlockHole[] = await BlockHelper.GetHoles_BoardAllBlocksByDoFace(board,doBackFace)
// 对孔列表 根据 孔直径 排序
allHoles = allHoles.sort((a, b) => a.radius - b.radius)
for (const key in allHoles) {
let hole = allHoles[key]
let block: PlaceBlock = board.blockList.find(e => e.blockNo == hole.blockNo)
// 加工项 孔的
let temp: CodeParamsObj = {
processItemInfo: {
code: template.value,
order: template.orderStr,
block: {
blockNo: block.blockNo,
cutLength: block.cutLength,
cutWidth: block.cutWidth
},
knife: {
diameter: hole.radius * 2
},
}
};
let list: CodeParams[] = [];
let depth = hole.depth >= block.thickness ? block.thickness : hole.depth
// 刀移动到孔的安全点
let moveToHolePoint = pointToCodeParams(hole.pointX, hole.pointY, block.placeX, block.placeY)
moveToHolePoint.dir = 0
moveToHolePoint.z = 30
moveToHolePoint.f = freeSpeed
list.push(moveToHolePoint)
// 刀下到版面
let moveToblockToDoHole = pointToCodeParams(hole.pointX, hole.pointY, block.placeX, block.placeY)
moveToblockToDoHole.dir = 0
moveToblockToDoHole.z = -block.thickness
moveToblockToDoHole.f = freeSpeed
list.push(moveToblockToDoHole)
// 下刀
let knifeDown_DoHole = pointToCodeParams(hole.pointX, hole.pointY, block.placeX, block.placeY)
knifeDown_DoHole.z = -depth
knifeDown_DoHole.dir = 1
knifeDown_DoHole.f = holeSpeed
list.push(knifeDown_DoHole)
// 抬刀
let knifeEnd_DoHoleEnd = pointToCodeParams(hole.pointX, hole.pointY, block.placeX, block.placeY)
knifeEnd_DoHoleEnd.dir = 0
knifeEnd_DoHoleEnd.z = 30
knifeEnd_DoHoleEnd.f = freeSpeed
list.push(knifeEnd_DoHoleEnd)
temp.list = list
data.processList?.push(temp);
}
//#endregion
//#region 造型
// 所有造型
let allModels: BlockModel[] = await BlockHelper.GetModels_BoardAllBlocksByDoFace(board,doBackFace)
allModels = allModels.sort((a, b) => a.knifeRadius - b.knifeRadius)
for (const key in allModels) {
let model = allModels[key]
let block: PlaceBlock = board.blockList.find(e => e.blockNo == model.blockNo)
let { placeX, placeY } = block;
let temp: CodeParamsObj = {
processItemInfo: {
code: template.value,
order: template.orderStr,
block: {
blockNo: block.blockNo,
cutLength: block.cutLength,
cutWidth: block.cutWidth
},
knife: {
diameter: model.realKnifeRadius * 2
},
}
};
let list: CodeParams[] = [];
let realPointList:any[] = []
// model.realPointList.forEach((p,i)=>{
// if(p.curve !=0 || p.radius != 0){
// }
// })
for (let index = 0; index < model.realPointList.length; index++) {
const p = model.realPointList[index];
let last_p: BlockModelPoint;
if (index == 0) {
last_p = model.realPointList[model.realPointList.length - 1]
} else {
last_p = model.realPointList[index - 1]
}
// p.curve
// p.radius
let new_p = { ...p, radius: last_p.radius, curve: last_p.curve }
realPointList.push(new_p);
}
let depth = model.depth >= block.thickness ? block.thickness : model.depth
// 移动到起点
let codeLineStart = pointToCodeParams(realPointList[0].pointX, realPointList[0].pointY, placeX, placeY)
codeLineStart.dir = 0;
codeLineStart.z = 30;
codeLineStart.f = freeSpeed;
list.push(codeLineStart);
// 下刀至版面
let knifeToBlock_DoModel = pointToCodeParams(realPointList[0].pointX, realPointList[0].pointY, placeX, placeY)
knifeToBlock_DoModel.dir = 0;
knifeToBlock_DoModel.z = block.thickness;
knifeToBlock_DoModel.f = freeSpeed
list.push(knifeToBlock_DoModel)
// 扎入 下刀至起点
let knifeInnerBlock_DoBlock = pointToCodeParams(realPointList[0].pointX, realPointList[0].pointY, placeX, placeY)
knifeInnerBlock_DoBlock.dir = 1;
knifeInnerBlock_DoBlock.z = -depth
knifeInnerBlock_DoBlock.f = modelSpeed
list.push(knifeInnerBlock_DoBlock)
// 开始造型走刀
for (const modelPoint of realPointList) {
let codeLineMove = pointToCodeParams(modelPoint.pointX, modelPoint.pointY, placeX, placeY, modelPoint.curve)
codeLineMove.z = -depth
codeLineMove.f = modelSpeed
if (modelPoint.radius != 0) {
codeLineMove.r = modelPoint.radius
}
list.push(codeLineMove)
}
// 走刀结束 抬刀
let endPoint = realPointList[realPointList.length - 1]
let codeLineEnd = pointToCodeParams(endPoint.pointX, endPoint.pointY, placeX, placeY)
codeLineEnd.dir = 0
codeLineEnd.f = freeSpeed
codeLineEnd.z = 30
list.push(codeLineEnd)
temp.list = list
data.processList?.push(temp);
}
//#endregion
//#region 开料
// 轮廓的集合 开料用
let borderFinalList = board.blockList.map(e => e.blockDetail.borderContour.borderFinal);
for (const i in borderFinalList) {
let block = board.blockList[i];
let border = borderFinalList[i];
// 添加标记
let temp1: CodeParamsObj = {
processItemInfo: {
code: 'MARK',
order: 'Mark',
codeParams: block.blockNo + ' cut block'
}
};
data.processList?.push(temp1);
// 加工项 开料的
let temp: CodeParamsObj = {
processItemInfo: {
code: template.value,
order: template.orderStr,
block: {
cutLength: block.cutLength,
cutWidth: block.cutWidth
},
knife: {
diameter: material.diameter
}
}
};
// 加工刀路信息 代码生成参数列表
let list: CodeParams[] = [];
let { placeX, placeY } = block;
// 移动到起点
let codeLineStart = BoardToCodeParams(border[0], placeX, placeY);
codeLineStart.dir = 0;
codeLineStart.z = 30;
codeLineStart.f = freeSpeed;
list.push(codeLineStart);
// 下刀到板面
let codeLine1 = BoardToCodeParams(border[0], placeX, placeY);
codeLine1.dir = 0;
codeLine1.z = block.thickness;
codeLine1.f = freeSpeed;
list.push(codeLine1);
// 扎入
let codeLine2 = BoardToCodeParams(border[0], placeX, placeY);
codeLine2.dir = 1;
codeLine2.z = 0;
codeLine2.f = workSpeed;
// 走刀
for (const p of border) {
// if (block.blockNo == '25044454400') {
// debugger
// }
let codeLine = BoardToCodeParams(p, placeX, placeY);
codeLine.z = -block.thickness;
codeLine.f = workSpeed;
list.push(codeLine);
}
// 回到起点
let codeLine3 = BoardToCodeParams(border[0], placeX, placeY);
codeLine3.z = -block.thickness;
codeLine3.f = freeSpeed;
list.push(codeLine3);
// 抬刀
let codeLineEnd = BoardToCodeParams(border[0], placeX, placeY);
codeLineEnd.dir = 0;
codeLineEnd.z = 30;
codeLineEnd.f = freeSpeed;
list.push(codeLineEnd);
temp.list = list;
data.processList?.push(temp);
}
//#endregion
} else {
// 处理非循环节点(文件头尾)
let temp: CodeParamsObj = {
processItemInfo: {
code: template.value,
order: template.orderStr
}
};
if (template.params) {
temp.processItemInfo.codeParams = template.params;
}
data.processList?.push(temp);
}
}
console.log('处理完成', data);
// 生成代码
let str = await parserMain.value.getCode(data);
testData1.value = str;
console.log('最终结果', str);
}
/**
* 将板轮廓转换为代码参数
* border 轮廓线
* placeX 板件优化X坐标
* placeY 板件优化Y坐标
*/
function BoardToCodeParams(border: Curve2d | Arc2d, placeX = 0, placeY = 0): CodeParams {
let codeLine: CodeParams = {};
codeLine.x = border.EndPoint.m_X + placeX;
codeLine.y = border.EndPoint.m_Y + placeY;
codeLine.dir = 1;
if (border instanceof Arc2d || (Reflect.has(border, 'm_Radius') && border['m_Radius'] != 0)) {
codeLine.r = border.m_Radius;
if (border.Bul > 0) {
codeLine.dir = 3;
} else if (border.Bul < 0) {
codeLine.dir = 2;
}
}
return codeLine;
}
/**
* x , y 点坐标
* hole 孔
* placeX 板件优化X坐标
* placeY 板件优化Y坐标
*/
function pointToCodeParams(x, y, placeX = 0, placeY = 0, bul?) {
let codeLine: CodeParams = {}
codeLine.x = x + placeX
codeLine.y = y + placeY
if (bul != undefined) {
if (bul > 0) {
codeLine.dir = 3
} else if (bul < 0) {
codeLine.dir = 2
}
}
return codeLine
}
/**
* 重新绘制画布
*/
function reDrawCanvas() {
if (!boardEditor.value || !dataBase.value) return;
let mIndex = dataBase.value.materialList.findIndex(e => e.goodsId == selectVal.value);
let pIndex = paginationCurrent.value - 1;
if (mIndex >= 0 && dataBase.value.materialList[mIndex].boardList?.length > 0) {
const pm = dataBase.value.materialList[mIndex];
const pb = pm.boardList[pIndex];
// 确保每个板件都有开料顺序和下刀点
if (_handleServe.value && pb.blockList.some(block => !block.cutOrder)) {
_handleServe.value.autoCalcCutOrder(pm, pb);
}
boardEditor.value.setMaterial(pm);
boardEditor.value.setBoard(pb);
// 清空画布并绘制基础内容
boardEditor.value.clearCanvas();
boardEditor.value.drawBase();
boardEditor.value.drawBoard(pb);
boardEditor.value.setDisplayFlags({
isLockd: displayFlags.value.isLockd,
showBlocks: displayFlags.value.showBlocks,
showCutPoints: displayFlags.value.showCutPoints,
showCutOrders: displayFlags.value.showCutOrders,
showCutArrow: displayFlags.value.showCutArrow,
showCutNo: displayFlags.value.showCutNo,
showHoles: displayFlags.value.showHoles,
showModels: displayFlags.value.showModels,
showManualPlace: displayFlags.value.showManualPlace
});
boardEditor.value.drawAllElements();
}
}
</script>
<template>
<div class="processDemo1">
<div class="tools">
<span class="toolItemLabel">生产单号</span>
<Input class="toolItem" v-model:value="orderNo" style="width: 170px;" @change="orderNoChange" />
<span class="toolItemLabel">机台选择</span>
<Select v-model:value="selectedMachineID" placeholder="请选择机台" :get-popup-container="getPopupContainer"
style="width: 170px;" @change="machineChange">
<SelectOption v-for="item in machineList" :key="item.id" :value="item.id">
{{ item.name }}
</SelectOption>
</Select>
<Button v-if="!isOptimizeing" @click="startPlace">开始优化</Button>
<Button @click="drawSortingPlace">开料顺序</Button>
<Button @click="drawCutPoint">下刀点</Button>
<Button @click="getParserParams"> 解析器</Button>
<BasicTable @register="registerTable" />
</div>
<div class="content">
<div class="contentLeft">
<div class="contentTools">
<Select v-model:value="selectVal" class="plateSelect" :style="{ width: '200px', marginLeft: '10px' }"
:options="plateSelectOptions" :field-names="{ label: 'goodsName', value: 'goodsId' }"
@change="reDrawCanvas" />
<Pagination v-model:current="paginationCurrent" @change="reDrawCanvas" :page-size="1" class="platePagination"
:total="paginationCurrentAll" />
</div>
<div class="contentBtns">
<Button class="contentBtn" @click="clearCanvas">清空</Button>
<Textarea class="testData" v-model:value="testData1"></Textarea>
</div>
</div>
<!-- 画布区域 -->
<div class="contentMain" ref="canvasMain">
<BoardView ref="canvas" class="BoardView" :width="canvasWidth" :height="canvasHeight" tabindex="0"
@keydown="boardViewEvent('keyDown', $event)" @dblclick="boardViewEvent('CanvasEvent_dblclick', $event)"
@mousedown="boardViewEvent('CanvasEvent_MouseDown', $event)"
@mouseup="boardViewEvent('CanvasEvent_Mouseup', $event)"
@mousemove="boardViewEvent('CanvasEvent_MouseMove', $event)"
@wheel="boardViewEvent('CanvasEvent_Wheel', $event)"
@contextmenu="boardViewEvent('CanvasEvent_RightClick', $event)" />
</div>
</div>
</div>
</template>
<style>
.processDemo1 {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
padding: 10px;
}
.tools {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.toolItemLabel {
margin: auto 0;
}
.content {
display: flex;
flex-direction: row;
}
.contentLeft {
display: flex;
flex-direction: column;
flex: 1;
}
.contentTools {
display: flex;
flex-direction: row;
}
.BoardView {
border: 1px solid silver;
}
.contentBtns {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.contentBtn {
margin: 6px 8px;
}
.testData {
overflow: auto;
min-height: 450px !important;
background-color: #FFFFFF !important;
color: #000000 !important;
}
</style>