feat: 提交

This commit is contained in:
2025-07-22 18:38:25 +08:00
parent 87e2804d1f
commit b7399fd6e7
23 changed files with 36662 additions and 58 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,75 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
var RectOptimizeMachine_1 = require("./RectOptimizeMachine");
var ctx = this;
if (typeof window !== 'undefined' && 'Worker' in window) {
ctx.addEventListener('message', function (event) { return __awaiter(void 0, void 0, void 0, function () {
var m, _a, blockList, boardList, boardCount, optimizeTimes, isDoubleFaceBlockFirst, gap, gzpb, isDoubleFaceBlockInRemain, info;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
m = new RectOptimizeMachine_1.RectOptimizeMachine();
m.CallBack = function (best, fit, arg, info) { return __awaiter(void 0, void 0, void 0, function () {
return __generator(this, function (_a) {
ctx.postMessage([best, fit, arg, info]);
return [2 /*return*/];
});
}); };
if (!(event.data.type == 'start')) return [3 /*break*/, 1];
_a = (event.data.data), blockList = _a[0], boardList = _a[1], boardCount = _a[2], optimizeTimes = _a[3], isDoubleFaceBlockFirst = _a[4], gap = _a[5], gzpb = _a[6], isDoubleFaceBlockInRemain = _a[7];
m.Start(blockList, boardList, boardCount, optimizeTimes, isDoubleFaceBlockFirst, gap, gzpb, isDoubleFaceBlockInRemain);
return [3 /*break*/, 3];
case 1:
info = {
type: 'isStop',
};
return [4 /*yield*/, m.Stop(info)];
case 2:
_b.sent();
ctx.postMessage([[], null, null, info]);
ctx === null || ctx === void 0 ? void 0 : ctx.terminate();
_b.label = 3;
case 3: return [2 /*return*/];
}
});
}); });
}
else {
}
exports.default = {};

View File

@@ -0,0 +1,42 @@
import type { Big_bang, xbang } from './bang'
import { RectOptimizeMachine } from './RectOptimizeMachine'
// import {Worker} from "worker_threads"
import { Worker as NodeWorker } from 'worker_threads';
const ctx: NodeWorker | Worker = self as any
debugger
if (typeof window !== 'undefined' && 'Worker' in window) {
ctx.addEventListener('message', async (event) => {
let m = new RectOptimizeMachine()
m.CallBack = async (best, fit, arg, info) => {
ctx.postMessage([best, fit, arg, info])
}
if (event.data.type == 'start') {
/**
* blockList 小板列表
* boardList 大板(N个元素前N-1个元素表示余料板且余料板须为矩形第N个元素表示大板)
* boardCount 余料板数量(bigBang中前N-1个元素对应的数量如果bigBang中只有一个元素即只有大板没有余料板则为空数组)
* optimizeTimes 新优化次数
* isDoubleFaceBlockFirst 双面加工的小板是否优先排入
* gap 排版缝隙 = 开料刀直径 + 缝隙
* gzpb 规则排版
* isDoubleFaceBlockInRemain 余料板是否排入双面加工的小板
*/
let [blockList, boardList, boardCount, optimizeTimes, isDoubleFaceBlockFirst, gap, gzpb, isDoubleFaceBlockInRemain] = (event.data.data) as [xbang[], Big_bang[], number[], number, boolean, number, boolean, boolean]
m.Start(blockList, boardList, boardCount, optimizeTimes, isDoubleFaceBlockFirst, gap, gzpb, isDoubleFaceBlockInRemain)
} else {
const info = {
type: 'isStop',
}
await m.Stop(info)
ctx.postMessage([[], null, null, info])
ctx?.terminate()
}
})
} else {
}
export default {} as typeof Worker & (new () => Worker)

View File

