Files
cut-abstractions/samples/confClass.ts

2762 lines
82 KiB
TypeScript
Raw Normal View History

import { StringFormat } from "./handleAbility/common/base/StringFormat"
import type * as CAD from './handleAbility/common/base/CAD'
import { Polyline } from "cadapi"
import { ArrayExt } from "./handleAbility/common/ArrayExt"
2025-06-24 11:48:26 +08:00
/**配置项属性 */
export class confItem {
/** 属性key */
key: string
/** 说明 */
label: string
/** 属性value 值 */
value: Array<any> | any
}
2025-06-24 11:48:26 +08:00
/** 内部指令 接收 */
export class CodeAction {
code?: String
order?: String
codeParams?: any
}
/**内部响应类 */
export class GCodeResType {
code: number = -1
data: any = null
msg: string = ''
logError(msg) {
console.error(msg)
}
}
/** 排孔类型 */
export enum HoleArrange {
/** 正面 */
FRONT = 0,
/** 反面 */
BACK = 1,
/** 随意面 */
RANDOM_FACE = 2,
}
2025-06-24 11:48:26 +08:00
// 加工项 点数据
export class CodeParams {
/** x坐标 */
x?: Number | String
/** y坐标 */
y?: Number | String
/** z坐标 */
z?: Number | String
/** 调用的代码编号 */
dir?: Number | String
/** 圆弧半径 */
r?: Number | String
/** 速度 */
f?: Number | String
/** IJK 模式的i */
i?: Number | String
/** IJK 模式的j */
j?: Number | String
/** IJK 模式的k */
k?: Number | String
/** 代码标识 */
codeKey?: String
/** x坐标 */
xKey?: String
/** y坐标 */
yKey?: String
/** z坐标 */
zKey?: String
/** 圆弧半径 */
rKey?: String
/** 速度 */
fKey?: String
/** IJK 模式的i */
iKey?: String
/** IJK 模式的j */
jKey?: String
/** IJK 模式的k */
kKey?: String
}
export type _knifeType = Partial<Knife>
2025-06-24 11:48:26 +08:00
/**
*
* 0 1 2 21 22 23 24 29 30
*/
export enum FaceType {
/** 正面 */
FRONT = 0,
/** 反面 */
BACK = 1,
/** 侧面 */
SIDE = 2,
/** 左侧面 */
LEFT_SIDE = 21,
/** 右侧面 */
RIGHT_SIDE = 22,
/** 上侧面 */
TOP_SIDE = 23,
/** 下侧面 */
BOTTOM_SIDE = 24,
/** 弧形侧面 */
CURVED_SIDE = 29,
/** 异形侧面 */
SPECIAL_SHAPED_SIDE = 30,
/** 未设置 */
UNSET = -1
2025-06-24 11:48:26 +08:00
}
/** 开料刀 */
export class Knife {
/** 是否启用 */
isEnabled = true;
/** 轴号 */
axleId = 0;
/** 开料刀ID号 */
knifeId = 1;
/** 加工面(0正面 1反面 2左侧面 3右侧面 4上侧面 5下侧面 6任意) */
processFace = 0;
/** 刀名称 */
knifeName = '';
/** 刀具类型(1铣刀 2成型刀 3钻头 4锯 5刀片) */
knifeType = KnifeType.MILLING_CUTTER;
/** 功能属性(数组): 1开料/切割 2拉槽 3铣型 4铣孔 5钻孔 6拉米诺 7乐扣 8T型 */
ability: any = [];
// /** 默认开料刀 */
// isDefaultCutKnife = false;
// /** 是否可用于开料切割 */
// isCuttingKnife = false;
// /** 是否允许铣孔(knifeType为铣刀生效) */
// isMillingAllowed = false;
/** 刀直径mm */
diameter = 6;
/** 刀长(最大深度) */
length = 20;
/** 锯齿厚度,单次加工切缝宽度 */
sawThiness = 0;
/**锯向: 0横向或长边 1纵向短边 2自由角度*/
sawDirection = 0;
/**切向加工方向: 0横向左往右 2横向右往左 3纵向上往下 4纵向下往上 5随意 */
processDirection = 0;
/**进给速度, 0取系统默认 */
speed = 0;
/** 进给深度 */
stepDepth = 0;
// /** 组号 */
// groupNo = 0;
// /** 主刀 */
// isMainKnife = false;
// /** 是否高级加工 */
// isAdvancedProcessEnabled = false;
// /** 是否集合加工 */
// isBatchProcessEnabled = false;
// /** 副刀偏置长边偏移(Y轴) */
// auxKnifeOffsetY = 0;
// /** 副刀偏置短边偏移(X轴) */
// auxKnifeOffsetX = 0;
/** 偏置短边偏移(X轴)-相对于工件原点位置XY坐标的短边方向偏移量 */
offsetX = 0;
/** 偏置长边偏移(Y轴) -相对于工件原点位置XY坐标的长边方向偏移量*/
offsetY = 0;
/** 偏置垂直偏移(Z轴) -相对于工件原点位置XY坐标的垂直方向偏移量*/
offsetZ = 0;
/** 基准坐标-短边(X轴) -钻头在钻包中短边方向(纵向)的相对位置 */
baseX = 0;
/** 基准坐标-长边(Y轴) -钻头在钻包中长边方向(横向)的相对位置 */
baseY = 0;
/**组合钻 */
isModularDrill = false;
/** 是否预启动 */
isPreStartEnabled = false;
/** 预启动提前动作数 */
preStartAheadActionCount = 5;
/** 预启动延迟换刀 */
isPreStartToolChangeDelay = false;
/** 预启动延迟换刀指令 */
preStartToolChangeDelayCode = '';
/** 轴启动指令后置 */
isAxisStartCodePostpost = false;
/** 轴停止指令前置 */
isAxisStopCodePrepose = false;
/** 钻组独立指令(启用后,刀起始指令、刀结束指令使用钻组起始指令、钻组结束指令替换) */
drillGroupCode = '';
/** 轴启动代码*/
axisStartCode = "";
/** 刀启动代码 */
knifeStartCode = '';
/** 钻组起始指令 */
drillGroupStartCode = '';
/** 钻组结束指令 */
drillGroupEndCode = '';
/** 刀停止代码 */
knifeStopCode = '';
/** 轴停止指令 */
axisStopCode = '';
// /** 高级加工指令 */
// advancedCode = '';
/** 开料刀 */
isCuttingKnife() {
return this.isEnabled && this.ability.includes(AbilityType.CUT);
}
/** 造型刀 */
isModelingKnife() {
return this.isEnabled && this.ability.includes(AbilityType.MILLING_MODEL);
}
/** 钻刀 */
isDrillingKnife() {
return this.isEnabled && this.ability.includes(AbilityType.DRILL_HOLE);
}
/** 铣孔 */
isCutting4HoleKnife() {
return this.isEnabled && this.ability.includes(AbilityType.MILLING_HOLE);
}
2025-06-24 11:48:26 +08:00
/** 设置刀具(轴号, 刀名, 刀直径, 是否主刀, 是否铣孔, 是否开料刀) */
// set(axleId: number, name: string, diameter: number, isMainKnife: boolean, isMillingAllowed: boolean, isCuttingKnife: boolean)
/** 设置刀具(轴号, 刀名, 刀类型, 刀直径, 刀长, 是否默认刀) */
}
/** 刀类型: MILLING_CUTTER铣刀 FORMING_CUTTER成型刀 DRILL钻头 SAW锯 BLADE刀片 */
export enum KnifeType {
/** 铣刀 */
MILLING_CUTTER = 1,
/** 成型刀 */
FORMING_CUTTER = 2,
/** 钻头 */
DRILL = 3,
/** 锯 */
SAW = 4,
/** 刀片 */
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 {
/** X轴正 */
X_POS = 0,
/** X轴负 */
X_NEG = 1,
/** Y轴正 */
Y_POS = 2,
/** Y轴负 */
Y_NEG = 3,
/** 向上Z轴正 */
Z_POS = 4,
/** 向下Z轴负 */
Z_NEG = 5,
}
/** 枚举 坐标轴类型 */
export enum OriginZPosition {
/** 台面向上Z轴正 */
WorkTop = 0,
/** 板面向上Z轴正 */
BoardFace = 1,
}
// nc文件编码
export const ncEncodeMap = {
'UTF-8': 'UTF-8',
'GB2312': 'GB2312',
'UTF-8-BOM': 'UTF-8-BOM',
'GBK': 'GBK',
'Big-5': 'Big-5',
'GB18030': 'GB18030',
'Unicode': 'Unicode'
}
// 小板文件名选项
export const smallPlateOptionsMap = {
: '{0}',
: '{1}',
: '{2}',
: '{3}',
: '{4}',
: '{5}',
: '{6}',
: '{7}',
: '{8}',
: '{9}',
: '{10}',
: '{11}',
}
// zip压缩包文件名选项
export const zipFileOptionsMap = {
'板宽': '{0}',
'板长': '{1}',
'颜色': '{2}',
'材质': '{3}',
'大板号': '{4}',
'工位号': '{5}',
'板厚': '{6}',
'开料顺序': '{7}',
'批次识别': '{8}',
'小板编号': '{9}',
'全局大板号': '{10}',
'品牌': '11',
}
/** 枚举 大板边角位置 */
export enum BoardPosition {
/** 左上角 */
// LEFT_TOP = 0,
// /** 左下角 */
// LEFT_BOTTOM = 1,
// /** 右下角 */
// RIGHT_BOTTOM = 2,
// /** 右上角 */
// RIGHT_TOP = 3,
/** 左上角 */
LEFT_TOP = 3,
/** 左下角 */
LEFT_BOTTOM = 0,
/** 右下角 */
RIGHT_BOTTOM = 1,
/** 右上角 */
RIGHT_TOP = 2,
/**
* = 0,
= 1,
= 2,
= 3
*/
}
/** 排版样式 */
export enum PlaceStyle {
/** 正面 */
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 enum EdgeType {
/** 下=0 */
BOTTOM = 0,
/** 右=1 */
RIGHT = 1,
/** 上=2 */
TOP = 2,
/** 左=3 */
LEFT = 3,
}
/** 开料小板 */
export class PlaceBlock {
/** 小板明细(异形,孔,造型) */
blockDetail: PlaceBlockDetail | null = null
// 订单信息----------------------------------------------------------
/** 订单号 */
orderId: number = 0
/** 板材ID */
goodsId = ''
// 小板属性-----------------------------------------------------------
// 房间名, 柜体名, 小板ID, 小板编号,小板名称, 板材名称, 备注
// 房间ID
roomId = ''
/** 房间名 */
roomName = ''
/** 柜体号 */
bodyId = ''
/** 柜体名 */
bodyName = ''
/** 小板ID */
blockId = 0
/** 原小板ID */
oldBlockId: number = 0
/** 板编号 */
blockNo: number = 0
/** 自定义板编号 */
customPlateNo: any = ''
/** 明细ID */
itemId: number = 0
/** 标签板号 */
labelNo = ''
/** 板名称 */
blockName = ''
/** 板件备注 */
plateRemark = ''
/** 备注1 */
remark1 = ''
/** 备注2 */
remark2 = ''
/** 备注3 */
remark3 = ''
/** 备注4 */
remark4 = ''
/** 备注5 */
remark5 = ''
/** 铰链备注 */
extraRemark: object = {}
// 尺寸,封边,开料尺寸-----------------------------------------------------
/** 板宽 */
width = 0
/** 板长 */
length = 0
/** 板厚 */
thickness = 0
/** 面积 Size */
area = 0
/** 左封边 BorderLeft */
sealLeft = 0
/** 右封边 BorderRight */
sealRight = 0
/** 上封边 BorderUpper */
sealTop = 0
/** 下封边 BorderUnder */
sealBottom = 0
/** 无封边板宽 开料板宽 CuttingWidth */
cutWidth = 0
/** 无封边板长 开料板长 CuttingLength */
cutLength = 0
/** 无封边面积 开料面积 CuttingSize */
cutArea = 0
// 高级-------------------------------------------------------------
/** 自增小板 */
isAdditionalBlock = false
/** 余料板 IsScrapBlock */
isRemainBlock = false
/** 开料纹路 */
texture = TextureType.ROTATABLE_TEXTURE // 可翻转
/** 排版面 PaiKong */
placeHole = HoleArrange.RANDOM_FACE // 随意面
/** 异型偏移x BorderLengthHeavy */
abnormalOffsetX = 0
/** 异型偏移y BorderLengthLight */
abnormalOffsetY = 0
/** 正面有大孔 */
bigHoleInFaceA(): boolean {
let res = false
if (this.blockDetail && this.blockDetail.bigHoleInFaceA) {
res = true
}
return res
}
/** 是否异形 */
isUnRegular = false
// isUnRegular(): boolean {
// return this.blockDetail && this.blockDetail.isUnRegular || false
// }
/** 正面孔数 */
holeCountFront(): number {
return this.blockDetail && this.blockDetail.holeCountFront || 0
}
/** 反面孔数 */
holeCountBack(): number {
return this.blockDetail && this.blockDetail.holeCountBack || 0
}
/** 通孔数 */
holeCountThrough(): number {
return this.blockDetail && this.blockDetail.holeCountThrough || 0
}
/** 侧孔数 HoleCount_Side */
holeCountSide(): number {
return this.blockDetail && this.blockDetail.holeCountSide || 0
}
/** 左侧孔数 HoleCount_Left */
holeCountLeft() { return this.blockDetail && this.blockDetail.holeCountLeft }
/** 右侧孔数 HoleCount_Right */
holeCountRight() { return this.blockDetail && this.blockDetail.holeCountRight }
/** 侧孔数 HoleCount_Upper */
holeCountTop() { return this.blockDetail && this.blockDetail.holeCountTop }
/** 侧孔数 HoleCount_Under */
holeCountBottom() { return this.blockDetail && this.blockDetail.holeCountBottom }
/** 正面造型数 */
modelCountFront(): number {
return this.blockDetail && this.blockDetail.modelCountFront || 0
}
/** 反面造型数 */
modelCountBack(): number {
return this.blockDetail && this.blockDetail.modelCountBack || 0
}
/** 打穿造型数 */
modelCountThrough(): number {
return (this.blockDetail && this.blockDetail.modelCountThrough) || 0
}
/** 有挖穿造型 */
hasModelThrough(): boolean {
return (this.blockDetail && this.blockDetail.hasModelThrogh) || false
}
/** 需双面处理 */
isDoubleFaceProcess(): boolean {
if (this.placeHole == HoleArrange.RANDOM_FACE) // 随意面
{
return (this.blockDetail && this.blockDetail.isTwoFaceProcess) || false
}
else if (this.placeHole == HoleArrange.FRONT) // 正面
{
return this.holeCountBack() + this.modelCountBack() > 0
}
else {
return this.holeCountFront() + this.modelCountFront() > 0
}
} // (根据排版规格计算)
/** 优化排版时,需反面(不是真正的反面开料) */
isTurnFaceToPlace = false
/** 优化排版时,可双面排版 */
isTwoFaceToPlace = false
/** 是否弧形地脚,不处理异形 IsHXDJX */
isCurvedGroundLine = false
/** 封边偏移值x */
offsetX(): number {
return (this.blockDetail && this.blockDetail.offsetX) || 0
}
/** 封边偏移值y */
offsetY(): number {
return (this.blockDetail && this.blockDetail.offsetY) || 0
}
// 异形、孔、造型明细列表
points(): BlockPoint[] {
return (this.blockDetail && this.blockDetail.points) || []
}
orgPoints(): BlockPoint[] {
return (this.blockDetail && this.blockDetail.orgPoints) || []
}
holes(): BlockHole[] {
return (this.blockDetail && this.blockDetail.holes) || []
}
models(): BlockModel[] {
return (this.blockDetail && this.blockDetail.models) || []
}
holeListOrgFaceA(): BlockHole[] {
return (this.blockDetail && this.blockDetail.holeListFaceA) || []
}
holeListOrgFaceB(): BlockHole[] {
return (this.blockDetail && this.blockDetail.holeListFaceB) || []
}
holeListOrgThrough(): BlockHole[] {
return (this.blockDetail && this.blockDetail.holeListThrough) || []
}
holeListOrgFaceSide(): SideHole[] {
return (this.blockDetail && this.blockDetail.holeListSide) || []
}
modelListOrgFaceA(): BlockModel[] {
return (this.blockDetail && this.blockDetail.modelListFaceA) || []
}
modelListOrgFaceB(): BlockModel[] {
return (this.blockDetail && this.blockDetail.modelListFaceB) || []
}
modelListOrgTrough(): BlockModel[] {
return (this.blockDetail && this.blockDetail?.modelListThrough) || []
}
// 排版情况
/** 已排版 */
isPlaced = false
/** 全局大板Id */
fullBoardId = 0
/** 大板ID */
boardId = 0
/** 排单ID */
placeId = 0
/** 坐标X */
placeX = 0
/** 坐标Y */
placeY = 0
/** 排版方式 */
placeStyle: PlaceStyle = PlaceStyle.FRONT // 正面
/** 下刀点区域 */
cutRegion = BlockRegion.LEFT_BOTTOM // 左下
/** 开料顺序 */
cutOrder = 0
/** 下刀点位 */
cutPointId = 0
/** 开料宽 */
placeWidth = 0
/** 开料长 */
placeLength = 0
/** 开料左封边 */
placeSealLeft = 0
/** 开料右封边 */
placeSealRight = 0
/** 开料上封边 */
placeSealTop = 0
/** 开料下封边 */
placeSealBottom = 0
/** 原造型下刀超出板外情况 OrgSizeOutOff */
orgSizeExpand: SizeExpand = new SizeExpand()
/** 造型下刀超出板外情况 尺寸扩展 SizeOutOff */
sizeExpand() { return this.blockDetail ? this.blockDetail.currentSizeExpand : '' };
/** 排版宽 加上预铣等外括 ,开料刀半径 ,缝隙 */
// placeFullWidth() { return this.cutWidth + this.blockDetail.currentSizeExpand.width }
placeFullWidth() { return this.cutWidth + (this.blockDetail ? this.blockDetail?.currentSizeExpand?.width || 0 : 0) }
/** 排版长 加上预铣等外括 ,开料刀半径 ,缝隙 */
placeFullLength() { return this.cutLength + (this.blockDetail ? this.blockDetail?.currentSizeExpand?.length || 0 : 0) }
/** 坐标偏移情况 */
placeOffX = 0
placeOffY = 0
/** 原始排版坐标 */
placeOrgX() { return this.placeX - this.placeOffX }
placeOrgY() { return this.placeY - this.placeOffY }
/** 反面开料 */
isTurnOver(): boolean {
return this.placeStyle > 3
}
/** 后转180 */
isTurnBack(): boolean {
return (
this.placeStyle == PlaceStyle.BACK_TURN_BACK
|| this.placeStyle == PlaceStyle.FRONT_TURN_BACK
)
}
/** 反纹开料 */
isTurnDown(): boolean {
return this.placeStyle % 2 == 1
}
/** 自动排版 */
isAutoPlaced = true
/** 超出板外 */
isOutBoard = false
/** 已重叠 */
isOverlap = false
/** 高方向 */
placeDirection = '→'
/** 长边方向 */
placeDirection_Length = '→'
// 开料情况
// isUseSameKnifeToHelpCut() { return this.blockDetail ? this.blockDetail.isHelpCut : false; };
/** 是否排钻 IsDoHoling */
isDrilling = true
/** 是否造型 IsDoModeling */
isModeling = true
/** 超限板标识 : -1=不是; 0=不判断 1=是 */
overBlockFlag = 0
/** 开料时需翻面 IsDoOtherFace */
isCutOtherFace = false
/** 开料反面要处理 NeedTurnFaceToDo */
isCutTurnOver = false
/** 开料面孔数 HoleCount_DoFaceA */
holeCountFaceA(): number {
return this.holeListFaceA.length
}
/** 开料反面孔数 HoleCount_DoFaceB */
holeCountFaceB(): number {
return this.holeListFaceB.length
}
/** 开料左侧孔数 HoleCount_DoLeft */
holeCountSideLeft = 0
/** 开料右侧孔数 HoleCount_DoRight */
holeCountSideRight = 0
/** 开料上侧孔数 HoleCount_DoUpper */
holeCountSideTop = 0
/** 开料下侧孔数 HoleCount_DoUnder */
holeCountSideBottom = 0
/** 开料面造型数 ModelCount_DoFaceA */
modelCountFaceA(): number {
return this.modelListFaceA.length
}
/** 开料反面造型数 ModelCount_DoFaceB */
modelCountFaceB(): number {
return this.modelListFaceB.length
} // 不显示
/** 开料面孔 Holes_DoFaceA */
holeListFaceA: BlockHole[] = [] // 不显示
/** 开料反面孔 Holes_DoFaceB */
holeListFaceB: BlockHole[] = [] // 不显示
/** 开料面造型 Models_DoFaceA */
modelListFaceA: BlockModel[] = [] // 不显示
/** 开料反面造型 Models_DoFaceB */
modelListFaceB: BlockModel[] = []
/** 贴标位置x NotePosX */
labelPosX = 0
/** 贴标位置y NotePosY */
labelPosY = 0
// CNC高级对接--------------------------------------------------------
/** CNC正面条码 CNC_NoteA */
isCncLabelA = false
/** CNC反面条码 CNC_NoteB */
isCncLabelB = false
/** CNC翻面条码 CNC_NoteT */
isCncLabelTurnOver = false
/** 类型 */
type = ''
/** 加工组 */
processGroupName = ''
/** 开门类型 */
openDoorType = OpenDoorType.NONE // 无
/** 自增小板的id接口获取 */
_blockId = ''
constructor(data: any = null) {
if (data != null) {
for (const key in data) {
if (Reflect.has(this, key)) {
if (['goodsId'].includes(key)) {
this[key] = data[key].toString()
} else if (['width', 'length', 'thickness', 'sealLeft', 'sealRight', 'sealTop', 'sealBottom'].includes(key)) {
this[key] = StringFormat.toFixed(data[key], 3)
} else if (key == 'texture') {
this.texture = <TextureType>data.texture
} else if (key == 'placeHole') {
this.placeHole = <HoleArrange>data.placeHole
} else if (key == 'remarkJson') {
let remarkList = JSON.parse(data.remarkJson == null || data.remarkJson == '' ? '[]' : data.remarkJson)
this.remark1 = remarkList[0] == null ? '' : remarkList[0]
this.remark2 = remarkList[1] == null ? '' : remarkList[1]
this.remark3 = remarkList[2] == null ? '' : remarkList[2]
this.remark4 = remarkList[3] == null ? '' : remarkList[3]
this.remark5 = remarkList[4] == null ? '' : remarkList[4]
}
else {
try {
if (Object.getOwnPropertyDescriptor(this, key)?.writable == true) {
this[key] = data[key]
}
} catch (error) {
console.log(error)
}
}
} else {
// console.log('PlaceBlock Init', key)
}
}
this.cutWidth = this.width - this.sealLeft - this.sealRight
this.cutLength = this.length - this.sealTop - this.sealBottom
this.cutArea = this.cutWidth * this.cutLength * 0.000001
this._blockId = data.blockId
}
}
getRemark(rname, st = '', ed = '') {
if (!this.extraRemark)
return ''
if (!this.extraRemark[rname])
return ''
let text: string = this.extraRemark[rname]
if (st != '') {
let index = text.indexOf(st)
if (index > -1) {
// text = text.substr(index + st.length, 99999);
text = text.substring(index + st.length, 99999)
}
}
if (ed != '') {
let index = text.indexOf(ed)
if (index > -1) {
text = text.substring(0, index)
}
}
return text
}
}
/** 小板明细(异形,造型,孔) */
export class PlaceBlockDetail {
// 数据库定义列
/** 用户ID */
organId: number = 0
/** 数据类型 */
dataType: number = 0
/** 订单号 */
orderId: number = 0
/** 小板ID */
blockId: number = 0
/** 原柜体编号rawBoxNo */
rawBoxNo: number = 0
/** 异形定义明细 */
pointDetail: any = []
/** 造型定义明细 */
modelDetail: any = []
/** 排钻定义明细 */
holeDetail: any = []
/** 封边偏移值x */
offsetX = 0
/** 封边偏移值y */
offsetY = 0
/** 开料宽度 KaiLiaoWidth */
cutWidth = 0
/** 开料长度 KaiLiaoLength */
cutLength = 0
/** 异形点阵 */
points: BlockPoint[] = []
/** 异形点阵含封边 */
orgPoints: BlockPoint[] = []
/** 原轮廓数据 */
orgContourData = null
/** 排钻 */
holes: BlockHole[] = []
/** 正面孔列表(不包含通孔和孔深大于板厚) Holes_FaceA */
holeListFaceA: BlockHole[] = []
/** 反面孔列表(不包含通孔和孔深大于板厚) Holes_FaceB */
holeListFaceB: BlockHole[] = []
/** 穿孔列表(通孔和孔深大于板厚) Holes_Through */
holeListThrough: BlockHole[] = []
/** 侧孔列表 Holes_FaceSide */
holeListSide: SideHole[] = []
/** 造型点阵 */
models: BlockModel[] = []
/** 正面造型列表(不包含打穿) Models_FaceA */
modelListFaceA: BlockModel[] = []
/** 反面造型列表(不包含打穿) Models_FaceB */
modelListFaceB: BlockModel[] = []
/** 打穿造型列表 Models_Through */
modelListThrough: BlockModel[] = []
/** 侧面造型 BlockModel SideModels 20241111 改为 BlockModel */
modelListSide: SideModel[] = []
// /** 切割板宽 */
// cuttingWidth = 0;
// /** 切割板厚 */
// cuttingLength = 0;
/** 板厚 */
thickness = 18
/** 是否异形 */
isUnRegular = false
/** 正面有打孔 */
bigHoleInFaceA = false
/** 正面孔数 */
holeCountFront = 0
/** 反面孔数 */
holeCountBack = 0
/** 穿孔数 */
holeCountThrough = 0
/** 侧孔数 */
holeCountSide = 0
/** 左侧孔数 */
holeCountLeft = 0
/** 右侧孔数 */
holeCountRight = 0
/** 上侧孔数 */
holeCountTop = 0
/** 下侧孔数 */
holeCountBottom = 0
/** 斜孔数量 */
holeCountBevelled = 0
/** 正面造型数 */
modelCountFront = 0
/** 反面造型数 */
modelCountBack = 0
/** 打穿造型数 */
modelCountThrough = 0
/** 侧面造型数量 */
modelCountSide(): number {
return this.modelListSide.length
}
/** 下侧造型数量 */
modelCountBottom(): number {
return this.modelListSide.filter(sideModel => sideModel.face == 0).length
}
/** 右侧造型数量 */
modelCountRight(): number {
return this.modelListSide.filter(sideModel => sideModel.face == 1).length
}
/** 下侧造型数量 */
modelCountTop(): number {
return this.modelListSide.filter(sideModel => sideModel.face == 2).length
}
/** 下侧造型数量 */
modelCountLeft(): number {
return this.modelListSide.filter(sideModel => sideModel.face == 3).length
}
/** 是否有挖穿的造型 */
hasModelThrogh = false
/** 双面处理 Do2Face */
isTwoFaceProcess = false
// isTwoFaceProcess(): boolean
// {
// return this.blockDetail && this.blockDetail.isTwoFaceProcess
// }
// 为了缺角空间 放在右边
/** 当需要正面正纹的,最佳放置方式: 正面或正面后转 Ps00 */
placeStyleFront = PlaceStyle.FRONT // 正面
/** 正面反纹放置方式 Ps01 */
placeStyleFrontReverse = PlaceStyle.FRONT_TURN_RIGHT // 正面右转
/** 反面正纹放置方式 Ps10 */
placeStyleBack = PlaceStyle.BACK // 反面
/** 反面反纹放置方式 Ps11 */
placeStyleBackReverse = PlaceStyle.BACK_TURN_LEFT // 反面左转
/** 开料序号贴标位置x */
labelPosX = -1
/** 开料序号贴标位置y */
labelPosY = -1
/** 是否初始化 */
isInited = false
/** 是否已检查 */
isChecked = false
/** 全部二维刀路径集合 { model, modelID, lineID, isFaceB, name, value, knife, knifeRadius, depth, points, offset} */
// vKnifeModels: any[];
/** 是否偏移倒角 IsOffsetRounding */
isOffsetRounding = false
/** 偏移值刀半径 CutR */
offsetKnifeRadius = 0
/** 当前的预铣值 preCutValue */
preMillingSize = 0
/** 该板需要辅助开料 isNeedHelpCut */
isUseSameKnifeToHelpCut = false
/** 同刀辅助值 */
useSameKnifeToHelpCutGap = 2
/** 预铣外扩尺寸 preCutSizeOutOff */
preMillingExpandSize: SizeExpand | null = null
/** 板外造型外扩尺寸 modelKnifeOutOff */
modelExpandSize: SizeExpand | null = null
/** 2V刀路V外扩尺寸 */
vKnifeModelExpandSize: SizeExpand | null = null
/** 同刀辅助外扩尺寸 sameKnfieHelpOutOff */
sameKnfieHelpExpandSize: SizeExpand | null = null
/** 当前外扩 currentOutOff */
currentSizeExpand: SizeExpand | null = null
/** 边框轮廓,走刀路径等(包含偏移后的轮廓结合) borderUnit */
borderContour: PlaceBorderContour | null = null
// 板件扩展尺寸 数据集
plateExtraRemark: any
/** 优化前的配置及其轮廓等用于恢复 */
savedSetting
/** 备注 数据集 */
remarkParams: any
constructor(data: any = null, sourceType: number = 2) {
if (data != null) {
this.remarkParams = data.remarkParams
this.orderId = data.orderId
this.dataType = data.dataType
this.orderId = data.orderId
this.blockId = data.blockId
this.rawBoxNo = data.rawBoxNo
// 封边偏移值
this.offsetX = data.offSet && data.offSet.x ? StringFormat.toFixed(data.offSet.x, 3) : 0
this.offsetY = data.offSet && data.offSet.y ? StringFormat.toFixed(data.offSet.y, 3) : 0
// 开料长宽(不含封边)
this.cutWidth = data.cutSize ? StringFormat.toFixed(data.cutSize.width, 3) : 0
this.cutLength = data.cutSize ? StringFormat.toFixed(data.cutSize.height, 3) : 0
// 初始化 异形点阵
data.pointDetail.forEach((p) => { this.points.push(new BlockPoint(p)) })
// 初始化 异形点阵 含封边
if (!data.orgPointDetail) {
data.orgPointDetail = []
}
data.orgPointDetail.forEach((p) => { this.orgPoints.push(new BlockPoint(p)) })
if (!data.holes) {
data.holes = data.holeDetail || []
}
// 初始化 排钻列表
data.holes.forEach((h) => { this.holes.push(new BlockHole(h)) })
// 初始化 侧孔列表
if (!data.holeListSide) {
data.holeListSide = data.sideHoleDetail || []
}
data.holeListSide.forEach((sh) => { this.holeListSide.push(new SideHole(sh)) })
// 初始化 造型列表
data.modelDetail.forEach((t) => { this.models.push(new BlockModel(t)) })
// 初始化 侧面造型列表
if (!data.modelListSide) {
data.modelListSide = []
}
this.plateExtraRemark = data.plateExtraRemark
data.modelListSide.forEach((t) => { this.modelListSide.push(new SideModel(t)) }) // 侧面
this.holeListFaceA = this.holes.filter(t => t.face == FaceType.FRONT) // 正面
this.holeListFaceB = this.holes.filter(t => t.face == FaceType.BACK) // 反面
this.holeListThrough = []
this.modelListFaceA = this.models.filter(t => t.face == FaceType.FRONT && (t.depth < this.thickness || t.isVKnifeModel()))
this.modelListFaceB = this.models.filter(t => t.face == FaceType.BACK && (t.depth < this.thickness || t.isVKnifeModel()))
this.modelListThrough = this.models.filter(t => t.depth > this.thickness - 0.01 && t.isVKnifeModel() == false)
this.holeCountFront = this.holeListFaceA.length
this.holeCountBack = this.holeListFaceB.length
this.holeCountThrough = this.holeListThrough.length
this.holeCountSide = this.holeListSide.length
this.modelCountFront = this.modelListFaceA.length
this.modelCountBack = this.modelListFaceB.length
this.modelCountThrough = this.modelListThrough.length
this.hasModelThrogh = this.modelListThrough.length > 0
this.bigHoleInFaceA = this.holeListFaceA.some(t => t.holeType == HoleType.BIG_HOLE) // 大孔
}
this.isUnRegular = this.points.length > 0
}
/** 保存 开料配置 */
saveSetting() {
this.savedSetting = {}
this.savedSetting.offsetKnifeRadius = this.offsetKnifeRadius
this.savedSetting.preMillingSize = this.preMillingSize
this.savedSetting.isUseSameKnifeToHelpCut = this.isUseSameKnifeToHelpCut
this.savedSetting.useSameKnifeToHelpCutGap = this.useSameKnifeToHelpCutGap
// SizeExpand
this.savedSetting.preMillingExpandSize = this.preMillingExpandSize
this.savedSetting.modelExpandSize = this.modelExpandSize
this.savedSetting.vKnifeModelExpandSize = this.vKnifeModelExpandSize
this.savedSetting.sameKnfieHelpExpandSize = this.sameKnfieHelpExpandSize
this.savedSetting.currentExpandSize = this.currentSizeExpand
// 轮廓,铣刀路径
if (this.borderContour != null) {
this.savedSetting.borderContour = this.borderContour.clone()
}
}
loadSetting() {
if (!this.savedSetting)
return
this.offsetKnifeRadius = this.savedSetting.offsetKnifeRadius
this.preMillingSize = this.savedSetting.preMillingSize
this.isUseSameKnifeToHelpCut = this.savedSetting.isUseSameKnifeToHelpCut
this.useSameKnifeToHelpCutGap = this.savedSetting.useSameKnifeToHelpCutGap
// SizeOutOff
this.preMillingExpandSize = this.savedSetting.preMillingExpandSize
this.modelExpandSize = this.savedSetting.modelExpandSize
this.vKnifeModelExpandSize = this.savedSetting.vKnifeModelExpandSize
this.sameKnfieHelpExpandSize = this.savedSetting.sameKnfieHelpExpandSize
this.currentSizeExpand = this.savedSetting.currentSizeExpand
// 轮廓,铣刀路径
this.borderContour = this.savedSetting.borderContour
}
}
/** 开门类型(0无 1左 2右 3上 4下) */
export enum OpenDoorType {
/** 无 */
NONE = 0,
/** 左 */
LEFT = 1,
/** 右 */
RIGHT = 2,
/** 上 */
TOP = 3,
/** 下 */
BOTTOM = 4,
}
/** 纹理类型 */
export enum TextureType {
/** 正纹 */
NORMAL_TEXTURE = 0,
/** 可翻转 */
ROTATABLE_TEXTURE = 1,
/** 反纹 */
REVERSE_TEXTURE = 2,
}
/** 排钻 */
export class BlockHole {
/** 孔类别 */
holeType: HoleType = 0
/** 面 */
face: FaceType = 0
/** 侧孔所在面 */
sideFace: FaceType = FaceType.FRONT // 正面
/** 坐标x */
pointX: number = 0
/** 坐标y */
pointY: number = 0
/** 坐标z */
pointZ: number = 0
/** 半径 */
radius: number = 5
/** 深度 */
depth: number = 12
/** 终点坐标 */
endPoint: string = ''
/** 角度 */
angle: number = 0
/** CNC不能加工 cncUndo */
isCncCanNotProcess: boolean = false
/** 不能加工类型 unDoType */
cncCanNotProcessType = ''
/** 是否在开料机上处理 IsDo */
isCutting: boolean = true
knife: Knife | null = null
constructor(data: any = null) {
if (data != null) {
this.holeType = <HoleType>data.holeType
this.face = <FaceType>data.face
this.pointX = StringFormat.toFixed(data.pointX, 3)
this.pointY = StringFormat.toFixed(data.pointY, 3)
this.pointZ = StringFormat.toFixed(data.pointZ, 3)
this.radius = StringFormat.toFixed(data.radius, 3)
this.depth = StringFormat.toFixed(data.depth, 3)
this.angle = data.angle ? data.angle : 0
this.endPoint = data.endPoint
}
}
ToSideHole(block: PlaceBlock): SideHole {
let newH = new SideHole()
newH.holeType = this.holeType
newH.faceId = 0
newH.sideFace = SideFaceType.BOTTOM // 下侧面
newH.pointX = this.pointX
newH.pointY = this.pointY
newH.pointZ = this.pointZ
newH.radius = 4
let diameter = this.radius * 2
if (Math.abs(diameter - 8.3) < 0.1 || Math.abs(diameter - 6.3) < 0.1 || Math.abs(diameter - 11.5) < 0.1 || Math.abs(diameter - 12) < 0.1) {
newH.radius = this.radius
}
newH.depth = this.depth
let cells = this.endPoint.split(',')
if (cells.length >= 3) {
// 起点坐标
let bx = Number.parseFloat(cells[0])
let by = Number.parseFloat(cells[1])
// x 相等 , 侧孔方向 上下
if (Math.abs(bx - this.pointX) < 0.1) {
let toUpper = this.isToTop(block, by)
if (toUpper) // y+ 向上
{
newH.pointX2 = bx
newH.pointY2 = this.pointY + this.depth
newH.direct = 0
newH.faceId = 0
newH.sideFace = SideFaceType.BOTTOM_SIDE // 下侧面
} // y- 向下
else {
newH.pointX2 = bx
newH.pointY2 = this.pointY - this.depth
newH.direct = 2
newH.faceId = 2
newH.sideFace = SideFaceType.TOP_SIDE // 上侧面
}
}
else if (Math.abs(by - this.pointY) < 0.1) {
let toRight = this.isToRight(block, bx)
// y相等, 侧孔方向左右
if (toRight) {
// x+ 向右
newH.pointX2 = this.pointX + this.depth
newH.pointY2 = by
newH.direct = 3
newH.faceId = 3
newH.sideFace = SideFaceType.LEFT_SIDE // 左侧面
} // x- 向左
else {
newH.pointX2 = this.pointX - this.depth
newH.pointY2 = by
newH.direct = 1
newH.faceId = 1
newH.sideFace = SideFaceType.RIGHT_SIDE // 右侧面
}
} // x ,y 都不相等
else {
newH.pointX2 = bx
newH.pointY2 = by
newH.direct = -1
newH.faceId = 4
newH.sideFace = SideFaceType.SPECIAL_SHAPED_SIDE // 异形侧面
}
}
return newH
}
/** 向右(bx: 起点坐标X) */
private isToRight(block: PlaceBlock, bx: number): boolean {
// 在左侧外
if (bx < 0)
return true
// 在板内 靠左侧
if (bx > 22 && bx < 40)
return true
// 在右侧外
if (bx > block.width)
return false
// 在右侧外
if (bx > block.width - 40 && bx < block.width - 22)
return false
for (let i = 0; i < block.points.length; i++) {
let j = i + 1
if (j == block.points.length)
j = 0
let p1 = block.points[i]
let p2 = block.points[j]
if (Math.abs(p1.pointX - this.pointX) < 3 && Math.abs(p2.pointX - this.pointX) < 3 && (p1.pointY > this.pointY != p2.pointY > this.pointY)) {
return p1.pointY > p2.pointY
}
}
return false
}
/** 向上(起点坐标Y) */
private isToTop(block: PlaceBlock, by: number): boolean {
// 在下侧外
if (by < 0)
return true
// 靠近下侧
if (by > 22 && by < 40)
return true
if (by > block.length)
return false
if (by > block.length - 40 && by < block.length - 20)
return false
for (let i = 0; i < block.points.length; i++) {
let j = i + 1
if (j == block.points.length)
j = 0
let p1 = block.points[i]
let p2 = block.points[j]
if (Math.abs(p1.pointY - this.pointY) < 3 && Math.abs(p2.pointY - this.pointY) < 3 && (p1.pointX > this.pointX != p2.pointX > this.pointX)) {
return p1.pointX < p2.pointX
}
}
return false
}
}
/** 异形点 */
export class BlockPoint {
/** 坐标x */
pointX: number = 0
/** 坐标y */
pointY: number = 0
/** 凹凸度 */
curve: number = 0
/** 半径 */
radius: number = 0
/** 封边 */
sealSize: number = 0
/** 是否这条边需预洗 */
isPreCutRequired = false
constructor(data: any = null) {
if (data != null) {
let x = data.PointX != undefined ? data.PointX : data.pointX
let y = data.PointY != undefined ? data.PointY : data.pointY
let curve = data.Curve != undefined ? data.Curve : data.curve
let radius = 1 / curve
this.pointX = StringFormat.toFixed(x)
this.pointY = StringFormat.toFixed(y)
this.curve = curve
this.radius = StringFormat.toFixed(Math.abs(radius))
if (Math.abs(this.curve) < 1e-5) {
this.curve = 0
this.radius = 0
}
this.sealSize = data.SealSize != undefined ? data.SealSize : data.sealSize || 0
}
}
copy(): BlockPoint {
let nw = new BlockPoint()
nw.pointX = this.pointX
nw.pointY = this.pointY
nw.curve = this.curve
nw.radius = this.radius
nw.sealSize = this.sealSize
return nw
}
}
/** 侧孔 */
export class SideHole {
/** 孔类别 */
holeType: HoleType = 0
/** 面 */
faceId: number = 0
/** 侧孔所在面 */
sideFace: SideFaceType = SideFaceType.BOTTOM // 正面
/** 方向 0向上 1向左 2向下 3向右 -1斜 */
direct: number = 0
/** 坐标x */
pointX: number = 0
/** 坐标y */
pointY: number = 0
/** 坐标z */
pointZ: number = 0
/** 半径 */
radius: number = 5
/** 深度 */
depth: number = 12
/** 坐标x */
pointX2: number = 0
/** 坐标y */
pointY2: number = 0
// cncUndo: boolean = true; //cnc不能做.
/** CNC不能处理 */
isCncCanNotProcess: boolean = true
/** 是否可处理 IsDo */
isProcess: boolean = true
knife: Knife | null = null
constructor(data: any = null) {
if (data != null) {
this.holeType = <HoleType>data.holeType
this.faceId = data.face
this.sideFace = data.sideFace
this.direct = data.sideFace
this.pointX = StringFormat.toFixed(data.pointX, 3)
this.pointY = StringFormat.toFixed(data.pointY, 3)
this.pointZ = StringFormat.toFixed(data.pointZ, 3)
this.radius = StringFormat.toFixed(data.radius, 3)
this.depth = StringFormat.toFixed(data.depth, 3)
this.pointX2 = StringFormat.toFixed(data.pointX2, 3)
this.pointY2 = StringFormat.toFixed(data.pointY2, 3)
}
}
}
/** 孔类型 */
export enum HoleType {
/** 大孔 */
BIG_HOLE = 0,
/** 小孔 */
TINY_HOLE = 10,
/** 木削 */
WOOD_DUST = 20,
/** 木削大孔 */
WOOD_DUST_BIG_HOLE = 21,
/** 层板钉 */
LAMINATED_NAIL = 30,
/** 通孔 */
THROUGH_HOLE = 40,
/** 造型孔 */
MODELING_HOLE = -10,
/** 连接杆 */
CONNECTING_ROD = 50,
2025-06-24 11:48:26 +08:00
}
/** 板件造型 */
export class BlockModel {
/** 订单号 */
orderId: string = ''
/** 小板号 */
blockId: number = 0
/** 造型Id */
modelId: number = 0
/**线ID */
lineId: number = 0;
/** 纹路Id */
textureId: number = 0
/** 板面 */
face: FaceType = FaceType.UNSET
/** 刀号 */
knifeName: string = ''
/** 刀半径 */
knifeRadius: number = 0
/** 深度 */
depth: number = 0
/** 是否可以挖空后排版 */
canSpace = false
/** 是否是矩形 */
isRect = false
/** 是否倾斜 至少有一条边是斜的 */
isTilt = false
type = ''
knife: Knife | null | undefined = null
/** 有轮廓 */
hasContour() {
let val = false
try {
if (this.originModeling != null && this.originModeling.outline != 0 && this.originModeling?.outline.map(e => e?.pts).length > 0) {
val = true
}
} catch (error) {
console.log('handle hasContour error',error)
}
return val // this.originModeling?.outline.map(e=>e?.pts).length >0 //this.originModeling?.outline?.pts?.length > 0
}
modelWidth: any = 0
modelLength: any = 0
modelStartPoint: any = null
modelEndPoint: any = null
/**
* ()
* OriginModeling.outline.pts.x | y ; outline.buls
*/
originModeling: any = null
/** 点列表 */
pointList: BlockModelPoint[] = []
/** 实际替代刀直径 */
realKnifeRadius = 0
/** 实际替代刀点阵 */
realPointList: BlockModelPoint[] = []
/** 实际刀编号 */
realKnifeId = -1
/** cnc不能加工 cncUndo */
isCncCanNotProcess: boolean = true
/** 超限类型(cnc为何不能加工) unDoType */
cncCanNotProcessType = ''
/** 是否在开料机加工 IsDo */
isCutting: boolean = true
/** 二维造型的偏移数组 */
offsetList: ModelOffsetData[] = []
/** 转换过的二维刀路路径{isFaceB, name刀名称, offset偏移, knife刀, knifeId刀Id, knifeRadius刀半径, depth深度, points{x,y,z,bul,r}, orgOffset(源偏移)} */
VLines :any[] = []
offsetInfo = ''
/** 是否二维造型 */
isVKnifeModel(): boolean {
return this.offsetList.length > 0
}
/** 是否三维造型 */
is3VModel(): boolean {
return this.offsetList.length == 0 && this.pointList.some(t => Math.abs(t.depth - this.depth) > 0.01)
}
constructor(data: any = null) {
if (data != null) {
this.modelId = data.modelId
this.lineId = data.lineId
this.textureId = data.textureId
this.face = <FaceType>data.face
this.knifeName = data.knifeName ? data.knifeName.trim() : ''
this.knifeRadius = StringFormat.toFixed(data.knifeRadius, 3)
this.depth = StringFormat.toFixed(data.depth, 3)
if (data.modelPoint)
data.modelPoint.forEach(pt => {
this.pointList.push(new BlockModelPoint(pt))
})
if (data.modelOffSet)
data.modelOffSet.forEach(os => this.offsetList.push(new ModelOffsetData(os)))
if (this.offsetList.length > 0) {
let names: any = []
for (let os of this.offsetList) {
if (os.name == this.knifeName)
continue
if (names.includes(os.name))
continue
names.push(name)
}
if (names.length == 0)
this.offsetInfo = `${this.offsetList.length - 1}`
else
this.offsetInfo = `${this.offsetList.length - 1}(${names.join(' ')})`
}
if (data.originModeling) {
this.originModeling = JSON.parse(JSON.stringify(data.originModeling))
// 计算造型
// this.countModelWidthAndLength(this)
}
}
}
}
/** 造型点 */
export class BlockModelPoint {
/** 坐标X */
pointX: number = 2
/** 坐标Y */
pointY: number = 2
/** 半径 */
radius: number = 0
/** 深度 */
depth: number = 6
/** 凹凸度 */
curve: number = 0
constructor(data: any = null) {
if (data != null) {
this.pointX = StringFormat.toFixed(data.PointX || data.pointX)
this.pointY = StringFormat.toFixed(data.PointY || data.pointY)
this.radius = StringFormat.toFixed(Math.abs(data.Radius || data.radius))
this.depth = StringFormat.toFixed(data.Depth || data.depth)
this.curve = data.Curve || data.curve
}
}
copy(): BlockModelPoint {
let obj = new BlockModelPoint()
obj.pointX = this.pointX
obj.pointY = this.pointY
obj.radius = this.radius
obj.depth = this.depth
obj.curve = this.curve
return obj
}
}
/** 二维造型的偏移数据 */
export class ModelOffsetData {
/** 刀名称 */
name: string = ''
/** 偏移 */
offset: number = 0
/** 刀半径 */
radius: number = 0
/** 深度 */
depth: number = 0
/** 角度 */
angle: number = 0
/** 板面类型 */
face: FaceType = FaceType.UNSET
fullName() {
return `偏移${this.offset}${this.depth}${this.name}`
}
constructor(data: any = null) {
if (data != null) {
let off = 0
if (data.offset != undefined) {
off = data.offset
} else if (data.value != undefined) {
off = data.value
} else if (data.value != undefined) {
off = data.value
}
this.name = data.Name != undefined ? data.Name : data.name
this.offset = StringFormat.toFixed(data.offset || data.value || data.value)
this.radius = StringFormat.toFixed(data.Radius || data.radius)
this.depth = StringFormat.toFixed(data.Deep || data.depth)
this.face = data.Face != undefined ? <FaceType>data.Face : <FaceType>data.face
this.angle = StringFormat.toFixed(data.Angle || data.angle)
}
}
}
/**
* 0 1 2 3
*/
export enum SideFaceType {
/** 下 */
BOTTOM = 0,
/** 右 */
RIGHT = 1,
/** 上 */
TOP = 2,
/** 左 */
LEFT = 3,
/** 左侧面 */
LEFT_SIDE = 21,
/** 右侧面 */
RIGHT_SIDE = 22,
/** 上侧面 */
TOP_SIDE = 23,
/** 下侧面 */
BOTTOM_SIDE = 24,
/** 弧形侧面 */
CURVED_SIDE = 29,
/** 异形侧面 */
SPECIAL_SHAPED_SIDE = 30,
}
/**
*
*
*
*
* 1 face
* 2 originModeling X Y轴
* Y X
* 使
*
* checkIsTilt
* 使 isPointInBlock
*
*
*
*
* 1face
* 2
* 1X轴 || 使 isPointInBlock
* 2Y轴 || 使 isPointInBlock
* 3
*
* 3
*/
export class SideModel {
/** 订单号 */
orderId: string = ''
/** 小板号 */
blockId: number = 0
/** 造型Id */
modelId: number = 0
/**线ID */
lineId: number = 0;
/** 纹路Id */
textureId: number = 0
/** 板面 造型所在的边 第几条边 */
face: SideFaceType = 0
/** 刀号 */
knifeName: string = ''
/** 刀半径 */
knifeRadius: number = 0
/** 深度 */
depth: number = 0
/** 是否可以挖空后排版 */
canSpace = false
/** 是否是矩形 */
isRect = false
/** 是否倾斜 至少有一条边是斜的 */
isTilt = false
/** 暂时没用 */
type = ''
/** 造型方向 -2 未知(是异常情况 要排查) -1 斜的 0 下 1右 2上 3左 10 左下斜 11 右下斜 12 右上斜 13 左上斜 */
direction = 0
knife: Knife | null = null
/** 有轮廓 */
hasContour() { return this.originModeling != null && this.originModeling.outline != 0 && this.originModeling?.outline?.pts?.length > 0 }
/** 侧面造型 宽 */
modelWidth: any = 0
/** 侧面造型 长 */
modelLength: any = 0
/** 侧面造型 起点 */
modelStartPoint: any = null
/** 侧面造型 终点 */
modelEndPoint: any = null
/**
* ()
* OriginModeling.outline.pts.x | y ; outline.buls
*/
originModeling: any = null
/** 点列表 */
pointList: BlockSideModelPoint[] = []
/** 实际替代刀直径 */
realKnifeRadius = 0
/** 实际替代刀点阵 */
realPointList: BlockSideModelPoint[] = []
/** 实际刀编号 */
realKnifeId = -1
/** cnc不能加工 cncUndo */
isCncCanNotProcess: boolean = true
/** 超限类型(cnc为何不能加工) unDoType */
cncCanNotProcessType = ''
/** 是否在开料机加工 IsDo */
isCutting: boolean = true
/** 二维造型的偏移数组 */
offsetList: ModelOffsetData[] = []
/** 转换过的二维刀路路径{isFaceB, name刀名称, offset偏移, knife刀, knifeId刀Id, knifeRadius刀半径, depth深度, points{x,y,z,bul,r}, orgOffset(源偏移)} */
VLines = []
offsetInfo = ''
/** 是否二维造型 */
isVKnifeModel(): boolean {
return this.offsetList.length > 0
}
/** 是否三维造型 */
is3VModel(): boolean {
return this.offsetList.length == 0 && this.pointList.some(t => Math.abs(t.depth - this.depth) > 0.01)
}
constructor(data: any = null) {
if (data != null) {
this.modelId = data.modelId
this.lineId = data.lineId
this.textureId = data.textureId
this.face = <SideFaceType>data.face
this.knifeName = data.knifeName ? data.knifeName.trim() : ''
this.knifeRadius = StringFormat.toFixed(data.knifeRadius, 3)
this.depth = StringFormat.toFixed(data.depth, 3)
// if (data.originModeling)
// {
// this.originModeling = JSON.parse(JSON.stringify(data.originModeling))
// MachineHelper.countModelWidthAndLength(this)
// }
}
}
}
/** 小板区域 */
export enum BlockRegion {
/** 左下 = 0 */
LEFT_BOTTOM = 0,
/** 右下 = 1 */
RIGHT_BOTTOM = 1,
/** 右上 = 2 */
RIGHT_TOP = 2,
/** 左上 = 3 */
LEFT_TOP = 3,
}
/** 造型偏移 */
export class SizeExpand {
/** 左 */
left: number = 0
/** 右 */
right: number = 0
/** 上 */
top: number = 0
/** 下 */
bottom: number = 0
/** 板外扩宽 */
width: number = 0
/** 板外扩长 */
length: number = 0
/** 排版外扩宽 */
outWidth: boolean
/** 排版外扩长 */
outLength: boolean
/** 是否完成 */
hasDone: boolean
constructor(data: any = null) {
if (data != null) {
this.left = data.left || 0
this.right = data.right || 0
this.bottom = data.bottom || 0
this.top = data.top || 0
this.width = (this.left + this.right) || 0
this.length = (this.top + this.bottom) || 0
}
}
/** 设置长宽 */
setSize() {
this.width = this.left + this.right
this.length = this.top + this.bottom
}
toString() {
return `左:${this.left.toFixed(2)} 右:${this.right.toFixed(2)} 上:${this.top.toFixed(2)} 下:${this.bottom.toFixed(2)}`
}
}
/**
*
*/
export class BlockSideModelPoint {
/** 坐标X */
pointX: number = 2
/** 坐标Y */
pointY: number = 2
/** 坐标Z */
pointZ: number = 2
/** 半径 */
radius: number = 0
/** 深度 */
depth: number = 6
/** 凹凸度 */
curve: number = 0
constructor(data: any = null) {
if (data != null) {
this.pointX = StringFormat.toFixed(data.pointX || data.x)
this.pointY = StringFormat.toFixed(data.pointY || data.y)
this.pointZ = StringFormat.toFixed(data.pointZ || data.z)
this.radius = StringFormat.toFixed(Math.abs(data.radius || 0))
this.depth = StringFormat.toFixed(data.depth)
this.curve = data.curve || data.buls || 0
if (this.radius == 0 && this.curve != 0) {
this.radius = 1 / this.curve
}
}
}
copy(): BlockSideModelPoint {
let obj = new BlockSideModelPoint()
obj.pointX = this.pointX
obj.pointY = this.pointY
obj.radius = this.radius
obj.depth = this.depth
obj.curve = this.curve
return obj
}
}
/** 放置板的边框集合,内部轮廓,偏移后轮廓 */
export class PlaceBorderContour {
/** 放置方式 */
placeStyle: PlaceStyle = PlaceStyle.FRONT // 正面
/** 1成品轮廓 必须提前生成 */
borderFinal: CAD.Curve2d[]
/** 2原始轮廓 <不含预铣> 必须提前生成 */
borderOrg: CAD.Curve2d[]
/** 2.原始轮廓含预铣 border_preCut */
borderPreMilling: CAD.Curve2d[] = []
/** 2原始多段线 《不含预铣》 必须提前生成,用于 计算造型2v板外干涉轮廓 */
polylineOrg: Polyline | null = null
/** 3.1开料轮廓 <含预铣> */
border: CAD.Curve2d[] = []
/** 3.2真.开料轮廓.同刀辅助._有预铣带预铣) border_tdfz */
borderSameKnifeHelpCut: CAD.Curve2d[] = []
/** 走刀路径(预铣) */
cutLines: CAD.Curve2d[] = []
/** 走刀路径2(预铣 同刀辅助) cutLines_tdfz */
cutLinesSameKnifeHelpCut: CAD.Curve2d[] = []
/** 排版轮廓+预铣+同刀辅助+刀半径+缝隙/2 再与造型外扩并集 border_moving */
borderMoving: CAD.Curve2d[] = []
/** 优化轮廓,用于王者优化 border_wxyh */
borderKingOptimize: CAD.Curve2d[] = []
/** 板内轮廓挖穿造型(borders_inner) */
borderModelThrough: CAD.Curve2d[][] = []
/** 板内轮廓挖穿r(borders_inner_r) */
borderModelThroughR: number[] = []
/** 板内挖穿造型走刀路径,内部走刀轮廓(cutLines_inner) */
cutLinesModelThrough: CAD.Curve2d[][] = []
/** 板内排版轮廓,用于手动排版定位(borders_inner_place) */
borderInnerPlace: CAD.Curve2d[][] = []
/** 板内空间:挖穿造型(spaces_inner) */
blockInnerSpace: PlaceSpace[] = []
/** 板外空间:缺角(spaces_outer) */
blockOuterSpace: PlaceSpace[] = []
/** 空间,包括造型矩形与缺角空间 */
spaces: PlaceSpace[] = []
/** 2v刀路板外轮廓 */
polylines2vModel: Polyline[] = []
/** 造型,板外轮廓 */
polylinesOutModel: Polyline[] = []
/** 翻转后的这些轮廓集合 */
placeContours: PlaceBorderContour[]
constructor(placeStyle: PlaceStyle, borderFinal: CAD.Curve2d[], borderOrg: CAD.Curve2d[]) {
this.placeStyle = placeStyle
this.borderFinal = borderFinal
this.borderOrg = borderOrg
this.placeContours = []
}
/** 开料刀 半径变化了 */
cutKnifeChanged() {
this.cutLines = []
this.cutLinesSameKnifeHelpCut = []
this.borderMoving = []
// this.borderKingOptimize = null;
this.borderModelThrough = []
this.borderInnerPlace = []
this.blockInnerSpace = []
this.blockOuterSpace = []
if (this.placeContours)
this.placeContours.forEach(t => t.cutKnifeChanged())
}
/** 预铣值变化, 将有关轮廓全部清理 */
preValueChanged() {
// console.log('预铣值变化, 将有关轮廓全部清理')
this.border = []
this.borderSameKnifeHelpCut = []
this.cutLines = []
this.cutLinesSameKnifeHelpCut = []
this.borderMoving = []
// this.borderKingOptimize = null;
this.blockOuterSpace = []
if (this.placeContours)
this.placeContours.forEach(t => t.preValueChanged())
}
/** 同刀辅助 变化了 */
sameKnifeGapChanged() {
this.borderSameKnifeHelpCut = []
this.cutLinesSameKnifeHelpCut = []
this.borderMoving = []
// this.borderKingOptimize = null;
this.blockOuterSpace = []
if (this.placeContours)
this.placeContours.forEach(t => t.sameKnifeGapChanged())
}
/** 克隆 */
clone(): PlaceBorderContour {
let newObj = new PlaceBorderContour(this.placeStyle, this.borderFinal, this.borderOrg)
newObj.borderPreMilling = this.borderPreMilling
newObj.polylineOrg = this.polylineOrg
newObj.border = this.border
newObj.borderSameKnifeHelpCut = this.borderSameKnifeHelpCut
newObj.cutLines = this.cutLines
newObj.cutLinesSameKnifeHelpCut = this.cutLinesSameKnifeHelpCut
newObj.borderMoving = this.borderMoving
// newObj.borderKingOptimize = this.borderKingOptimize;
newObj.borderModelThrough = this.borderModelThrough
newObj.borderModelThroughR = this.borderModelThroughR
newObj.cutLinesModelThrough = this.cutLinesModelThrough
newObj.borderInnerPlace = this.borderInnerPlace
newObj.blockInnerSpace = this.blockInnerSpace
newObj.blockOuterSpace = this.blockOuterSpace
newObj.spaces = this.spaces
newObj.polylines2vModel = this.polylines2vModel
newObj.polylinesOutModel = this.polylinesOutModel
newObj.placeContours = []
for (let pc of this.placeContours) {
if (pc) {
let npc = pc.clone()
newObj.placeContours.push(npc)
}
}
console.log('克隆', newObj)
return newObj
}
}
/** 优化空间 */
export class PlaceSpace {
/** 大板ID */
boardId: number
/** 空间ID */
spaceId: number
/** 坐标x */
x: number
/** 坐标y */
y: number
/** 宽 */
width: number
/** 长 */
length: number
/** 是否是小板内部造型空间 IsInner */
isBlockInnerSpace = false
/** 顶点Y */
topY(): number { return this.y + this.length }
/** 右边X */
topX(): number { return this.x + this.width };
constructor(x: number, y: number, width: number, length: number) {
this.boardId = 0
this.spaceId = 0
this.x = x
this.y = y
this.width = width
this.length = length
}
/** 克隆 */
clone(): PlaceSpace {
let obj = new PlaceSpace(this.x, this.y, this.width, this.length)
return obj
}
static create(x1, y1, x2, y2): PlaceSpace {
return new PlaceSpace(x1, y1, x2 - x1, y2 - y1)
}
}
/** 开料板材 */
export class PlaceMaterial {
/** 订单号(*) */
orderId = ''
/** 板材ID(*) */
goodsId = ''
/** 板材名称(*) */
goodsName = ''
/** 规格(*) */
spec = ''
/** 材质(*) */
material = ''
/** 颜色(*) */
color = ''
/** 品牌(*) */
brand = ''
/** 有纹路 */
hasTexture = false
/** 最后保存时间 */
updateTime = ''
/** 纹路标识 */
get textureFlag(): string { return this.hasTexture ? '有' : '无' }
/** 板材全名 */
get fullName(): string { return `${this.hasTexture ? '' : '【无纹】'}${this.thickness} ${this.goodsName} ${this.material} ${this.color}` }
/** 板材原宽 */
orgWidth = 1220
/** 板材原长 */
orgLength = 2440
/** 板宽,用于生产 */
width = 1220
/** 板长 */
length = 2440
/** 板厚 */
thickness = 18
/** 全部尺寸 */
get fullSize(): string { return `${this.length}*${this.width}*${this.thickness}` }
/** 修边值(*) Border */
cutBorder = 3
/** 开料刀直径(*) CutDia */
diameter = 6
/** 开料刀路间隙(*) CutGap */
cutKnifeGap = 1
/** 预铣值 PreCutValue */
preMillingSize = 0
/** 是否辅助开料 HelpCut */
isHelpCut = false
/** 辅助开料标识 */
get strHelpCut() { return this.isHelpCut ? '✔' : '✘' }
/** 同刀辅助开料偏移 SameKnifeHelpCutGap */
helpCutGap = 0
/** 开料刀ID */
cutKnifeId = -1
/** 开料刀名称 */
cutKnifeName = ''
/** 辅助刀ID */
helpKnifeId = -1
/** 辅助刀名称 */
helpKnifeName = ''
get strHelpKnifeName() { return this.isHelpCut ? this.helpKnifeName : '' }
/** 是否已优化(*) isSorted */
isOptimized = false
get optimizedFlag() { return this.isOptimized ? '是' : '-' }
/** 大板数(*) */
boardCount = 0
/** 余料板数 */
remainBoardCount = 0
/** 最小板号(*) */
minBoardId = 0
/** 最大板号(*) */
maxBoardId = 0
/** 当前板号 */
currentBoardId = 0
/** 总平均利用率(*) AvgLyr_All */
avgUsageRateAll = 0
/** 前N块板(不包含最后一块板)的平均利用率(*) AvgLyr_NoLastOne */
avgUsageRateExcludeLastBoard = 0
/** 最后一块板的利用率(*) Lyr_LastOne */
usageRateLastBoard = 0
/** 分配到该板材的 小板数量 */
allBlockCount = 0
/**分配到该板材的优化后小板数量 -- 选择优化的板件数目 */
selectedBlockCount = 0
/** 分配到该板材的优化后 未被优化的 小板数量 */
noPlaceBlockCount = 0
/** 优化时大板数(*) */
optimizingBoardCount = 0
/** 优化时余料板数 */
optimizingRemainBoardCount = 0
/** 优化时不含余料的大板数 */
get OptimizingNoRemainBoardCount() { return this.optimizingBoardCount - this.optimizingRemainBoardCount }
/** 优化时总平均利用率(*) */
optimizingAvgUsageRateAll = 0
/** 优化时前N块板(不包含最后一块板)的平均利用率(*) */
optimizingAvgUsageRateExcludeLastBoard = 0
/** 优化时最后一块板的利用率(*) */
optimizingUsageRateLastBoard = 0
/** 优化时间 */
placeTime
/** 使用大板情况(*) */
usedBoardInfo = ''
/** 小板排版情况(*) */
blockPlaceInfo = ''
/** 余料板情况 */
remainBoardInfo = ''
/** 翻面开料的大板数 BoardCount_do2Face */
boardCountFlipFace = 0
/** 小板数 */
blockCount = 0
/** 小板总面积 */
blockArea = 0
/** 封边长度 [{t:1,l:233}, {t:2,l:100}] */
edgeSealLengthList = []
edgeSealLengthStr() {
let s = ''
for (let rt of this.edgeSealLengthList) {
s += `[${rt.t}]${rt.l}米;`
}
return s
}
/** 余料前利用(异形优化) */
// ScrapBoardList: ScrapBoard[] = [];
remainBoardList: RemainBoard[] = []
/** 后余料板 */
remainList: any[] = []
/** 大板(优化)列表 */
boardList: PlaceBoard[] = []
/** 小板(优化)列表 */
blockList: PlaceBlock[] = []
/** 是否有锁定的大板 */
hasBoardLocked() { return this.boardList.some(t => t.isLocked) }
/** 最优优化结果(临时) */
tempBestPlaceResult: MaterialPlaceResult | null = null
tempBestPlaceResultLast: MaterialPlaceResult | null = null
tempBestPlaceResultLastTime = 0
/** 需要最后一片重新计算 */
rePlaceLastBoardRequired = false
tempPlaceUnregular: boolean = false
/** 最优优化结果(临时)标识 */
tempPlaceResultFlag() { return (this.tempBestPlaceResult) ? '有' : '-' }
/** 最优优化结果是否只使用没锁定的 */
tempPlaceResultOnyUnlockedBoard = false
/** 最后优化错误信息 */
tempPlaceResultError: string = ''
/** 移动小板临时仓 */
moveBlockList: PlaceBlock[] = []
/** 新优化前原配置,用于取消优化后还原到原先的配置 */
savedSetting
constructor(data: any = null) {
if (data != null) {
this.boardList = data?.boardList || []
this.boardCount = data?.boardCount || 0
this.orderId = data.orderId
this.goodsId = data.goodsId
this.goodsName = data.goodsName
this.spec = data.spec
this.material = data.material
this.color = data.color
this.brand = data.brand
this.hasTexture = true
if (!(data.hasTexture == null || data.hasTexture == undefined))
this.hasTexture = data.hasTexture
this.orgWidth = StringFormat.toFixed(Number(data.orgWidth || data.width))
this.orgLength = StringFormat.toFixed(Number(data.orgLength || data.length))
this.width = StringFormat.toFixed(Number(data.width))
this.length = StringFormat.toFixed(Number(data.length))
this.thickness = StringFormat.toFixed(Number(data.thickness))
this.cutBorder = StringFormat.toFixed(Number(data.cutBorder))
this.diameter = StringFormat.toFixed(Number(data.diameter))
this.cutKnifeGap = StringFormat.toFixed(Number(data.cutKnifeGap))
this.preMillingSize = data.preMillingSize || 0
this.isHelpCut = data.isHelpCut || false
this.helpCutGap = data.helpCutGap || 0
this.cutKnifeId = data.cutKnifeId || -1
this.helpKnifeId = data.helpKnifeId || -1
this.isOptimized = Boolean(data.isOptimized)
this.boardCount = StringFormat.toFixed(Number(data.boardCount))
this.remainBoardCount = StringFormat.toFixed(data.remainBoardCount ? Number(data.remainBoardCount) : 0)
this.minBoardId = Number(data.minBoardId)
this.maxBoardId = Number(data.maxBoardId)
this.avgUsageRateAll = StringFormat.toFixed(Number(data.avgUsageRateAll))
this.avgUsageRateExcludeLastBoard = StringFormat.toFixed(Number(data.avgUsageRateExcludeLastBoard))
this.usageRateLastBoard = StringFormat.toFixed(Number(data.usageRateLastBoard))
this.usedBoardInfo = data.usedBoardInfo
this.blockPlaceInfo = data.blockPlaceInfo
this.remainBoardInfo = data.remainBoardInfo ? data.remainBoardInfo : ''
// this.remainBoardList = data.remainBoardList ? data.remainBoardList : []
if (Array.isArray(data.remainBoardList)) {
this.remainBoardList = data.remainBoardList
} else {
this.remainBoardList = data.remainBoardInfo ? JSON.parse(this.remainBoardInfo) : ''
}
this.updateTime = data['this.updateTime'] || ''
}
}
/** 保存 原尺寸,开料刀,预铣,辅助开料 */
saveSetting() {
let setting: any = {}
// 尺寸,
setting.orgWidth = this.orgWidth
setting.orgLength = this.orgLength
setting.width = this.width
setting.length = this.length
setting.thickness = this.thickness
setting.preMillingSize = this.preMillingSize
setting.isHelpCut = this.isHelpCut
setting.helpCutGap = this.helpCutGap
setting.diameter = this.diameter
setting.cutKnifeId = this.cutKnifeId
setting.cutKnifeName = this.cutKnifeName
setting.helpKnifeId = this.helpKnifeId
setting.helpKnifeName = this.helpKnifeName
this.savedSetting = setting
// 小板备份资料
let createTime = Date.now()
for (let block of this.blockList) {
if (block.blockDetail) {
let savedObj = block.blockDetail.savedSetting
if (savedObj && savedObj.createTime == createTime)
break // 已备份
block.blockDetail.saveSetting()
block.blockDetail.savedSetting.createTime = createTime
}
}
}
loadSetting() {
if (this.savedSetting == null)
return
// 尺寸,
this.orgWidth = this.savedSetting.orgWidth
this.orgLength = this.savedSetting.orgLength
this.width = this.savedSetting.width
this.length = this.savedSetting.length
this.thickness = this.savedSetting.thickness
this.preMillingSize = this.savedSetting.preMillingSize
this.isHelpCut = this.savedSetting.isHelpCut
this.helpCutGap = this.savedSetting.helpCutGap
this.diameter = this.savedSetting.diameter
this.cutKnifeId = this.savedSetting.cutKnifeId
this.cutKnifeName = this.savedSetting.cutKnifeName
this.helpKnifeId = this.savedSetting.helpKnifeId
this.helpKnifeName = this.savedSetting.helpKnifeName
for (let block of this.blockList) {
if (block.blockDetail) {
block.blockDetail.loadSetting()
block.blockDetail.savedSetting = null
}
}
}
}
/** 排单大板 */
export class PlaceBoard {
/** 数据源ID */
sourceId = 0
/** 大板编码(余料板号) */
boardNo = ''
/** 大板ID */
boardId = 0
/** 大板ID(按全排单) */
fullBoardId = 0
/** 大板宽 */
width = 0
/** 大板长/高 */
length = 0
/** 面积 */
area = 0
/** 小板数 */
blockCount = 0
/** 利用面积 BlockSize */
blockArea = 0
/** 利用率 */
usageRate = 0
/** 余料板异形 IsOddmengt */
isAdnormal() { return this.points && this.points.length > 0 }
/** 余料板异形点{x,y,bul} */
points: any[] = []
/** 是否加工2面, 需反面 IsDo2Face */
isTwoFaceProcessing() {
let res = this.blockList.some(e => e.isDoubleFaceProcess())
return res
}
/** 是否锁定 */
isLocked = false
/** 是否开料 */
isCuted = false
/**
*
* 0 1 2
*/
cutedType = 0
/** 小板列表 */
blockList: PlaceBlock[] = []
/** 余料板列表 ScrapBlockList */
remainBlockList: RemainBlock[] = []
/** 需要生成余料空间 needToScrapSpace */
isCreateRemainSpace = false
/** 异形大板的轮廓线 */
polyline?: Polyline
/** 无法加工的左边出现造型 */
hasModelOnLeft = false
/** 无法加工的右边出现造型 */
hasModelOnRight = false
/** 构造函数 */
constructor(boardId: number, width: number, length: number, sourceId = 0, boardNo = '') {
this.sourceId = sourceId
this.boardId = boardId
this.width = width
this.length = length
this.boardNo = boardNo
this.area = width * length * 0.000001
this.blockList = []
}
reset() {
this.blockCount = this.blockList.length
this.blockArea = ArrayExt.sum(this.blockList, t => t.area)
this.usageRate = (100 * this.blockArea) / this.area
// this.isTwoFaceProcessing = this.blockList.some(t => t.isCutOtherFace)
}
addBlock(block: PlaceBlock) {
if (this.blockList.includes(block))
return
this.blockList.push(block)
this.reset()
}
removeBlock(block: PlaceBlock) {
let index = this.blockList.findIndex(t => t == block)
if (index == -1)
return
this.blockList.splice(index, 1)
this.reset()
}
getSize(): string {
return `${this.width}*${this.length}`
}
}
/** 实际开料的板材 || 余料板材 */
export class RemainBoard {
/** 余料板ID */
id: number | string = ''
/** 源排单ID */
orgPlanId: number | string = ''
/** 排单ID */
planId: number | string = ''
/** 状态(未使用 = 0, 已使用 = 1) */
status: number = 0
/** 商品ID */
goodsId: number | string = ''
/** 商品名 */
goodsName: string = ''
/** 材质 */
material: string = ''
// /** 材料名 */
// materialName: string = '';
/** 颜色 */
color: string = ''
/** 宽 */
width: number = 0
/** 长 */
length: number = 0
/** 品牌 */
brand: string = ''
// /** 保存仓库 */
// storeHouse: string = '';
/** 纹路 */
texture?: string
/** 排单号 */
planCode: string = ''
/** 数量 */
count: number = 0
/** 排版宽 */
placeWidth() { return this.placeStyle % 2 == 0 ? this.width : this.length }
/** 排版长 */
placeLength() { return this.placeStyle % 2 == 0 ? this.length : this.width }
/** 厚度 */
thickness: number | undefined
/** 轮廓 */
outLineJson: string = '{}'
/** 备注 */
remark: string = ''
/** */
basePolyline: Polyline | undefined
/** 排版样式 */
placeStyle: PlaceStyle = PlaceStyle.FRONT
/** 排版多段线 */
placePolyline: Polyline | undefined
/** 是否已使用 */
isUsed: boolean = false
/** 是否已入库 */
isStored = false
/** 是否开料 */
isCuted = false
/**是否开料 */
cutedType = 0
/** 实际优化板材的优化数据 */
// placeBoardList: BoardPlaceResult[] = []
/** 实际开料大板的数量 */
usedCount = 0
/** 总利用率 */
avgUsageRateAll = 0
/** 前N块板利用率 */
avgUsageRateExcludeLastBoard = 0
/** 最后一块板利用率 */
usageRateLastBoard = 0
copy(): RemainBoard {
let obj = new RemainBoard()
obj.id = this.id
obj.planId = this.planId
obj.status = this.status
obj.goodsId = this.goodsId
obj.goodsName = this.goodsName
obj.material = this.material
obj.color = this.color
obj.width = this.width
obj.length = this.length
obj.thickness = this.thickness
obj.outLineJson = this.outLineJson
obj.remark = this.remark
obj.placeStyle = this.placeStyle
obj.isUsed = this.isUsed
obj.texture = this.texture
return obj
}
}
/** 余料小板 */
export class RemainBlock {
/** 余料板ID */
remainId: number = 0
/** 排版坐标x */
placeX: number
/** 排版坐标y */
placeY: number
/** 开料宽 */
placeWidth: number
/** 开料长 */
placeLength: number
/** 是否不规则 */
isUnRegular = false
/** 是否重叠 */
isOverlap = false
/** 是否已录入余料库 */
isStored = false
private pointlist: any = []
points() {
if (this.pointlist.length == 0) {
this.pointlist.push({ x: 0, y: 0 })
this.pointlist.push({ x: this.placeWidth, y: 0 })
this.pointlist.push({ x: this.placeWidth, y: this.placeLength })
this.pointlist.push({ x: 0, y: this.placeLength })
}
return this.pointlist
}
private pl: Polyline | null = null
get polyline() { return this.pl }
set polyline(v) { this.pl = v; this.polylineOffset = null }
/** 多段线偏移 */
polylineOffset?: Polyline | null
constructor(x, y, width, length) {
this.placeX = x
this.placeY = y
this.placeWidth = width
this.placeLength = length
}
/** 修改大小 */
reSize(width, length) {
if (this.isUnRegular)
return
this.placeWidth = width
this.placeLength = length
this.pointlist = []
this.pl = null
this.polylineOffset = null
}
setPoints(pts) {
this.pointlist = pts
if (this.pointlist.length == 0 || this.pointlist.length == 4)
this.isUnRegular = false
else
this.isUnRegular = true
this.polyline = null
this.polylineOffset = null
}
load(data) {
this.remainId = data.remainId
this.placeX = data.placeX
this.placeY = data.placeY
this.placeWidth = data.placeWidth
this.placeLength = data.placeLength
this.isUnRegular = data.isUnRegular
this.pointlist = data.pointlist
this.isStored = data.isStored || false
}
}
/** 板材优化结果 */
export class MaterialPlaceResult {
/** 线程ID */
threadId = 0
/** 使用时间 */
usedTime = 0
/** 优化次数 */
placeCount = 0
/** 大板数 */
boardCount = 0
/** 总平均利用率 */
avgUsageRateAll = 0
/** 前N块板(不包含最后一块板)的平均利用率 */
avgUsageRateExcludeLastBoard = 0
/** 最后一块板的利用率 */
usageRateLastBoard = 0
/** 余料板数 */
remainBoardCount = 0
/** 大板列表 */
boards: BoardPlaceResult[] = []
/** 小板优化数据 */
results: BlockPlaceResult[] = []
/** 优化是否全部完成 */
placeStoped = false
/** 余料板利用情况 */
remailBoardList: any[] = []
constructor() {
}
/** 比other 更好 */
isBetterThan(other: MaterialPlaceResult): boolean {
if (this.boardCount < other.boardCount)
return true
if (this.usageRateLastBoard < other.usageRateLastBoard)
return true
return false
}
}
export class BoardPlaceResult {
/** 大板ID */
boardId = 0
/** 宽 */
width = 0
/** 长 */
length = 0
/** 是否余料板 */
isRemainBoard = false
/** 余料板编码 */
remainNo = ''
/** 余料板ID */
remainId = 0
/** 是否废弃物 */
isScrap = false
/** 点列表 */
points: any[] = []
/** 小板排版结果 */
blocks: BlockPlaceResult[] = []
/** 小板排版 */
objects: any[] = []
/** 面积 */
area = 0
/** 是否双面加工 */
isTwoFaceProcess = false
cutedType = 0
isLock = false
/**当前大板的利用率 */
// avgUsageRate = 0
constructor() {
}
/** 是否有异形板重叠 */
hasOverLapBlock() {
for (let i = 0; i < this.blocks.length; i++) {
let b1 = this.blocks[i]
for (let j = i + 1; j < this.blocks.length; j++) {
let b2 = this.blocks[j]
if (this.isOverLap(b1, b2))
return true
}
}
return false
}
/** 两块板是否是否重叠 */
isOverLap(b1: BlockPlaceResult, b2: BlockPlaceResult): boolean {
let l1 = { x: b1.placeX, y: b1.placeY + b1.length }
let r1 = { x: b1.placeX + b1.width, y: b1.placeY }
let l2 = { x: b2.placeX, y: b2.placeY + b2.length }
let r2 = { x: b2.placeX + b2.width, y: b2.placeY }
if (l1.x > r2.x || l2.x > r1.x)
return false
if (l1.y < r2.y || l2.y < r1.y)
return false
return true
}
}
/** 小板优化结果 */
export class BlockPlaceResult {
/** 小板号 */
blockId = 0
/** 小板编号 */
blockNo = ''
/** 大板ID */
boardId: number
/** 排版情况: 排版ID */
placeId: number
/** 排版情况: 大板坐标X */
placeX: number // 坐标
/** 排版情况: 大板坐标Y */
placeY: number
/** 宽 */
width: number
/** 长 */
length: number
/** 排版情况正纹 */
placeStyle: PlaceStyle
/** 面积 */
area: number
constructor(blockId: number, boardId: number, placeId: number, x: number, y: number, width: number, length: number, pstyle: PlaceStyle, area: number) {
this.blockId = blockId
this.boardId = boardId
this.placeId = placeId
this.placeX = x
this.placeY = y
this.placeStyle = pstyle
this.width = width
this.length = length
this.area = area
}
}