From 75495b450398243742d8584ff0418e2390732dd7 Mon Sep 17 00:00:00 2001 From: ZoeLeeFZ Date: Fri, 23 Aug 2019 15:28:44 +0800 Subject: [PATCH] =?UTF-8?q?!463=20=E6=A8=A1=E5=9D=97=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Add-on/Extends.ts | 2 - src/Add-on/FilletUtils.ts | 22 +- src/Add-on/Template/ShowTemplateDesign.ts | 31 + src/Common/InputState.ts | 3 +- src/Common/KeyEnum.ts | 1 + src/Common/StretchParse.ts | 2 +- src/Common/Utils.ts | 3 +- src/DatabaseServices/Entity/Circle.ts | 20 +- src/DatabaseServices/Entity/Curve.ts | 10 +- src/DatabaseServices/Entity/DragPointType.ts | 5 + src/DatabaseServices/Entity/Extrude.ts | 34 +- src/DatabaseServices/Entity/Polyline.ts | 28 +- .../Template/Action/TempateThicknessAction.ts | 94 +++ .../Template/Action/TemplateAction.ts | 41 +- .../Template/Action/TemplateFilletAction.ts | 105 ++- .../Template/Action/TemplateMoveAction.ts | 24 +- .../Action/TemplateStretchGripAction.ts | 21 +- .../Action/TemplateStretchScaleBoxAction.ts | 15 +- .../Template/Param/TemplateParam.ts | 8 +- .../Positioning/PositioningClampSpace.ts | 4 +- src/DatabaseServices/Template/TempateUtils.ts | 796 ++++++++++++++++++ .../Template/TemplateRecord.ts | 110 +-- src/DatabaseServices/Template/TemplateTest.ts | 499 +++-------- src/Editor/CommandMachine.ts | 1 + src/Editor/CommandRegister.ts | 2 + src/Editor/Editor.ts | 11 +- src/Editor/GetPointServices.ts | 3 +- src/Editor/GetStringService.ts | 101 +++ src/Editor/PromptOptions.ts | 5 + src/Editor/SelectSet.ts | 22 +- src/UI/Components/Board/BoardModal.tsx | 1 + src/UI/Components/Board/UserConfig.tsx | 17 +- src/UI/Components/Common/PopoverButton.tsx | 49 ++ src/UI/Components/Modal/ModalsManage.tsx | 4 + src/UI/Components/SimpleDialog.tsx | 48 ++ .../Components/SourceManage/CommonPanel.tsx | 32 +- src/UI/Components/SourceManage/SoucePanel.tsx | 2 +- src/UI/Components/Template/ActionTree.tsx | 91 ++ src/UI/Components/Template/Template.less | 146 ++++ .../Template/TemplateActionDiglog.tsx | 353 ++++++++ .../Template/TemplateActionList.tsx | 287 +++++++ .../Components/Template/TemplateComponent.tsx | 90 +- src/UI/Components/Template/TemplateEditor.tsx | 151 +++- src/UI/Components/Template/TemplateList.tsx | 3 +- .../Components/Template/TemplateParamList.tsx | 218 +++++ .../Components/Template/TemplateSaveDir.tsx | 72 ++ src/UI/Css/style.less | 3 - src/UI/Store/TemplateEditorStore.ts | 115 +++ src/UI/Store/UserConfigStore.ts | 12 +- 49 files changed, 3054 insertions(+), 663 deletions(-) create mode 100644 src/Add-on/Template/ShowTemplateDesign.ts create mode 100644 src/DatabaseServices/Entity/DragPointType.ts create mode 100644 src/DatabaseServices/Template/Action/TempateThicknessAction.ts create mode 100644 src/Editor/GetStringService.ts create mode 100644 src/UI/Components/Common/PopoverButton.tsx create mode 100644 src/UI/Components/SimpleDialog.tsx create mode 100644 src/UI/Components/Template/ActionTree.tsx create mode 100644 src/UI/Components/Template/TemplateActionDiglog.tsx create mode 100644 src/UI/Components/Template/TemplateActionList.tsx create mode 100644 src/UI/Components/Template/TemplateParamList.tsx create mode 100644 src/UI/Components/Template/TemplateSaveDir.tsx diff --git a/src/Add-on/Extends.ts b/src/Add-on/Extends.ts index e07c3501a..60ec25796 100644 --- a/src/Add-on/Extends.ts +++ b/src/Add-on/Extends.ts @@ -53,8 +53,6 @@ export class Command_Extend implements Command if (exSs.Status !== PromptStatus.OK) break; - if (exSs.SelectSet.SelectEntityList.length === 0) - break; this.Extend(exSs.SelectSet, exRefCus, false); } } diff --git a/src/Add-on/FilletUtils.ts b/src/Add-on/FilletUtils.ts index e6fd52704..992409d1e 100644 --- a/src/Add-on/FilletUtils.ts +++ b/src/Add-on/FilletUtils.ts @@ -304,18 +304,32 @@ export class FilletUtils else//经过起点 { let sp = AsVector2(fres.arc.EndPoint.applyMatrix4(pln.OCSInv)); + + let keepF1 = 0; if (parF2 + 1 <= pln.LineData.length) - pln.AddVertexAt(parF2 + 1, sp) + { + if (parF1 === 0 || pln.GetBuilgeAt(parF1 - 1) == 0) + pln.AddVertexAt(parF2 + 1, sp); + else + { + pln.SetPointAt(parF1 - 1, sp); + keepF1 = -1;//保留圆弧位 + } + } else pln.SetPointAt(parF2 + 1, sp); - pln.SetBulgeAt(parF2 + 1, -fres.arc.Bul); + + if (keepF1 === 0) + pln.SetBulgeAt(parF2 + 1, -fres.arc.Bul); + else + pln.SetBulgeAt(parF1 - 1, -fres.arc.Bul); let ep = AsVector2(fres.cu1.StartPoint.applyMatrix4(pln.OCSInv)); pln.SetPointAt(parF1, ep); pln.CloseMark = true; - pln.LineData.splice(parF2 + 2); - pln.LineData.splice(0, parF1); + pln.LineData.splice(parF2 + 2 + keepF1); + pln.LineData.splice(0, parF1 + keepF1); pln.Update(); return { cu1: pln }; } diff --git a/src/Add-on/Template/ShowTemplateDesign.ts b/src/Add-on/Template/ShowTemplateDesign.ts new file mode 100644 index 000000000..0d0940faa --- /dev/null +++ b/src/Add-on/Template/ShowTemplateDesign.ts @@ -0,0 +1,31 @@ +import { app } from "../../ApplicationServices/Application"; +import { Board } from "../../DatabaseServices/Entity/Board"; +import { InitTemplate } from "../../DatabaseServices/Template/TempateUtils"; +import { Command } from "../../Editor/CommandMachine"; +import { PromptStatus } from "../../Editor/PromptResult"; +import { ModalPosition } from "../../UI/Components/Modal/ModalsManage"; +import { TemplateEditor } from "../../UI/Components/Template/TemplateEditor"; +import { TempalteEditorStore } from "../../UI/Store/TemplateEditorStore"; +export class ShowTemplateDesign implements Command +{ + async exec() + { + let enRes = await app.Editor.GetSelection({ + Msg: "请选择构建模块的板件", + Filter: { filterTypes: [Board] } + }); + if (enRes.Status !== PromptStatus.OK) + return; + + let brs = enRes.SelectSet.SelectEntityList as Board[]; + + let template = await InitTemplate(brs); + if (!template) return; + + let store = TempalteEditorStore.GetInstance() as TempalteEditorStore; + template.Name = "模板"; + store.Template = template; + store.InitParams(); + app.Editor.ModalManage.RenderModeless(TemplateEditor, ModalPosition.Center, { store }); + } +} diff --git a/src/Common/InputState.ts b/src/Common/InputState.ts index 38af35cbd..b74d3a5ef 100644 --- a/src/Common/InputState.ts +++ b/src/Common/InputState.ts @@ -13,7 +13,8 @@ export enum InputState Entsel = 16, GetKeyWord = 32, GetRect = 64, - All = ~(~0 << 7) + GetString = 128, + All = ~(~0 << 8) } diff --git a/src/Common/KeyEnum.ts b/src/Common/KeyEnum.ts index 8c7dbcbf0..aef03d008 100644 --- a/src/Common/KeyEnum.ts +++ b/src/Common/KeyEnum.ts @@ -330,4 +330,5 @@ export enum StoreageKeys UserName = "userName", RenderType = "renderType", ExactDrill = "openExactDrill", + ConfigName = "configName_", } diff --git a/src/Common/StretchParse.ts b/src/Common/StretchParse.ts index 35ef9ff77..5775a304b 100644 --- a/src/Common/StretchParse.ts +++ b/src/Common/StretchParse.ts @@ -25,7 +25,7 @@ export function StretchParse(ss: SelectSet): StretchData } else if (set instanceof SelectBox) { - if (set.m_SelectType == SelectType.W) + if (set.m_SelectType === SelectType.W) { for (let en of set.SelectEntityList) data.moveEntityList.push(en); diff --git a/src/Common/Utils.ts b/src/Common/Utils.ts index 10c84e42f..e89994d97 100644 --- a/src/Common/Utils.ts +++ b/src/Common/Utils.ts @@ -54,7 +54,7 @@ export function FixIndex(index: number, arr: Array | number) { let count = (arr instanceof Array) ? arr.length : arr; if (index < 0) - return count - 1; + return count + index; else if (index >= count) return index - count; else @@ -155,6 +155,7 @@ export function FixedNotZero(v: number | string, fractionDigits: number = 0) { if (typeof v === "string") v = parseFloat(v); + if (isNaN(v)) return ""; if (equaln(v, 0)) return "0"; let str = v.toFixed(fractionDigits); let commonIndex = str.indexOf("."); diff --git a/src/DatabaseServices/Entity/Circle.ts b/src/DatabaseServices/Entity/Circle.ts index ac48771ed..439622da5 100644 --- a/src/DatabaseServices/Entity/Circle.ts +++ b/src/DatabaseServices/Entity/Circle.ts @@ -1,4 +1,4 @@ -import { Box3, BufferGeometry, EllipseCurve, Material, Matrix3, Matrix4, Object3D, Shape, Vector3, Line as TLine } from 'three'; +import { Box3, BufferGeometry, EllipseCurve, Line as TLine, Material, Matrix3, Matrix4, Object3D, Shape, Vector3 } from 'three'; import { arrayLast, arrayRemoveDuplicateBySort } from '../../Common/ArrayExt'; import { ColorMaterial } from '../../Common/ColorPalette'; import { getArcOrCirNearPts, GetTanPtsOnArcOrCircle } from '../../Common/CurveUtils'; @@ -6,16 +6,17 @@ import { reviseMirrorMatrix } from '../../Common/Matrix4Utils'; import { clamp } from '../../Common/Utils'; import { ObjectSnapMode } from '../../Editor/ObjectSnapMode'; import { BufferGeometryUtils } from '../../Geometry/BufferGeometryUtils'; -import { angle, equaln, MoveMatrix, polar, AsVector3 } from '../../Geometry/GeUtils'; -import { IntersectCircleAndArc, IntersectCircleAndCircle, IntersectLineAndCircle, IntersectOption, IntersectPolylineAndCurve, reverseIntersectOption, IntersectEllipseAndCircleOrArc } from '../../GraphicsSystem/IntersectWith'; +import { angle, AsVector3, equaln, MoveMatrix, polar } from '../../Geometry/GeUtils'; +import { IntersectCircleAndArc, IntersectCircleAndCircle, IntersectEllipseAndCircleOrArc, IntersectLineAndCircle, IntersectOption, IntersectPolylineAndCurve, reverseIntersectOption } from '../../GraphicsSystem/IntersectWith'; import { RenderType } from '../../GraphicsSystem/RenderType'; -import { Arc } from './Arc'; import { Factory } from '../CADFactory'; import { CADFiler } from '../CADFiler'; +import { Arc } from './Arc'; import { Curve } from './Curve'; +import { DragPointType } from './DragPointType'; +import { Ellipse } from './Ellipse'; import { Line } from './Line'; import { Polyline } from './Polyline'; -import { Ellipse } from './Ellipse'; let circleGeometry: BufferGeometry; function GetCircleGeometry() @@ -249,6 +250,14 @@ export class Circle extends Curve m.material = material ? material : ColorMaterial.GetLineMaterial(this._Color); } + GetDragPointCount(drag: DragPointType): number + { + if (drag === DragPointType.Grip) + return 5; + else + return 1; + } + GetGripPoints(): Array { let pts = [ @@ -263,6 +272,7 @@ export class Circle extends Curve pts.forEach(p => p.applyMatrix4(ocs)); return pts; } + GetObjectSnapPoints( snapMode: ObjectSnapMode, pickPoint: Vector3, diff --git a/src/DatabaseServices/Entity/Curve.ts b/src/DatabaseServices/Entity/Curve.ts index d1fbe7009..b9ec973b8 100644 --- a/src/DatabaseServices/Entity/Curve.ts +++ b/src/DatabaseServices/Entity/Curve.ts @@ -1,11 +1,12 @@ -import { Line, Object3D, Shape, Vector3, Material } from 'three'; +import { Line, Material, Object3D, Shape, Vector3 } from 'three'; import { arrayRemoveDuplicateBySort, arraySortByNumber } from '../../Common/ArrayExt'; import { ColorMaterial } from '../../Common/ColorPalette'; import { Status } from '../../Common/Status'; import { equaln, equalv3 } from '../../Geometry/GeUtils'; -import { RenderType } from '../../GraphicsSystem/RenderType'; import { IntersectOption } from '../../GraphicsSystem/IntersectWith'; +import { RenderType } from '../../GraphicsSystem/RenderType'; import { Factory } from '../CADFactory'; +import { DragPointType } from './DragPointType'; import { Entity } from './Entity'; export enum ExtendType @@ -153,6 +154,11 @@ export abstract class Curve extends Entity */ IntersectWith(curve: Curve, intType: IntersectOption, tolerance = 1e-6): Vector3[] { return []; } + /** + * 拽托点个数 + */ + GetDragPointCount(drag: DragPointType): number { return 0; } + //------------------绘制相关------------------ //重载 protected OnlyRenderType = true; diff --git a/src/DatabaseServices/Entity/DragPointType.ts b/src/DatabaseServices/Entity/DragPointType.ts new file mode 100644 index 000000000..f31794408 --- /dev/null +++ b/src/DatabaseServices/Entity/DragPointType.ts @@ -0,0 +1,5 @@ +export enum DragPointType +{ + Grip = 0, + Stretch = 1 +} diff --git a/src/DatabaseServices/Entity/Extrude.ts b/src/DatabaseServices/Entity/Extrude.ts index 471f58228..f1c5e5da5 100644 --- a/src/DatabaseServices/Entity/Extrude.ts +++ b/src/DatabaseServices/Entity/Extrude.ts @@ -24,6 +24,7 @@ import { Contour } from "../Contour"; import { Shape } from "../Shape"; import { ShapeManager } from "../ShapeManager"; import { Circle } from "./Circle"; +import { DragPointType } from "./DragPointType"; import { Entity } from "./Entity"; import { Polyline } from "./Polyline"; import { Region } from "./Region"; @@ -31,12 +32,6 @@ import { Region } from "./Region"; export type ExtureContourCurve = Polyline | Circle; export type ExtureContour = Polyline | Circle | ExtrudeSolid | Region; -enum DragPointType -{ - Grip = 0, - Stretch = 1, -} - @Factory export class ExtrudeSolid extends Entity { @@ -150,7 +145,6 @@ export class ExtrudeSolid extends Entity Clone() { let en = super.Clone(); - en.strectchPointCountList = this.strectchPointCountList; return en; } @@ -449,16 +443,12 @@ export class ExtrudeSolid extends Entity //#region Stretch - /** - * 用于缓存子对象的点拉伸点表个数,可能为空 - */ - private strectchPointCountList: number[]; - private GetStrectchPointCountList(dragType: DragPointType) + private GetStrectchPointCountList(dragType: DragPointType): number[] { - if (!this.strectchPointCountList) - this.GetGripOrStretchPoints(dragType); - - return this.strectchPointCountList; + let counts: number[] = [this.ContourCurve.GetDragPointCount(dragType) * 2]; + for (let g of this.grooves) + counts.push(g.ContourCurve.GetDragPointCount(dragType) * 2); + return counts; } GetGripOrStretchPoints(dragType: DragPointType) { @@ -469,12 +459,9 @@ export class ExtrudeSolid extends Entity pts.push(...pts.map(p => p.clone().add(v))); pts.forEach(p => { p.applyMatrix4(this.OCS) }); - this.strectchPointCountList = [pts.length]; - for (let g of this.grooves) { let gpts = g.GetGripOrStretchPoints(dragType); - this.strectchPointCountList.push(gpts.length); pts.push(...gpts); } return pts; @@ -560,14 +547,7 @@ export class ExtrudeSolid extends Entity */ MoveGripOrStretchPointsOnly(indexList: Array, vec: Vector3, dragType: DragPointType) { - let stretchCount = - this.strectchPointCountList - ? this.strectchPointCountList[0] / 2 - : ( - dragType === DragPointType.Grip - ? this.ContourCurve.GetGripPoints() - : this.ContourCurve.GetStretchPoints() - ).length; + let stretchCount = this.ContourCurve.GetDragPointCount(dragType); if (dragType === DragPointType.Stretch) { diff --git a/src/DatabaseServices/Entity/Polyline.ts b/src/DatabaseServices/Entity/Polyline.ts index f2f8b9826..5136c51d3 100644 --- a/src/DatabaseServices/Entity/Polyline.ts +++ b/src/DatabaseServices/Entity/Polyline.ts @@ -1,23 +1,24 @@ -import { Box3, BufferGeometry, Matrix4, Object3D, Vector2, Vector3, Matrix3, Line as TLine } from 'three'; +import { Box3, BufferGeometry, Line as TLine, Matrix3, Matrix4, Object3D, Vector2, Vector3 } from 'three'; import { CreateBoardUtil } from '../../ApplicationServices/mesh/createBoard'; import { arrayLast, arrayRemoveDuplicateBySort, changeArrayStartIndex } from '../../Common/ArrayExt'; import { ColorMaterial } from '../../Common/ColorPalette'; import { getDeterminantFor2V } from '../../Common/CurveUtils'; -import { matrixAlignCoordSys, reviseMirrorMatrix, matrixIsCoplane } from '../../Common/Matrix4Utils'; +import { matrixAlignCoordSys, matrixIsCoplane, reviseMirrorMatrix } from '../../Common/Matrix4Utils'; import { Status } from '../../Common/Status'; import { FixIndex } from '../../Common/Utils'; import { ObjectSnapMode } from '../../Editor/ObjectSnapMode'; import { BufferGeometryUtils } from '../../Geometry/BufferGeometryUtils'; -import { equaln, equalv2, equalv3, updateGeometry, AsVector3, AsVector2 } from '../../Geometry/GeUtils'; -import { RenderType } from '../../GraphicsSystem/RenderType'; +import { AsVector2, AsVector3, equaln, equalv2, equalv3, updateGeometry } from '../../Geometry/GeUtils'; import { IntersectOption, IntersectPolylineAndCurve } from '../../GraphicsSystem/IntersectWith'; import { PolyOffsetUtil } from '../../GraphicsSystem/OffsetPolyline'; -import { Arc } from './Arc'; +import { RenderType } from '../../GraphicsSystem/RenderType'; import { Factory } from '../CADFactory'; import { CADFiler } from '../CADFiler'; +import { IsPointInPolyLine } from '../PointInPolyline'; +import { Arc } from './Arc'; import { Curve, ExtendType } from './Curve'; +import { DragPointType } from './DragPointType'; import { Line } from './Line'; -import { IsPointInPolyLine } from '../PointInPolyline'; export interface PolylineProps { @@ -1140,6 +1141,21 @@ export class Polyline extends Curve updateGeometry(plObj, BufferGeometryUtils.CreateFromPts(pts)); } } + + GetDragPointCount(drag: DragPointType): number + { + if (drag === DragPointType.Grip) + { + let count = this.EndParam * 2 + 1; + if (this.CloseMark) count--; + return count; + } + else + { + return this.m_LineData.length; + } + } + GetObjectSnapPoints( snapMode: ObjectSnapMode, pickPoint: Vector3, diff --git a/src/DatabaseServices/Template/Action/TempateThicknessAction.ts b/src/DatabaseServices/Template/Action/TempateThicknessAction.ts new file mode 100644 index 000000000..bbd15c6aa --- /dev/null +++ b/src/DatabaseServices/Template/Action/TempateThicknessAction.ts @@ -0,0 +1,94 @@ +import { Factory } from "../../CADFactory"; +import { Board } from "../../Entity/Board"; +import { TemplateAction } from "./TemplateAction"; +import { CADFiler } from "../../CADFiler"; +import { ObjectId } from "../../ObjectId"; + +export enum ThicknessDirection +{ + Center = 0, + Back = 1, + Front = 2, +} + +export interface ThicknessActionData +{ + //方向 + Direction: ThicknessDirection; + /** + * 附加的动作 + */ + Actions: TemplateAction[]; +} + +/** + * 模版动作 + */ +@Factory +export class TempateThicknessAction extends TemplateAction +{ + //正 true 反 false + EntityDirectionMap: Map = new Map(); + protected _Update(paramDiff: number, newValue: number) + { + for (let [id, d] of this.EntityDirectionMap) + { + if (id.IsErase) continue; + + let br = id.Object as Board; + + br.Thickness += paramDiff; + if (d.Direction === ThicknessDirection.Back) + br.Position = br.Position.sub(br.Normal.multiplyScalar(paramDiff)); + else if (d.Direction === ThicknessDirection.Center) + br.Position = br.Position.sub(br.Normal.multiplyScalar(paramDiff * 0.5)); + + for (let a of d.Actions) + { + a.parent = this.parent; + a.Update(paramDiff, newValue); + } + } + } + + + //#region -------------------------File------------------------- + //对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化 + //对象从文件中读取数据,初始化自身 + ReadFile(file: CADFiler) + { + let ver = file.Read(); + super.ReadFile(file); + + let count = file.Read() as number; + this.EntityDirectionMap.clear(); + for (let i = 0; i < count; i++) + { + let id = file.ReadObjectId(); + let direction = file.Read() as ThicknessDirection; + let actionsCount = file.Read() as number; + let actions: TemplateAction[] = []; + for (let j = 0; j < actionsCount; j++) + { + actions.push(file.ReadObject() as TemplateAction); + } + this.EntityDirectionMap.set(id, { Direction: direction, Actions: actions }); + } + } + //对象将自身数据写入到文件. + WriteFile(file: CADFiler) + { + file.Write(1); + super.WriteFile(file); + + file.Write(this.EntityDirectionMap.size); + for (let [id, d] of this.EntityDirectionMap) + { + file.WriteObjectId(id); + file.Write(d.Direction); + file.Write(d.Actions.length); + for (let a of d.Actions) + file.WriteObject(a); + } + } +} diff --git a/src/DatabaseServices/Template/Action/TemplateAction.ts b/src/DatabaseServices/Template/Action/TemplateAction.ts index 63cb10ef6..4112d3c32 100644 --- a/src/DatabaseServices/Template/Action/TemplateAction.ts +++ b/src/DatabaseServices/Template/Action/TemplateAction.ts @@ -1,7 +1,8 @@ +import { safeEval } from "../../../Common/eval"; +import { AutoRecord } from "../../AutoRecord"; import { Factory } from "../../CADFactory"; import { CADFiler } from "../../CADFiler"; import { TemplateParam } from "../Param/TemplateParam"; -import { AutoRecord } from "../../AutoRecord"; /** * 模版动作 @@ -9,7 +10,10 @@ import { AutoRecord } from "../../AutoRecord"; @Factory export class TemplateAction { - @AutoRecord Name: string; + @AutoRecord Name: string = "动作"; + /** 表达式应该只能依赖自身 */ + @AutoRecord Expr: string; + @AutoRecord Description: string; parent: TemplateParam; WriteAllObjectRecord() { @@ -18,20 +22,47 @@ export class TemplateAction } Update(paramDiff: number | string, newValue: number | string) { + if (this.Expr) + { + let varDefines = {}; + varDefines[this.parent.name] = newValue; + newValue = safeEval(this.Expr, varDefines) || newValue; + + varDefines[this.parent.name] = paramDiff; + paramDiff = safeEval(this.Expr, varDefines) || paramDiff; + } + + this._Update(paramDiff, newValue); + } + + + /** + * @重载 + */ + protected _Update(paramDiff: number | string, newValue: number | string) + { + } + //#region -------------------------File------------------------- //对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化 //对象从文件中读取数据,初始化自身 ReadFile(file: CADFiler) { let ver = file.Read(); - if (ver > 1) - this.Name = file.Read(); + this.Name = file.Read(); + if (ver > 2) + { + this.Expr = file.Read(); + this.Description = file.Read(); + } } //对象将自身数据写入到文件. WriteFile(file: CADFiler) { - file.Write(2); + file.Write(3); file.Write(this.Name); + file.Write(this.Expr); + file.Write(this.Description); } } diff --git a/src/DatabaseServices/Template/Action/TemplateFilletAction.ts b/src/DatabaseServices/Template/Action/TemplateFilletAction.ts index f7706cef5..4a0b1602e 100644 --- a/src/DatabaseServices/Template/Action/TemplateFilletAction.ts +++ b/src/DatabaseServices/Template/Action/TemplateFilletAction.ts @@ -1,46 +1,61 @@ +import { FilletUtils } from "../../../Add-on/FilletUtils"; +import { FixIndex } from "../../../Common/Utils"; +import { PromptEntityResult } from "../../../Editor/PromptResult"; import { Factory } from "../../CADFactory"; -import { TemplateAction } from "./TemplateAction"; import { CADFiler } from "../../CADFiler"; -import { ObjectId } from "../../ObjectId"; import { Board } from "../../Entity/Board"; -import { FilletUtils } from "../../../Add-on/FilletUtils"; -import { PromptEntityResult } from "../../../Editor/PromptResult"; -import { Polyline } from "../../Entity/Polyline"; import { Circle } from "../../Entity/Circle"; +import { ExtureContourCurve } from "../../Entity/Extrude"; +import { Polyline } from "../../Entity/Polyline"; +import { ObjectId } from "../../ObjectId"; +import { TemplateAction } from "./TemplateAction"; @Factory export class TemplateFilletAction extends TemplateAction { - constructor(protected _FilletEntity?: ObjectId, - protected _CurveParam1?: number, - protected _CurveParam2?: number - ) + FilletDatas: { Entity: ObjectId, ArcParams: number[] }[] = []; + + constructor() { super(); } - Update(paramDiff: number | string, newValue: number | string) + protected _Update(paramDiff: number, newValue: number) { - if (this._FilletEntity.IsErase) return; + for (let d of this.FilletDatas) + { + if (d.Entity.IsErase) + continue; + + let br = d.Entity.Object as Board; + + let cu = br.ContourCurve; + if (cu instanceof Circle) + return; - let br = this._FilletEntity.Object as Board; - let cu = br.ContourCurve; - if (cu instanceof Circle) - return; + let fillet = new FilletUtils(); + fillet.FilletRadius = Math.max(newValue, 0.1); - let fillet = new FilletUtils(); - fillet.FilletRadius = newValue as number; + let cuOld = cu as Polyline; + for (let arcParam of d.ArcParams) + { + let param1 = FixIndex(arcParam - 1, cu.EndParam); + let param2 = FixIndex(arcParam + 1, cu.EndParam); + let p1 = cu.GetPointAtParam(param1); + let p2 = cu.GetPointAtParam(param2); - let p1 = cu.GetPointAtParam(this._CurveParam1); - let p2 = cu.GetPointAtParam(this._CurveParam2); + let res1 = new PromptEntityResult(cu, p1); + let res2 = new PromptEntityResult(cu, p2); - let res1 = new PromptEntityResult(cu, p1); - let res2 = new PromptEntityResult(cu, p2); + let fres = fillet.FilletPolyLineSelf(res1, res2); + if (fres) + cu = fres.cu1 as ExtureContourCurve; + } - let fres = fillet.FilletPolyLineSelf(res1, res2); - if (fres) - br.ContourCurve = fres.cu1 as Polyline; + if (cu !== cuOld) + br.ContourCurve = cu; + } } //#region -------------------------File------------------------- @@ -49,16 +64,44 @@ export class TemplateFilletAction extends TemplateAction ReadFile(file: CADFiler) { let ver = file.Read(); - this._FilletEntity = file.ReadObjectId(); - this._CurveParam1 = file.Read(); - this._CurveParam2 = file.Read(); + super.ReadFile(file); + this.FilletDatas.length = 0; + if (ver === 1) + { + let id = file.ReadObjectId(); + let param1 = file.Read(); + let param2 = file.Read(); + let arcParam: number = param2 !== 0 ? param2 - 1 : param1 + 1; + this.FilletDatas.push({ Entity: id, ArcParams: [arcParam] }); + } + else + { + let count = file.Read(); + for (let i = 0; i < count; i++) + { + let id = file.ReadObjectId(); + let params: number[] = []; + let parCount = file.Read(); + for (let i = 0; i < parCount; i++) + { + params.push(file.Read()); + } + this.FilletDatas.push({ Entity: id, ArcParams: params }); + } + } } //对象将自身数据写入到文件. WriteFile(file: CADFiler) { - file.Write(1); - file.WriteObjectId(this._FilletEntity); - file.Write(this._CurveParam1); - file.Write(this._CurveParam2); + file.Write(2); + super.WriteFile(file); + file.Write(this.FilletDatas.length); + for (let d of this.FilletDatas) + { + file.WriteObjectId(d.Entity); + file.Write(d.ArcParams.length); + for (let param of d.ArcParams) + file.Write(param); + } } } diff --git a/src/DatabaseServices/Template/Action/TemplateMoveAction.ts b/src/DatabaseServices/Template/Action/TemplateMoveAction.ts index 726aaa13b..15842cecb 100644 --- a/src/DatabaseServices/Template/Action/TemplateMoveAction.ts +++ b/src/DatabaseServices/Template/Action/TemplateMoveAction.ts @@ -1,5 +1,5 @@ import { Vector3 } from "three"; -import { MoveMatrix } from "../../../Geometry/GeUtils"; +import { MoveMatrix, ZeroVec } from "../../../Geometry/GeUtils"; import { Factory } from "../../CADFactory"; import { CADFiler } from "../../CADFiler"; import { Entity } from "../../Entity/Entity"; @@ -11,15 +11,19 @@ export class TemplateMoveAction extends TemplateAction { constructor(public StretchDirection = new Vector3, - public Entitys: ObjectId[] = [] + public MoveEntitys: ObjectId[] = [] ) { super(); } - Update(paramDiff: number) + protected _Update(paramDiff: number) { - let moveMatrix = MoveMatrix(this.StretchDirection.clone().multiplyScalar(paramDiff)); - for (let id of this.Entitys) + let v = this.StretchDirection.clone() + .applyMatrix4(this.parent.parent.GetTemplateSpaceCS().setPosition(ZeroVec)) + .multiplyScalar(paramDiff); + + let moveMatrix = MoveMatrix(v); + for (let id of this.MoveEntitys) { let ent = id.Object as Entity; ent.ApplyMatrix(moveMatrix); @@ -31,21 +35,23 @@ export class TemplateMoveAction extends TemplateAction ReadFile(file: CADFiler) { let ver = file.Read(); + super.ReadFile(file); this.StretchDirection.fromArray(file.Read()); - this.Entitys.length = 0; + this.MoveEntitys.length = 0; let count = file.Read(); for (let i = 0; i < count; i++) { - this.Entitys.push(file.ReadObjectId()); + this.MoveEntitys.push(file.ReadObjectId()); } } //对象将自身数据写入到文件. WriteFile(file: CADFiler) { file.Write(1); + super.WriteFile(file); file.Write(this.StretchDirection.toArray()); - file.Write(this.Entitys.length); - for (let ent of this.Entitys) + file.Write(this.MoveEntitys.length); + for (let ent of this.MoveEntitys) file.WriteObjectId(ent); } } diff --git a/src/DatabaseServices/Template/Action/TemplateStretchGripAction.ts b/src/DatabaseServices/Template/Action/TemplateStretchGripAction.ts index e1438c076..d16609a3a 100644 --- a/src/DatabaseServices/Template/Action/TemplateStretchGripAction.ts +++ b/src/DatabaseServices/Template/Action/TemplateStretchGripAction.ts @@ -1,29 +1,28 @@ -import { Vector3 } from "three"; import { arrayClone } from "../../../Common/ArrayExt"; import { Factory } from "../../CADFactory"; import { CADFiler } from "../../CADFiler"; import { Entity } from "../../Entity/Entity"; import { ObjectId } from "../../ObjectId"; -import { TemplateAction } from "./TemplateAction"; +import { TemplateMoveAction } from "./TemplateMoveAction"; +import { ZeroVec } from "../../../Geometry/GeUtils"; /** * Stretch夹点动作 */ @Factory -export class TemplateStretchGripAction extends TemplateAction +export class TemplateStretchGripAction extends TemplateMoveAction { - /** - * 正常不会直接修改下面的2个属性,如果真的需要修改,请调用 `this.WriteAllObjectRecord`; - * 避免历史记录没有记录更新. - */ - StretchDirection: Vector3 = new Vector3(); EntityStretchPointMap: { entity: ObjectId; indexs: number[]; }[] = []; - Update(dist: number) + + protected _Update(dist: number) { - let v = this.StretchDirection.clone().multiplyScalar(dist); + super._Update(dist); + let v = this.StretchDirection.clone() + .applyMatrix4(this.parent.parent.GetTemplateSpaceCS().setPosition(ZeroVec)) + .multiplyScalar(dist); for (let { entity, indexs } of this.EntityStretchPointMap) { let ent = entity.Object as Entity; @@ -37,7 +36,6 @@ export class TemplateStretchGripAction extends TemplateAction { let ver = file.Read(); super.ReadFile(file); - this.StretchDirection.fromArray(file.Read()); this.EntityStretchPointMap.length = 0; let count = file.Read() as number; for (let i = 0; i < count; i++) @@ -52,7 +50,6 @@ export class TemplateStretchGripAction extends TemplateAction { file.Write(1); super.WriteFile(file); - file.Write(this.StretchDirection.toArray()); file.Write(this.EntityStretchPointMap.length); for (let d of this.EntityStretchPointMap) { diff --git a/src/DatabaseServices/Template/Action/TemplateStretchScaleBoxAction.ts b/src/DatabaseServices/Template/Action/TemplateStretchScaleBoxAction.ts index c2c18c416..adb3d78d2 100644 --- a/src/DatabaseServices/Template/Action/TemplateStretchScaleBoxAction.ts +++ b/src/DatabaseServices/Template/Action/TemplateStretchScaleBoxAction.ts @@ -3,13 +3,14 @@ import { Factory } from "../../CADFactory"; import { CADFiler } from "../../CADFiler"; import { Entity } from "../../Entity/Entity"; import { ObjectId } from "../../ObjectId"; -import { TemplateAction } from "./TemplateAction"; +import { TemplateMoveAction } from "./TemplateMoveAction"; +import { ZeroVec } from "../../../Geometry/GeUtils"; /** * 拽拖比例盒子动作 */ @Factory -export class TemplateStretchScaleBoxAction extends TemplateAction +export class TemplateStretchScaleBoxAction extends TemplateMoveAction { /** * 正常不会直接修改下面的2个属性,如果真的需要修改,请调用 `this.WriteAllObjectRecord`; @@ -23,9 +24,13 @@ export class TemplateStretchScaleBoxAction extends TemplateAction super(); } - Update(dist: number) + protected _Update(dist: number) { - let v = this.StretchDirection.clone().multiplyScalar(dist); + super._Update(dist); + + let v = this.StretchDirection.clone() + .applyMatrix4(this.parent.parent.GetTemplateSpaceCS().setPosition(ZeroVec)) + .multiplyScalar(dist); for (let { entity, scaleBox } of this.EntityStretchData) { let ent = entity.Object as Entity; @@ -54,7 +59,6 @@ export class TemplateStretchScaleBoxAction extends TemplateAction { let ver = file.Read(); super.ReadFile(file); - this.StretchDirection.fromArray(file.Read()); this.EntityStretchData.length = 0; let count = file.Read() as number; for (let i = 0; i < count; i++) @@ -70,7 +74,6 @@ export class TemplateStretchScaleBoxAction extends TemplateAction { file.Write(1); super.WriteFile(file); - file.Write(this.StretchDirection.toArray()); file.Write(this.EntityStretchData.length); for (let d of this.EntityStretchData) { diff --git a/src/DatabaseServices/Template/Param/TemplateParam.ts b/src/DatabaseServices/Template/Param/TemplateParam.ts index e81d78049..b1a679422 100644 --- a/src/DatabaseServices/Template/Param/TemplateParam.ts +++ b/src/DatabaseServices/Template/Param/TemplateParam.ts @@ -27,7 +27,7 @@ export class TemplateParam @AutoRecord value: string | number; @AutoRecord default: string | number; @AutoRecord description: string; - @AutoRecord type: TemplateParamType; + @AutoRecord type: TemplateParamType = TemplateParamType.Float; @AutoRecord min: number; @AutoRecord max: number; //可选值 @@ -78,12 +78,12 @@ export class TemplateParam let newV = value as number; if (!equaln(oldV, newV)) { + this.WriteAllObjectRecord(); + this.value = newV; + let diff = newV - oldV; for (let a of this.actions) a.Update(diff, newV); - - this.WriteAllObjectRecord(); - this.value = newV; } break; case TemplateParamType.Int: diff --git a/src/DatabaseServices/Template/Positioning/PositioningClampSpace.ts b/src/DatabaseServices/Template/Positioning/PositioningClampSpace.ts index 3c3476dd8..a1238100c 100644 --- a/src/DatabaseServices/Template/Positioning/PositioningClampSpace.ts +++ b/src/DatabaseServices/Template/Positioning/PositioningClampSpace.ts @@ -40,9 +40,7 @@ export class PositioningClampSpace extends Positioning await parse.Parse(); if (parse.ParseOK) { - this.SpaceCS = parse.SpaceOCS; - let p = parse.SpaceBox.min.clone().applyMatrix4(this.SpaceCS); - this.SpaceCS.setPosition(p); + this.SpaceCS = parse.DrawCS; this.SpaceSize = parse.Size; } else diff --git a/src/DatabaseServices/Template/TempateUtils.ts b/src/DatabaseServices/Template/TempateUtils.ts index 56fa7296c..d5d47ae4a 100644 --- a/src/DatabaseServices/Template/TempateUtils.ts +++ b/src/DatabaseServices/Template/TempateUtils.ts @@ -1,4 +1,25 @@ +import { Intent } from "@blueprintjs/core"; +import { Box3, Matrix4, Vector3 } from "three"; +import { app } from "../../ApplicationServices/Application"; +import { StretchParse } from "../../Common/StretchParse"; +import { FixedNotZero, log } from "../../Common/Utils"; +import { PromptStatus } from "../../Editor/PromptResult"; +import { SelectBox } from "../../Editor/SelectBox"; +import { SelectPick } from "../../Editor/SelectPick"; +import { AxisSnapMode } from "../../Editor/SnapServices"; +import { Box3Ext } from "../../Geometry/Box"; +import { AsVector3, equaln, isParallelTo, isPerpendicularityTo, ZAxis, ZeroVec, XAxis } from "../../Geometry/GeUtils"; +import { AppToaster } from "../../UI/Components/Toaster"; import { Board } from "../Entity/Board"; +import { Polyline } from "../Entity/Polyline"; +import { ObjectId } from "../ObjectId"; +import { TempateThicknessAction, ThicknessActionData, ThicknessDirection } from "./Action/TempateThicknessAction"; +import { TemplateAction } from "./Action/TemplateAction"; +import { TemplateFilletAction } from "./Action/TemplateFilletAction"; +import { TemplateMoveAction } from "./Action/TemplateMoveAction"; +import { TemplateStretchGripAction } from "./Action/TemplateStretchGripAction"; +import { TemplateStretchScaleBoxAction } from "./Action/TemplateStretchScaleBoxAction"; +import { TemplateParam } from "./Param/TemplateParam"; import { TemplateRecord } from "./TemplateRecord"; /** @@ -23,3 +44,778 @@ export function GetDeepestTemplate(brs: Board[]): TemplateRecord | undefined return deepestTemplate; } + +/** + * 获得模块的尺寸 + */ +export function GetTempateSize(template: TemplateRecord): Vector3 +{ + return new Vector3(template.LParam.value as number, template.WParam.value as number, template.HParam.value as number); +} + +export function GetTempateBoards(template: TemplateRecord): Board[] +{ + let brs: Board[] = []; + + for (let id of template.Objects) + { + if (!id.IsErase) + brs.push(id.Object as Board); + } + return brs; +} + +/** + * 初始化模块 + * + * 如果所有板件都在同一个模块, 那么传回原先的模块(或生成新模块) + * 如果所有板件都不在模块中,那么生成新模块. + * 如果板件在不同的模块中,那么询问用户是否生成新模块. + * + * @param brs 板件列表 + * @returns 模块记录 + */ +export async function InitTemplate(brs: Board[]): Promise +{ + let templates: Set = new Set(); + for (let br of brs) + { + if (!br.Template) + templates.add(undefined); + else + { + + let template = (br.Template.Object as TemplateRecord); + templates.add(template); + } + } + + let templateSize: Vector3; + + if (templates.size > 1) + { + let keyRes = await app.Editor.GetKeyWords({ + Msg: "选择的实体存在多个模块内,是否忽略原先模块,创建新的模块?", + KeyWordList: [ + { key: "1", msg: "是" }, + { key: "2", msg: "否" }, + ], + Default: "1" + }); + + if (keyRes.StringResult !== "1") + return undefined; + + templates.delete(undefined); + } + else // (templates.size === 1)//都在一个模块内或者都不在模块内 + { + templates.delete(undefined); + if (templates.size === 1)//都在模块内 + { + let keyRes = await app.Editor.GetKeyWords({ + Msg: "编辑当前模块或者重新创建", + KeyWordList: [ + { key: "Y", msg: "创建新模块" }, + { key: "N", msg: "编辑当前模块" }, + ], + Default: "N" + }); + if (keyRes.Status === PromptStatus.Cancel) return; + if (keyRes.StringResult === "N") + return [...templates][0]; + } + } + + let keyRes = await app.Editor.GetKeyWords({ + Msg: "将选择实体移动到世界坐标系0点?", + KeyWordList: [ + { key: "1", msg: "是" }, + { key: "2", msg: "否" }, + ], + Default: "1" + }); + + if (keyRes.Status === PromptStatus.Cancel) return; + + let box = new Box3(); + for (let br of brs) + box.union(br.BoundingBox); + + templateSize = box.max; + if (keyRes.StringResult === "1") + { + let m = new Matrix4().setPosition(box.min.negate()); + for (let br of brs) + br.ApplyMatrix(m); + + templateSize.add(box.min); + } + + //清空旧模块信息(这里的代码能多余,因为模块中可能还有其他的板件没有被重新创建?) + for (let template of templates) + app.Database.TemplateTable.Remove(template); + + //初始化模块 + let template = new TemplateRecord().InitBaseParams(); + + let bhParam = new TemplateParam(); + bhParam.value = 18; + bhParam.name = "BH"; + bhParam.description = "板厚"; + template.Params.push(bhParam); + + if (templateSize) + { + template.LParam.value = templateSize.x; + template.WParam.value = templateSize.y; + template.HParam.value = templateSize.z; + } + app.Database.TemplateTable.Append(template); + + let wcs = new Matrix4(); + + for (let br of brs) + { + template.Objects.push(br.Id); + br.SpaceOCS = wcs; + } + + return template; +} + +/** + * 使用板件更新模块的尺寸 + */ +export function UpdateTemplateSizeOffBoards(template: TemplateRecord) +{ + let box = new Box3(); + let spaceCSInv: Matrix4; + for (let id of template.Objects) + { + if (id.IsErase) continue; + + let br = id.Object as Board; + + if (!spaceCSInv) + spaceCSInv = br.SpaceOCSInv; + + let brbox = br.GetBoardBoxInMtx(spaceCSInv); + + box.union(brbox); + } + + let size = box.max; + + let parmas = template.Params; + parmas[0].value = FixedNotZero(size.x, 2); + parmas[1].value = FixedNotZero(size.y, 2); + parmas[2].value = FixedNotZero(size.z, 2); +} + +/** + * 设置模块坐标系 + * + * 通常需要调用一下`UpdateTemplateSizeOffBoards` + */ +export async function SetTempateCoordinate(template: TemplateRecord) +{ + let ptRes = await app.Editor.GetPoint({ + Msg: "选择模板基点", + }); + if (ptRes.Status !== PromptStatus.OK) return; + + let basePt = ptRes.Point; + + ptRes = await app.Editor.GetPoint({ + Msg: "请选择X轴方向(空格使用世界坐标系方向):", + BasePoint: basePt, + AllowDrawRubberBand: true, + AllowNone: true, + }); + if (ptRes.Status === PromptStatus.Cancel) return; + + let spaceCS = new Matrix4(); + + if (ptRes.Status === PromptStatus.None) + { + spaceCS.setPosition(basePt); + } + else + { + let xVec = ptRes.Point.sub(basePt).normalize(); + let yVec: Vector3; + + let canAllowNone = isPerpendicularityTo(xVec, ZAxis); + + while (true) + { + ptRes = await app.Editor.GetPoint({ + Msg: canAllowNone ? "请选择Y轴方向(空格使用标准平面方向):" : "请选择Y轴方向:", + BasePoint: basePt, + AllowDrawRubberBand: true, + AllowNone: canAllowNone, + }); + + if (ptRes.Status === PromptStatus.Cancel) + return; + + if (ptRes.Status === PromptStatus.None) + yVec = ZAxis.clone().cross(xVec); + else + yVec = ptRes.Point.sub(basePt).normalize(); + + if (!isPerpendicularityTo(xVec, yVec)) + { + AppToaster.show({ + message: "x轴和y轴必须垂直", + timeout: 2000, + intent: Intent.DANGER + }); + } + else break; + } + + let zVec = xVec.clone().cross(yVec); + spaceCS.makeBasis(xVec, yVec, zVec).setPosition(basePt); + } + + for (let id of template.Objects) + { + if (!id.IsErase) + { + let br = id.Object as Board; + br.SpaceOCS = spaceCS; + } + } +} + +/** + * 初始化模块的大小动作 + * + * 应该已经传入正确的模块大小 + * 应该先判断是否存在动作,如果有,则清空它. + * @param template + * @param [useScaleBox=true] 使用比例盒子拉伸动作?如果`=false`则使用夹点拉伸动作. + */ +export function InitTempateSizeActions(template: TemplateRecord, useScaleBox = true) +{ + //清除原先的动作 + template.LParam.actions.length = 0; + template.WParam.actions.length = 0; + template.HParam.actions.length = 0; + + //模块信息 + let scs = template.GetTemplateSpaceCS(); + let scsInv = new Matrix4().getInverse(scs); + let size = GetTempateSize(template); + + //拉伸盒子范围 + let max = size.clone().addScalar(1); + let backBox = new Box3Ext(new Vector3(-1, size.y / 2, -1), max); + let rightBox = new Box3Ext(new Vector3(size.x / 2, -1, -1), max); + let topBox = new Box3Ext(new Vector3(-1, -1, size.z / 2), max); + + //板件列表 + let brs = GetTempateBoards(template); + + //动作列表 + let ActionType = useScaleBox ? TemplateStretchScaleBoxAction : TemplateStretchGripAction; + let lAction = new ActionType(new Vector3(1, 0, 0)); + let wAction = new ActionType(new Vector3(0, 1, 0)); + let hAction = new ActionType(new Vector3(0, 0, 1)); + + for (let br of brs) + { + let sps = br.GetStretchPoints(); + + let boxContainsIndexMap = [ + { box: rightBox, indexs: [], action: lAction }, + { box: backBox, indexs: [], action: wAction }, + { box: topBox, indexs: [], action: hAction } + ]; + + for (let i = 0; i < sps.length; i++) + { + const p = sps[i].applyMatrix4(scsInv); + + for (let d of boxContainsIndexMap) + { + if (d.box.containsPoint(p)) + d.indexs.push(i); + } + } + + let spaceToLocalMtx: Matrix4; + if (useScaleBox) + spaceToLocalMtx = br.OCSInv.multiply(scs); + + for (let d of boxContainsIndexMap) + { + if (d.indexs.length === 0) + continue; + + if (d.indexs.length === sps.length || br.IsStretchThickness(d.indexs)) + d.action.MoveEntitys.push(br.Id); + else + { + if (useScaleBox) + { + let scaleBox = d.box.clone().applyMatrix4(spaceToLocalMtx); + let size = new Vector3(br.Width, br.Height, br.Thickness); + scaleBox.min.divide(size); + scaleBox.max.divide(size); + let action = d.action as TemplateStretchScaleBoxAction; + action.EntityStretchData.push({ entity: br.Id, scaleBox }); + } + else + { + let action = d.action as TemplateStretchGripAction; + action.EntityStretchPointMap.push({ entity: br.Id, indexs: d.indexs }); + } + } + } + } + + template.LParam.actions.push(lAction); + template.WParam.actions.push(wAction); + template.HParam.actions.push(hAction); +} + +/** + * 初始化模块的板厚动作 + * + * 如果已经存在动作,则会清空旧的动作. + * @param template + * @param [autoCalculate=true] 自动计算板厚的变化方向,如果为否则交给用户选择 + */ +export async function InitTempateBoardThicknessActions(template: TemplateRecord, autoCalculate = true) +{ + //清理所有的动作 + let param = template.GetParam("BH"); + if (!param) + return; + + param.actions.length = 0; + + //开启正交 + let snapModeBak = app.Editor.GetPointServices.snapServices.AxisSnapMode; + let ucsBak = app.Editor.UCSMatrix; + app.Editor.GetPointServices.snapServices.AxisSnapMode = AxisSnapMode.Ortho; + + //模块信息 + let scs = template.GetTemplateSpaceCS(); + let scsInv = new Matrix4().getInverse(scs).setPosition(ZeroVec); + let size = GetTempateSize(template); + let brs = GetTempateBoards(template); + + let center = size.clone().multiplyScalar(0.5).applyMatrix4(scs); + + let directionMap: Map = new Map(); + + for (let br of brs) + { + let p: Vector3; + if (!autoCalculate) + { + //亮显它 + app.Viewer.OutlinePass.selectedObjects = [br.DrawObject]; + app.Editor.UpdateScreen(); + + //板件中心 + let boardCenter = new Vector3(br.Width, br.Height, br.Thickness).multiplyScalar(.5); + boardCenter.applyMatrix4(br.OCS); + + //设置UCS + app.Editor.UCSMatrix = br.OCS; + + let ptRes = await app.Editor.GetPoint({ BasePoint: boardCenter, AllowDrawRubberBand: true }); + + if (ptRes.Status !== PromptStatus.OK) + { + //还原 + app.Editor.GetPointServices.snapServices.AxisSnapMode = snapModeBak; + app.Editor.UCSMatrix = ucsBak; + return; + } + + p = ptRes.Point; + } + else + p = center.clone(); + + //构建板厚动作 + GeneralBoardThicknessAction(br, p, scsInv, brs, directionMap); + } + let action = new TempateThicknessAction(); + action.EntityDirectionMap = directionMap; + param.actions.push(action); + + //还原 + app.Editor.GetPointServices.snapServices.AxisSnapMode = snapModeBak; + app.Editor.UCSMatrix = ucsBak; +} + + +/** + * 构建板厚动作 + * @param br 需要构建的板件 + * @param p wcs点,确定板厚变厚方向 + * @param scsInv 模块坐标系逆矩阵 + * @param brs 模块所有的板件列表 + * @param directionMap 板厚动作数据 + */ +function GeneralBoardThicknessAction(br: Board, p: Vector3, scsInv: Matrix4, brs: Board[], directionMap: Map) +{ + p.applyMatrix4(br.OCSInv); + + let direction: ThicknessDirection; + let actions: TemplateAction[] = []; + + let frontBox = new Box3Ext(new Vector3(0, 0, br.Thickness).subScalar(1), new Vector3(br.Width, br.Height, br.Thickness).addScalar(1)); + let backBox = new Box3Ext(new Vector3().subScalar(1), new Vector3(br.Width, br.Height, 0).addScalar(1)); + + let frontStretchMap: { entity: ObjectId; indexs: number[]; }[] = []; + let backStretchMap: { entity: ObjectId; indexs: number[]; }[] = []; + + let frontVec = br.Normal.applyMatrix4(scsInv); + let backVec = frontVec.clone().negate(); + + let brOcsInv = br.OCSInv; + + let brN = br.Normal; + + for (let br2 of brs) + { + if (br === br2) continue; + + if (isParallelTo(brN, br2.Normal)) continue; + + let sps = br2.GetStretchPoints(); + + let frontIndexs: number[] = []; + let backIndexs: number[] = []; + + for (let i = 0; i < sps.length; i++) + { + let p = sps[i]; + p.applyMatrix4(brOcsInv); + + if (frontBox.containsPoint(p)) + frontIndexs.push(i); + else if (backBox.containsPoint(p)) + backIndexs.push(i); + } + + if (frontIndexs.length > 0) + frontStretchMap.push({ entity: br2.Id, indexs: frontIndexs }); + + if (backIndexs.length > 0) + backStretchMap.push({ entity: br2.Id, indexs: backIndexs }); + } + + //判断拉伸方向 + if (equaln(p.z, 0))//居中 + { + direction = ThicknessDirection.Center; + + let frontAction = new TemplateStretchGripAction(frontVec); + frontAction.EntityStretchPointMap = frontStretchMap; + frontAction.Expr = "BH*0.5"; + actions.push(frontAction); + + let backAction = new TemplateStretchGripAction(backVec); + backAction.EntityStretchPointMap = backStretchMap; + backAction.Expr = "BH*0.5"; + actions.push(backAction); + } + else + { + if (p.z > 0) + { + direction = ThicknessDirection.Front; + let frontAction = new TemplateStretchGripAction(frontVec); + frontAction.EntityStretchPointMap = frontStretchMap; + actions.push(frontAction); + } + else + { + direction = ThicknessDirection.Back; + let backAction = new TemplateStretchGripAction(backVec); + backAction.EntityStretchPointMap = backStretchMap; + actions.push(backAction); + } + } + + directionMap.set(br.Id, { Direction: direction, Actions: actions }); +} + +/** + * 对指定的板厚动作方向进行修改 + * + * 大量抄自动初始化板厚动作的代码 + */ +export async function UpdateTempateBoardThicknessAction(template: TemplateRecord) +{ + let param = template.GetParam("BH"); + if (!param) + return; + + //模块信息 + let scs = template.GetTemplateSpaceCS(); + let scsInv = new Matrix4().getInverse(scs).setPosition(ZeroVec); + let brs = GetTempateBoards(template); + let sbrs = new Set(brs); + + let ssRes = await app.Editor.GetSelection({ + Filter: { + filterFunction: (obj, ent) => + { + return sbrs.has(ent); + } + } + }); + + if (ssRes.Status !== PromptStatus.OK) return; + + let cbrs = ssRes.SelectSet.SelectEntityList as Board[]; + + //开启正交 + let snapModeBak = app.Editor.GetPointServices.snapServices.AxisSnapMode; + let ucsBak = app.Editor.UCSMatrix; + app.Editor.GetPointServices.snapServices.AxisSnapMode = AxisSnapMode.Ortho; + + let thicknessAction = param.actions.find(a => a instanceof TempateThicknessAction) as TempateThicknessAction; + if (!thicknessAction) + { + thicknessAction = new TempateThicknessAction(); + param.actions.push(thicknessAction); + } + else + param.WriteAllObjectRecord(); + + for (let br of cbrs) + { + //亮显它 + app.Viewer.OutlinePass.selectedObjects = [br.DrawObject]; + app.Editor.UpdateScreen(); + + //板件中心 + let boardCenter = new Vector3(br.Width, br.Height, br.Thickness).multiplyScalar(.5); + boardCenter.applyMatrix4(br.OCS); + + //设置UCS + app.Editor.UCSMatrix = br.OCS; + + let ptRes = await app.Editor.GetPoint({ BasePoint: boardCenter, AllowDrawRubberBand: true }); + + if (ptRes.Status !== PromptStatus.OK) + { + //还原 + app.Editor.GetPointServices.snapServices.AxisSnapMode = snapModeBak; + app.Editor.UCSMatrix = ucsBak; + return; + } + + let p = ptRes.Point; + //构建板厚动作 + GeneralBoardThicknessAction(br, p, scsInv, brs, thicknessAction.EntityDirectionMap); + } + + //还原 + app.Editor.GetPointServices.snapServices.AxisSnapMode = snapModeBak; + app.Editor.UCSMatrix = ucsBak; +} + +//拉伸盒子的最大和最小 +const SCALEMIN = new Vector3(-0.1, -0.1, -0.1); +const SCALEMAX = new Vector3(1.1, 1.1, 1.1); + +/** + * 增加拉伸动作 + * + * 返回动作,并不会直接加入到模块中,可以设置完动作属性在加入 + * @param [useScaleBox=false] 使用比例盒子,否则使用夹点拽拖 + */ +export async function AddStretchAction(template: TemplateRecord, useScaleBox = false): Promise +{ + //模块信息 + let scs = template.GetTemplateSpaceCS(); + let scsInv = new Matrix4().getInverse(scs); + let brs = GetTempateBoards(template); + let sbrs = new Set(brs); + + //拾取需要增加的板件 + let ssRes = await app.Editor.GetSelection({ + Msg: "选择要增加动作的板件(空格全选):", + AllowNone: true, + Filter: { + filterFunction: (obj, ent) => + { + return sbrs.has(ent); + } + } + }); + + if (ssRes.Status === PromptStatus.Cancel) return; + if (ssRes.Status === PromptStatus.OK) + sbrs = new Set(ssRes.SelectSet.SelectEntityList as Board[]); + + ssRes = await app.Editor.GetSelection({ + Msg: "选择拉伸范围:", + Filter: { + filterFunction: (obj, ent) => + { + return sbrs.has(ent); + } + } + }); + if (ssRes.Status !== PromptStatus.OK) return; + + //方向拾取 + let p1Res = await app.Editor.GetPoint({}); + if (p1Res.Status !== PromptStatus.OK) return; + + let p2Res = await app.Editor.GetPoint({ Msg: "点击下一个点确认方向:", BasePoint: p1Res.Point }); + if (p2Res.Status !== PromptStatus.OK) return; + + let direction = p2Res.Point.sub(p1Res.Point); + direction.transformDirection(scsInv); + + //构建动作 + let action: TemplateMoveAction; + + let stretchData = StretchParse(ssRes.SelectSet); + if (useScaleBox) + { + let saction = new TemplateStretchScaleBoxAction(); + action = saction; + for (let set of ssRes.SelectSet.SelectSetList) + { + if (set instanceof SelectBox) + { + let selectBox3 = new Box3(AsVector3(set.SelectBox.min).setZ(-6e6), AsVector3(set.SelectBox.max).setZ(6e6)); + let widthHalf = set.m_ViewerWidth * 0.5; + let heightHalf = set.m_ViewerHeight * 0.5; + let dcs = new Matrix4() + .setPosition(new Vector3(widthHalf, heightHalf)) + .multiply(new Matrix4().set(widthHalf, 0, 0, 0, 0, -heightHalf, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)) + .multiply(set.m_ProjScreenMatrix); + let dcsInv = new Matrix4().getInverse(dcs); + for (let e of set.SelectEntityList) + { + if (stretchData.moveEntityList.includes(e)) + continue; + + let br = e as Board; + let mtx = new Matrix4().multiplyMatrices(br.OCSInv, dcsInv); + let scaleBox = selectBox3.clone().applyMatrix4(mtx); + let size = new Vector3(br.Width, br.Height, br.Thickness); + scaleBox.min.divide(size); + scaleBox.max.divide(size); + scaleBox.min.clamp(SCALEMIN, SCALEMAX); + scaleBox.max.clamp(SCALEMIN, SCALEMAX); + saction.EntityStretchData.push({ + entity: br.Id, + scaleBox + }); + } + } + } + } + else + { + let saction = new TemplateStretchGripAction(); + action = saction; + for (let { ent, indexs } of stretchData.stretchEntityMap) + { + saction.EntityStretchPointMap.push({ entity: ent.Id, indexs }); + } + } + action.MoveEntitys = stretchData.moveEntityList.map(ent => ent.Id); + action.StretchDirection = direction; + + return action; +} + + +/** + * 增加倒角动作 + * + * 动作不会直接加到模块中,需要修改动作的参数后在加入 + * @param template + * @returns + */ +export async function AddFilletAction(template: TemplateRecord): Promise +{ + //模块信息 + let brs = GetTempateBoards(template); + let objs = brs.map(br => br.DrawObject); + + let brParamMap: Map> = new Map(); + while (true) + { + let ptRes = await app.Editor.GetPoint({ + Msg: "请点击需要添加动作的圆弧", + AllowNone: true, + }); + if (ptRes.Status === PromptStatus.OK) + { + //选择添加圆角动作的板件 + let ptScreen = ptRes.Point; + app.Viewer.WorldToScreen(ptScreen); + let selectPick = new SelectPick(app.Viewer, ptScreen); + selectPick.Select(objs); + let ens = selectPick.SelectEntityList as Board[]; + + for (let br of ens) + { + let cu = (ens[0] as Board).ContourCurve; + if (cu instanceof Polyline) + { + let pOCS = ptRes.Point.applyMatrix4(br.OCSInv).setZ(0); + let par = cu.GetParamAtPoint(pOCS); + if (isNaN(par)) + { + log("点取的点不在圆弧上!"); + continue; + } + + par = Math.floor(par); + let bul = cu.GetBuilgeAt(par); + if (!equaln(bul, 0)) + { + //避免统一圆弧添加多个参数,修正为圆弧中心 + par = par + 0.5; + if (brParamMap.has(br)) + brParamMap.get(br).add(par); + else + brParamMap.set(br, new Set([par])); + + log("成功添加!"); + } + else + log("点取的点不在圆弧上!"); + } + } + } + else if (ptRes.Status === PromptStatus.Cancel) + { + log("取消添加动作!"); + return; + } + else break; + } + + if (brParamMap.size === 0) return; + + let action = new TemplateFilletAction(); + for (let [br, pars] of brParamMap) + { + action.FilletDatas.push({ + Entity: br.Id, + ArcParams: [...pars] + }); + } + return action; +} diff --git a/src/DatabaseServices/Template/TemplateRecord.ts b/src/DatabaseServices/Template/TemplateRecord.ts index a7ca2807a..945219abe 100644 --- a/src/DatabaseServices/Template/TemplateRecord.ts +++ b/src/DatabaseServices/Template/TemplateRecord.ts @@ -13,6 +13,9 @@ import { PositioningClampSpace } from "./Positioning/PositioningClampSpace"; import { PositioningTemporary } from "./Positioning/PositioningTemporary"; import { TemplateSplitType, TemplateType } from "./TemplateType"; +const TemplateDefaultParams = ["L", "W", "H", "PX", "PY", "PZ", "RX", "RY", "RZ"]; +export const TempateDefaultParamCount = TemplateDefaultParams.length; + /** * ### 模板记录 * 模版与实体总是互相关联的,所以添加实体进入模版的时候,应该保证这个记录已经加入到数据库 @@ -76,6 +79,19 @@ export class TemplateRecord extends SymbolTableRecord ); } + get Name() + { + return this.name; + } + set Name(name: string) + { + if (name !== this.name) + { + this.WriteAllObjectRecord(); + this.name = name; + } + } + get Root(): TemplateRecord { if (this.Parent) @@ -148,14 +164,10 @@ export class TemplateRecord extends SymbolTableRecord //#region param - static BaseParamName = ["L", "W", "H", - "PX", "PY", "PZ", - "RX", "RY", "RZ"]; - /** 初始化基础参数 */ InitBaseParams() { - for (let paramName of TemplateRecord.BaseParamName) + for (let paramName of TemplateDefaultParams) { let value = 0; let param = new TemplateParam(); @@ -164,6 +176,9 @@ export class TemplateRecord extends SymbolTableRecord param.value = value; this.Params.push(param); } + this.LParam.description = "宽"; + this.WParam.description = "深"; + this.HParam.description = "高"; return this; } @@ -179,22 +194,18 @@ export class TemplateRecord extends SymbolTableRecord get RYParam() { return this.Params[7]; } get RZParam() { return this.Params[8]; } - - - /** - * 通常只有真的只需要更新一个参数的时候需要调用这个方法 - * 如果同时修改多个参数,因为参数可能互相引用,不应该直接调用这个方法 - */ - UpdateParam(name: string, value: any, expr?: string) + GetParam(paramName: string): TemplateParam | undefined { - let param = this.GetParam(name); - if (param) - param.UpdateParam(value); + return this.Params.find(param => param.name === paramName); } - GetParam(paramName: string): TemplateParam | undefined + DeleteParam(paramName: string) { - return this.Params.find(param => param.name === paramName); + let index = this.Params.findIndex(p => p.name === paramName); + if (index !== -1 && index > TempateDefaultParamCount)//LWH P R 禁止删除 + this.Params.splice(index, 1); + + return this; } //#endregion param @@ -224,17 +235,16 @@ export class TemplateRecord extends SymbolTableRecord * * - `LWH`将被`positioning`替代,但变量定义仍然正常存在. * - * - (未实现)变量大部分时候都是被批量更新,(同时传入许多参数). + * - 变量大部分时候都是被批量更新,(同时传入许多参数). * */ protected async Update() { - let varDefines = this.GetParameterDefinition(false); + this._CacheParamVars = this.GetParameterDefinition(false); let brs = this.Objects.filter(id => !id.IsErase).map(id => id.Object as Board); let evaled = new Set(); - let spaceCS = this.GetTemplateSpaceCS(false); - let spaceSize: Vector3; + this._CacheSpaceCS = this.GetTemplateSpaceCS(false); let paramMap = new Map(); for (let param of this.Params) @@ -250,16 +260,16 @@ export class TemplateRecord extends SymbolTableRecord if (!this.positioning.SpaceCS) return;//出事故 - spaceCS = this.positioning.SpaceCS; - spaceSize = this.positioning.SpaceSize; + this._CacheSpaceCS = this.positioning.SpaceCS; + this._CacheSpaceSize = this.positioning.SpaceSize; - spaceCS = this.RotateSpaceCS(varDefines, paramMap, evaled, spaceCS, spaceSize); + this._CacheSpaceCS = this.RotateSpaceCS(this._CacheParamVars, paramMap, evaled, this._CacheSpaceCS, this._CacheSpaceSize); //更新LWH(通过定位空间) - this.LParam.UpdateParam(spaceSize.x); + this.LParam.UpdateParam(this._CacheSpaceSize.x); this.LParam.expr = ""; - this.WParam.UpdateParam(spaceSize.y); + this.WParam.UpdateParam(this._CacheSpaceSize.y); this.WParam.expr = ""; - this.HParam.UpdateParam(spaceSize.z); + this.HParam.UpdateParam(this._CacheSpaceSize.z); this.HParam.expr = ""; if (this.positioning instanceof PositioningTemporary) @@ -268,24 +278,24 @@ export class TemplateRecord extends SymbolTableRecord else { - this.LParam.EvalUpdate(varDefines, paramMap, evaled); - this.WParam.EvalUpdate(varDefines, paramMap, evaled); - this.HParam.EvalUpdate(varDefines, paramMap, evaled); + this.LParam.EvalUpdate(this._CacheParamVars, paramMap, evaled); + this.WParam.EvalUpdate(this._CacheParamVars, paramMap, evaled); + this.HParam.EvalUpdate(this._CacheParamVars, paramMap, evaled); - this.PXParam.EvalUpdate(varDefines, paramMap, evaled); - this.PYParam.EvalUpdate(varDefines, paramMap, evaled); - this.PZParam.EvalUpdate(varDefines, paramMap, evaled); + this.PXParam.EvalUpdate(this._CacheParamVars, paramMap, evaled); + this.PYParam.EvalUpdate(this._CacheParamVars, paramMap, evaled); + this.PZParam.EvalUpdate(this._CacheParamVars, paramMap, evaled); let l = this.LParam.value as number; let w = this.WParam.value as number; let h = this.HParam.value as number; - spaceSize = new Vector3(l, w, h); + this._CacheSpaceSize = new Vector3(l, w, h); //相对定位. use PX PY pZ let baseP = new Vector3(this.PXParam.value as number, this.PYParam.value as number, this.PZParam.value as number); - baseP.applyMatrix4(spaceCS); - spaceCS.setPosition(baseP); - spaceCS = this.RotateSpaceCS(varDefines, paramMap, evaled, spaceCS, spaceSize); + baseP.applyMatrix4(this._CacheSpaceCS); + this._CacheSpaceCS.setPosition(baseP); + this._CacheSpaceCS = this.RotateSpaceCS(this._CacheParamVars, paramMap, evaled, this._CacheSpaceCS, this._CacheSpaceSize); if (!this.Parent) { @@ -307,14 +317,14 @@ export class TemplateRecord extends SymbolTableRecord } //更新LWH(通过定位空间) - this.LParam.UpdateParam(spaceSize.x); - this.WParam.UpdateParam(spaceSize.y); - this.HParam.UpdateParam(spaceSize.z); + this.LParam.UpdateParam(this._CacheSpaceSize.x); + this.WParam.UpdateParam(this._CacheSpaceSize.y); + this.HParam.UpdateParam(this._CacheSpaceSize.z); } - varDefines["L"] = spaceSize.x; - varDefines["W"] = spaceSize.y; - varDefines["H"] = spaceSize.z; + this._CacheParamVars["L"] = this._CacheSpaceSize.x; + this._CacheParamVars["W"] = this._CacheSpaceSize.y; + this._CacheParamVars["H"] = this._CacheSpaceSize.z; //#endregion @@ -323,26 +333,21 @@ export class TemplateRecord extends SymbolTableRecord //变换到新的模版空间 for (let br of brs) - br.ApplyMatrix(spaceCS); + br.ApplyMatrix(this._CacheSpaceCS); //#endregion //更新其他参数变量 Eval local params for (const param of this.Params) { - param.EvalUpdate(varDefines, paramMap, evaled); + param.EvalUpdate(this._CacheParamVars, paramMap, evaled); } //保持SpaceCS for (let ent of brs) { - ent.SpaceOCS = spaceCS; + ent.SpaceOCS = this._CacheSpaceCS; } - - //Cache - this._CacheParamVars = varDefines; - this._CacheSpaceCS = spaceCS; - this._CacheSpaceSize = spaceSize; } /** @@ -434,7 +439,6 @@ export class TemplateRecord extends SymbolTableRecord protected _CacheParamVars: any; protected _CacheSpaceCS: Matrix4; protected _CacheSpaceSize: Vector3; - /** * 本节点可用的所有变量定义.(包括变量继承) * @param [useCache=true] 当更新当前节点的时候,我们不希望使用缓存,(因为父节点的参数可能已经被更新) @@ -493,7 +497,7 @@ export class TemplateRecord extends SymbolTableRecord * * @param [useCache=true] 当更新当前节点的时候,我们不希望使用缓存,(因为父节点的参数可能已经被更新) */ - private GetTemplateSpaceCS(useCache = true): Matrix4 + GetTemplateSpaceCS(useCache = true): Matrix4 { if (useCache && this._CacheSpaceCS) return this._CacheSpaceCS.clone(); diff --git a/src/DatabaseServices/Template/TemplateTest.ts b/src/DatabaseServices/Template/TemplateTest.ts index 61d1086b1..439e75887 100644 --- a/src/DatabaseServices/Template/TemplateTest.ts +++ b/src/DatabaseServices/Template/TemplateTest.ts @@ -1,145 +1,139 @@ -import { Box3, Matrix4, Vector3 } from "three"; import { app } from "../../ApplicationServices/Application"; -import { StretchParse } from "../../Common/StretchParse"; +import { Sleep } from "../../Common/Sleep"; +import { DuplicateRecordCloning } from "../../Common/Status"; import { commandMachine } from "../../Editor/CommandMachine"; -import { PromptSsgetResult, PromptStatus } from "../../Editor/PromptResult"; -import { SelectBox, SelectType } from "../../Editor/SelectBox"; -import { AsVector3, equalv3, MoveMatrix, ZeroVec } from "../../Geometry/GeUtils"; +import { PromptStatus } from "../../Editor/PromptResult"; +import { ClampSpaceParse } from "../../Geometry/SpaceParse/ClampSpaceParse"; import { EnableSelectType } from "../../Geometry/SpaceParse/PointSelectSpace"; import { PointSelectSpaceClamp } from "../../Geometry/SpaceParse/PointSelectSpaceClamp"; +import { Database } from "../Database"; import { Board } from "../Entity/Board"; import { TemplateAction } from "./Action/TemplateAction"; -import { TemplateMoveAction } from "./Action/TemplateMoveAction"; -import { TemplateStretchGripAction } from "./Action/TemplateStretchGripAction"; -import { TemplateStretchScaleBoxAction } from "./Action/TemplateStretchScaleBoxAction"; -import { TemplateRecord } from "./TemplateRecord"; -import { ClampSpaceParse } from "../../Geometry/SpaceParse/ClampSpaceParse"; import { PositioningClampSpace } from "./Positioning/PositioningClampSpace"; -import { Sleep } from "../../Common/Sleep"; +import { AddFilletAction, AddStretchAction, InitTempateBoardThicknessActions, InitTempateSizeActions, InitTemplate, SetTempateCoordinate, UpdateTemplateSizeOffBoards } from "./TempateUtils"; +import { TemplateRecord } from "./TemplateRecord"; import { TemplateSplitType } from "./TemplateType"; import { TemplateParam } from "./Param/TemplateParam"; -import { TemplateParamType } from "./Param/TemplateParamType"; -import { FilletUtils } from "../../Add-on/FilletUtils"; -import { Polyline } from "../Entity/Polyline"; -import { Line } from "../Entity/Line"; -import { IntersectOption } from "../../GraphicsSystem/IntersectWith"; -import { TemplateFilletAction } from "./Action/TemplateFilletAction"; -import { Database } from "../Database"; -import { DuplicateRecordCloning } from "../../Common/Status"; -import { TemplateWineRackRecord } from "./ProgramTempate/TemplateWineRackRecord"; -export function GetDefaultTemplate() +export async function SelectTempate(): Promise { - let templates = app.Database.TemplateTable.Objects; - if (templates.length === 0) - { - let template = new TemplateRecord().InitBaseParams(); - app.Database.TemplateTable.Append(template); - return template; - } - else - return templates[0]; -} + let enRes = await app.Editor.GetEntity({ + Msg: "选择模块:", + NotNone: true, + Filter: { + filterFunction: (obj, ent) => + { + return ent.Template !== undefined; + } + } + }); + if (enRes.Status !== PromptStatus.OK) return; -const SCALEMIN = new Vector3(-0.1, -0.1, -0.1); -const SCALEMAX = new Vector3(1.1, 1.1, 1.1); + let e = enRes.Entity; + let template = e.Template.Object as TemplateRecord; + + return template; +} export class AddTemplateAction { - constructor(public name: string = "L") - { - - } async exec() { - //不能在透视相机下执行这个工作. + let template = await SelectTempate(); + let keyRes = await app.Editor.GetKeyWords({ + Msg: "选择变量", + KeyWordList: template.Params.map(p => + { + return { + key: p.name, + msg: `` + } + }) + }); - let ssRes = await app.Editor.GetSelection({ SelectType: SelectType.C }); - if (ssRes.Status !== PromptStatus.OK) - return; + if (keyRes.Status !== PromptStatus.Keyword) return; - let bpRes = await app.Editor.GetPoint({ Msg: "指定方向的基点:" }); - if (bpRes.Status !== PromptStatus.OK) - return; + let paramname = keyRes.StringResult; - let toRes = await app.Editor.GetPoint({ Msg: "指定方向的终点:", BasePoint: bpRes.Point, AllowDrawRubberBand: true }); - if (toRes.Status !== PromptStatus.OK) - return; + keyRes = await app.Editor.GetKeyWords({ + Msg: "动作类型:", + KeyWordList: [ + { key: "1", msg: "夹点" }, + { key: "2", msg: "盒子" }, + { key: "3", msg: "倒角" }, + { key: "4", msg: "板厚" }, + ], + Default: "1" + }); - let direction = toRes.Point.sub(bpRes.Point).normalize(); - if (equalv3(direction, ZeroVec)) - return; + let action: TemplateAction; + + switch (keyRes.StringResult) + { + case "1": + action = await AddStretchAction(template, false); + break; + case "2": + action = await AddStretchAction(template, true); + break; + case "3": + action = await AddFilletAction(template); + break; + case "4": + keyRes = await app.Editor.GetKeyWords({ + Msg: "类型:", + KeyWordList: [ + { key: "1", msg: "自动" }, + { key: "2", msg: "手动" }, + ], + Default: "1" + }); + await InitTempateBoardThicknessActions(template, keyRes.StringResult === "1"); + break; + default: + break; + } + + if (action) + { + let exprRes = await app.Editor.GetString({ Msg: "表达式:" }); + if (!exprRes.StringResult) + { + action.Expr = exprRes.StringResult; + } - this.GripStretchAction(direction, ssRes); - // this.ScaleBoxStretchAction(direction, ssRes); + template.WriteAllObjectRecord(); + template.GetParam(paramname).actions.push(action); + } } +} - private GripStretchAction(direction: Vector3, ssRes: PromptSsgetResult) +export class TemplateAddParam +{ + async exec() { - let stretchData = StretchParse(ssRes.SelectSet); + let template = await SelectTempate(); + let nameRes = await app.Editor.GetString({ Msg: "名称" }); + if (!nameRes.StringResult) return; - let stretchAction = new TemplateStretchGripAction(); - stretchAction.StretchDirection = direction; + let vRes = await app.Editor.GetDistance({ Msg: "值" }); + if (vRes.Status !== PromptStatus.OK) return; - let moveAction = new TemplateMoveAction(); - moveAction.StretchDirection = direction; + let param = new TemplateParam(); + param.name = nameRes.StringResult; + param.value = vRes.Distance; - for (let { ent, indexs } of stretchData.stretchEntityMap) - { - stretchAction.EntityStretchPointMap.push({ - entity: ent.Id, - indexs - }); - } - if (stretchData.stretchEntityMap.length > 0) - { - GetDefaultTemplate().GetParam(this.name).actions.push(stretchAction); - } - - moveAction.Entitys = stretchData.moveEntityList.map(ent => ent.Id); - if (moveAction.Entitys.length > 0) - { - GetDefaultTemplate().GetParam(this.name).actions.push(moveAction); - } + template.Params.push(param); } +} - private ScaleBoxStretchAction(direction: Vector3, ssRes: PromptSsgetResult) +export class TemplateSetCoordinate +{ + async exec() { - let action = new TemplateStretchScaleBoxAction(); - action.StretchDirection = direction; - for (let set of ssRes.SelectSet.SelectSetList) - { - if (set instanceof SelectBox) - { - let selectBox3 = new Box3(AsVector3(set.SelectBox.min).setZ(-6e6), AsVector3(set.SelectBox.max).setZ(6e6)); - let widthHalf = set.m_ViewerWidth * 0.5; - let heightHalf = set.m_ViewerHeight * 0.5; - let dcs = new Matrix4() - .setPosition(new Vector3(widthHalf, heightHalf)) - .multiply(new Matrix4().set(widthHalf, 0, 0, 0, 0, -heightHalf, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)) - .multiply(set.m_ProjScreenMatrix); - let dcsInv = new Matrix4().getInverse(dcs); - for (let e of set.SelectEntityList) - { - let br = e as Board; - let mtx = new Matrix4().multiplyMatrices(br.OCSInv, dcsInv); - let scaleBox = selectBox3.clone().applyMatrix4(mtx); - let size = new Vector3(br.Width, br.Height, br.Thickness); - scaleBox.min.divide(size); - scaleBox.max.divide(size); - scaleBox.min.clamp(SCALEMIN, SCALEMAX); - scaleBox.max.clamp(SCALEMIN, SCALEMAX); - action.EntityStretchData.push({ - entity: br.Id, - scaleBox - }); - } - } - } - if (action.EntityStretchData.length > 0) - { - GetDefaultTemplate().GetParam(this.name).actions.push(action); - } + let template = await SelectTempate(); + await SetTempateCoordinate(template); + await UpdateTemplateSizeOffBoards(template); } } @@ -152,139 +146,31 @@ export class AutoTempateSizeAction if (brsRes.Status !== PromptStatus.OK) return; let brs = brsRes.SelectSet.SelectEntityList as Board[]; - let m0 = new Matrix4(); - - let box = new Box3(); - for (let br of brs) - { - box.union(br.BoundingBox); - br.SpaceOCS = m0; - } + let template = await InitTemplate(brs); - //归0? let keyRes = await app.Editor.GetKeyWords({ - Msg: "自动将所有的板件移动到0点后初始化动作?", + Msg: "初始化大小动作?", KeyWordList: [ - { key: "Y", msg: "是" }, - { key: "N", msg: "否" }, - ] + { key: "1", msg: "是" }, + { key: "2", msg: "否" }, + ], + Default: "1" }); + if (keyRes.StringResult === "1") + InitTempateSizeActions(template, true); - let isToZero = keyRes.Status === PromptStatus.Keyword && keyRes.StringResult === "Y"; - - if (isToZero) - { - //将板件移动到0点. - { - let m = MoveMatrix(box.min.clone().negate()); - for (let br of brs) - { - br.ApplyMatrix(m); - br.SpaceOCS = m0; - } - } - - //休整box - box.max.sub(box.min); - } - - box.min.set(0, 0, 0); - - let size = box.max; - - let v = new Vector3(1, 1, 1); - //后 - let frontBox = new Box3(box.min.clone().add(new Vector3(-1, size.y / 2, -1)), box.max.clone().add(v)); - //右缩 - let rightBox = new Box3(box.min.clone().add(new Vector3(size.x / 2, -1, -1)), box.max.clone().add(v)); - //上缩 - let topBox = new Box3(box.min.clone().add(new Vector3(-1, -1, size.z / 2)), box.max.clone().add(v)); - - let template = new TemplateRecord().InitBaseParams(); - - let rParam = new TemplateParam(); - rParam.name = "R"; - rParam.value = 0; - rParam.type = TemplateParamType.Float; - template.Params.push(rParam); - - app.Database.TemplateTable.Append(template); - template.GetParam("L").value = size.x; - template.GetParam("W").value = size.y; - template.GetParam("H").value = size.z; - - template.Objects = brs.map(br => br.Id); - - let mmp = [ - { - ParamName: "L", Box: rightBox, Direction: new Vector3(1), - StretchAction: new TemplateStretchScaleBoxAction(new Vector3(1)), - MoveAction: new TemplateMoveAction(new Vector3(1)), - MoveThicknessAction: new TemplateMoveAction(new Vector3(0.5)), - }, - { - ParamName: "W", Box: frontBox, Direction: new Vector3(0, 1), - StretchAction: new TemplateStretchScaleBoxAction(new Vector3(0, 1)), - MoveAction: new TemplateMoveAction(new Vector3(0, 1)), - MoveThicknessAction: new TemplateMoveAction(new Vector3(0, 0.5)), - }, - { - ParamName: "H", Box: topBox, Direction: new Vector3(0, 0, 1), - StretchAction: new TemplateStretchScaleBoxAction(new Vector3(0, 0, 1)), - MoveAction: new TemplateMoveAction(new Vector3(0, 0, 1)), - MoveThicknessAction: new TemplateMoveAction(new Vector3(0, 0, 0.5)), - }, - ]; - - //构建scalebox - for (let br of brs) - { - for (let m of mmp) - { - if (br.BoundingBox.intersect(m.Box)) - { - let pts = br.GetStretchPoints(); - let indexs: number[] = []; - for (let i = 0; i < pts.length; i++) - { - const p = pts[i]; - if (m.Box.containsPoint(p)) - indexs.push(i); - } - - if (br.IsStretchThickness(indexs)) - { - m.MoveThicknessAction.Entitys.push(br.Id); - } - else if (indexs.length === pts.length) - { - m.MoveAction.Entitys.push(br.Id); - } - else if (indexs.length > 0) - { - let scaleBox = m.Box.clone().applyMatrix4(br.OCSInv); - let size = new Vector3(br.Width, br.Height, br.Thickness); - scaleBox.min.divide(size); - scaleBox.max.divide(size); - m.StretchAction.EntityStretchData.push({ entity: br.Id, scaleBox }); - } - } - } - } - - for (let m of mmp) - { - let param = template.GetParam(m.ParamName); - if (m.MoveAction.Entitys.length > 0) - param.actions.push(m.MoveAction); - - if (m.StretchAction.EntityStretchData.length > 0) - param.actions.push(m.StretchAction); - if (m.MoveThicknessAction.Entitys.length > 0) - param.actions.push(m.MoveThicknessAction); - } + keyRes = await app.Editor.GetKeyWords({ + Msg: "初始化板厚动作?", + KeyWordList: [ + { key: "1", msg: "是" }, + { key: "2", msg: "否" }, + ], + Default: "1" + }); + if (keyRes.StringResult === "1") + await InitTempateBoardThicknessActions(template, true); } } @@ -431,16 +317,6 @@ export class UpdateParam2 } } -export class Clear -{ - async exec() - { - GetDefaultTemplate().GetParam("L").actions.length = 0; - GetDefaultTemplate().GetParam("L").actions.push(new TemplateAction()) - GetDefaultTemplate().GetParam("L").value = 0; - } -} - export class TemplateAttach { async exec() @@ -681,133 +557,18 @@ export class TemplateAttach3 } } -export class TemplateAddFilletAction -{ - - async exec() - { - let brRes = await app.Editor.GetEntity({ - Msg: "选择附加的模版", - NotNone: true, - Filter: { - filterFunction: (obj, ent) => - { - if (ent instanceof Board) - return ent.Template !== undefined; - - return false; - } - } - }); - if (brRes.Status !== PromptStatus.OK) return; - - //------1.画辅助线 - let ptRes = await app.Editor.GetPoint({ - BasePoint: brRes.Point, - AllowDrawRubberBand: true, - AllowNone: true, - Msg: "选择下一个点:" - }); - if (ptRes.Status === PromptStatus.Cancel) - return; - - //------2.倒角 - let fillet = new FilletUtils(); - fillet.FilletRadius = 100; - let fres = fillet.FilletBoard(brRes, ptRes); - if (fres instanceof Polyline) - { - let br = brRes.Entity as Board; - br.ContourCurve = fres; - let brContour = fres; - - //------1.求交 - let brResPt = brRes.Point.clone().applyMatrix4(br.OCSInv).setZ(0); - let ptResPt = ptRes.Point.clone().applyMatrix4(br.OCSInv).setZ(0); - let l = new Line(brResPt, ptResPt); - - let ipts = l.IntersectWith(brContour, IntersectOption.ExtendThis); - - if (ipts.length > 2)//超过2个则有可能有多余交点 - //找最近点 - ipts = [fillet.FindNearestPt(ipts, brResPt), fillet.FindNearestPt(ipts, ptResPt)] - - if (ipts.length !== 2) - return "倒角失败!交点个数异常."; - - let param1 = brContour.GetParamAtPoint(ipts[0]); - let param2 = brContour.GetParamAtPoint(ipts[1]); - - let filletAction = new TemplateFilletAction(br.Id, param1, param2); - - let template = br.Template.Object as TemplateRecord; - - let rParam = template.GetParam("R"); - rParam.actions.push(filletAction); - } - else - app.Editor.Prompt(fres); - - } -} - -export class Command_TemplateWineRack -{ - async exec() - { - let selectSpace = new PointSelectSpaceClamp(); - selectSpace.Enable = EnableSelectType.Stretch; - await selectSpace.Select(); - - if (!selectSpace.ParseOK) - { - app.Editor.Prompt("未能分析出有效空间!"); - return; - } - let brs = selectSpace.SpaceParse.Boards; - let tbrs = brs.filter(br => br.Template !== undefined); - tbrs.sort((b1, b2) => - { - let t1 = b1.Template.Object as TemplateRecord; - let t2 = b2.Template.Object as TemplateRecord; - - return t2.NodeDepth - t1.NodeDepth; - }); - - let templateSource: TemplateRecord; - if (tbrs.length > 0) - templateSource = tbrs[0].Template.Object as TemplateRecord; - - let parse = selectSpace.SpaceParse as ClampSpaceParse; - - let positioning = new PositioningClampSpace(); - positioning.FromSpaceParse(parse); - - - let wineRack = new TemplateWineRackRecord().InitBaseParams(); - app.Database.TemplateTable.Append(wineRack); - wineRack.Positioning = positioning; - - if (templateSource) - templateSource.Children.push(wineRack.Id); - wineRack.UpdateTemplateTree(); - } -} commandMachine.RegisterCommand("Attach", new TemplateAttach()); commandMachine.RegisterCommand("Attach2", new TemplateAttach2()); commandMachine.RegisterCommand("Attach3", new TemplateAttach3()); -commandMachine.RegisterCommand("Attach4", new Command_TemplateWineRack()); -commandMachine.RegisterCommand("templateAddFilletAction", new TemplateAddFilletAction()); +commandMachine.RegisterCommand("as", new AddTemplateAction()); +commandMachine.RegisterCommand("ap", new TemplateAddParam()); +commandMachine.RegisterCommand("tsc", new TemplateSetCoordinate()); -commandMachine.RegisterCommand("al", new AddTemplateAction("L")); -commandMachine.RegisterCommand("aw", new AddTemplateAction("W")); -commandMachine.RegisterCommand("ah", new AddTemplateAction("H")); -commandMachine.RegisterCommand("uu", new UpdateTemplate()); -commandMachine.RegisterCommand("uur", new UpdateTemplateRo()); -commandMachine.RegisterCommand("uuu", new UpdateParam2()); - -commandMachine.RegisterCommand("clear", new Clear); +commandMachine.RegisterCommand("uu", new UpdateTemplate()); +// commandMachine.RegisterCommand("uur", new UpdateTemplateRo()); +// commandMachine.RegisterCommand("uuu", new UpdateParam2()); +// commandMachine.RegisterCommand("clear", new Clear); diff --git a/src/Editor/CommandMachine.ts b/src/Editor/CommandMachine.ts index 53cba8b2b..c05d5420a 100644 --- a/src/Editor/CommandMachine.ts +++ b/src/Editor/CommandMachine.ts @@ -112,6 +112,7 @@ window["end"] = commandMachine.CommandEnd; export async function CommandWrap(exec: Function, cmdName: string = "") { + await app.Editor.ModalManage.EndExecingCmd(); if (!commandMachine.CommandStart(cmdName)) return; diff --git a/src/Editor/CommandRegister.ts b/src/Editor/CommandRegister.ts index dc158a30c..2de2e0233 100644 --- a/src/Editor/CommandRegister.ts +++ b/src/Editor/CommandRegister.ts @@ -106,6 +106,7 @@ import { Command_SwitchCamera } from '../Add-on/SwitchCamera'; import { CMD_Conceptual, CMD_Physical, CMD_Wireframe } from '../Add-on/SwitchVisualStyles'; import { DrawTangentLine } from '../Add-on/Tangent'; import { ShowTemplate } from '../Add-on/Template/ShowTemplate'; +import { ShowTemplateDesign } from "../Add-on/Template/ShowTemplateDesign"; import { ShowTopLine } from '../Add-on/Template/ShowTopline'; import { Command_TemplateSearch } from '../Add-on/TemplateSearch'; // import { DrawFloor } from '../Add-on/DrawFloor'; @@ -352,6 +353,7 @@ export function registerCommand() commandMachine.RegisterCommand("batchmodify", new BatchModify()); commandMachine.RegisterCommand("template", new ShowTemplate()); + commandMachine.RegisterCommand("templatedesign", new ShowTemplateDesign()); commandMachine.RegisterCommand("TemplateSearch", new Command_TemplateSearch()); diff --git a/src/Editor/Editor.ts b/src/Editor/Editor.ts index 51d10e42a..d6e235da6 100644 --- a/src/Editor/Editor.ts +++ b/src/Editor/Editor.ts @@ -18,12 +18,13 @@ import { SsgetServiecs } from './GetSelectionServices'; import { GripDragServices } from './GripDragServices'; import { KeyBoardControls } from './KeyBoardControls'; import { MouseControls } from './MouseControls'; -import { GetDistendPrompt, GetEntityPrompt, GetKeyWordPrommpt, GetPointPrompt, GetSelectionPrompt, PromptRectPointOptions } from "./PromptOptions"; +import { GetDistendPrompt, GetEntityPrompt, GetKeyWordPrommpt, GetPointPrompt, GetSelectionPrompt, PromptRectPointOptions, GetStringPrompt } from "./PromptOptions"; import { PromptDistendResult, PromptEntityResult, PromptPointResult, PromptRectResult, PromptResult, PromptSsgetResult } from './PromptResult'; import { SelectControls } from './SelectControls'; import { TransformServicess } from './TranstrolControl/TransformServices'; import { UCSServices } from './UCSServices'; import { SpeechBoxManage } from '../UI/Components/SpeechBox/SpeechBoxManage'; +import { GetStringService } from './GetStringService'; //用户交互编辑工具 @@ -51,6 +52,7 @@ export class Editor KeywordsServices: GetKeyWordsServices; ContextMenuServices: ContextMenuServices; InteractiveServices: EditorService[] = []; + GetStringService: any; //用户坐标系 constructor(app: ApplicationService) @@ -71,6 +73,7 @@ export class Editor this.KeywordsServices = new GetKeyWordsServices(this); this.ContextMenuServices = new ContextMenuServices(this); + this.GetStringService = new GetStringService(); xaop.end(this.MouseCtrl, this.MouseCtrl.onMouseMove, () => { @@ -157,6 +160,12 @@ export class Editor { return this.KeywordsServices.Start(prompt); } + + GetString(prompt: GetStringPrompt): Promise + { + return this.GetStringService.Start(prompt); + } + GetEntity(prompt?: GetEntityPrompt): Promise { return this.GetEntitytServices.Start(prompt); diff --git a/src/Editor/GetPointServices.ts b/src/Editor/GetPointServices.ts index abbe7eb60..52f13796c 100644 --- a/src/Editor/GetPointServices.ts +++ b/src/Editor/GetPointServices.ts @@ -177,8 +177,7 @@ export class GetPointServices implements EditorService { this.removeCalls.push(xaop.end(app.Editor.KeyCtrl, app.Editor.KeyCtrl.OnKeyDown, (e: KeyboardEvent) => { - - if (e.keyCode == KeyBoard.Escape) + if (e.keyCode === KeyBoard.Escape) { this.Cancel(); return true; diff --git a/src/Editor/GetStringService.ts b/src/Editor/GetStringService.ts new file mode 100644 index 000000000..a533c7b16 --- /dev/null +++ b/src/Editor/GetStringService.ts @@ -0,0 +1,101 @@ +import { EditorService } from "./Editor"; +import { GetStringPrompt } from "./PromptOptions"; +import { PromptResult, PromptStatus } from "./PromptResult"; +import { InitKeyWord } from "./InitKeyword"; +import { end, begin } from "xaop"; +import { app } from "../ApplicationServices/Application"; +import { KeyBoard } from "../Common/KeyEnum"; +import { InputState } from "../Common/InputState"; + +export class GetStringService implements EditorService +{ + IsReady: boolean = true; + private _prompt: GetStringPrompt; + protected removeCalls: Function[] = []; //结束回调 + private promisResolve: (value?: any) => void; + async Doit(e: MouseEvent): Promise + { + return true; + } + + Start(prompt?: GetStringPrompt): Promise + { + prompt = prompt ? prompt : {}; + this._prompt = prompt; + + this.InitState(); + this.InitPrompt(prompt); + this.removeCalls.push(InitKeyWord(prompt)); + this.InitHandleInput(prompt); + this.InitHandleKeyDown(); + return new Promise((resolve, reject) => + { + this.promisResolve = resolve; + }); + } + + Cancel() + { + let v = new PromptResult(); + v.Status = PromptStatus.Cancel; + this.ReturnResult(v); + } + + protected InitState() + { + app.Editor.InputState |= InputState.GetString; + } + + private RestState() + { + this.IsReady = false; + app.Editor.InputState &= ~InputState.GetString; + this.removeCalls.forEach(f => f()); + this.removeCalls.length = 0; + } + + protected ReturnResult(retValue: PromptResult) + { + if (!this.promisResolve) return; + this.RestState(); + this.promisResolve(retValue); + this.promisResolve = undefined; + } + + protected InitPrompt(prompt: GetStringPrompt) + { + prompt.Msg = prompt.Msg || "请输入一个点:"; + if (prompt.Msg) + { + app.Editor.CommandStore.commandPrompt = prompt.Msg; + this.removeCalls.push(() => + { + app.Editor.CommandStore.commandPrompt = ""; + }); + } + } + protected InitHandleInput(prompt: GetStringPrompt) + { + this.removeCalls.push(begin(app.Editor, app.Editor.InputEvent, (inputData: string) => + { + let res = new PromptResult(); + res.Status = PromptStatus.OK; + res.StringResult = inputData; + + this.ReturnResult(res); + })); + } + + private InitHandleKeyDown() + { + this.removeCalls.push(end(app.Editor.KeyCtrl, app.Editor.KeyCtrl.OnKeyDown, (e: KeyboardEvent) => + { + if (e.keyCode === KeyBoard.Escape) + { + this.Cancel(); + return true; + } + })); + } + +} diff --git a/src/Editor/PromptOptions.ts b/src/Editor/PromptOptions.ts index 175d982c9..a149584f3 100644 --- a/src/Editor/PromptOptions.ts +++ b/src/Editor/PromptOptions.ts @@ -17,6 +17,11 @@ export interface GetKeyWordPrommpt extends PromptOptions Modal?: boolean; } +export interface GetStringPrompt extends PromptOptions +{ + Default?: string; +} + export interface GetPointPrompt extends PromptOptions { //基点 diff --git a/src/Editor/SelectSet.ts b/src/Editor/SelectSet.ts index b09574a5e..0313c3e02 100644 --- a/src/Editor/SelectSet.ts +++ b/src/Editor/SelectSet.ts @@ -14,13 +14,13 @@ export class SelectSet * 选择数据 */ private m_SelectSetList = new Array(); - private m_IdSelect = new Map(); + IdSelectMap = new Map(); AddSelect(selectData: SelectSetBase) { let selectCount = selectData.m_SelectList.length; //1.校验重复 - selectData.m_SelectList = selectData.m_SelectList.filter(obj => !this.m_IdSelect.has(obj.id)); + selectData.m_SelectList = selectData.m_SelectList.filter(obj => !this.IdSelectMap.has(obj.id)); let dupCount = selectCount - selectData.m_SelectList.length; //加入集合 @@ -28,7 +28,7 @@ export class SelectSet for (let obj of selectData.m_SelectList) { - this.m_IdSelect.set(obj.id, selectData); + this.IdSelectMap.set(obj.id, selectData); } //Group 操作 @@ -42,10 +42,10 @@ export class SelectSet { let ent = entId.Object as Entity; let obj = ent.DrawObject; - if (!this.m_IdSelect.has(obj.id)) + if (!this.IdSelectMap.has(obj.id)) { selectData.m_SelectList.push(obj); - this.m_IdSelect.set(obj.id, selectData); + this.IdSelectMap.set(obj.id, selectData); groupCount++; } @@ -71,10 +71,14 @@ export class SelectSet log(`取消选择${selectData.m_SelectList.length}个.`); for (let obj of selectData.m_SelectList) { - if (this.m_IdSelect.has(obj.id)) + if (this.IdSelectMap.has(obj.id)) { - arrayRemoveOnce(this.m_IdSelect.get(obj.id).m_SelectList, obj); - this.m_IdSelect.delete(obj.id); + let set = this.IdSelectMap.get(obj.id); + arrayRemoveOnce(set.m_SelectList, obj); + this.IdSelectMap.delete(obj.id); + + if (set.m_SelectList.length === 0) + arrayRemoveOnce(this.m_SelectSetList, set); } } } @@ -82,7 +86,7 @@ export class SelectSet Clear() { this.m_SelectSetList.length = 0; - this.m_IdSelect.clear(); + this.IdSelectMap.clear(); } get SelectSetList() diff --git a/src/UI/Components/Board/BoardModal.tsx b/src/UI/Components/Board/BoardModal.tsx index a23e0c277..9adb68fdc 100644 --- a/src/UI/Components/Board/BoardModal.tsx +++ b/src/UI/Components/Board/BoardModal.tsx @@ -33,6 +33,7 @@ export enum BoardModalType Find = "findBr", // 查找 JG = "jg", //酒格 Lat = "lattice", // 格子抽 + TempDes="templatedesign", } export interface BoardModalProps { diff --git a/src/UI/Components/Board/UserConfig.tsx b/src/UI/Components/Board/UserConfig.tsx index 438ef25cd..1e39a4903 100644 --- a/src/UI/Components/Board/UserConfig.tsx +++ b/src/UI/Components/Board/UserConfig.tsx @@ -2,13 +2,13 @@ import { Button, InputGroup, Intent, Menu, MenuItem, Popover, Position } from '@ import { observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { arrayLast } from '../../../Common/ArrayExt'; import { BoardProcessOption, IGrooveOption, LayerNailOption, TBBoardOption } from '../../Store/BoardInterface'; import { IConfigStore } from '../../Store/BoardStore'; import { DrillingOption } from '../../Store/drillInterface'; import { userConfigStore, UserConfigStore } from '../../Store/UserConfigStore'; import { BoardModalType } from './BoardModal'; import { IDoorInfo } from '../../Store/DoorInterface'; +import { StoreageKeys } from '../../../Common/KeyEnum'; //保存的配置 export interface IConfigOption @@ -68,6 +68,12 @@ export class UserConfig extends React.Component{ //更新配置 private updateBoardOption = async (k: string) => { + if (this.props.type === BoardModalType.TempDes) + { + if (!confirm("你确定要初始化参数列表?")) + return; + } + await this._userConfigStore.UpdateBoardOption(k, this.props.type, this.props.store); } async UNSAFE_componentWillMount() @@ -85,14 +91,19 @@ export class UserConfig extends React.Component{ } else { - let curName = localStorage.getItem("configName_" + type); + let curName = localStorage.getItem(StoreageKeys.ConfigName + type); if (!curName || !confNames.includes(curName)) curName = confNames[0]; this._userConfigStore.configName = curName; - if (type !== BoardModalType.Zx && !this._userConfigStore.readConfigs.has(type)) + if (type !== BoardModalType.Zx && type !== BoardModalType.TempDes && !this._userConfigStore.readConfigs.has(type)) this.updateBoardOption(curName); } + if (type === BoardModalType.TempDes) + { + this._userConfigStore.configsNames.push(""); + this._userConfigStore.configName = ""; + } this._userConfigStore.readConfigs.add(type); } diff --git a/src/UI/Components/Common/PopoverButton.tsx b/src/UI/Components/Common/PopoverButton.tsx new file mode 100644 index 000000000..b768350bc --- /dev/null +++ b/src/UI/Components/Common/PopoverButton.tsx @@ -0,0 +1,49 @@ +import * as React from 'react'; +import { Popover, Position, Button, Intent, Classes, Card, IconName, MaybeElement } from '@blueprintjs/core'; + +export interface IPopOverButtonProps +{ + position: Position; + disabled?: boolean; + confirmCallback: () => void; + message: string; + targetTitle: string; + icon?: IconName | MaybeElement; +} + +export class PopoverButton extends React.Component { + public render() + { + return ( + +

{this.props.message}

+
+
+ + } + target={ +