diff --git a/src/Add-on/AlignLine/AlignLineGroupPanel.tsx b/src/Add-on/AlignLine/AlignLineGroupPanel.tsx index 46e3f1a7e..e8ad5b517 100644 --- a/src/Add-on/AlignLine/AlignLineGroupPanel.tsx +++ b/src/Add-on/AlignLine/AlignLineGroupPanel.tsx @@ -9,7 +9,9 @@ import { arrayRemove } from "../../Common/ArrayExt"; import { EBoardKeyList } from "../../Common/BoardKeyList"; import { CommandNames } from "../../Common/CommandNames"; import { GroupEntitysByBox } from "../../Common/GroupEntitysByBox"; +import { CheckInterfereTool } from "../../Common/InterfereUtil"; import { KeyBoard } from "../../Common/KeyEnum"; +import { LogType } from "../../Common/Log"; import { AlignLineGroupRecord } from "../../DatabaseServices/AlignLine/AlignLineGroupRecord"; import { Board } from "../../DatabaseServices/Entity/Board"; import { LinesType } from "../../DatabaseServices/Entity/BoardInterface"; @@ -430,79 +432,149 @@ export class AlignLineGroupPanel extends React.Component<{ store: AlignLineGroup await CommandWrap(async () => { - let ssRes = await app.Editor.GetSelection({ - Msg: `请选择需要加入对纹组的实体`, - Filter: { filterTypes: [Board] } - }); - - if (ssRes.Status === PromptStatus.OK) + while (true) { - let brs = ssRes.SelectSet.SelectEntityList as Board[]; - if (!brs.every(br => isParallelTo(br.Normal, brs[0].Normal))) + let alignLineGroupSpacing = this.props.store.m_Option.alignLineGroupSpacing ?? 20; + let ssRes = await app.Editor.GetSelection({ + Msg: `选择加入对纹组的板件(当前规定对纹组板件间距小于等于:${alignLineGroupSpacing})`, + KeyWordList: [{ key: "D", msg: "板件间距" }], + Filter: { filterTypes: [Board] } + }); + if (ssRes.Status === PromptStatus.Keyword) { - AppToaster.show({ - message: "所选的板件不在同一平面上", - timeout: 5000, - intent: Intent.WARNING, - }); - return; + if (ssRes.StringResult === "D") + { + let ret = await app.Editor.GetDistance({ Msg: "当前规定板件间距小于等于:", Default: alignLineGroupSpacing }); + if (ret.Status === PromptStatus.OK) + { + 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; + } } - - let invalidBoard = brs.filter(br => br.AlignLineObject); - if (invalidBoard.length) + else if (ssRes.Status === PromptStatus.OK) { - AppToaster.show({ - message: "存在已经组合的板!", - timeout: 5000, - intent: Intent.WARNING, - }, "hasInvalidBoard"); + let brs = ssRes.SelectSet.SelectEntityList as Board[]; - app.Editor.SetSelection(invalidBoard); - return; - } + let tool = new CheckInterfereTool(); + let p = await tool.Check(brs); + if (p.length) + { + AppToaster.show({ + message: "所选的板件存在干涉!", + timeout: 7000, + intent: Intent.WARNING, + }); + return; + } - let brBoxMap = GroupEntitysByBox(brs); - let name = this.props.store.selectedLeftNode; - for (let [box, brs] of brBoxMap) - { - if (brs.length < 2) + let spliteSizeBrs = brs.filter((b) => b.BoardProcessOption.spliteHeight || b.BoardProcessOption.spliteThickness || b.BoardProcessOption.spliteWidth); + + if (spliteSizeBrs.length) { + app.Editor.SetSelection(spliteSizeBrs); AppToaster.show({ - message: "存在无效的对纹组合!", - timeout: 5000, + message: "所选的板件存在有拆单尺寸(已选中)!", + timeout: 7000, 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]; - 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) + if (!brs.every(br => isParallelTo(br.Normal, brs[0].Normal))) { AppToaster.show({ - message: "所选板块中,板材料、板材颜色、板材名、板厚、排版面或者板纹路不一致,无法组成对纹组!", - timeout: 5000, + message: "所选的板件不在同一平面上", + timeout: 7000, 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 spliteSize = box.applyMatrix4(ocsInv).getSize(new Vector3); 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) { + app.Editor.SetSelection(brs); AppToaster.show({ message: "组合的对纹组尺寸超长!", - timeout: 5000, + timeout: 7000, intent: Intent.DANGER, }); - continue; + return; } - } + //---超长板件检查 end--- - let al = new AlignLineGroupRecord; - al.Name = name || "未命名"; - app.Database.AlignLineGroupTable.Add(al); - for (let br of brs) - { - br.AlignLineObject = al.Id; - al.Objects.push(br.Id); + let al = new AlignLineGroupRecord; + al.Name = name || "未命名"; + app.Database.AlignLineGroupTable.Add(al); + for (let br of brs) + { + br.AlignLineObject = al.Id; + al.Objects.push(br.Id); + } } + break; } + else + break; } }, CommandNames.AddAlignLineGroup); diff --git a/src/Add-on/AlignLine/AlignLineGroupStore.ts b/src/Add-on/AlignLine/AlignLineGroupStore.ts index b9620135c..d7693828a 100644 --- a/src/Add-on/AlignLine/AlignLineGroupStore.ts +++ b/src/Add-on/AlignLine/AlignLineGroupStore.ts @@ -22,10 +22,13 @@ interface TemplatePgData //跟随模块自动识别的对纹组的数据 export interface AlignLineGroupOption { alignLineGroupCategory: string[]; + alignLineGroupSpacing: number; + } const DefaultAlingnLineOption: AlignLineGroupOption = { alignLineGroupCategory: ["门板"], + alignLineGroupSpacing: 20 }; export class AlignLineGroupModalStore extends Singleton implements IConfigStore diff --git a/src/Add-on/Erp/ErpCommands.ts b/src/Add-on/Erp/ErpCommands.ts index d831c6f2a..587e09db3 100644 --- a/src/Add-on/Erp/ErpCommands.ts +++ b/src/Add-on/Erp/ErpCommands.ts @@ -230,15 +230,17 @@ async function ExecChaiDan(chaiDanRoute: ErpRoutes) return; } - const alignLineErrorBoards = CheckAlignLineMtl(boardList); - if (alignLineErrorBoards.length) + const { errorBrs, msg } = await CheckAlignLineMtl(boardList); + + if (errorBrs.length) { let res = await AppConfirm.show({ intent: Intent.WARNING, - message: "部分板件与对纹组中首个板材料、板材颜色、板材名、板厚、排版面或者板纹路不一致 , 详情见左下角日志 , 是否先排查?" + message: `${msg} , 是否先排查?` }); if (res) { + app.Editor.SetSelection(errorBrs); return; } } diff --git a/src/Add-on/Erp/ParseDataFunction.ts b/src/Add-on/Erp/ParseDataFunction.ts index 66ceeab94..593d3738a 100644 --- a/src/Add-on/Erp/ParseDataFunction.ts +++ b/src/Add-on/Erp/ParseDataFunction.ts @@ -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 { AlignLineGroupRecord } from "../../DatabaseServices/AlignLine/AlignLineGroupRecord"; 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"; //解析对纹信息 @@ -49,17 +50,26 @@ export function DealAlignLineGroup(alignLineMap: Map, alignLine } } -export function CheckAlignLineMtl(brs: Board[]) +export async function CheckAlignLineMtl(brs: Board[]): Promise<{ errorBrs: Board[]; msg: string; }> { let alignLineErrorBoards: Board[] = []; let alignLineMap: Map = new Map(); - for (let br of brs) ParseAlignLine(br, alignLineMap); + if (!alignLineMap.size) return { errorBrs: [], msg: "" }; + + 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 composingFace = firstBr.BoardProcessOption.composingFace; const lineType = firstBr.BoardProcessOption.lines; @@ -68,6 +78,7 @@ export function CheckAlignLineMtl(brs: Board[]) const matName = firstBr.BoardProcessOption.boardName; const thickness = firstBr.Thickness; + //---材料检查 begin--- for (let br of brs) { if ( @@ -80,10 +91,41 @@ export function CheckAlignLineMtl(brs: Board[]) ) alignLineErrorBoards.push(br); } - } - for (let br of alignLineErrorBoards) - InteractionLog([{ msg: `板件:${br.Name}`, entity: [br] }, { msg: "与对纹组首个板件材料等信息不同" }], LogType.Warning); + if (alignLineErrorBoards.length) + { + 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: "" }; } diff --git a/src/Editor/CommandRegister.ts b/src/Editor/CommandRegister.ts index cedbd5667..8cd434200 100644 --- a/src/Editor/CommandRegister.ts +++ b/src/Editor/CommandRegister.ts @@ -753,8 +753,7 @@ export function registerCommand() //加工组 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()); diff --git a/src/UI/Components/TopToolBar/TopToolBar.tsx b/src/UI/Components/TopToolBar/TopToolBar.tsx index 74a1968a8..4dbeccacf 100644 --- a/src/UI/Components/TopToolBar/TopToolBar.tsx +++ b/src/UI/Components/TopToolBar/TopToolBar.tsx @@ -164,6 +164,7 @@ export class TopToolBar extends React.Component<{}, {}> { svg: IconEnum.HistoryOptimize, title: "查看优化", command: CommandNames.ShowYouhua }, { svg: IconEnum.DoubleSplitOrder, title: "成倍拆单", command: CommandNames.ChaiDanJB }, { svg: IconEnum.ProcessGroup, title: "加工组", command: CommandNames.ShowProcessingGroupModal }, + { svg: IconEnum.AlignLineGroup, title: "对纹组", command: CommandNames.AlignLineGroup }, // { svg: IconEnum.QuotePrice, title: "报价", command: "" },//暂时隐藏 // { svg: IconEnum.ERPManage, title: "ERP", command: "" }, ]; diff --git a/src/UI/IconEnum.ts b/src/UI/IconEnum.ts index 718208e3f..e61db01cc 100644 --- a/src/UI/IconEnum.ts +++ b/src/UI/IconEnum.ts @@ -155,6 +155,7 @@ export enum IconEnum CheckInterference = "CheckInterference.svg", ShareMaterial = "ShareMaterial.svg", ProcessGroup = "ProcessGroup.svg", + AlignLineGroup = "AlignLineGroup.svg", TemplateReplace = "TemplateReplace.svg", CutSpace = "CutSpace.svg", Text2Curve = "Text2Curve.svg",