!2808 优化:添加对纹组和拆单时的检测算法

pull/2803/MERGE
林三 4 months ago committed by ChenX
parent d4ea91d1a1
commit da3604d47d

@ -9,7 +9,9 @@ import { arrayRemove } from "../../Common/ArrayExt";
import { EBoardKeyList } from "../../Common/BoardKeyList"; import { EBoardKeyList } from "../../Common/BoardKeyList";
import { CommandNames } from "../../Common/CommandNames"; import { CommandNames } from "../../Common/CommandNames";
import { GroupEntitysByBox } from "../../Common/GroupEntitysByBox"; import { GroupEntitysByBox } from "../../Common/GroupEntitysByBox";
import { CheckInterfereTool } from "../../Common/InterfereUtil";
import { KeyBoard } from "../../Common/KeyEnum"; import { KeyBoard } from "../../Common/KeyEnum";
import { LogType } from "../../Common/Log";
import { AlignLineGroupRecord } from "../../DatabaseServices/AlignLine/AlignLineGroupRecord"; import { AlignLineGroupRecord } from "../../DatabaseServices/AlignLine/AlignLineGroupRecord";
import { Board } from "../../DatabaseServices/Entity/Board"; import { Board } from "../../DatabaseServices/Entity/Board";
import { LinesType } from "../../DatabaseServices/Entity/BoardInterface"; import { LinesType } from "../../DatabaseServices/Entity/BoardInterface";
@ -430,79 +432,149 @@ export class AlignLineGroupPanel extends React.Component<{ store: AlignLineGroup
await CommandWrap(async () => await CommandWrap(async () =>
{ {
let ssRes = await app.Editor.GetSelection({ while (true)
Msg: `请选择需要加入对纹组的实体`,
Filter: { filterTypes: [Board] }
});
if (ssRes.Status === PromptStatus.OK)
{ {
let brs = ssRes.SelectSet.SelectEntityList as Board[]; let alignLineGroupSpacing = this.props.store.m_Option.alignLineGroupSpacing ?? 20;
if (!brs.every(br => isParallelTo(br.Normal, brs[0].Normal))) let ssRes = await app.Editor.GetSelection({
Msg: `选择加入对纹组的板件(当前规定对纹组板件间距小于等于:${alignLineGroupSpacing})`,
KeyWordList: [{ key: "D", msg: "板件间距" }],
Filter: { filterTypes: [Board] }
});
if (ssRes.Status === PromptStatus.Keyword)
{ {
AppToaster.show({ if (ssRes.StringResult === "D")
message: "所选的板件不在同一平面上", {
timeout: 5000, let ret = await app.Editor.GetDistance({ Msg: "当前规定板件间距小于等于:", Default: alignLineGroupSpacing });
intent: Intent.WARNING, if (ret.Status === PromptStatus.OK)
}); {
return; if (ret.Distance < 0 || isNaN(ret.Distance))
{
app.Editor.Prompt("请输入为正数的间距!", LogType.Error);
return;
}
this.props.store.m_Option.alignLineGroupSpacing = Math.abs(ret.Distance);
userConfigStore.SaveConfig(BoardModalType.AlignLineGroupStore, this.props.store, { toaster: false });
}
else if (ret.Status === PromptStatus.Cancel)
return;
}
} }
else if (ssRes.Status === PromptStatus.OK)
let invalidBoard = brs.filter(br => br.AlignLineObject);
if (invalidBoard.length)
{ {
AppToaster.show({ let brs = ssRes.SelectSet.SelectEntityList as Board[];
message: "存在已经组合的板!",
timeout: 5000,
intent: Intent.WARNING,
}, "hasInvalidBoard");
app.Editor.SetSelection(invalidBoard); let tool = new CheckInterfereTool();
return; let p = await tool.Check(brs);
} if (p.length)
{
AppToaster.show({
message: "所选的板件存在干涉!",
timeout: 7000,
intent: Intent.WARNING,
});
return;
}
let brBoxMap = GroupEntitysByBox(brs); let spliteSizeBrs = brs.filter((b) => b.BoardProcessOption.spliteHeight || b.BoardProcessOption.spliteThickness || b.BoardProcessOption.spliteWidth);
let name = this.props.store.selectedLeftNode;
for (let [box, brs] of brBoxMap) if (spliteSizeBrs.length)
{
if (brs.length < 2)
{ {
app.Editor.SetSelection(spliteSizeBrs);
AppToaster.show({ AppToaster.show({
message: "存在无效的对纹组合!", message: "所选的板件存在有拆单尺寸(已选中)!",
timeout: 5000, timeout: 7000,
intent: Intent.WARNING, intent: Intent.WARNING,
}, "notGroupAlignLine"); });
continue; return;
}
let invalidBoard = brs.filter(br => br.AlignLineObject);
if (invalidBoard.length)
{
app.Editor.SetSelection(invalidBoard);
AppToaster.show({
message: "存在已经组合的板(已选中)!",
timeout: 7000,
intent: Intent.WARNING,
}, "hasInvalidBoard");
return;
} }
const FirstBr = brs[0]; if (!brs.every(br => isParallelTo(br.Normal, brs[0].Normal)))
const ComposingFace = FirstBr.BoardProcessOption.composingFace;
const LineType = FirstBr.BoardProcessOption.lines;
const Material = FirstBr.BoardProcessOption.material;
const Color = FirstBr.BoardProcessOption.color;
const MatName = FirstBr.BoardProcessOption.boardName;
const Thickness = FirstBr.Thickness;
let canAdd = brs.every(
br => br.BoardProcessOption.material === Material &&
br.BoardProcessOption.color === Color &&
br.BoardProcessOption.boardName === MatName &&
br.BoardProcessOption.lines === LineType &&
br.BoardProcessOption.composingFace === ComposingFace &&
equaln(br.Thickness, Thickness)
);
if (!canAdd)
{ {
AppToaster.show({ AppToaster.show({
message: "所选板块中,板材料、板材颜色、板材名、板厚、排版面或者板纹路不一致,无法组成对纹组!", message: "所选的板件不在同一平面上",
timeout: 5000, timeout: 7000,
intent: Intent.WARNING, intent: Intent.WARNING,
}); });
continue; return;
} }
let brBoxMap = GroupEntitysByBox(brs, alignLineGroupSpacing);
let name = this.props.store.selectedLeftNode;
for (let [box, brs] of brBoxMap)
{ {
//超长板件 //---独立板件检查 begin---
if (brs.length < 2)
{
app.Editor.SetSelection(brs);
AppToaster.show({
message: "存在独立的单板(已选中),未组成对纹组合!",
timeout: 7000,
intent: Intent.WARNING,
}, "notGroupAlignLine");
return;
}
//---材料检查 begin---
const firstBr = brs[0];
const composingFace = firstBr.BoardProcessOption.composingFace;
const lineType = firstBr.BoardProcessOption.lines;
const material = firstBr.BoardProcessOption.material;
const color = firstBr.BoardProcessOption.color;
const matName = firstBr.BoardProcessOption.boardName;
const thickness = firstBr.Thickness;
let hasDifferentMtl = brs.every(
br => br.BoardProcessOption.material === material &&
br.BoardProcessOption.color === color &&
br.BoardProcessOption.boardName === matName &&
br.BoardProcessOption.lines === lineType &&
br.BoardProcessOption.composingFace === composingFace &&
equaln(br.Thickness, thickness)
);
if (!hasDifferentMtl)
{
app.Editor.SetSelection(brs);
AppToaster.show({
message: "所选板块中,板材料、板材颜色、板材名、板厚、排版面或者板纹路不一致,无法组成对纹组!",
timeout: 7000,
intent: Intent.WARNING,
});
return;
}
//---材料检查 end---
//---对纹方向检查 begin---
const yNormal = new Vector3().setFromMatrixColumn(firstBr.OCS, 1);
let hasDifferentYNormal = brs.every(
br => isParallelTo(yNormal, new Vector3().setFromMatrixColumn(br.OCS, 1))
);
if (!hasDifferentYNormal)
{
app.Editor.SetSelection(brs);
AppToaster.show({
message: "所选板块中,存在实际纹路方向不一致(已选中),无法组成对纹组!",
timeout: 7000,
intent: Intent.WARNING,
});
return;
}
//---对纹方向检查 end---
//---超长板件检查 begin---
let ocsInv = brs[0].OCSInv; let ocsInv = brs[0].OCSInv;
let spliteSize = box.applyMatrix4(ocsInv).getSize(new Vector3); let spliteSize = box.applyMatrix4(ocsInv).getSize(new Vector3);
let width = spliteSize.x; let width = spliteSize.x;
@ -516,24 +588,29 @@ export class AlignLineGroupPanel extends React.Component<{ store: AlignLineGroup
if (height > userConfig.maxSize.height + 1e-5 || width > userConfig.maxSize.width + 1e-5) if (height > userConfig.maxSize.height + 1e-5 || width > userConfig.maxSize.width + 1e-5)
{ {
app.Editor.SetSelection(brs);
AppToaster.show({ AppToaster.show({
message: "组合的对纹组尺寸超长!", message: "组合的对纹组尺寸超长!",
timeout: 5000, timeout: 7000,
intent: Intent.DANGER, intent: Intent.DANGER,
}); });
continue; return;
} }
} //---超长板件检查 end---
let al = new AlignLineGroupRecord; let al = new AlignLineGroupRecord;
al.Name = name || "未命名"; al.Name = name || "未命名";
app.Database.AlignLineGroupTable.Add(al); app.Database.AlignLineGroupTable.Add(al);
for (let br of brs) for (let br of brs)
{ {
br.AlignLineObject = al.Id; br.AlignLineObject = al.Id;
al.Objects.push(br.Id); al.Objects.push(br.Id);
}
} }
break;
} }
else
break;
} }
}, CommandNames.AddAlignLineGroup); }, CommandNames.AddAlignLineGroup);

@ -22,10 +22,13 @@ interface TemplatePgData //跟随模块自动识别的对纹组的数据
export interface AlignLineGroupOption export interface AlignLineGroupOption
{ {
alignLineGroupCategory: string[]; alignLineGroupCategory: string[];
alignLineGroupSpacing: number;
} }
const DefaultAlingnLineOption: AlignLineGroupOption = { const DefaultAlingnLineOption: AlignLineGroupOption = {
alignLineGroupCategory: ["门板"], alignLineGroupCategory: ["门板"],
alignLineGroupSpacing: 20
}; };
export class AlignLineGroupModalStore extends Singleton implements IConfigStore export class AlignLineGroupModalStore extends Singleton implements IConfigStore

@ -230,15 +230,17 @@ async function ExecChaiDan(chaiDanRoute: ErpRoutes)
return; return;
} }
const alignLineErrorBoards = CheckAlignLineMtl(boardList); const { errorBrs, msg } = await CheckAlignLineMtl(boardList);
if (alignLineErrorBoards.length)
if (errorBrs.length)
{ {
let res = await AppConfirm.show({ let res = await AppConfirm.show({
intent: Intent.WARNING, intent: Intent.WARNING,
message: "部分板件与对纹组中首个板材料、板材颜色、板材名、板厚、排版面或者板纹路不一致 , 详情见左下角日志 , 是否先排查?" message: `${msg} , 是否先排查?`
}); });
if (res) if (res)
{ {
app.Editor.SetSelection(errorBrs);
return; return;
} }
} }

