feat: 提交
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { FaceType, PlaceBlock, PlaceBlockDetail, PlaceBorderContour, PlaceMaterial, PlaceStyle, SizeExpand } from "../confClass"
|
import { FaceType, PlaceBlock, PlaceBlockDetail, PlaceBorderContour, PlaceMaterial, PlaceStyle, SizeExpand } from "../confClass"
|
||||||
import { BlockDetailHelperBase } from "../handleAbility/blockDetailHelperBase"
|
import { BlockDetailHelperBase } from "../handleAbility/blockDetailHelperBase"
|
||||||
import { PolylineHelper } from "../handleAbility/common/LayoutEngine/PolylineHelper"
|
// import { PolylineHelper } from "../handleAbility/common/LayoutEngine/PolylineHelper"
|
||||||
import { KnifeHelper } from "../handleAbility/knifeHelper"
|
import { KnifeHelper } from "../handleAbility/knifeHelper"
|
||||||
|
|
||||||
|
|
||||||
|
@@ -237,27 +237,7 @@ export enum KnifeType {
|
|||||||
BLADE = 5
|
BLADE = 5
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 刀功能:
|
|
||||||
** 1-CUT开料/切割 2-PULLING_GROOVE拉槽 3-MILLING_MODEL铣型 4-MILLING_HOLE铣孔
|
|
||||||
** 5-DRILL_HOLE钻孔 6-RAMINO拉米诺 7-EASY_FASTEN乐扣 8-T_TYPE T型 */
|
|
||||||
export enum AbilityType {
|
|
||||||
/** 1开料/切割 */
|
|
||||||
CUT = 1,
|
|
||||||
/** 2拉槽 */
|
|
||||||
PULLING_GROOVE = 2,
|
|
||||||
/** 3铣型 */
|
|
||||||
MILLING_MODEL = 3,
|
|
||||||
/** 4铣孔 */
|
|
||||||
MILLING_HOLE = 4,
|
|
||||||
/** 5钻孔 */
|
|
||||||
DRILL_HOLE = 5,
|
|
||||||
/** 6拉米诺 */
|
|
||||||
RAMINO = 6,
|
|
||||||
/** 7乐扣 */
|
|
||||||
EASY_FASTEN = 7,
|
|
||||||
/** 8T型 */
|
|
||||||
T_TYPE = 8
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 枚举 坐标轴类型 */
|
/** 枚举 坐标轴类型 */
|
||||||
export enum AxisType {
|
export enum AxisType {
|
||||||
@@ -511,13 +491,15 @@ export class PlaceBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 左侧孔数 HoleCount_Left */
|
/** 左侧孔数 HoleCount_Left */
|
||||||
holeCountLeft() { return this.blockDetail && this.blockDetail.holeCountLeft }
|
holeCountLeft() { return this?.blockDetail?.holeCountLeft || 0 }
|
||||||
/** 右侧孔数 HoleCount_Right */
|
/** 右侧孔数 HoleCount_Right */
|
||||||
holeCountRight() { return this.blockDetail && this.blockDetail.holeCountRight }
|
holeCountRight() {
|
||||||
|
return this?.blockDetail?.holeCountRight || 0
|
||||||
|
}
|
||||||
/** 侧孔数 HoleCount_Upper */
|
/** 侧孔数 HoleCount_Upper */
|
||||||
holeCountTop() { return this.blockDetail && this.blockDetail.holeCountTop }
|
holeCountTop() { return this?.blockDetail?.holeCountTop || 0 }
|
||||||
/** 侧孔数 HoleCount_Under */
|
/** 侧孔数 HoleCount_Under */
|
||||||
holeCountBottom() { return this.blockDetail && this.blockDetail.holeCountBottom }
|
holeCountBottom() { return this?.blockDetail?.holeCountBottom || 0 }
|
||||||
/** 正面造型数 */
|
/** 正面造型数 */
|
||||||
modelCountFront(): number {
|
modelCountFront(): number {
|
||||||
return this.blockDetail && this.blockDetail.modelCountFront || 0
|
return this.blockDetail && this.blockDetail.modelCountFront || 0
|
||||||
|
@@ -5,7 +5,10 @@ import { ToolsModule } from "../moduleManager/module_tools";
|
|||||||
import { CheckMaterial } from "../moduleManager/module_checkMaterial";
|
import { CheckMaterial } from "../moduleManager/module_checkMaterial";
|
||||||
import { CheckBlocks } from "../moduleManager/module_checkBlocks";
|
import { CheckBlocks } from "../moduleManager/module_checkBlocks";
|
||||||
import { ResetModelContour } from "../moduleManager/module_resetModelContour";
|
import { ResetModelContour } from "../moduleManager/module_resetModelContour";
|
||||||
import { Init2VModel } from "../moduleManager/module_init2VModel";
|
import { AutoCalcCutOrder } from "../moduleManager/module_autoCalcCutOrder";
|
||||||
|
import { HandleMaterialPlaceResult } from "../moduleManager/module_handleMaterialPlaceResult";
|
||||||
|
import { handlePlaceResultToPlaceMaterial } from "../moduleManager/module_handlePlaceResultToPlaceMaterial";
|
||||||
|
// import { Init2VModel } from "../moduleManager/module_init2VModel";
|
||||||
/**
|
/**
|
||||||
* demo 开料机处理器
|
* demo 开料机处理器
|
||||||
*
|
*
|
||||||
@@ -15,6 +18,7 @@ export class demoHandleGroupCutting {
|
|||||||
processorName = "cutting"
|
processorName = "cutting"
|
||||||
processor: StepControllerProcessor<any, any>
|
processor: StepControllerProcessor<any, any>
|
||||||
constructor() {
|
constructor() {
|
||||||
|
// 主线程
|
||||||
const demoCallbackModule: ProcessorModule<any, any> = {
|
const demoCallbackModule: ProcessorModule<any, any> = {
|
||||||
moduleName: "callbackStyle",
|
moduleName: "callbackStyle",
|
||||||
process(input, next, context) {
|
process(input, next, context) {
|
||||||
@@ -41,28 +45,67 @@ export class demoHandleGroupCutting {
|
|||||||
|
|
||||||
this.processor = new StepControllerProcessor<any, any>();
|
this.processor = new StepControllerProcessor<any, any>();
|
||||||
this.processor.setOnMessageFunc(this.getMessageByModules)
|
this.processor.setOnMessageFunc(this.getMessageByModules)
|
||||||
|
|
||||||
this.processor.use([
|
this.processor.use([
|
||||||
demoCallbackModule,
|
// demoCallbackModule,
|
||||||
ToolsModule, // 刀库
|
ToolsModule, // 刀库
|
||||||
CheckMaterial,
|
// CheckMaterial,
|
||||||
CheckBlocks,
|
// CheckBlocks,
|
||||||
ResetModelContour,
|
// ResetModelContour,
|
||||||
Init2VModel,
|
// Init2VModel,
|
||||||
RectOptimizeMachineModule, // 优化
|
RectOptimizeMachineModule, // 优化
|
||||||
{
|
// {
|
||||||
moduleName: "final",
|
// moduleName: "final",
|
||||||
process(input, next) {
|
// process(input, next,context) {
|
||||||
// 不调用 next,终止流程
|
// // 不调用 next,终止流程
|
||||||
console.log('结束了')
|
// console.log('结束了')
|
||||||
return next(input);
|
// return next(input);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// 获取到模块的消息
|
||||||
getMessageByModules(data) {
|
async getMessageByModules(data) {
|
||||||
console.log('getMessageByModules', data);
|
console.log('getMessageByModules', data);
|
||||||
|
this.processor = new StepControllerProcessor<any, any>();
|
||||||
|
switch (data.moduleName) {
|
||||||
|
// 处理优化模块的消息
|
||||||
|
case 'RectOptimizeMachine':
|
||||||
|
|
||||||
|
// 处理优化数据
|
||||||
|
this.processor.use([HandleMaterialPlaceResult,
|
||||||
|
handlePlaceResultToPlaceMaterial,
|
||||||
|
AutoCalcCutOrder])
|
||||||
|
this.processor.setOnMessageFunc(this.getMessageByModules)
|
||||||
|
let bList = []
|
||||||
|
data.pm.blockList.forEach(b => {
|
||||||
|
bList[b.blockNo] = b
|
||||||
|
});
|
||||||
|
let params = {
|
||||||
|
bList: bList,
|
||||||
|
best:data.result[0],
|
||||||
|
yl:data.result[1],
|
||||||
|
pm:data.pm,
|
||||||
|
width:data.pm.width,
|
||||||
|
length:data.pm.length
|
||||||
|
}
|
||||||
|
let context = {
|
||||||
|
MaterialPlaceSource:params
|
||||||
|
}
|
||||||
|
let res = await this.processor.process(data.input,context)
|
||||||
|
|
||||||
|
console.log(res);
|
||||||
|
|
||||||
|
// this.processor.use(handlePlaceResultToPlaceMaterial)
|
||||||
|
// let params1 = res
|
||||||
|
// let res1 = await this.processor.process(res)
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
import { ConfigBase } from "../src/base";
|
import { ConfigBase } from "../src";
|
||||||
import { ParserBase } from "../src/parsers";
|
import { ParserBase } from "../src/parsers";
|
||||||
import { _knifeType, CodeParams } from "./confClass";
|
import { _knifeType, CodeParams } from "./confClass";
|
||||||
import { knifeData, knifeData1, knifeData2 } from "./demoKnives";
|
import { knifeData, knifeData1, knifeData2 } from "./demoKnives";
|
||||||
|
1752
samples/moduleManager/RectOptimizeWorker/RectOptimizeMachine.js
Normal file
1752
samples/moduleManager/RectOptimizeWorker/RectOptimizeMachine.js
Normal file
File diff suppressed because it is too large
Load Diff
1746
samples/moduleManager/RectOptimizeWorker/RectOptimizeMachine.ts
Normal file
1746
samples/moduleManager/RectOptimizeWorker/RectOptimizeMachine.ts
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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 = {};
|
@@ -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)
|
60
samples/moduleManager/RectOptimizeWorker/bang.js
Normal file
60
samples/moduleManager/RectOptimizeWorker/bang.js
Normal 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;
|
1605
samples/moduleManager/RectOptimizeWorker/bang.ts
Normal file
1605
samples/moduleManager/RectOptimizeWorker/bang.ts
Normal file
File diff suppressed because it is too large
Load Diff
245
samples/moduleManager/module_RectOptimizeMachine.ts
Normal file
245
samples/moduleManager/module_RectOptimizeMachine.ts
Normal 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
|
||||||
|
},
|
||||||
|
]
|
130
samples/moduleManager/module_autoCalcCutOrder.ts
Normal file
130
samples/moduleManager/module_autoCalcCutOrder.ts
Normal 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
76
samples/moduleManager/module_checkBlocks.ts
Normal file
76
samples/moduleManager/module_checkBlocks.ts
Normal 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
77
samples/moduleManager/module_checkMaterial.ts
Normal file
77
samples/moduleManager/module_checkMaterial.ts
Normal 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
58
samples/moduleManager/module_demoCallback.ts
Normal file
58
samples/moduleManager/module_demoCallback.ts
Normal 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
152
samples/moduleManager/module_handleMaterialPlaceResult.ts
Normal file
152
samples/moduleManager/module_handleMaterialPlaceResult.ts
Normal 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
639
samples/moduleManager/module_handlePlaceResultToPlaceMaterial.ts
Normal file
639
samples/moduleManager/module_handlePlaceResultToPlaceMaterial.ts
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
83
samples/moduleManager/module_init2VModel.ts
Normal file
83
samples/moduleManager/module_init2VModel.ts
Normal 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
66
samples/moduleManager/module_resetModelContour.ts
Normal file
66
samples/moduleManager/module_resetModelContour.ts
Normal 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
93
samples/moduleManager/module_tools.ts
Normal file
93
samples/moduleManager/module_tools.ts
Normal 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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@@ -3,7 +3,7 @@ import { error } from "console";
|
|||||||
// 回调函数类型定义
|
// 回调函数类型定义
|
||||||
type ProcessCallback<T, R> = (
|
type ProcessCallback<T, R> = (
|
||||||
input: T,
|
input: T,
|
||||||
next: (input: T) => R | Promise<R>,
|
next?: (input: T) => R | Promise<R>,
|
||||||
context?: any
|
context?: any
|
||||||
) => R | Promise<R>;
|
) => R | Promise<R>;
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ type ProcessCallback<T, R> = (
|
|||||||
type ModuleConfig = Record<string, any>;
|
type ModuleConfig = Record<string, any>;
|
||||||
|
|
||||||
// 回调函数类型
|
// 回调函数类型
|
||||||
type ModuleCallback<T, R> = (result: R, input?: T) => void | Promise<void>;
|
type ModuleCallback<T, R> = (result: R, input?: T,context?:any) => void | Promise<void>;
|
||||||
|
|
||||||
export interface ErrorInfo {
|
export interface ErrorInfo {
|
||||||
moduleName?: string
|
moduleName?: string
|
||||||
@@ -56,8 +56,8 @@ export interface ProcessorModuleBase<T, R> {
|
|||||||
// 主处理函数(可回调)
|
// 主处理函数(可回调)
|
||||||
process?: ProcessCallback<T, R>;
|
process?: ProcessCallback<T, R>;
|
||||||
|
|
||||||
// 直接是处理函数(无回调)
|
// // 直接是处理函数(无回调)
|
||||||
handle?: (input: T, next?: (input: T) => R | Promise<R>, context?: Record<string, any>) => R | Promise<R>;
|
// handle?: (input: T, next?: (input: T) => R | Promise<R>, context?: Record<string, any>) => R | Promise<R>;
|
||||||
|
|
||||||
// 模块名称(用于标识和排序)
|
// 模块名称(用于标识和排序)
|
||||||
moduleName?: string;
|
moduleName?: string;
|
||||||
@@ -65,25 +65,25 @@ export interface ProcessorModuleBase<T, R> {
|
|||||||
moduleVersion?: string
|
moduleVersion?: string
|
||||||
// 模块配置
|
// 模块配置
|
||||||
config?: ModuleConfig;
|
config?: ModuleConfig;
|
||||||
// 多线程列表
|
// // 多线程列表
|
||||||
workerList?: any[]
|
// workerList?: any[]
|
||||||
// 获取配置列表
|
// 获取配置列表
|
||||||
getConfigList?: () => any[]
|
getConfigList?: () => any[]
|
||||||
// 设置配置的方法
|
// 设置配置的方法
|
||||||
setConfig?: (config: ModuleConfig) => void;
|
setConfig?: (config: ModuleConfig) => void;
|
||||||
|
|
||||||
// 前置回调(在模块处理前执行)
|
// // 前置回调(在模块处理前执行)
|
||||||
before?: ModuleCallback<T, R>;
|
// before?: ModuleCallback<T, R>;
|
||||||
|
|
||||||
// 后置回调(在模块处理后执行)
|
// // 后置回调(在模块处理后执行)
|
||||||
after?: ModuleCallback<T, R>;
|
// after?: ModuleCallback<T, R>;
|
||||||
|
|
||||||
// 错误处理回调
|
// 错误处理回调
|
||||||
onError?: (error: unknown, input?: T) => void | Promise<void>;
|
onError?: (error: unknown, input?: T) => void | Promise<void>;
|
||||||
|
|
||||||
// 消息传递 模块将数据传给处理器
|
// 消息传递 模块将数据传给处理器
|
||||||
onMessage?: Function//(data:unknown) => void | Promise<void>;
|
onMessage?: Function//(data:unknown) => void | Promise<void>;
|
||||||
// [key: string]:any
|
[key: string]:any
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 支持自定义函数 */
|
/** 支持自定义函数 */
|
||||||
@@ -211,7 +211,7 @@ export class StepControllerProcessor<T, R> implements Processor<T, R> {
|
|||||||
let str = log.map(e => {
|
let str = log.map(e => {
|
||||||
let s = '模块:' + e.moduleName
|
let s = '模块:' + e.moduleName
|
||||||
if (e.configKey) {
|
if (e.configKey) {
|
||||||
s = s + ',' + e.configKey
|
s = s + '-' + e.configKey
|
||||||
}
|
}
|
||||||
s = s + ',' + e.info + ';'
|
s = s + ',' + e.info + ';'
|
||||||
return s
|
return s
|
||||||
@@ -292,7 +292,7 @@ export class StepControllerProcessor<T, R> implements Processor<T, R> {
|
|||||||
|
|
||||||
// 执行后置回调
|
// 执行后置回调
|
||||||
if (module.after) {
|
if (module.after) {
|
||||||
await module.after(result, input);
|
await module.after(result, input,context);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -306,18 +306,26 @@ export class StepControllerProcessor<T, R> implements Processor<T, R> {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async process(input: T): Promise<R> {
|
|
||||||
|
private async executeModuleByModuleName(moduleName:string,input){
|
||||||
|
let module =this.modulesMap.get(moduleName)
|
||||||
|
|
||||||
|
return module.process(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
async process(input: T,_context?:Record<string, any>): Promise<R> {
|
||||||
if (this.modules.length === 0) {
|
if (this.modules.length === 0) {
|
||||||
throw new Error("No modules registered");
|
throw new Error("No modules registered");
|
||||||
}
|
}
|
||||||
|
|
||||||
let currentIndex = 0;
|
let currentIndex = 0;
|
||||||
const modules = this.modules;
|
const modules = this.modules;
|
||||||
const context: Record<string, any> = {};
|
const context: Record<string, any> = {..._context};
|
||||||
|
|
||||||
const executeNext = async (currentInput: T): Promise<R> => {
|
const executeNext = async (currentInput: T): Promise<R> => {
|
||||||
const currentModule = modules[currentIndex++];
|
const currentModule = modules[currentIndex++];
|
||||||
if (!currentModule) {
|
if (!currentModule) {
|
||||||
|
console.log('执行结束,上下文',context);
|
||||||
return currentInput as unknown as R;
|
return currentInput as unknown as R;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
221
src/paser.test.ts
Normal file
221
src/paser.test.ts
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
import { describe, it, expect, test } from 'vitest';
|
||||||
|
import { DemoParser } from '../samples/demoParser';
|
||||||
|
// import { ProcessorModule, StepControllerProcessor } from '../src/device';
|
||||||
|
import { ProcessorManager, StepControllerProcessor } from '../src/device';
|
||||||
|
import { demoHandleGroupCutting } from '../samples/demoDatahandle/demoDataHandle1';
|
||||||
|
import testJson from "./test.json"
|
||||||
|
import { RectOptimizeMachineModule } from '../samples/moduleManager/module_RectOptimizeMachine';
|
||||||
|
// import { Worker, parentPort } from 'worker_threads';
|
||||||
|
// import { UniversalWorker } from '../samples/WorkerHelper';
|
||||||
|
|
||||||
|
|
||||||
|
// 在测试文件中直接使用 console.log 或 debugger 语句
|
||||||
|
test('demoParser', () => {
|
||||||
|
// expect(1 + 1).toBe(2);
|
||||||
|
const text = `FSTART
|
||||||
|
TD 5
|
||||||
|
G0 X100 Y100 Z10 F8000
|
||||||
|
g0 x100 y100 z18 f8000
|
||||||
|
g2 x120 y120 z18 R20 f8000
|
||||||
|
g3 x100 y100 z18 i20 j0 f8000
|
||||||
|
TN T2
|
||||||
|
FEND
|
||||||
|
`
|
||||||
|
const demoParser = new DemoParser();
|
||||||
|
const result = demoParser.execTest(text);
|
||||||
|
console.log(result);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('dataHandle', async () => {
|
||||||
|
const sysConfig = {
|
||||||
|
placeStyle: 1,
|
||||||
|
boardWidth: 2440,
|
||||||
|
boardLength: 1220,
|
||||||
|
cutBoardBorder:3,
|
||||||
|
cutKnifeGap:1,
|
||||||
|
isDoubleFaceBlockFirst:true,
|
||||||
|
// 测试刀库数据
|
||||||
|
knifeList: [knifeData, knifeData1, knifeData2]
|
||||||
|
|
||||||
|
}
|
||||||
|
const json = testJson
|
||||||
|
// 创建处理器集合
|
||||||
|
const processorManager = new ProcessorManager<any, any>();
|
||||||
|
// 这里省略了 选择处理器的环节 --这里选了demo开料机
|
||||||
|
const cuttingHandle = new demoHandleGroupCutting()
|
||||||
|
// 注册处理器
|
||||||
|
processorManager.registerProcessor(cuttingHandle.processorName, cuttingHandle.processor)
|
||||||
|
// 使用XX处理器 会返回激活【正在使用】的 处理器
|
||||||
|
let processor = processorManager.useProcessor(cuttingHandle.processorName)
|
||||||
|
// 或者 这样 获取 正在使用的处理器 注:若未执行useProcessor 将会返回 undefind
|
||||||
|
// processor = processorManager.getCurrentProcessor()
|
||||||
|
/** 处理器配置加载 */
|
||||||
|
processor.updateModuleConfig(sysConfig)
|
||||||
|
// 方式1
|
||||||
|
const res = await processor.process(json)
|
||||||
|
console.log('处理器所有流程都结束了', res);
|
||||||
|
})
|
||||||
|
test('Module Test',async()=>{
|
||||||
|
//测试 模块
|
||||||
|
// 配置项
|
||||||
|
const sysConfig = {
|
||||||
|
placeStyle: 1,
|
||||||
|
boardWidth: 2440,
|
||||||
|
boardLength: 1220,
|
||||||
|
// 测试刀库数据
|
||||||
|
knifeList: [knifeData, knifeData1, knifeData2]
|
||||||
|
|
||||||
|
}
|
||||||
|
// 测试数据
|
||||||
|
const json = testJson
|
||||||
|
// 处理器集合 的管理器
|
||||||
|
const processorManager = new ProcessorManager<any, any>();
|
||||||
|
// 处理器的管理器
|
||||||
|
const stepManager = new StepControllerProcessor<any, any>();
|
||||||
|
// 处理器 要调用的模块 可设置多个
|
||||||
|
stepManager.use([RectOptimizeMachineModule])
|
||||||
|
stepManager.setOnMessageFunc(callBack)
|
||||||
|
function callBack(data){
|
||||||
|
console.log('数据回调,这里测试优化',)
|
||||||
|
}
|
||||||
|
//
|
||||||
|
let processName = 'testRectOptimize'
|
||||||
|
processorManager.registerProcessor(processName,stepManager)
|
||||||
|
processorManager.useProcessor(processName,)
|
||||||
|
})
|
||||||
|
|
||||||
|
/** demo 刀具数据 */
|
||||||
|
export const knifeData = {
|
||||||
|
"isEnabled": true,
|
||||||
|
"axleId": 2,
|
||||||
|
"knifeId": 2,
|
||||||
|
"processFace": "",
|
||||||
|
"knifeName": "T1",
|
||||||
|
"knifeType": 3,
|
||||||
|
"ability": [
|
||||||
|
5
|
||||||
|
],
|
||||||
|
"diameter": 5,
|
||||||
|
"length": 20,
|
||||||
|
"sawThiness": 7,
|
||||||
|
"sawDirection": 2,
|
||||||
|
"processDirection": 4,
|
||||||
|
"speed": 0,
|
||||||
|
"stepDepth": 0,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"offsetZ": 0,
|
||||||
|
"baseX": 0,
|
||||||
|
"baseY": 0,
|
||||||
|
"isModularDrill": false,
|
||||||
|
"isPreStartEnabled": false,
|
||||||
|
"preStartAheadActionCount": 5,
|
||||||
|
"isPreStartToolChangeDelay": false,
|
||||||
|
"preStartToolChangeDelayCode": "",
|
||||||
|
"isAxisStartCodePostpost": false,
|
||||||
|
"isAxisStopCodePrepose": false,
|
||||||
|
"drillGroupCode": "",
|
||||||
|
"axisStartCode": "M03 S18000\n",
|
||||||
|
"knifeStartCode": `M06 T1\nG43 H1\n`,
|
||||||
|
"drillGroupStartCode": "T1",
|
||||||
|
"drillGroupEndCode": "",
|
||||||
|
"knifeStopCode": "",
|
||||||
|
"axisStopCode": "M05\n",
|
||||||
|
"preStartActionDeferCode": "",
|
||||||
|
"useHolesGroupKnife": false,
|
||||||
|
"preStartActionStepsLimit": "",
|
||||||
|
"knifeNo": "",
|
||||||
|
"editable": true,
|
||||||
|
"isDefaultCutKnife": false,
|
||||||
|
"isPreStartChangeKnifeDefer": false
|
||||||
|
}
|
||||||
|
export const knifeData1 = {
|
||||||
|
"isEnabled": true,
|
||||||
|
"axleId": 2,
|
||||||
|
"knifeId": 2,
|
||||||
|
"processFace": "",
|
||||||
|
"knifeName": "T2",
|
||||||
|
"knifeType": 3,
|
||||||
|
"ability": [
|
||||||
|
5
|
||||||
|
],
|
||||||
|
"diameter": 6,
|
||||||
|
"length": 20,
|
||||||
|
"sawThiness": 7,
|
||||||
|
"sawDirection": 2,
|
||||||
|
"processDirection": 4,
|
||||||
|
"speed": 0,
|
||||||
|
"stepDepth": 0,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"offsetZ": 0,
|
||||||
|
"baseX": 0,
|
||||||
|
"baseY": 0,
|
||||||
|
"isModularDrill": false,
|
||||||
|
"isPreStartEnabled": false,
|
||||||
|
"preStartAheadActionCount": 5,
|
||||||
|
"isPreStartToolChangeDelay": false,
|
||||||
|
"preStartToolChangeDelayCode": "",
|
||||||
|
"isAxisStartCodePostpost": false,
|
||||||
|
"isAxisStopCodePrepose": false,
|
||||||
|
"drillGroupCode": "",
|
||||||
|
"axisStartCode": "M03 S18000\n",
|
||||||
|
"knifeStartCode": `M06 T2\nG43 H2\n`,
|
||||||
|
"drillGroupStartCode": "T2",
|
||||||
|
"drillGroupEndCode": "",
|
||||||
|
"knifeStopCode": "",
|
||||||
|
"axisStopCode": "M05\n",
|
||||||
|
"preStartActionDeferCode": "",
|
||||||
|
"useHolesGroupKnife": false,
|
||||||
|
"preStartActionStepsLimit": "",
|
||||||
|
"knifeNo": "",
|
||||||
|
"editable": true,
|
||||||
|
"isDefaultCutKnife": false,
|
||||||
|
"isPreStartChangeKnifeDefer": false
|
||||||
|
}
|
||||||
|
export const knifeData2 = {
|
||||||
|
"isEnabled": true,
|
||||||
|
"axleId": 2,
|
||||||
|
"knifeId": 2,
|
||||||
|
"processFace": "",
|
||||||
|
"knifeName": "T3",
|
||||||
|
"knifeType": 3,
|
||||||
|
"ability": [
|
||||||
|
5
|
||||||
|
],
|
||||||
|
"diameter": 6,
|
||||||
|
"length": 20,
|
||||||
|
"sawThiness": 7,
|
||||||
|
"sawDirection": 2,
|
||||||
|
"processDirection": 4,
|
||||||
|
"speed": 0,
|
||||||
|
"stepDepth": 0,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"offsetZ": 0,
|
||||||
|
"baseX": 0,
|
||||||
|
"baseY": 0,
|
||||||
|
"isModularDrill": false,
|
||||||
|
"isPreStartEnabled": false,
|
||||||
|
"preStartAheadActionCount": 5,
|
||||||
|
"isPreStartToolChangeDelay": false,
|
||||||
|
"preStartToolChangeDelayCode": "",
|
||||||
|
"isAxisStartCodePostpost": false,
|
||||||
|
"isAxisStopCodePrepose": false,
|
||||||
|
"drillGroupCode": "",
|
||||||
|
|
||||||
|
"axisStartCode": "M03 S18000\n",
|
||||||
|
"knifeStartCode": `M06 T2\nG43 H2\n`,
|
||||||
|
"drillGroupStartCode": "T3",
|
||||||
|
"drillGroupEndCode": "",
|
||||||
|
"knifeStopCode": "",
|
||||||
|
"axisStopCode": "M05\n",
|
||||||
|
|
||||||
|
"preStartActionDeferCode": "",
|
||||||
|
"useHolesGroupKnife": false,
|
||||||
|
"preStartActionStepsLimit": "",
|
||||||
|
"knifeNo": "",
|
||||||
|
"editable": true,
|
||||||
|
"isDefaultCutKnife": false,
|
||||||
|
"isPreStartChangeKnifeDefer": false
|
||||||
|
}
|
29451
src/test.json
Normal file
29451
src/test.json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user