Files
imes-modelProcessPoints/src/processors/modelProcessPoints/modelProcessPoints.ts
2025-08-11 09:36:23 +08:00

542 lines
18 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { ConfigBase, ProcessorBase, ProcessorContext } from "cut-abstractions";
/**
* 获取造型在开料大板的坐标
*
* 输入的造型数据为 要处理的造型数据
*/
export class ModelProcessPointsProc extends ProcessorBase<ModelProcessPointsInput, ModelProcessPointsOutput, ModelProcessPointsProcConfig> {
get name(): string {
return 'ModelProcessPoints';
}
get version(): string {
return '1.0.0';
}
exec(context: ProcessorContext<ModelProcessPointsInput, ModelProcessPointsOutput, ModelProcessPointsProcConfig>): Promise<void> | void {
return new Promise(async (resolve, reject) => {
try {
if (context.input) {
if (context.input.block) {
// if (Array.isArray(context.input.block.models) && context.input.block.models.length > 0) {
/** 板件的坐标X */
let placeX = context.input.block.x
/** 板件的坐标Y */
let placeY = context.input.block.y
let output: ModelProcessPointsOutput = {
block: {
id: context.input.block.id,
positionType: context.input.block.positionType || 0,
models: [],
width: context.input.block.width,
length: context.input.block.length,
offsetInfo: context.input.block.offsetInfo
}
}
/**
* 提要:
* 1、这里的造型数据 都是 基于板件(小板)的正面的点阵数据
* 2、坐标转换 依据2个要素进行转换 【板件(小板)的优化坐标】 和 【板件(小板)的放置方式】
*
* 先处理放置方式 在处理 优化坐标 会简单很多
*/
let resBlock = this.handleByPositionType(context.input.block, context.input.targetPosition)
let res1 = this.handleByPlaceXY(resBlock.models, placeX, placeY)
resBlock.models = res1
output.block = {
...output.block,
...resBlock,
}
context.output = output
resolve()
} else {
reject('ModelProcessPoints error: input.block is undefined;')
}
} else {
reject('ModelProcessPoints error: input is undefined;')
}
resolve()
} catch (error) {
reject(error);
}
});
}
/**
* 根据小板的放置方式进行偏移
*
* 提要:models内的造型数据 都是以小板正面 为基准
* 即 PositionType.FRONT
* 需要 以下几种情况
* 加工项所在的面 -- 2种 正 反 -- 但实际 在改处理器应该是不考虑的
* 小板放置方式 -- 8 种 详见 PositionType 处理器入参 默认为 PositionType.FRONT
*
* 细节:
* 加工项 为正面 且放置方式为正面的 无需操作 直接输出,其它情况 都需要做处理
*
* 如果有 翻面的情况 弧度值需要取反
*
* 思考: 坐标转换的实质 其实 也就是以下几种行为
* 面与面的行为: 翻面a 面到 b 面
* 单面内的行为: 左转 右转 翻转
*
* 这里其实 可以有个流程
* 先判定 是不是要 翻面
* 然后再去 做 单面内的行为 相关的坐标转换 将问题集中在一个面的操作上
*
* PositionType XXX 转到 PositionType XX 无非就是 【左转 或 右转 或 翻转】 或者 先 翻面 然后 【左转 或 右转 或 翻转】
* 那么 就
* 有翻面 先 翻面 然后 再 【左| 右 | 翻】 转
*
* 注: 这里的操作 都依据绘图可视的X Y 轴进行处理
* block.width 对应 Y轴的值
* block.length 对应 x轴的值
*/
handleByPositionType(block: ModelProcessPointsInputBlock, targetPosition: PositionType) {
/** 造型输出的数据 */
let models: ModelProcessItem[] = []
let _width = block.width
let _length = block.length
let temp = JSON.parse(JSON.stringify(block))
let resBlock: ModelProcessPointsInputBlock = {
...temp
}
/** 默认 正面 */
if (resBlock.positionType == undefined) {
resBlock.positionType = PositionType.FRONT
}
//#region 板件 进行分析 翻面 以及 行为
let face = this.getFace(resBlock.positionType)
let targetFace = this.getFace(targetPosition)
if (face == -1) {
// 异常情况
console.log(`block-${resBlock.id}:block.positionType is invalid`)
}
if (targetFace == -1) {
// 异常情况
console.log(`targetFace:targetFace is invalid`)
}
// 判定是否要翻面
const isTurn = !(face == targetFace)
/** 翻面后的 放置方式 */
let tempPosition = resBlock.positionType
if (isTurn) {
tempPosition = this.getPositionAfterTurnFace(resBlock.positionType)
}
// 获取行为 左|右|翻转|不操作
const action = this.getDir(tempPosition, targetPosition)
//#endregion
// 处理造型的部分
for (const i in resBlock.models) {
let model = { ...resBlock.models[i] }
/** 如果要 翻面 那就先把面 翻过来 */
if (isTurn) {
// 翻面 x 不变 Y 变
model = this.change_turnFace(model, _width)
// 然后 弧度值要取反
model = this.reverseBuls(model)
}
/**
* 根据 行为标识 转换坐标
* 注: 左转 或者时右转 需要 转换 板件(小板)的 长宽值
*
*/
switch (action) {
case 'doNothing':
// 啥事也不做
break;
case 'turnAround':
// 翻转 x 变 y 也变
model = this.change_turnAround(model, _length, _width)
break;
case 'turnLeft':
model = this.change_turnLeft(model, _length, _width)
break;
case 'turnRight':
model = this.change_turnRight(model, _length, _width)
break;
default:
break;
}
models.push(model)
}
/** 左转 或者 右转 长宽值 要互换 */
if (action == 'turnLeft' || action == 'turnRight') {
resBlock = {
...resBlock,
width: _length,
length: _width,
}
}
/** 更加行为 以及是否 翻转 转换 板件的偏移值 */
if (isTurn) {
// 翻面 左右封边互换 上下不变
resBlock.offsetInfo = {
...resBlock.offsetInfo,
top: resBlock.offsetInfo.bottom,
bottom: resBlock.offsetInfo.top
}
}
switch (action) {
case 'turnAround':
// 翻转
resBlock.offsetInfo = {
top: resBlock.offsetInfo.bottom,
bottom: resBlock.offsetInfo.top,
left: resBlock.offsetInfo.right,
right: resBlock.offsetInfo.left
}
break;
case 'turnLeft':
resBlock.offsetInfo = {
top: resBlock.offsetInfo.right,
right: resBlock.offsetInfo.bottom,
bottom: resBlock.offsetInfo.left,
left: resBlock.offsetInfo.top
}
break
case 'turnRight':
resBlock.offsetInfo = {
top: resBlock.offsetInfo.left,
left: resBlock.offsetInfo.bottom,
bottom: resBlock.offsetInfo.right,
right: resBlock.offsetInfo.top
}
break
default:
break;
}
return resBlock
}
/** 获取翻面 后的 放置方式 */
getPositionAfterTurnFace(v: PositionType) {
let res = transitions_PositionTurnFace[v]
return res
}
/** 获取行为 左|右|翻转|不需要操作 */
getDir(v1: PositionType, v2: PositionType) {
let flag: RotationAction = 'doNothing'
try {
flag = transitions_PositionToAction[v1][v2]
} catch (error) {
console.log('逻辑异常!请保证 v1 v2 的放置方式处在同一个面上,或者输入的值在转换关系中没有匹配的值')
flag = 'doNothing'
}
return flag
}
/** 右转
* @param model 造型数据
* @param valueX 排版长
*/
change_turnRight(model: ModelProcessItem, valueX: number) {
let newModel = { ...model }
for (const i in newModel.pts) {
newModel.pts[i] = {
x: valueX - newModel.pts[i].y,
y: newModel.pts[i].x
}
}
return newModel
}
/** 左转
* @param model 造型数据
* @param valueX 排版长
*/
change_turnLeft(model: ModelProcessItem, valueX: number) {
let newModel = { ...model }
for (const i in newModel.pts) {
newModel.pts[i] = {
x: newModel.pts[i].y,
y: valueX - newModel.pts[i].x
}
}
return newModel
}
/** 翻转 改变 xy 坐标
* @param model 造型数据
* @param valueX 排版长
* @param valueY 排版宽
*/
change_turnAround(model: ModelProcessItem, valueX: number, valueY: number) {
let newModel = { ...model }
for (const i in newModel.pts) {
newModel.pts[i] = {
x: valueX - newModel.pts[i].x,
y: valueY - newModel.pts[i].y
}
}
return newModel
}
/**翻面 改变 y坐标 */
change_turnFace(model: ModelProcessItem, valueY: number) {
let newModel = { ...model }
for (const i in newModel.pts) {
newModel.pts[i].y = valueY - newModel.pts[i].y
}
return newModel
}
/** 给 弧度值 取反 */
reverseBuls(model: ModelProcessItem) {
let newModel = { ...model }
for (const i in newModel.buls) {
newModel.buls[i] = -newModel.buls[i]
}
return newModel
}
/**正面的放置方式 集合*/
frontArr = [
PositionType.FRONT,
PositionType.FRONT_TURN_BACK,
PositionType.FRONT_TURN_LEFT,
PositionType.FRONT_TURN_RIGHT
]
/** 反面的放置方式 集合*/
backArr = [
PositionType.BACK,
PositionType.BACK_TURN_BACK,
PositionType.BACK_TURN_LEFT,
PositionType.BACK_TURN_RIGHT
]
/** 根据放置方式 获取面 */
getFace(positionValue: PositionType) {
let res = -1
if (this.frontArr.includes(positionValue)) {
res = FaceType.FRONT
}
if (this.backArr.includes(positionValue)) {
res = FaceType.BACK
}
return res
}
/** 根据 优化后的坐标XY便宜 */
handleByPlaceXY(models: ModelProcessItem[], placeX: number, placeY: number) {
let newModels: ModelProcessItem[] = []
for (const model of models) {
let newModel: ModelProcessItem = { ...model }
let newPts = []
for (const k in newModel.pts) {
let p = {
x: model.pts[k].x + placeX,
y: model.pts[k].y + placeY
}
newPts.push(p)
}
newModel.pts = newPts
newModels.push(newModel)
}
return newModels
}
}
/** 处理器输入-- 获取造型在大板的刀路 */
export type ModelProcessPointsInput = {
/** 小板数据 */
block: ModelProcessPointsInputBlock,
/** 小板的最终的放置位置 */
targetPosition: PositionType
}
/** 处理器输入--小板 -- 获取造型在大板的刀路 */
export type ModelProcessPointsInputBlock = {
/** 板件唯一标识 */
id: string | number,
/** 板件基于大板的 坐标X */
x: number,
/** 板件基于大板的 坐标y */
y: number,
/** 板件(小板)长 */
length: number,
/** 板件(小板)宽 */
width: number,
/** 造型数据 依据放置方式positionType 下的造型数据 默认为 依据放置方式positionType.FRONT 的造型数据 */
models: ModelProcessItem[],
/** 板件的原放置方式 默认为正面0 不传则为正面 原 placestyle*/
positionType?: PositionType,
/** 偏移值 */
offsetInfo: OffsetInfo
}
/** 板件 上下左右 偏移值信息 */
export type OffsetInfo = {
top: number,
bottom: number,
left: number,
right: number,
}
/** 处理器输出--小板 -- 获取造型在大板的刀路 */
export type ModelProcessPointsOutputBlock = {
/** 板件唯一标识 */
id: string | number
/** 放置方式 */
positionType: PositionType
/** 造型数据 */
models: ModelProcessItem[]
/** 板件(小板)长 */
length: number,
/** 板件(小板)宽 */
width: number,
/** 偏移值 */
offsetInfo: OffsetInfo
}
/** 处理器输出-- 获取造型在大板的刀路 */
export type ModelProcessPointsOutput = {
block: ModelProcessPointsOutputBlock
}
/** 处理器配置-- 获取造型在大板的刀路 暂无 */
export declare class ModelProcessPointsProcConfig extends ConfigBase {
}
/** 造型类 */
export interface ModelProcessItem {
/** 加工项唯一标识 */
id?: string | number
/**
* 加工点数组
*/
pts: IPoint[];
/**
* 凸度数组
*/
buls: number[];
/** 加工面 */
face: FaceType
}
/** 加工面 */
export enum FaceType {
/** 正面 */
FRONT = 0,
/** 反面 */
BACK = 1,
}
/** 点坐标类 */
export interface IPoint { x: number, y: number; }
/** 小板的放置方式 */
export enum PositionType {
/** 正面 */
FRONT = 0,
/** 正面右转 */
FRONT_TURN_RIGHT = 1,
/** 正面后转 */
FRONT_TURN_BACK = 2,
/** 正面左转 */
FRONT_TURN_LEFT = 3,
/** 反面 */
BACK = 4,
/** 反面右转 */
BACK_TURN_RIGHT = 5,
/** 反面后转 */
BACK_TURN_BACK = 6,
/** 反面左转 */
BACK_TURN_LEFT = 7,
}
/** 行为类型 */
export type RotationAction = 'doNothing' | 'turnLeft' | 'turnRight' | 'turnAround'
/**
* 原放置方式 依据 目标放置方式 转 行为的 转换关系
*
* 注:原放置方式 为 翻面 转换后 的数值
* 若要支持 翻转转换前 需对内容进一步填充
*/
export const transitions_PositionToAction: any = {
[PositionType.FRONT]: {
[PositionType.FRONT_TURN_BACK]: 'turnAround',
[PositionType.FRONT_TURN_LEFT]: 'turnLeft',
[PositionType.FRONT_TURN_RIGHT]: 'turnRight',
[PositionType.FRONT]: 'doNothing'
},
[PositionType.FRONT_TURN_LEFT]: {
[PositionType.FRONT]: 'turnRight',
[PositionType.FRONT_TURN_RIGHT]: 'turnAround',
[PositionType.FRONT_TURN_BACK]: 'turnLeft',
[PositionType.FRONT_TURN_LEFT]: 'doNothing'
},
[PositionType.FRONT_TURN_RIGHT]: {
[PositionType.FRONT]: 'turnLeft',
[PositionType.FRONT_TURN_LEFT]: 'turnAround',
[PositionType.FRONT_TURN_BACK]: 'turnRight',
[PositionType.FRONT_TURN_RIGHT]: 'doNothing'
},
[PositionType.FRONT_TURN_BACK]: {
[PositionType.FRONT]: 'turnAround',
[PositionType.FRONT_TURN_LEFT]: 'turnRight',
[PositionType.FRONT_TURN_RIGHT]: 'turnLeft',
[PositionType.FRONT_TURN_BACK]: 'doNothing'
},
[PositionType.BACK]: {
[PositionType.BACK_TURN_BACK]: 'turnAround',
[PositionType.BACK_TURN_LEFT]: 'turnLeft',
[PositionType.BACK_TURN_RIGHT]: 'turnRight',
[PositionType.BACK]: 'doNothing'
},
[PositionType.BACK_TURN_LEFT]: {
[PositionType.BACK]: 'turnRight',
[PositionType.BACK_TURN_RIGHT]: 'turnAround',
[PositionType.BACK_TURN_BACK]: 'turnLeft',
[PositionType.BACK_TURN_LEFT]: 'doNothing'
},
[PositionType.BACK_TURN_RIGHT]: {
[PositionType.BACK]: 'turnLeft',
[PositionType.BACK_TURN_LEFT]: 'turnAround',
[PositionType.BACK_TURN_BACK]: 'turnRight',
[PositionType.BACK_TURN_RIGHT]: 'doNothing'
},
[PositionType.BACK_TURN_BACK]: {
[PositionType.BACK]: 'turnAround',
[PositionType.BACK_TURN_LEFT]: 'turnRight',
[PositionType.BACK_TURN_RIGHT]: 'turnLeft',
[PositionType.BACK_TURN_BACK]: 'doNothing'
}
}
/** 放置方式 翻转后的转换关系 */
export const transitions_PositionTurnFace: any = {
[PositionType.FRONT]: PositionType.BACK,
[PositionType.FRONT_TURN_RIGHT]: PositionType.BACK_TURN_LEFT,
[PositionType.FRONT_TURN_BACK]: PositionType.BACK_TURN_BACK,
[PositionType.FRONT_TURN_LEFT]: PositionType.BACK_TURN_RIGHT,
[PositionType.BACK]: PositionType.FRONT,
[PositionType.BACK_TURN_BACK]: PositionType.FRONT_TURN_BACK,
[PositionType.BACK_TURN_LEFT]: PositionType.FRONT_TURN_RIGHT,
[PositionType.BACK_TURN_RIGHT]: PositionType.FRONT_TURN_LEFT
}