@@ -0,0 +1,60 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WorkerItemType = exports.BlockRegion = exports.Big_bang = exports.HoleType = exports.ComposingType = exports.LineType = void 0;
/**纹路类型 Positive=0正纹 Reverse=1反纹 CanReversal=2可翻转 */
var LineType;
(function (LineType) {
/**正纹 */
LineType[LineType["Positive"] = 0] = "Positive";
/**反纹 */
LineType[LineType["Reverse"] = 1] = "Reverse";
/**可翻转 */
LineType[LineType["CanReversal"] = 2] = "CanReversal";
})(LineType || (exports.LineType = LineType = {}));
/**版面类型: Positive=0正面 Reverse=1反面 Arbitrary=2任意面 */
var ComposingType;
(function (ComposingType) {
/**正面 */
ComposingType[ComposingType["Positive"] = 0] = "Positive";
/**反面 */
ComposingType[ComposingType["Reverse"] = 1] = "Reverse";
/**任意面 */
ComposingType[ComposingType["Arbitrary"] = 2] = "Arbitrary";
})(ComposingType || (exports.ComposingType = ComposingType = {}));
/**孔类型 None=0无 Positive=1正面 Reverse=2反面 Two=3正反 */
var HoleType;
(function (HoleType) {
/**无 */
HoleType[HoleType["None"] = 0] = "None";
/**正面 */
HoleType[HoleType["Positive"] = 1] = "Positive";
/**反面 */
HoleType[HoleType["Reverse"] = 2] = "Reverse";
/**正反 */
HoleType[HoleType["Two"] = 3] = "Two";
})(HoleType || (exports.HoleType = HoleType = {}));
/** 大板 */
var Big_bang //待优化的板
= /** @class */ (function () {
function Big_bang() {
}
return Big_bang;
}());
exports.Big_bang = Big_bang;
var BlockRegion;
(function (BlockRegion) {
/** 左下 = 0 */
BlockRegion[BlockRegion["LEFT_BOTTOM"] = 0] = "LEFT_BOTTOM";
/** 右下 = 1 */
BlockRegion[BlockRegion["RIGHT_BOTTOM"] = 1] = "RIGHT_BOTTOM";
/** 右上 = 2 */
BlockRegion[BlockRegion["RIGHT_TOP"] = 2] = "RIGHT_TOP";
/** 左上 = 3 */
BlockRegion[BlockRegion["LEFT_TOP"] = 3] = "LEFT_TOP";
})(BlockRegion || (exports.BlockRegion = BlockRegion = {}));
var WorkerItemType = /** @class */ (function () {
function WorkerItemType() {
}
return WorkerItemType;
}());
exports.WorkerItemType = WorkerItemType;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,245 @@
import { Processor, 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 { UniversalWorker } from "../WorkerHelper";
import { RectOptimizeMachine } from "./RectOptimizeWorker/RectOptimizeMachine";
/** 模块 新优化
*
* input 入参
*
* ProcessorModule<any, any>这里的any 可以自定义 根据组件需求
*/
export const RectOptimizeMachineModule: ProcessorModule<any, any> = {
moduleName: "RectOptimizeMachine",
moduleVersion: '20250714',
config: {
placeStyle: 1,
/** 总修边宽度 */
cutBoardBorder: 3,
cutKnifeGap: 1,
isDoubleFaceBlockFirst: true,
blockKnifeLineSpacing: 0,
isRectPlace: false,
isDoubleFaceBlockInRemain: true,
},
workerList: [],
setConfig(config) {
this.config = { ...this.config, ...config };
},
before(input) {
// console.log(`优化前要做的事情`, input);
},
// 会在处理器自动执行
/**
*
* @param input 输入数据
* @param next 下一个流程的函数
* @param context 上下文
* @returns
*/
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.config.cutBoardBorder
pm.cutKnifeGap = this.config.cutKnifeGap
/** 小板 */
let bans: xbang[] = []
// 实际开料大板的列表
let big_Bang: Big_bang[] = []
let big_BangSL: number[] = []
let border = this.config.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.config.isDoubleFaceBlockFirst // 双面加工排前面
let gap = this.config.blockKnifeLineSpacing
/** 这里要做个多线程 测试环境下 这部分有问题 暂时略过 */
const m = new RectOptimizeMachine()
const self = this
m.CallBack = async (best, fit, arg, info) => {
console.log('优化结果', pm, [best, fit, arg, info]);
let res={
moduleName:self.moduleName,
pm,
result: [best, fit, arg, info],
input,
context
}
self.onMessage(res)
}
const data = {
type: 'start',
data: [bans, big_Bang, big_BangSL, xyhcs, isDoubleFaceBlockFirst, gap, this.config.isRectPlace, this.config.isDoubleFaceBlockInRemain],
}
m.Start(bans, big_Bang, big_BangSL, xyhcs, isDoubleFaceBlockFirst, gap, this.config.isRectPlace, this.config.isDoubleFaceBlockInRemain)
return next ? next(input) : input;
},
after(result, input, context) {
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
},
]

View File

