diff --git a/__test__/EdgeSealing/EdgeSealing.test.ts b/__test__/EdgeSealing/EdgeSealing.test.ts index 3aafc92fd..38b4285a5 100644 --- a/__test__/EdgeSealing/EdgeSealing.test.ts +++ b/__test__/EdgeSealing/EdgeSealing.test.ts @@ -1,7 +1,7 @@ import { Board } from "../../src/DatabaseServices/Entity/Board"; import { Curve } from "../../src/DatabaseServices/Entity/Curve"; import { Polyline } from "../../src/DatabaseServices/Entity/Polyline"; -import { CalcEdgeSealing, GetBoardSealingData, GetSealedBoardContour, ParagraphCulist } from "../../src/GraphicsSystem/CalcEdgeSealing"; +import { CalcEdgeSealing, GetBoardSealingData, GetSealedBoardContour, SubsectionCurvesOfHightSeal } from "../../src/GraphicsSystem/CalcEdgeSealing"; import { ConverToPtsBul } from "../../src/Production/Convert2PtsBul"; import "../Utils/jest.util"; import { LoadBoardsFromFileData } from "../Utils/LoadEntity.util"; @@ -11,7 +11,7 @@ function testBrSealing(br: Board, sealingSize: number[]) let originCurve = br.ContourCurve; let dir = Math.sign(originCurve.Area2) * -1; let calcCus = originCurve.Explode() as Curve[]; - ParagraphCulist(calcCus); + SubsectionCurvesOfHightSeal(calcCus); let offsetCus: Curve[] = []; for (let i = 0; i < calcCus.length; i++) diff --git a/src/Add-on/KJL/Import/KJLImport.ts b/src/Add-on/KJL/Import/KJLImport.ts index 2cc6d1d6a..c6fec052b 100644 --- a/src/Add-on/KJL/Import/KJLImport.ts +++ b/src/Add-on/KJL/Import/KJLImport.ts @@ -1,4 +1,3 @@ -import { Intent } from "@blueprintjs/core"; import { Box3, Euler, Matrix4, Vector3 } from "three"; import { app } from "../../../ApplicationServices/Application"; import { arrayLast, arrayRemoveIf } from "../../../Common/ArrayExt"; @@ -9,6 +8,7 @@ import { BuyZengZhiBao } from "../../../Common/HostUrl"; import { JigMoveEntity } from "../../../Common/JigMove"; import { MakeMirrorMtx, NormalMatrix, RoundMatrix } from "../../../Common/Matrix4Utils"; import { DuplicateRecordCloning } from "../../../Common/Status"; +import { Intent, ToasterShowEntityMsg } from "../../../Common/Toaster"; import { Board } from "../../../DatabaseServices/Entity/Board"; import { Entity } from "../../../DatabaseServices/Entity/Entity"; import { ExtrudeSolid } from "../../../DatabaseServices/Entity/Extrude"; @@ -21,7 +21,7 @@ import { TemplateRecord } from "../../../DatabaseServices/Template/TemplateRecor import { Command, CommandWrap } from "../../../Editor/CommandMachine"; import { userConfig } from "../../../Editor/UserConfig"; import { equaln, ZAxis } from "../../../Geometry/GeUtils"; -import { ParagraphSealinglist, SetBoardTopDownLeftRightSealData } from "../../../GraphicsSystem/CalcEdgeSealing"; +import { ConverEachSeal2HightSealData, SetBoardTopDownLeftRightSealData } from "../../../GraphicsSystem/CalcEdgeSealing"; import { BoardModalType } from "../../../UI/Components/Board/BoardModalType"; import { AppConfirm } from "../../../UI/Components/Common/Confirm"; import { AppToaster } from "../../../UI/Components/Toaster"; @@ -340,9 +340,25 @@ async function ParseModel(model: KJL_ParamModel, let last = arrayLast(sealeds); for (let i = sealeds.length; i < cus.length; i++) sealeds.push(last); - let edges = ParagraphSealinglist(sealeds, cus); - br.BoardProcessOption.highSealed = edges; - SetBoardTopDownLeftRightSealData(br, edges); + + let hightSeals = ConverEachSeal2HightSealData(sealeds, cus); + br.BoardProcessOption.highSealed = hightSeals; + try + { + SetBoardTopDownLeftRightSealData(br, hightSeals); + } + catch (error) + { + setTimeout(() => + { + ToasterShowEntityMsg({ + intent: Intent.DANGER, + msg: "无法计算板的上下左右封边,请检查板的轮廓是否正常!", + ent: br, + timeout: 60000 + }); + }, 1000); + } } for (let i = 1; i < pls.length; i++) diff --git a/src/GraphicsSystem/CalcEdgeSealing.ts b/src/GraphicsSystem/CalcEdgeSealing.ts index f6d3e7763..e58bdb162 100644 --- a/src/GraphicsSystem/CalcEdgeSealing.ts +++ b/src/GraphicsSystem/CalcEdgeSealing.ts @@ -16,119 +16,128 @@ import { IHighSealedItem, ISealingData } from "../UI/Store/BoardInterface"; import { IntersectOption } from "./IntersectWith"; import { ParseEdgeSealDir } from "./ParseEdgeSealDir"; +type CurveGroups = (Curve[])[]; + /** - *曲线列表分段 + * 将曲线分段(根据高级封边的特性 (因为圆弧无法单独使用封边,所以和圆弧在一起的曲线必须和圆弧一样的封边,否则偏移失败)) * @l-arc-l,l-arc-arc-l,l-arc-l-arc-l.... + * @param in_out_curves 曲线组( 函数结束后 这个数组被改变 ) + * @returns 返回编组 curveGroups */ -export function ParagraphCulist(cus: Curve[]) +export function SubsectionCurvesOfHightSeal(in_out_curves: Curve[]): CurveGroups { - let newCulist: (Curve[])[] = []; + let curveGroups: CurveGroups = []; let usedCu: WeakSet = new WeakSet(); //归类曲线,返回归类是否成功 - const paragraph = (cu: Curve, originCu: Curve, cuList: Curve[], isBack: boolean) => + const paragraph = (nextCurve: Curve, curCurve: Curve, curvesGroup: Curve[], isBack: boolean) => { - const cuIsLine = cu instanceof Line; - const originCuIsLine = originCu instanceof Line; + const curIsLine = curCurve instanceof Line; + const nextIsLine = nextCurve instanceof Line; - if (usedCu.has(cu)) + if (usedCu.has(nextCurve)) return false; - if (originCuIsLine !== cuIsLine) + if (curIsLine !== nextIsLine)//直线和圆弧 { - if (originCuIsLine) + if (curIsLine) { if (isBack) { - if (!isParallelTo(originCu.GetFistDeriv(0), cu.GetFistDeriv(0))) + if (!isParallelTo(curCurve.GetFistDeriv(0), nextCurve.GetFistDeriv(0))) return false; } else { - if (!isParallelTo(originCu.GetFistDeriv(0), cu.GetFistDeriv(1))) + if (!isParallelTo(curCurve.GetFistDeriv(0), nextCurve.GetFistDeriv(1))) return false; } } - if (cuIsLine) + if (nextIsLine) { if (isBack) { - if (!isParallelTo(originCu.GetFistDeriv(1), cu.GetFistDeriv(0))) + if (!isParallelTo(curCurve.GetFistDeriv(1), nextCurve.GetFistDeriv(0))) return false; } else { - if (!isParallelTo(originCu.GetFistDeriv(0), cu.GetFistDeriv(0))) + if (!isParallelTo(curCurve.GetFistDeriv(0), nextCurve.GetFistDeriv(0))) return false; } } } - else if (cuIsLine) + else if (nextIsLine)//都是直线 { //共线且相连的直线分为一组 #I11T1Z - if (!isParallelTo(cu.GetFistDeriv(0).normalize(), originCu.GetFistDeriv(0).normalize())) + if (!isParallelTo(nextCurve.GetFistDeriv(0).normalize(), curCurve.GetFistDeriv(0).normalize())) return false; - let pts = [originCu.StartPoint, originCu.EndPoint]; - let pts2 = [cu.StartPoint, cu.EndPoint]; - if (pts.every(p => pts2.every(p2 => !equalv3(p, p2, 1e-6)))) + + let pts = [curCurve.StartPoint, curCurve.EndPoint]; + let pts2 = [nextCurve.StartPoint, nextCurve.EndPoint]; + if (pts.every(p => pts2.every(p2 => !equalv3(p, p2, 1e-6))))//2条线完全分离 没有共同点 return false; } + //else 都是圆弧 必然成组 + if (isBack) - cuList.push(cu); + curvesGroup.push(nextCurve); else - cuList.unshift(cu); - usedCu.add(cu); + curvesGroup.unshift(nextCurve); + + usedCu.add(nextCurve); return true; }; - let caclCus = cus.filter(c => !equaln(c.Length, 0)); + let caclCus = in_out_curves.filter(c => !equaln(c.Length, 0)); while (caclCus.length > 0) { - let originCu = caclCus.shift(); - if (usedCu.has(originCu)) + let curCurve = caclCus.shift(); + if (usedCu.has(curCurve)) continue; - let originCus = [originCu]; - usedCu.add(originCu); + let curvesGroup = [curCurve];//编组 + usedCu.add(curCurve); //往后搜索 for (let i = 0; i < caclCus.length; i++) { - if (!paragraph(caclCus[i], originCu, originCus, true)) + if (!paragraph(caclCus[i], curCurve, curvesGroup, true)) break; - originCu = caclCus[i]; + curCurve = caclCus[i]; } //只有第一条才需要往前搜索 - if (caclCus.length === cus.length - 1) + if (caclCus.length === in_out_curves.length - 1) { - originCu = originCus[0]; + curCurve = curvesGroup[0]; //往前搜索 for (let i = caclCus.length - 1; i >= 0; i--) { - if (!paragraph(caclCus[i], originCu, originCus, false)) + if (!paragraph(caclCus[i], curCurve, curvesGroup, false)) break; - originCu = caclCus[i]; + curCurve = caclCus[i]; } } - newCulist.push(originCus); + curveGroups.push(curvesGroup); } - cus.length = 0; + + in_out_curves.length = 0; //同组多条曲线连接为多段线 - for (let g of newCulist) + for (let g of curveGroups) { if (g.length === 1) - cus.push(g[0]); + in_out_curves.push(g[0]); else { let pl = new Polyline(); for (let c of g) - { pl.Join(c); - } - cus.push(pl); + in_out_curves.push(pl); } } + + return curveGroups; } /** @@ -351,13 +360,14 @@ export function GetBoardSealingCurves(br: Board, isOffset = false): Curve[] { cus = cu.Explode() as Curve[]; if (br.IsSpecialShape) - ParagraphCulist(cus); + SubsectionCurvesOfHightSeal(cus); return cus; } } -const SEAL_VALUE_KEY = "__highSeals__"; +//曲线的每段封边值 +const __CURVE_EACH_SEAL_VALUE_KEY__ = "__CURVE_EACH_SEAL_VALUE__"; /** @@ -477,7 +487,7 @@ export function GetSealedBoardContour(br: Board, hasSealing: boolean, isParseSea { let cir = offsetCus[0]; - if (highSealsExpd) cir[SEAL_VALUE_KEY] = highSealsExpd; + if (highSealsExpd) cir[__CURVE_EACH_SEAL_VALUE_KEY__] = highSealsExpd; return cir; } @@ -490,14 +500,14 @@ export function GetSealedBoardContour(br: Board, hasSealing: boolean, isParseSea highSealsExpd?.reverse(); } - if (highSealsExpd) pl[SEAL_VALUE_KEY] = highSealsExpd; + if (highSealsExpd) pl[__CURVE_EACH_SEAL_VALUE_KEY__] = highSealsExpd; return pl; } export function GetBoardSealingData(curve: Polyline | Circle) { - let sealData = curve[SEAL_VALUE_KEY] as ISealingData[]; + let sealData = curve[__CURVE_EACH_SEAL_VALUE_KEY__] as ISealingData[]; if (curve instanceof Circle) { sealData[0].length *= 0.5; @@ -507,90 +517,28 @@ export function GetBoardSealingData(curve: Polyline | Circle) } -export function ParagraphSealinglist(hightSeal: IHighSealedItem[], cus: Curve[]) +/** + * 将11对应的封边数值改成WebCAD的高级封边 + * @param seals 每段曲线的封边 + * @param curves 曲线表 + * @returns 转换成高级封边后的封边值 (圆弧会编组) + */ +export function ConverEachSeal2HightSealData(seals: IHighSealedItem[], curves: Curve[]): IHighSealedItem[] { - if (hightSeal.length !== cus.length) return hightSeal; - - let usedCu: WeakSet = new WeakSet(); - let newHighSeal: IHighSealedItem[] = []; - - //归类曲线,返回归类是否成功 - const paragraph = (cu: Curve, originCu: Curve, isBack: boolean) => - { - const cuIsLine = cu instanceof Line; - const originCuIsLine = originCu instanceof Line; + curves = curves.concat(); + seals = seals.concat(); + let s = seals[seals.length - 1]; + for (let i = seals.length; i < curves.length; i++) + seals.push(s); - if (usedCu.has(cu)) - return false; + const KEY = "__CURVE_SEAL_DATA__"; - if (originCuIsLine !== cuIsLine) - { - if (originCuIsLine && - !isParallelTo(originCu.GetFistDeriv(0), cu.GetFistDeriv(0)) - && !isParallelTo(originCu.GetFistDeriv(0), cu.GetFistDeriv(1)) - ) - { - return false; - } - - if (cuIsLine - && !isParallelTo(originCu.GetFistDeriv(1), cu.GetFistDeriv(0)) - && !isParallelTo(originCu.GetFistDeriv(0), cu.GetFistDeriv(0) - )) - { - return false; - } - } - else if (cuIsLine) - { - //共线且相连的直线分为一组 #I11T1Z - if (!isParallelTo(cu.GetFistDeriv(0).normalize(), originCu.GetFistDeriv(0).normalize())) - return false; - let pts = [originCu.StartPoint, originCu.EndPoint]; - let pts2 = [cu.StartPoint, cu.EndPoint]; - if (pts.every(p => pts2.every(p2 => !equalv3(p, p2, 1e-6)))) - return false; - } - if (isBack) - hightSeal.shift(); - else - hightSeal.pop(); - usedCu.add(cu); - return true; - }; - let caclCus = cus.slice(); + for (let i = 0; i < curves.length; i++) + curves[i][KEY] = seals[i]; - while (caclCus.length > 0) - { - let originCu = caclCus.shift(); - if (usedCu.has(originCu)) - continue; - let oldCu = originCu; - let originSeal = hightSeal.shift(); - newHighSeal.push(originSeal); - usedCu.add(originCu); - //往后搜索 - for (let i = 0; i < caclCus.length; i++) - { - if (!paragraph(caclCus[i], originCu, true)) - break; - originCu = caclCus[i]; - } - //只有第一条才需要往前搜索 - if (caclCus.length === cus.length - 1) - { - originCu = oldCu; - //往前搜索 - for (let i = caclCus.length - 1; i >= 0; i--) - { - if (!paragraph(caclCus[i], originCu, false)) - break; - originCu = caclCus[i]; - } - } - } + let groups = SubsectionCurvesOfHightSeal(curves); - return newHighSeal; + return groups.map(g => g[0][KEY]); } /** 设置板的上下左右封边 */ diff --git a/src/UI/Components/CameraControlButton/CameraState/CameraSnapshootPanel.tsx b/src/UI/Components/CameraControlButton/CameraState/CameraSnapshootPanel.tsx index 1370b41d9..f2eeef640 100644 --- a/src/UI/Components/CameraControlButton/CameraState/CameraSnapshootPanel.tsx +++ b/src/UI/Components/CameraControlButton/CameraState/CameraSnapshootPanel.tsx @@ -3,10 +3,10 @@ import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; import React, { Component } from 'react'; import { end } from 'xaop'; -import { CADFiler } from '../../../../api'; import { app } from '../../../../ApplicationServices/Application'; import { equalArray } from '../../../../Common/ArrayExt'; import { GetCurrentViewPreViewImage } from '../../../../Common/SerializeMaterial'; +import { CADFiler } from '../../../../DatabaseServices/CADFiler'; import { CameraSnapshootRecord } from '../../../../DatabaseServices/CameraSnapshoot/CameraSnapshootRecord'; import { RestoreCameraSnapshootRecord, SaveCameraSnapshootRecord } from '../../../../DatabaseServices/CameraSnapshoot/CameraSnapshootRecordUtil'; import { userConfig } from '../../../../Editor/UserConfig';