@ -1,8 +1,9 @@
import { Box3, Vector2 } from "three"; import { Box3, Vector2, Vector3 } from "three";
import { CheckInterfereTool } from "../../Common/InterfereUtil";
import { InteractionLog, LogType } from "../../Common/Log"; import { InteractionLog, LogType } from "../../Common/Log";
import { AlignLineGroupRecord } from "../../DatabaseServices/AlignLine/AlignLineGroupRecord"; import { AlignLineGroupRecord } from "../../DatabaseServices/AlignLine/AlignLineGroupRecord";
import { Board } from "../../DatabaseServices/Entity/Board"; import { Board } from "../../DatabaseServices/Entity/Board";
import { equaln, equalv2 } from "../../Geometry/GeUtils"; import { equaln, equalv2, isParallelTo } from "../../Geometry/GeUtils";
import { AlignLineBoardObject, AlignLineGroupObject } from "./Models/CadObject"; import { AlignLineBoardObject, AlignLineGroupObject } from "./Models/CadObject";
//解析对纹信息 //解析对纹信息
@ -49,17 +50,26 @@ export function DealAlignLineGroup(alignLineMap: Map<string, Board[]>, alignLine
} }
} }
export function CheckAlignLineMtl(brs: Board[]) export async function CheckAlignLineMtl(brs: Board[]): Promise<{ errorBrs: Board[]; msg: string; }>
{ {
let alignLineErrorBoards: Board[] = []; let alignLineErrorBoards: Board[] = [];
let alignLineMap: Map<string, Board[]> = new Map(); let alignLineMap: Map<string, Board[]> = new Map();
for (let br of brs) for (let br of brs)
ParseAlignLine(br, alignLineMap); ParseAlignLine(br, alignLineMap);
if (!alignLineMap.size) return { errorBrs: [], msg: "" };
for (let [str, brs] of alignLineMap) for (let [str, brs] of alignLineMap)
{ {
let tool = new CheckInterfereTool();
let p = await tool.Check(brs);
if (p.length)
{
return { errorBrs: p[0][1] as unknown as Board[], msg: "对纹组中存在板件干涉" };
}
const firstBr = brs[0]; const firstBr = brs[0];
const composingFace = firstBr.BoardProcessOption.composingFace; const composingFace = firstBr.BoardProcessOption.composingFace;
const lineType = firstBr.BoardProcessOption.lines; const lineType = firstBr.BoardProcessOption.lines;
@ -68,6 +78,7 @@ export function CheckAlignLineMtl(brs: Board[])
const matName = firstBr.BoardProcessOption.boardName; const matName = firstBr.BoardProcessOption.boardName;
const thickness = firstBr.Thickness; const thickness = firstBr.Thickness;
//---材料检查 begin---
for (let br of brs) for (let br of brs)
{ {
if ( if (
@ -80,10 +91,41 @@ export function CheckAlignLineMtl(brs: Board[])
) )
alignLineErrorBoards.push(br); alignLineErrorBoards.push(br);
} }
}
for (let br of alignLineErrorBoards) if (alignLineErrorBoards.length)
InteractionLog([{ msg: `板件:${br.Name}`, entity: [br] }, { msg: "与对纹组首个板件材料等信息不同" }], LogType.Warning); {
for (let br of alignLineErrorBoards)
InteractionLog([{ msg: `板件:${br.Name}`, entity: [br] }, { msg: "与对纹组首个板件材料等信息不同 " }], LogType.Warning);
return alignLineErrorBoards; return { errorBrs: alignLineErrorBoards, msg: "部分所选的板件与对纹组中板材料、板材颜色、板材名、板厚、排版面或者板纹路不一致" };
}
//拆单尺寸检查
let spliteSizeBrs = brs.filter((b) => b.BoardProcessOption.spliteHeight || b.BoardProcessOption.spliteThickness || b.BoardProcessOption.spliteWidth);
if (spliteSizeBrs.length)
{
for (let br of spliteSizeBrs)
InteractionLog([{ msg: `板件:${br.Name}`, entity: [br] }, { msg: "存在有拆单尺寸 " }], LogType.Warning);
return { errorBrs: spliteSizeBrs, msg: "部分对纹组板件存在有拆单尺寸" };
}
//检查板所在平面
if (!brs.every(br => isParallelTo(br.Normal, firstBr.Normal)))
{
return { errorBrs: brs, msg: "部分所选的板件与对纹组中板件不在同一平面上 " };
}
//---对纹方向检查 begin---
const yNormal = new Vector3().setFromMatrixColumn(firstBr.OCS, 1);
let hasDifferentYNormal = brs.every(
br => isParallelTo(yNormal, new Vector3().setFromMatrixColumn(br.OCS, 1))
);
if (!hasDifferentYNormal)
{
return { errorBrs: brs, msg: "部分所选的板件与对纹组中板件纹路方向不一致" };
}
}
return { errorBrs: [], msg: "" };
} }