@@ -0,0 +1,130 @@
import { Processor, ProcessorModule } from "../../src/device";
import { ErrorInfo } from "../../src/device";
import { KLSC, YH_bang } from "./RectOptimizeWorker/bang";
/** 模块 开料顺序
*
* input 入参
*/
/** 开料顺序 */
export const AutoCalcCutOrder: ProcessorModule<any, any> = {
moduleName: "AutoCalcCutOrder",
moduleVersion: '20250714',
config: {
boardWidth: 0,
boardLength: 0,
placeStyle: 1,
},
setConfig(config) {
this.config = { ...this.config, ...config };
},
// 会在处理器自动执行
/**
*
* @param input 输入数据
* @param next 下一个流程的函数
* @param context 上下文
* @returns
*/
process(input, next, context) {
const { materialList } = input
for (const pm of materialList) {
for (const pb of pm.boardList) {
let selectBs = pb.blockList;
let beginId = 0;
const has0 = pb.blockList.filter(t => t.cutOrder == 0);
const has1 = pb.blockList.filter(t => t.cutOrder > 0);
const has2 = pb.blockList.filter(t => t.cutOrder < 0);
//有手动指定开料顺序的
if (has0.length > 0 && (has1.length + has2.length) > 0) {
selectBs = has0;
if (has1.length > 0) //开头的
{
const bs = has1.sort((a, b) => a.cutOrder - b.cutOrder);
for (const b of bs) {
beginId++;
b.cutOrder = beginId;
}
}
if (has2.length > 0) //结尾的
{
const bs = has2.sort((a, b) => a.cutOrder - b.cutOrder);
let endId = has0.length + has1.length;
for (const b of bs) {
endId++;
b.cutOrder = endId;
}
}
}
let bangs: YH_bang[] = [];
let blocks = new Array();
for (let i = 0; i < selectBs.length; i++) {
let block = selectBs[i];
let bangid = i + 1;
let x = block.placeX;
let y = block.placeY;
let pbg = block.placeLength;
let pbk = block.placeWidth;
blocks[bangid] = block;
bangs.push({
bangid,
line: 0,
pbg,
pbk,
x,
y,
ishb: false,
hb: [],
isbig: false,
isqg: false,
isgr: false,
gr: [],
grid: -1
});
}
let dt = pm.diameter + pm.cutKnifeGap;
let k = pb.width;
let g = pb.length;
let xdsc: KLSC = new KLSC(bangs, k, g, dt, 0, 0, 1);
// try {
// xdsc
// } catch (error) {
// console.log(error);
// }
let rt = xdsc.SCid;
// let rt = JSXDSC(bangs, dt, k, g);
if (rt.length < selectBs.length) return;
for (let i = 0; i < rt.length; i++) {
let bid = rt[i];
beginId++;
blocks[bid].cutOrder = beginId;
}
}
}
return next ? next(input) : input;
},
onError(error) {
console.error('出错了哦', error);
}
};

View File

@@ -0,0 +1,76 @@
import { Processor, ProcessorModule } from "../../src/device";
import { ErrorInfo } from "../../src/device";
/** 模块 检查异常板
*
* input 入参
*/
export const CheckBlocks: ProcessorModule<any, any> = {
moduleName: "CheckMaterial",
moduleVersion: '20250714',
config: {
minBlockWidth: 0,
minBlockThickness: 0,
},
setConfig(config) {
this.config = { ...this.config, ...config };
},
// 会在处理器自动执行
/**
*
* @param input 输入数据
* @param next 下一个流程的函数
* @param context 上下文
* @returns
*/
process(input, next, context) {
const { materialList, blockList } = input
const self = this;
let checkArr = checkBlocks(materialList, blockList)
if (checkArr.length > 0) {
const _errinfo: ErrorInfo = {
moduleName: this.moduleName,
moduleVersion: this.moduleVersion,
info: {
data: checkArr,
msg: '该订单内小板有异常'
}
}
this.onError(_errinfo)
}
function checkBlocks(materialList, blockList): any[] {
let allBlocks: any[] = []
for (let pm of materialList) {
let bList = blockList.filter(e => e.goodsId == pm.goodsId)
for (const pb of bList) {
if (pb.width < self.minBlockWidth) {
allBlocks.push(pb)
}
if (pb.thickness < self.minBlockThickness) {
allBlocks.push(pb)
}
}
}
return allBlocks
}
return next ? next(input) : input;
},
onError(error) {
console.error('出错了哦', error);
}
};

View File

@@ -0,0 +1,77 @@
import { Processor, ProcessorModule } from "../../src/device";
import { ErrorInfo } from "../../src/device";
/** 模块 检查是否 板材尺寸大于机台尺寸
*
* input 入参
*/
/** 检查是否 板材尺寸大于机台尺寸 */
export const CheckMaterial: ProcessorModule<any, any> = {
moduleName: "CheckMaterial",
moduleVersion: '20250714',
config: {
boardWidth: 0,
boardLength: 0,
placeStyle:1,
},
setConfig(config) {
this.config = { ...this.config, ...config };
},
// 会在处理器自动执行
/**
*
* @param input 输入数据
* @param next 下一个流程的函数
* @param context 上下文
* @returns
*/
process(input, next, context) {
const { materialList } = input
const self = this;
let checkArr = checkMetrial(materialList)
if (checkArr.length > 0) {
const _errinfo: ErrorInfo = {
moduleName: this.moduleName,
moduleVersion: this.moduleVersion,
info: {
data: checkArr,
msg: '该订单内大板有异常'
}
}
this.onError(_errinfo)
}
function checkMetrial(materialList): any[] {
let errPMs: any = []
if (self.placeStyle !== 1) {
for (let pm of materialList) {
if (pm.orgWidth > self.boardWidth || pm.orgLength > self.boardLength) {
// console.log('板材尺寸大于机台尺寸', PlaceStore.sysConfig)
errPMs.push(pm)
}
}
}
return errPMs
}
return next ? next(input) : input;
},
onError(error) {
console.error('出错了哦', error);
}
};

View File

