2762 lines
82 KiB
TypeScript
2762 lines
82 KiB
TypeScript
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"
|
||
|
||
|
||
/**配置项属性 */
|
||
export class confItem {
|
||
/** 属性key */
|
||
key: string
|
||
/** 说明 */
|
||
label: string
|
||
/** 属性value 值 */
|
||
value: Array<any> | any
|
||
}
|
||
/** 内部指令 接收 */
|
||
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,
|
||
}
|
||
|
||
|
||
// 加工项 点数据
|
||
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>
|
||
|
||
/**
|
||
* 板面类型
|
||
* 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
|
||
}
|
||
|
||
/** 开料刀 */
|
||
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);
|
||
}
|
||
/** 设置刀具(轴号, 刀名, 刀直径, 是否主刀, 是否铣孔, 是否开料刀) */
|
||
// 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,
|
||
}
|
||
|
||
/** 板件造型 */
|
||
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
|
||
*
|
||
* 要求:要得到
|
||
*
|
||
* 转换逻辑
|
||
* 1、通过face 获取 该造型所在的边
|
||
* 2、将这条边 与 板件的坐标轴做比较 判断平行
|
||
* 情况1:与板件的X轴 平行 则造型 可能为 上 || 下 ,使用 isPointInBlock 判断 具体是上 还是下
|
||
* 情况2:与板件的Y轴 平行 则造型 可能为 左 || 右 , 使用 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
|
||
}
|
||
} |