@ -753,8 +753,7 @@ export function registerCommand()
//加工组 //加工组
commandMachine.RegisterCommand(CommandNames.ShowProcessingGroupModal, new Command_ShowProcessingGroupModal()); commandMachine.RegisterCommand(CommandNames.ShowProcessingGroupModal, new Command_ShowProcessingGroupModal());
//对纹组 //对纹组
if (IsTest()) commandMachine.RegisterCommand(CommandNames.AlignLineGroup, new Command_AlignLineGroup());
commandMachine.RegisterCommand(CommandNames.AlignLineGroup, new Command_AlignLineGroup());
commandMachine.RegisterCommand(CommandNames.Text2Curve, new Text2Curve()); commandMachine.RegisterCommand(CommandNames.Text2Curve, new Text2Curve());

@ -164,6 +164,7 @@ export class TopToolBar extends React.Component<{}, {}>
{ svg: IconEnum.HistoryOptimize, title: "查看优化", command: CommandNames.ShowYouhua }, { svg: IconEnum.HistoryOptimize, title: "查看优化", command: CommandNames.ShowYouhua },
{ svg: IconEnum.DoubleSplitOrder, title: "成倍拆单", command: CommandNames.ChaiDanJB }, { svg: IconEnum.DoubleSplitOrder, title: "成倍拆单", command: CommandNames.ChaiDanJB },
{ svg: IconEnum.ProcessGroup, title: "加工组", command: CommandNames.ShowProcessingGroupModal }, { svg: IconEnum.ProcessGroup, title: "加工组", command: CommandNames.ShowProcessingGroupModal },
{ svg: IconEnum.AlignLineGroup, title: "对纹组", command: CommandNames.AlignLineGroup },
// { svg: IconEnum.QuotePrice, title: "报价", command: "" },//暂时隐藏 // { svg: IconEnum.QuotePrice, title: "报价", command: "" },//暂时隐藏
// { svg: IconEnum.ERPManage, title: "ERP", command: "" }, // { svg: IconEnum.ERPManage, title: "ERP", command: "" },
]; ];

@ -155,6 +155,7 @@ export enum IconEnum
CheckInterference = "CheckInterference.svg", CheckInterference = "CheckInterference.svg",
ShareMaterial = "ShareMaterial.svg", ShareMaterial = "ShareMaterial.svg",
ProcessGroup = "ProcessGroup.svg", ProcessGroup = "ProcessGroup.svg",
AlignLineGroup = "AlignLineGroup.svg",
TemplateReplace = "TemplateReplace.svg", TemplateReplace = "TemplateReplace.svg",
CutSpace = "CutSpace.svg", CutSpace = "CutSpace.svg",
Text2Curve = "Text2Curve.svg", Text2Curve = "Text2Curve.svg",

Loading…
Cancel
Save