@@ -0,0 +1,58 @@
import { Processor, ProcessorModule } from "../../src/device";
import { ErrorInfo } from "../../src/device";
/** 模块 开料顺序
*
* input 入参
*/
/** 开料顺序 */
export const AutoCalcCutOrder: ProcessorModule<any, any> = {
moduleName: "CheckMaterial",
moduleVersion: '20250714',
config: {
boardWidth: 0,
boardLength: 0,
placeStyle:1,
},
setConfig(config) {
this.config = { ...this.config, ...config };
},
// 会在处理器自动执行
/**
*
* @param input 输入数据
* @param next 下一个流程的函数
* @param context 上下文
* @returns
*/
process(input, next, context) {
const { materialList } = input
// if (pb.isLocked) return;
// let blocks = pb.blockList;
// if (blocks.length == 0) return;
// if (blocks.length == 1) {
// blocks[0].cutOrder = 1;
// }
// else {
// this.autoSortBlockNew(pm, pb);
// }
return next ? next(input) : input;
},
onError(error) {
console.error('出错了哦', error);
}
};

View File

@@ -0,0 +1,152 @@
import { Processor, ProcessorModule } from "../../src/device";
import { ErrorInfo } from "../../src/device";
import { BlockPlaceResult, BoardPlaceResult, BoardPosition, MaterialPlaceResult, PlaceStyle } from "../confClass";
/** 模块 处理优化源数据 数据处理 将优化数据转 为 MaterialPlaceResult
*
* input 入参
*/
export const HandleMaterialPlaceResult: ProcessorModule<any, any> = {
moduleName: "HandleMaterialPlaceResult",
moduleVersion: '20250714',
config: {
cutBoardBorder:3,
// 是否跟随大板定位
placeOriginByBoardLocation: true,
boardLocation: 0
},
setConfig(config) {
this.config = { ...this.config, ...config };
},
// 会在处理器自动执行
/**
*
* @param input 输入数据
* @param next 下一个流程的函数
* @param context 上下文
* @returns
*/
process(input, next, context) {
let {
bList, best, yl, pm, width, length
} = context.MaterialPlaceSource
let blocks = bList
let retData = new MaterialPlaceResult()
let boardCount = 0
let remainCount = 0
let border = this.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 = this.config.placeOriginByBoardLocation && (
this.config.boardLocation == BoardPosition.RIGHT_BOTTOM || this.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
console.log({ placeResult: retData, pm } )
let res = { module:this.moduleName, placeResult: retData, pm }
Reflect.set(context,'MaterialPlaceResult',res)
return next ? next(input) : input;
},
onError(error) {
console.error('出错了哦', error);
}
};

View File

@@ -0,0 +1,639 @@
import { Processor, ProcessorModule } from "../../src/device";
import { ErrorInfo } from "../../src/device";
import { BoardPosition, PlaceBlock, PlaceBoard, PlaceMaterial, PlaceStyle } from "../confClass";
import { ArrayExt } from "../handleAbility/common/ArrayExt";
/** 模块 检查是否 板材尺寸大于机台尺寸
*
* input 入参
*/
class Point {
/** 坐标x */
x: number
/** 坐标y */
y: number
constructor(x: number, y: number) {
this.x = x
this.y = y
}
}
/** 检查是否 板材尺寸大于机台尺寸 */
export const handlePlaceResultToPlaceMaterial: ProcessorModule<any, any> = {
moduleName: "handlePlaceResultToPlaceMaterial",
moduleVersion: '20250714',
config: {
boardWidth: 0,
boardLength: 0,
placeStyle: 1,
},
setConfig(config) {
this.config = { ...this.config, ...config };
},
// 会在处理器自动执行
/**
*
* @param input 输入数据
* @param next 下一个流程的函数
* @param context 上下文
* @returns
*/
process(input, next, context) {
// const { placeResult,pm } = input
let pm: PlaceMaterial = context.MaterialPlaceResult.pm
pm.tempBestPlaceResult = context.MaterialPlaceResult.placeResult
// 没发现优化结果
if (!pm.tempBestPlaceResult) {
let errInfo: ErrorInfo = {
moduleName: this.moduleName,
info: '没有优化数据'
}
return errInfo
}
let placeResult = pm.tempBestPlaceResult
let orgBoardList = pm.boardList
let dic: any = [] // 存放当前 优化的小板
pm.boardList = []
let boardId = 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 = boardId
pm.boardList.push(pb)
boardId++
}
}
}
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 = this.boardLocation
// 大板优化结果
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 = 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)
// 大板靠板翻转
this.turnPlacePosition(pb, locator)
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 {
this.resetPlaceStyle(block, block.placeStyle)
}
}
}
//【功能】 大板长边两侧 width 范围内 避免出现造型 DisPoseModelInBoardBorderWidth > 0 生效
// this.DisPoseModelInBoardBorder(
// pm,
// this.boardBorderModelRange,
// this.boardBorderModelModeToFace,
// this.boardBorderModelByMachine,
// this.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 = this.getMaterialSealEdge(pm.blockList)
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
let res = { module:this.moduleName, pm }
Reflect.set(context,this.moduleName,res)
return next ? next(input) : input;
},
onError(error) {
console.error('出错了哦', error);
},
/** 获得板件偏移值 */
getOffDis(block: PlaceBlock, placeStyle?: PlaceStyle): any {
// console.log('获得板件偏移值')
if (placeStyle == null || placeStyle == undefined) {
placeStyle = block.placeStyle
}
let expandSize: any = block.sizeExpand
let posOff = { x: 0, y: 0, left: 0, right: 0, top: 0, bottom: 0 }
if (expandSize) {
switch (placeStyle) {
case PlaceStyle.FRONT: // 正面
posOff.x = expandSize.left
posOff.y = expandSize.bottom
posOff.left = expandSize.left
posOff.right = expandSize.right
posOff.bottom = expandSize.bottom
posOff.top = expandSize.top
break
case PlaceStyle.FRONT_TURN_RIGHT: // 正面右转
posOff.x = expandSize.bottom
posOff.y = expandSize.right
posOff.left = expandSize.bottom
posOff.right = expandSize.top
posOff.bottom = expandSize.right
posOff.top = expandSize.left
break
case PlaceStyle.FRONT_TURN_BACK: // 正面后转
posOff.x = expandSize.right
posOff.y = expandSize.top
posOff.left = expandSize.right
posOff.right = expandSize.left
posOff.bottom = expandSize.top
posOff.top = expandSize.bottom
break
case PlaceStyle.FRONT_TURN_LEFT: // 正面左转
posOff.x = expandSize.top
posOff.y = expandSize.left
posOff.left = expandSize.top
posOff.right = expandSize.bottom
posOff.bottom = expandSize.left
posOff.top = expandSize.right
break
case PlaceStyle.BACK: // 反面
posOff.x = expandSize.right
posOff.y = expandSize.bottom
posOff.left = expandSize.right
posOff.right = expandSize.left
posOff.bottom = expandSize.bottom
posOff.top = expandSize.top
break
case PlaceStyle.BACK_TURN_RIGHT: // 反面右转
posOff.x = expandSize.bottom
posOff.y = expandSize.left
posOff.left = expandSize.bottom
posOff.right = expandSize.top
posOff.bottom = expandSize.left
posOff.top = expandSize.right
break
case PlaceStyle.BACK_TURN_BACK: // 反面后转
posOff.x = expandSize.left
posOff.y = expandSize.top
posOff.left = expandSize.left
posOff.right = expandSize.right
posOff.bottom = expandSize.top
posOff.top = expandSize.bottom
break
case PlaceStyle.BACK_TURN_LEFT: // 反面左转
posOff.x = expandSize.top
posOff.y = expandSize.right
posOff.left = expandSize.bottom
posOff.right = expandSize.bottom
posOff.bottom = expandSize.right
posOff.top = expandSize.left
break
default:
break
}
}
return posOff
},
/**翻转 */
turnPlacePosition(pb: PlaceBoard, newlocator: BoardPosition) {
if (this.placeOriginByBoardLocation == false)
return
if (pb.isAdnormal())
return // 余料板是余料板,不参与翻转
let width = pb.width
let length = pb.length
// RIGHT_BOTTOM, 靠板
if (newlocator == BoardPosition.RIGHT_BOTTOM) {
for (let block of pb.blockList) {
let x = width - block.placeX - block.placeWidth
let y = block.placeY
let placeStyle = this.getPlaceStyle_zy(block)
block.placeX = x
block.placeY = y
block.placeStyle = placeStyle
}
}
// RIGHT_TOP, 靠板
if (newlocator == BoardPosition.RIGHT_TOP) {
console.log('BoardPosition=BoardPosition.RIGHT_TOP')
for (let block of pb.blockList) {
let x = width - block.placeX - block.placeWidth
let y = length - block.placeLength - block.placeY
let placeStyle = this.getPlaceStyle_dj(block)
block.placeX = x
block.placeY = y
block.placeStyle = placeStyle
}
}
// 左上角, 靠板
if (newlocator == BoardPosition.LEFT_TOP) {
console.log('BoardPosition=BoardPosition.左上角')
for (let block of pb.blockList) {
let x = block.placeX
let y = length - block.placeLength - block.placeY
let placeStyle = this.getPlaceStyle_sx(block)
block.placeX = x
block.placeY = y
block.placeStyle = placeStyle
}
}
},
/** 板放置后重置placeWidth, placeLength, 封边, 正反面, 面孔, 造型等 */
resetPlaceStyle(_block: PlaceBlock, newStyle: PlaceStyle) {
let block = new PlaceBlock(_block)
block = { ..._block }
// console.debug('resetPlaceStyle test!!!',newStyle)
block.placeStyle = newStyle
// tryFix
let _width = block.cutWidth
let _lenth = block.cutLength
if (block.width > block.length) {
block.cutWidth = Math.max(_width, _lenth)
block.cutLength = Math.min(_width, _lenth)
} else {
block.cutWidth = Math.min(_width, _lenth)
block.cutLength = Math.max(_width, _lenth)
}
switch (newStyle) {
case PlaceStyle.FRONT: // 正面
block.placeWidth = block.cutWidth
block.placeLength = block.cutLength
block.placeSealLeft = block.sealLeft
block.placeSealRight = block.sealRight
block.placeSealTop = block.sealTop
block.placeSealBottom = block.sealBottom
block.holeCountSideLeft = block?.blockDetail?.holeCountLeft || 0
block.holeCountSideRight = block?.blockDetail?.holeCountRight || 0
block.holeCountSideTop = block?.blockDetail?.holeCountTop || 0
block.holeCountSideBottom = block?.blockDetail?.holeCountBottom || 0
block.placeDirection = '→'
block.placeDirection_Length = block.length > block.width - 0.001 ? '→' : '↓'
break
case PlaceStyle.FRONT_TURN_RIGHT: // 正面右转
block.placeWidth = block.cutLength
block.placeLength = block.cutWidth
block.placeSealLeft = block.sealBottom
block.placeSealRight = block.sealTop
block.placeSealTop = block.sealLeft
block.placeSealBottom = block.sealRight
block.holeCountSideLeft = block?.blockDetail?.holeCountBottom || 0
block.holeCountSideRight = block?.blockDetail?.holeCountTop || 0
block.holeCountSideTop = block?.blockDetail?.holeCountLeft || 0
block.holeCountSideBottom = block?.blockDetail?.holeCountRight || 0
block.placeDirection = '↓'
block.placeDirection_Length = block.length > block.width - 0.001 ? '↓' : '←'
break
case PlaceStyle.FRONT_TURN_BACK: // 正面后转
block.placeWidth = block.cutWidth
block.placeLength = block.cutLength
block.placeSealLeft = block.sealRight
block.placeSealRight = block.sealLeft
block.placeSealTop = block.sealBottom
block.placeSealBottom = block.sealTop
block.holeCountSideLeft = block?.blockDetail?.holeCountRight || 0
block.holeCountSideRight = block?.blockDetail?.holeCountLeft || 0
block.holeCountSideTop = block?.blockDetail?.holeCountBottom || 0
block.holeCountSideBottom = block?.blockDetail?.holeCountTop || 0
block.placeDirection = '←'
block.placeDirection_Length = block.length > block.width - 0.001 ? '←' : '↑'
break
case PlaceStyle.FRONT_TURN_LEFT: // 正面左转
block.placeWidth = block.cutLength
block.placeLength = block.cutWidth
block.placeSealLeft = block.sealTop
block.placeSealRight = block.sealBottom
block.placeSealTop = block.sealRight
block.placeSealBottom = block.sealLeft
block.holeCountSideLeft = block?.blockDetail?.holeCountTop || 0
block.holeCountSideRight = block?.blockDetail?.holeCountBottom || 0
block.holeCountSideTop = block?.blockDetail?.holeCountRight || 0
block.holeCountSideBottom = block?.blockDetail?.holeCountLeft || 0
block.placeDirection = '↑'
block.placeDirection_Length = block.length > block.width - 0.001 ? '↑' : '→'
break
case PlaceStyle.BACK: // 反面
block.placeWidth = block.cutWidth
block.placeLength = block.cutLength
block.placeSealLeft = block.sealRight
block.placeSealRight = block.sealLeft
block.placeSealTop = block.sealTop
block.placeSealBottom = block.sealBottom
block.holeCountSideLeft = block?.blockDetail?.holeCountRight || 0
block.holeCountSideRight = block?.blockDetail?.holeCountLeft || 0
block.holeCountSideTop = block?.blockDetail?.holeCountTop || 0
block.holeCountSideBottom = block?.blockDetail?.holeCountBottom || 0
block.placeDirection = '→'
block.placeDirection_Length = block.length > block.width - 0.001 ? '→' : '↑'
break
case PlaceStyle.BACK_TURN_RIGHT: // 反面右转
block.placeWidth = block.cutLength
block.placeLength = block.cutWidth
block.placeSealLeft = block.sealBottom
block.placeSealRight = block.sealTop
block.placeSealTop = block.sealRight
block.placeSealBottom = block.sealLeft
block.holeCountSideLeft = block?.blockDetail?.holeCountBottom || 0
block.holeCountSideRight = block?.blockDetail?.holeCountTop || 0
block.holeCountSideTop = block?.blockDetail?.holeCountRight || 0
block.holeCountSideBottom = block?.blockDetail?.holeCountLeft || 0
block.placeDirection = '↓'
block.placeDirection_Length = block.length > block.width - 0.001 ? '↓' : '→'
break
case PlaceStyle.BACK_TURN_BACK: // 反面后转
block.placeWidth = block.cutWidth
block.placeLength = block.cutLength
block.placeSealLeft = block.sealLeft
block.placeSealRight = block.sealRight
block.placeSealTop = block.sealTop
block.placeSealBottom = block.sealBottom
block.holeCountSideLeft = block?.blockDetail?.holeCountLeft || 0
block.holeCountSideRight = block?.blockDetail?.holeCountRight || 0
block.holeCountSideTop = block?.blockDetail?.holeCountTop || 0
block.holeCountSideBottom = block?.blockDetail?.holeCountBottom || 0
block.placeDirection = '←'
block.placeDirection_Length = block.length > block.width - 0.001 ? '←' : '↓'
break
case PlaceStyle.BACK_TURN_LEFT: // 反面左转
block.placeWidth = block.cutLength
block.placeLength = block.cutWidth
block.placeSealLeft = block.sealTop
block.placeSealRight = block.sealBottom
block.placeSealTop = block.sealLeft
block.placeSealBottom = block.sealRight
block.holeCountSideLeft = block?.blockDetail?.holeCountTop || 0
block.holeCountSideRight = block?.blockDetail?.holeCountBottom || 0
block.holeCountSideTop = block?.blockDetail?.holeCountLeft || 0
block.holeCountSideBottom = block?.blockDetail?.holeCountRight || 0
block.placeDirection = '↑'
block.placeDirection_Length = block.length > block.width - 0.001 ? '↑' : '←'
break
default:
break
}
this.resetDoFace_HoleModel(block)
},
resetDoFace_HoleModel(block: PlaceBlock) {
let isTurnOver = block.isTurnOver
if (block.blockDetail == null) {
console.error('resetDoFace_HoleModel error,with out blockDetail');
return
}
let orgMA = block.blockDetail.modelListFaceA
let orgMB = block.blockDetail.modelListFaceB
let orgMT = block.blockDetail.modelListThrough
let orgHA = block.blockDetail.holeListFaceA
let orgHB = block.blockDetail.holeListFaceB
let orgHT = block.blockDetail.holeListThrough
if (isTurnOver) {
block.modelListFaceA = orgMB.concat(orgMT);
block.modelListFaceB = orgMA;
block.holeListFaceA = orgHB.concat(orgHT);
block.holeListFaceB = orgHA;
}
else {
block.modelListFaceA = orgMA.concat(orgMT);
block.modelListFaceB = orgMB;
block.holeListFaceA = orgHA.concat(orgHT);;
block.holeListFaceB = orgHB;
}
//获取贴标位置
let p = this.getPlaceXYInBlock(block, block.blockDetail.labelPosX, block.blockDetail.labelPosY, false, false);
block.labelPosX = p.x;
block.labelPosY = p.y;
},
getPlaceXYInBlock(block: PlaceBlock, x: number, y: number, isSealed: boolean, isFaceB = false, preCutValueOff = null): Point {
let bwidth = block.cutWidth
let blength = block.cutLength
let x0: any = x
let y0: any = y
if (isSealed) // 已封边
{
bwidth = block.width
blength = block.length
x0 += block.offsetX
y0 += block.offsetY
}
if (!isSealed && preCutValueOff) // 没封边,且有封边
{
bwidth += preCutValueOff.w
blength += preCutValueOff.l
x0 += preCutValueOff.x
y0 += preCutValueOff.y
}
let _point: any = this.getPlacedPostionInBlock(block.placeStyle, bwidth, blength, x0, y0, isFaceB)
return _point
},
/** 获得翻转后的新坐标 */
getPlacedPostionInBlock(placeStyle: PlaceStyle, bwidth: number, blength: number, x0: number, y0: number, isFaceB: boolean): Point {
let posX = x0
let posY = y0
let placeWidth = bwidth
switch (placeStyle) {
case PlaceStyle.FRONT:
break
case PlaceStyle.FRONT_TURN_RIGHT:
posX = y0
posY = bwidth - x0
placeWidth = blength
break
case PlaceStyle.FRONT_TURN_BACK:
posX = bwidth - x0
posY = blength - y0
break
case PlaceStyle.FRONT_TURN_LEFT:
posX = blength - y0
posY = x0
placeWidth = blength
break
case PlaceStyle.BACK:
posX = bwidth - x0
posY = y0
break
case PlaceStyle.BACK_TURN_RIGHT:
posX = y0
posY = x0
placeWidth = blength
break
case PlaceStyle.BACK_TURN_BACK:
posX = x0
posY = blength - y0
break
case PlaceStyle.BACK_TURN_LEFT:
posX = blength - y0
posY = bwidth - x0
placeWidth = blength
break
default:
break
}
if (isFaceB) {
posX = placeWidth - posX
}
return new Point(posX, posY)
}
}

View File

@@ -0,0 +1,83 @@
import { Processor, ProcessorModule } from "../../src/device";
import { ErrorInfo } from "../../src/device";
import { FaceType, PlaceBlockDetail } from "../confClass";
// import { PolylineHelper } from "../handleAbility/common/LayoutEngine/PolylineHelper";
// import {PolylineHelper} from "../handleAbility/common/LayoutEngine/PolylineHelper.js"
/** 模块 造型轮廓(含封边),扣除封边, 变成开料坐标
* 有异常 要调整
* input 入参
*/
export const Init2VModel: ProcessorModule<any, any> = {
moduleName: "Init2VModel",
moduleVersion: '20250714',
config: {
},
setConfig(config) {
this.config = { ...this.config, ...config };
},
// 会在处理器自动执行
/**
*
* @param input 输入数据
* @param next 下一个流程的函数
* @param context 上下文
* @returns
*/
process(input, next, context) {
const { blockDetailList } = input
for (const bd of blockDetailList) {
init2VModel(bd);
}
function init2VModel(blockDetail: PlaceBlockDetail, isCNC = false) {
for (let model of blockDetail.models) {
if (!model.isVKnifeModel)
continue
let vModels: any = []
model.VLines = vModels
let isFaceB = model.face == FaceType.BACK
if (model.pointList.length < 1)
continue
let ps = model.pointList.map((t) => { return { x: t.pointX, y: t.pointY, bul: t.curve } })
let pl = PolylineHelper.create(ps)
if (model.VLines?.length > 0)
return // 已经分析了
model.VLines = []
for (let os of model.offsetList) {
let knife1 = isCNC ? null : this.getModelKnifeByName(os.name)
let knifeR = os.radius
let knifeId = knife1 ? knife1.knifeId : -1
try {
let vps_1 = PolylineHelper.getVModelPoints_offset(pl, os.offset, os.depth, os.angle)
let vLine = { isFaceB, name: os.name, value: os.offset, knife: knife1, knifeId, knifeRadius: knifeR, depth: os.depth, points: vps_1, offset: os }
vModels.push(vLine) // 偏移路径
model.VLines.push(vLine)
}
catch (err) {
console.log('v型刀走刀路径算法出错。' + err)
}
}
model.VLines = vModels
}
}
return next ? next(input) : input;
},
onError(error) {
console.error('出错了哦', error);
}
};

View File

@@ -0,0 +1,66 @@
import { Processor, ProcessorModule } from "../../src/device";
import { ErrorInfo } from "../../src/device";
import { PlaceBlockDetail } from "../confClass";
/** 模块 造型轮廓(含封边),扣除封边, 变成开料坐标
* !!!!!!!!! 有异常 要调整
* input 入参
*/
export const ResetModelContour: ProcessorModule<any, any> = {
moduleName: "ResetModelContour",
moduleVersion: '20250714',
config: {
},
setConfig(config) {
this.config = { ...this.config, ...config };
},
// 会在处理器自动执行
/**
*
* @param input 输入数据
* @param next 下一个流程的函数
* @param context 上下文
* @returns
*/
process(input, next, context) {
const { blockDetailList } = input
for (const bd of blockDetailList) {
let blockDetail = new PlaceBlockDetail(bd);
resetModelContour(blockDetail);
}
/** 造型轮廓(含封边),扣除封边, 变成开料坐标 */
function resetModelContour(bd: PlaceBlockDetail) {
let ox = bd.offsetX
let oy = bd.offsetY
for (let m of bd.models) {
if (m.hasContour()) {
let ptsArr = m.originModeling.outline.map(e => e.pts)
for (let pt of ptsArr) {
// 23.8.5 发现矩形的挖穿轮廓坐标是不含封边的
pt.x -= ox
pt.y -= oy
}
}
}
}
return next ? next(input) : input;
},
onError(error) {
console.error('出错了哦', error);
}
};

View File

@@ -0,0 +1,93 @@
import { Processor, ProcessorModule } from "../../src/device";
import { confItem, Knife, PlaceBlock, PlaceBlockDetail, PlaceMaterial, _knifeType } from "../confClass";
import { Big_bang, ComposingType, LineType, WorkerItemType, xbang } from "../handleAbility/RectOptimizeWorker/bang";
/** 模块 刀库
*
* input 入参
*/
/** 优化前的 刀库 */
export const ToolsModule: ProcessorModule<any, any> = {
moduleName: "RectOptimizeMachine",
moduleVersion: '20250714',
config: {
knifeList: [],
},
setConfig(config) {
this.config = { ...this.config, ...config };
},
// 会在处理器自动执行
/**
*
* @param input 输入数据
* @param next 下一个流程的函数
* @param context 上下文
* @returns
*/
process(input, next, context) {
// 将刀库添加到上下文
Reflect.set(context, 'knifeList', this.config.knifeList)
// 将刀具查询方法加到上下文
Reflect.set(context, 'getKnifeByParams', getKnifeByParams)
/** 通用 找刀具 根据查询条件 */
function getKnifeByParams(params: _knifeType, knifeList: Knife[]) {
let knife: Knife | null = null
if (params) {
let tempKnifeList: Knife[] = [...knifeList] // []
let keys = Object.keys(params)
if (keys.length > 0) {
keys.forEach(key => {
if (Array.isArray(params[key]) && key == 'ability') {
// 进来的应该是ability 是数组 判断刀的能力
for (const arrItem of params[key]) {
let _knifeList = knifeList.filter(e => e.ability.includes(arrItem))
_knifeList.forEach(k => {
if (!this.KnifeIsInKnifeList(k, tempKnifeList)) {
tempKnifeList.push(k)
}
})
}
} else if (['string', 'number'].includes(typeof (params[key]))) {
if (params && params[key] && typeof (params[key]) == 'number') {
if (key == 'length') {
tempKnifeList = tempKnifeList.filter(e => e[key] >= params[key])
} else {
tempKnifeList = tempKnifeList.filter(e => e[key] == params[key])
}
}
}
});
if (tempKnifeList.length > 0) {
knife = tempKnifeList[0]
}
} else {
console.log('传入的查询条件 没有参数')
}
}
return knife
}
return next ? next(input) : input;
},
onError(error) {
console.log('出错了哦', error);
}
};