From f2435f2d0e7712b328b7df5cb53e419303f99489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E4=B8=89?= <940119273@qq.com> Date: Fri, 21 Jul 2023 02:32:09 +0000 Subject: [PATCH] =?UTF-8?q?!2303=20=E5=8A=9F=E8=83=BD:=E5=90=8A=E9=A1=B6,?= =?UTF-8?q?=E7=BA=BF=E6=9D=A1=E6=94=AF=E6=8C=81=E6=8B=BE=E5=8F=96=E5=A4=A9?= =?UTF-8?q?=E8=8A=B1=E6=9D=BF=E5=92=8C=E5=9C=B0=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DrawBoard/DrawSpecialShapeBoardTool.ts | 25 +- src/Add-on/DrawTopline.ts | 85 ++- src/Add-on/testEntity/test.ts | 21 +- src/Common/ColorPalette.ts | 8 + src/Common/CommandNames.ts | 6 +- src/Common/Request.ts | 1 + src/Common/SerializeMaterial.ts | 6 +- src/DatabaseServices/Database.ts | 3 + src/DatabaseServices/Entity/Polyline.ts | 5 +- .../Room/Entity/Ceiling/BulkheadCeiling.ts | 541 +++++++++++++++++ .../Ceiling/BulkheadCeilingShapeExtendData.ts | 37 ++ .../Room/ParseService/RoomRegionParse.ts | 2 +- src/DatabaseServices/Shape2.ts | 3 +- src/Editor/CommandRegister.ts | 67 ++- src/Editor/DbClick/DbClick.ts | 14 + src/Editor/DefaultConfig.ts | 7 +- src/Editor/TranstrolControl/ParsePlacePos.ts | 3 +- src/Geometry/CreatePolylinePath.ts | 4 +- src/Geometry/SweepGeometry.ts | 28 +- src/UI/Components/Board/BoardModalType.ts | 3 + src/UI/Components/CommandPanel/CommandList.ts | 17 + .../Components/HeadCeiling/HeadCeiling.less | 216 +++++++ .../HeadCeiling/HeadCeilingContourList.tsx | 106 ++++ .../HeadCeiling/HeadCeilingContourManage.tsx | 483 +++++++++++++++ .../HeadCeilingContourManageCommand.ts | 11 + .../HeadCeilingInfoConfigPanel.tsx | 247 ++++++++ .../HeadCeilingInfoConfigPanelCommand.ts | 31 + .../HeadCeiling/HeadCeilingInfoItem.tsx | 96 +++ src/UI/Components/MaterialExplorer.tsx | 3 + .../OnlySelectManage/OnlySelectDataList.tsx | 33 + .../OnlySelectManage/OnlySelectManage.tsx | 397 ++++++++++++ .../OnlySelectManage/OnlySelectPanelStore.ts | 23 + .../OnlySelectManage/SelectManagePanel.less | 93 +++ .../OnlySelectManage/SelectManagePanel.tsx | 110 ++++ .../RightPanel/Modeling/KnifeList.tsx | 28 +- .../Components/SourceManage/CommonPanel.tsx | 4 +- .../Components/SourceManage/MaterialList.tsx | 32 +- src/UI/Components/Template/ToplineList.tsx | 2 +- .../ToolBar/ModifyModel/ModifyModel.less | 11 + .../ToolBar/ModifyModel/ModuleBaseParams.tsx | 16 +- .../ToolBar/ModifyModel/RoomFlatTopParams.tsx | 563 ++++++++++++++++++ .../Components/TopToolBar/RoomDesignPanel.tsx | 6 + .../Components/TopToolBar/ToolsBlockStore.ts | 1 + src/UI/Components/TopToolBar/TopToolBar.tsx | 4 + .../TopToolBar/TopToolBarInterface.ts | 1 + src/UI/Css/golden.less | 6 + src/UI/IconEnum.ts | 3 + .../HeadCeilingStore/HeadCeilingInfoStore.ts | 196 ++++++ .../HeadCeilingMaterialStore.ts | 189 ++++++ .../OptionInterface/BulkheadCeilingOption.ts | 33 + 50 files changed, 3723 insertions(+), 107 deletions(-) create mode 100644 src/DatabaseServices/Room/Entity/Ceiling/BulkheadCeiling.ts create mode 100644 src/DatabaseServices/Room/Entity/Ceiling/BulkheadCeilingShapeExtendData.ts create mode 100644 src/UI/Components/HeadCeiling/HeadCeiling.less create mode 100644 src/UI/Components/HeadCeiling/HeadCeilingContourList.tsx create mode 100644 src/UI/Components/HeadCeiling/HeadCeilingContourManage.tsx create mode 100644 src/UI/Components/HeadCeiling/HeadCeilingContourManageCommand.ts create mode 100644 src/UI/Components/HeadCeiling/HeadCeilingInfoConfigPanel.tsx create mode 100644 src/UI/Components/HeadCeiling/HeadCeilingInfoConfigPanelCommand.ts create mode 100644 src/UI/Components/HeadCeiling/HeadCeilingInfoItem.tsx create mode 100644 src/UI/Components/OnlySelectManage/OnlySelectDataList.tsx create mode 100644 src/UI/Components/OnlySelectManage/OnlySelectManage.tsx create mode 100644 src/UI/Components/OnlySelectManage/OnlySelectPanelStore.ts create mode 100644 src/UI/Components/OnlySelectManage/SelectManagePanel.less create mode 100644 src/UI/Components/OnlySelectManage/SelectManagePanel.tsx create mode 100644 src/UI/Components/ToolBar/ModifyModel/RoomFlatTopParams.tsx create mode 100644 src/UI/Store/HeadCeilingStore/HeadCeilingInfoStore.ts create mode 100644 src/UI/Store/HeadCeilingStore/HeadCeilingMaterialStore.ts create mode 100644 src/UI/Store/OptionInterface/BulkheadCeilingOption.ts diff --git a/src/Add-on/DrawBoard/DrawSpecialShapeBoardTool.ts b/src/Add-on/DrawBoard/DrawSpecialShapeBoardTool.ts index 444e40d7b..ad7c322e2 100644 --- a/src/Add-on/DrawBoard/DrawSpecialShapeBoardTool.ts +++ b/src/Add-on/DrawBoard/DrawSpecialShapeBoardTool.ts @@ -11,7 +11,7 @@ import { PromptStatus } from "../../Editor/PromptResult"; import { SelectSetBase } from "../../Editor/SelectBase"; import { SelectSet } from "../../Editor/SelectSet"; import { CreateContour2 } from "../../Geometry/CreateContour2"; -import { isParallelTo, MoveMatrix } from "../../Geometry/GeUtils"; +import { MoveMatrix, isParallelTo } from "../../Geometry/GeUtils"; import { LastExtractBoardContour } from "../../UI/Components/Board/LastExtractBoardContour"; import { Ellipse } from './../../DatabaseServices/Entity/Ellipse'; import { Spline } from './../../DatabaseServices/Spline'; @@ -65,10 +65,21 @@ export function BoardApplyContour(contour: ExtrudeContour, brs: Board[], isKeepS app.Editor.UpdateScreen(); } -async function SelectEntitys(useExtrude = false, Once = true): Promise +async function SelectEntitys(useExtrude = false, Once = true, onlyUseCurve = false): Promise { - let Msg = useExtrude ? "请选择(拉伸实体,面域或曲线)" : "请选择(面域或曲线)"; - let filterTypes = useExtrude ? [Region, ExtrudeSolid, Curve] : [Region, Curve]; + let Msg = ""; + let filterTypes = []; + + if (onlyUseCurve) + { + Msg = "请选择曲线"; + filterTypes = [Curve]; + } + else + { + Msg = useExtrude ? "请选择(拉伸实体,面域或曲线)" : "请选择(面域或曲线)"; + filterTypes = useExtrude ? [Region, ExtrudeSolid, Curve] : [Region, Curve]; + } let allowNone = LastExtractBoardContour.Contour?.IsErase === false; if (allowNone) Msg += "<空格使用提取的轮廓>"; @@ -100,14 +111,14 @@ async function SelectEntitys(useExtrude = false, Once = true): Promise { - let ens = await SelectEntitys(useExtrude); + let ens = await SelectEntitys(useExtrude, true, onlyUseCurve); if (!ens) return {}; let en = ens[0]; diff --git a/src/Add-on/DrawTopline.ts b/src/Add-on/DrawTopline.ts index 11e68dc8f..ac24028af 100644 --- a/src/Add-on/DrawTopline.ts +++ b/src/Add-on/DrawTopline.ts @@ -1,16 +1,21 @@ import { Scene } from "three"; import { app } from "../ApplicationServices/Application"; +import { arrayRemoveIf } from "../Common/ArrayExt"; import { curveLinkGroup } from "../Common/CurveUtils"; import { DisposeThreeObj } from "../Common/Dispose"; +import { BlockTableRecord } from "../DatabaseServices/BlockTableRecord"; import { Arc } from "../DatabaseServices/Entity/Arc"; import { Board } from "../DatabaseServices/Entity/Board"; import { Curve } from "../DatabaseServices/Entity/Curve"; import { Line } from "../DatabaseServices/Entity/Line"; import { Polyline } from "../DatabaseServices/Entity/Polyline"; import { HardwareTopline } from "../DatabaseServices/Hardware/HardwareTopline"; +import { RoomFlatBase } from "../DatabaseServices/Room/Entity/Flat/RoomFlatBase"; +import { RoomFlatFloor } from "../DatabaseServices/Room/Entity/Flat/RoomFlatFloor"; +import { RoomHolePolyline } from "../DatabaseServices/Room/Entity/Wall/Hole/RoomHolePolyline"; import { JigUtils } from "../Editor/JigUtils"; import { PromptStatus } from "../Editor/PromptResult"; -import { equalv3 } from "../Geometry/GeUtils"; +import { equaln, equalv3 } from "../Geometry/GeUtils"; import { SurroundOutlineParse } from "../Geometry/SpaceParse/SurroundOutlineParse"; /**构建顶线 */ @@ -19,7 +24,7 @@ export async function buildTopline(outline: Polyline, name: string) let brsRes = await app.Editor.GetSelection({ Msg: "选择柜体或者曲线", UseSelect: true, - Filter: { filterTypes: [Board, Arc, Line, Polyline] } + Filter: { filterTypes: [Board, Arc, Line, Polyline, RoomFlatBase] } }); if (brsRes.Status !== PromptStatus.OK) @@ -27,14 +32,28 @@ export async function buildTopline(outline: Polyline, name: string) let brs: Board[] = []; let cus: Curve[] = []; + let roomFlatEnts: RoomFlatBase[] = []; + for (let en of brsRes.SelectSet.SelectEntityList) { + if (en instanceof Board) brs.push(en); + else if (en instanceof RoomFlatBase) + roomFlatEnts.push(en); else cus.push(en as Curve); } + let metals: HardwareTopline[] = []; + + if (roomFlatEnts.length > 0) + { + //吊顶 + await drawCeiling(outline, roomFlatEnts); + return; + } + if (brs.length > 0) metals = await handleBoard(outline, brs); else @@ -43,6 +62,68 @@ export async function buildTopline(outline: Polyline, name: string) metals.forEach(m => m.HardwareOption.name = name); } +//吊顶 地脚线 +async function drawCeiling(outline: Polyline, roomFlatEnts: RoomFlatBase[]) +{ + for (let ent of roomFlatEnts) + { + let name = ""; + let polylines = [ent.Contour.Clone()]; + + if (ent instanceof RoomFlatFloor) + { + name = "地脚线"; + let holes = (ent.Owner.Object as BlockTableRecord).Entitys.filter(e => { return !e.IsErase && e instanceof RoomHolePolyline; }) as RoomHolePolyline[]; + let ocsInv = ent.OCSInv; + for (let hole of holes) + { + let entBox = ent.BoundingBoxInOCS; + let box = entBox.intersect(hole.GetBoundingBoxInMtx(ocsInv)); + if (isFinite(box.min.x) && isFinite(box.max.x)) + { + let params: number[] = []; + let cachePolyline = []; + let needRemoveIf = []; + let pts = [hole.LidCurves[0].StartPoint, hole.LidCurves[0].EndPoint, hole.LidCurves[1].StartPoint, hole.LidCurves[1].EndPoint]; + for (let polyline of polylines) + { + for (let p of pts) + { + let param = polyline.GetParamAtPoint(p.clone().applyMatrix4(ocsInv)); + if (!param) continue; + if (polyline.ParamOnCurve(param)) + params.push(param); + } + + if (params.length === 0) continue; + let cus = polyline.GetSplitCurves(params); + arrayRemoveIf(cus, (cu) => box.containsPoint(cu.Midpoint)); + cachePolyline.push(...cus); + needRemoveIf.push(polyline); + } + + arrayRemoveIf(polylines, (polyline) => needRemoveIf.includes(polyline)); + polylines.push(...cachePolyline); + } + } + } + else name = "吊顶"; + + let group = curveLinkGroup(polylines); + for (let cus of group) + { + let path = Polyline.Combine(cus); + let sweepSolid = new HardwareTopline(outline, path); + JigUtils.Draw(sweepSolid); + if (!equaln(sweepSolid.BoundingBox.min.x, 0)) + sweepSolid.Reverse(); + sweepSolid.ApplyMatrix(ent.OCSNoClone); + sweepSolid.HardwareOption.name = name; + app.Database.ModelSpace.Append(sweepSolid); + } + } +} + async function handleBoard(outline: Polyline, brs: Board[]) { let spaceParse = new SurroundOutlineParse(brs); diff --git a/src/Add-on/testEntity/test.ts b/src/Add-on/testEntity/test.ts index 978749916..f9e6976c5 100644 --- a/src/Add-on/testEntity/test.ts +++ b/src/Add-on/testEntity/test.ts @@ -1,25 +1,18 @@ -import { CADFiler } from "../../DatabaseServices/CADFiler"; -import { Region } from "../../DatabaseServices/Entity/Region"; +import { app } from "../../ApplicationServices/Application"; +import { Entity } from "../../DatabaseServices/Entity/Entity"; import { Command } from "../../Editor/CommandMachine"; -import { BoolOpeartionType } from "../../GraphicsSystem/BoolOperateUtils"; +import { PromptStatus } from "../../Editor/PromptResult"; import { HotCMD } from "../../Hot/HotCommand"; -import { TestDraw } from "../test/TestUtil"; @HotCMD export class Test implements Command { async exec() { - let d = { "file": [2, "Region", 10, 2, 110, 0, 1, 7, 71, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, 1, 1, 1, 1, "Polyline", 10, 2, 0, 0, 0, 1, 71, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, 2, 4, [100, 0], 0, [400, 0], 0, [400, 864], 0, [100, 864], 0, true, 0, "Region", 10, 2, 111, 0, 1, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 1, 1, 1, 1, "Polyline", 10, 2, 0, 0, 0, 2, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -614.9118387909318, -117.20906801007538, 0, 1], 0, 0, 1, 2, 4, [0, 0], 0, [1728.0001196034718, 0], 0, [1728.0001196034718, 9.5], 0, [0, 9.5], 0, true, 0], "basePt": { "x": -0.00023216125555336475, "y": -100, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; - let f = new CADFiler(d.file); + let enRes = await app.Editor.GetEntity({ Filter: { filterTypes: [Entity] } }); + if (enRes.Status !== PromptStatus.OK) return; + let pl = enRes.Entity as Entity; + console.log(pl); - f.Read(); - let el1 = f.ReadObject() as Region; - let el2 = f.ReadObject() as Region; - - TestDraw(el1.Clone()); - TestDraw(el2.Clone()); - - el1.BooleanOper(el2, BoolOpeartionType.Intersection); } } diff --git a/src/Common/ColorPalette.ts b/src/Common/ColorPalette.ts index 91ec0fd6f..5a7c2e104 100644 --- a/src/Common/ColorPalette.ts +++ b/src/Common/ColorPalette.ts @@ -457,6 +457,14 @@ export class ColorMaterial side: DoubleSide, }); + static PrintLineWhiterMatrial = new LineMaterial({ + color: 0xFFFFFF, + linewidth: LINE_WIDTH, + dashed: false, + resolution: new Vector2(1000, 1000), + side: DoubleSide, + }); + //灰色半透明(板件为不拆单时候的显示样式) static GrayTransparentMeshMaterial = new MeshBasicMaterial({ color: 0xcccccc, diff --git a/src/Common/CommandNames.ts b/src/Common/CommandNames.ts index f42c3aa22..297a5fec1 100644 --- a/src/Common/CommandNames.ts +++ b/src/Common/CommandNames.ts @@ -356,6 +356,11 @@ export enum CommandNames ZJPC = "ZHUANJIAOPIAOCHUANG", //转角飘窗 YJHM = "YIJIANHUAMEN",//一键画门 + //吊顶 + HeadCeilingContour = "HEADCEILINGCONTOUR",//吊顶轮廓模板 + HeadCeilingMaterialPanel = "HEADCEILINGMATERIALPANEL",//吊顶截面轮廓材质面板 + HeadCeilingInfoConfigPanel = "HEADCEILINGINFOCONFIGPANEL",//吊顶轮廓面板 + Gallery = "GALLERY", //打开画廊 Freeze = "FREEZE",//冻结实体 @@ -363,6 +368,5 @@ export enum CommandNames ShareView = "SHAREVIEW", //分享图纸(只读模式) VisibleInRender = "VISIBLEINRENDER", //渲染器中显示实体 UnVisibleInRender = "UNVISIBLEINRENDER", //渲染器中隐藏实体 - SendCADFileToKF = "SENDCADFILETOKF",//发送当前文件给在线客服 } diff --git a/src/Common/Request.ts b/src/Common/Request.ts index f8a140eef..27fa4bdce 100644 --- a/src/Common/Request.ts +++ b/src/Common/Request.ts @@ -15,6 +15,7 @@ export enum DirectoryId DrillingDir = "6", //排钻目录 KnifePathDir = "7", //刀路目录 Frame = "8", //图框目录 + CeilingContour = "9", //吊顶轮廓 HistoryDit = "-1",//历史编辑目录 } diff --git a/src/Common/SerializeMaterial.ts b/src/Common/SerializeMaterial.ts index 9a653f354..e1314b1e6 100644 --- a/src/Common/SerializeMaterial.ts +++ b/src/Common/SerializeMaterial.ts @@ -39,7 +39,7 @@ export function MaterialIn(fileData: Object[]): PhysicalMaterialRecord return db.MaterialTable.Symbols.entries().next().value[1]; } -export function TemplateOut(template: TemplateRecord, tempDb = new Database(false, false, true)) +export function TemplateOut(template: TemplateRecord, tempDb = new Database(false, false, true)): string { template = template.Root; let idMap = new Map(); @@ -55,9 +55,9 @@ export function TemplateOut(template: TemplateRecord, tempDb = new Database(fals if (l.Id.Index > 99) l.ApplyMatrix(scsInv); - return JSON.stringify(tempDb.FileWrite().Data); + return tempDb.FileWrite().ToString(); } -export function TemplateIn(fileData: Object[]): TemplateRecord +export function TemplateIn(fileData: any[]): TemplateRecord { let f = new CADFiler(fileData); let db = new Database(false, false, true).FileRead(f); diff --git a/src/DatabaseServices/Database.ts b/src/DatabaseServices/Database.ts index 752113f3d..bfc5f78d1 100644 --- a/src/DatabaseServices/Database.ts +++ b/src/DatabaseServices/Database.ts @@ -61,6 +61,9 @@ export class Database //默认材质 DefaultMaterial: PhysicalMaterialRecord; + /** 这是为UE设计器提供的拓展数据,WebCAD只负责保存,不使用它. + * 在存储吊顶模块时,存储了材质槽信息 + */ ExtendedData: any = null; private idIndex = 1; diff --git a/src/DatabaseServices/Entity/Polyline.ts b/src/DatabaseServices/Entity/Polyline.ts index 78b0cea8a..be4ea98ce 100644 --- a/src/DatabaseServices/Entity/Polyline.ts +++ b/src/DatabaseServices/Entity/Polyline.ts @@ -1,4 +1,4 @@ -import { Box3, Matrix3, Matrix4, Shape, Vec2, Vector2, Vector3 } from 'three'; +import { Box3, Matrix3, Matrix4, Vec2, Vector2, Vector3 } from 'three'; import { arrayLast, arrayRemoveDuplicateBySort, changeArrayStartIndex } from '../../Common/ArrayExt'; import { ComputerCurvesNormalOCS, getDeterminantFor2V } from '../../Common/CurveUtils'; import { matrixAlignCoordSys, matrixIsCoplane, reviseMirrorMatrix } from '../../Common/Matrix4Utils'; @@ -13,6 +13,7 @@ import { OffsetPolyline } from '../../GraphicsSystem/OffsetPolyline'; import { Factory } from '../CADFactory'; import { CADFiler } from '../CADFiler'; import { IsPointInPolyLine } from '../PointInPolyline'; +import { Shape2 } from '../Shape2'; import { Arc } from './Arc'; import { Curve, ExtendType } from './Curve'; import { DragPointType } from './DragPointType'; @@ -1470,7 +1471,7 @@ export class Polyline extends Curve } return true; } - get Shape(): Shape + get Shape(): Shape2 { let { pts, buls } = this.PtsBuls; return CreatePolylinePath(pts, buls); diff --git a/src/DatabaseServices/Room/Entity/Ceiling/BulkheadCeiling.ts b/src/DatabaseServices/Room/Entity/Ceiling/BulkheadCeiling.ts new file mode 100644 index 000000000..7b413af63 --- /dev/null +++ b/src/DatabaseServices/Room/Entity/Ceiling/BulkheadCeiling.ts @@ -0,0 +1,541 @@ +import { BufferAttribute, BufferGeometry, Float32BufferAttribute, InstancedInterleavedBuffer, InterleavedBufferAttribute, Intersection, LineSegments, Material, Mesh, Object3D, ShapeBufferGeometry, Vector3 } from "three"; +import { Line2 } from "three/examples/jsm/lines/Line2"; +import { LineGeometry } from "three/examples/jsm/lines/LineGeometry"; +import { ColorMaterial } from "../../../../Common/ColorPalette"; +import { DisposeThreeObj, Object3DRemoveAll } from "../../../../Common/Dispose"; +import { BufferGeometryUtils } from "../../../../Geometry/BufferGeometryUtils"; +import { ContourTreeNode } from "../../../../Geometry/ExtrudeMeshGeomBuilder/ExtrudeEdgeGeometry2"; +import { AsVector3, equaln } from "../../../../Geometry/GeUtils"; +import { SweepGeometry } from "../../../../Geometry/SweepGeometry"; +import { RenderType } from "../../../../GraphicsSystem/RenderType"; +import { AutoRecord } from "../../../AutoRecord"; +import { Factory } from "../../../CADFactory"; +import { CADFiler } from "../../../CADFiler"; +import { Contour } from "../../../Contour"; +import { Curve } from "../../../Entity/Curve"; +import { Entity } from "../../../Entity/Entity"; +import { Polyline } from "../../../Entity/Polyline"; +import { ObjectId } from "../../../ObjectId"; +import { PhysicalMaterialRecord } from "../../../PhysicalMaterialRecord"; +import { Shape } from "../../../Shape"; +import { TemplateRecord } from "../../../Template/TemplateRecord"; +import { RoomFlatBase } from "../Flat/RoomFlatBase"; + +export enum BulkheadCeiling_ContourType +{ + Hole = 0, + Land = 1, + Sweep = 2,//放样线条(不影响岛的建模) +} + +export interface BulkheadCeiling_ContourData +{ + ContourType: BulkheadCeiling_ContourType;//洞 还是岛 + Path: Curve;//轮廓(可能闭合 可能是一条直线) + SweepShapeTempalteId: ObjectId;//放样形状的模块id + Materials: ObjectId[]; + Contour: Polyline; //截面轮廓 + ContourId: number; //截面轮廓ID + ShapeMaterialSlotData: number[]; + OverWriteMaterial?: Map>;//替代材质 +} + +/** + * 吊顶(灯带) + */ +@Factory +export class BulkheadCeiling extends Entity +{ + constructor() { super(); } + private _ContourData: BulkheadCeiling_ContourData[] = []; + private _GemoIdMap = new Map(); + + get ContourData(): BulkheadCeiling_ContourData[] + { + return this._ContourData; + } + set ContourData(value: BulkheadCeiling_ContourData[]) + { + this.WriteAllObjectRecord(); + this._ContourData = value; + this.Update(); + } + + private _Height = 300;//吊顶高度 + + get Height() + { + return this._Height; + } + set Height(value: number) + { + this.WriteAllObjectRecord(); + if (!equaln(value, this._Height)) + { + this._Height = value; + this.Update(); + } + } + + @AutoRecord RelativeRoomFlatTop: ObjectId; + + private _EdgeGeometrys: BufferGeometry[]; + get EdgeGeometrys(): BufferGeometry[] + { + if (!this._EdgeGeometrys) + this.MeshGeometry; + + return this._EdgeGeometrys; + } + + + private _LineGeometry: LineGeometry[] = []; + get LineGeometry() + { + if (this._LineGeometry.length !== 0) + return this._LineGeometry; + + this.MeshGeometry; + return this._LineGeometry; + } + + private _FaceGeometry: BufferGeometry; //底面 + get FaceGeometry() + { + if (this._FaceGeometry) + return this._FaceGeometry; + + this.MeshGeometry; + return this._FaceGeometry; + } + + private _MeshGeometry: SweepGeometry[] = []; + get MeshGeometry() + { + if (this._MeshGeometry.length !== 0) return this._MeshGeometry; + + //绘制底面start + + //#region //分析包含关系 + let contours: ContourTreeNode[] = []; + let contour_data_Map = new Map(); + for (let con_data of this._ContourData) + { + if (!con_data.Path?.IsClose || con_data.ContourType === BulkheadCeiling_ContourType.Sweep) continue; + let contour = Contour.CreateContour(con_data.Path as Polyline); + if (!contour) continue; + + let contourNode = new ContourTreeNode(contour); + contours.push(contourNode); + contour_data_Map.set(contourNode, con_data); + } + ContourTreeNode.ParseContourTree(contours); + //#endregion + + let faceGeoms: BufferGeometry[] = []; + this._EdgeGeometrys = []; + this._GemoIdMap.clear(); + + for (let contourNode of contours) + { + let con_data = contour_data_Map.get(contourNode); + + if (con_data.ContourType === BulkheadCeiling_ContourType.Land)//Land 岛 + { + //#region 绘制平面 + if (contourNode.parent && contour_data_Map.get(contourNode.parent).ContourType === BulkheadCeiling_ContourType.Land)//上级也是岛 不需要在绘制平面了 + continue; + + let holes: Contour[] = []; + for (let chiNode of contourNode.children) + { + let chi_con_data = contour_data_Map.get(chiNode); + if (chi_con_data.ContourType === BulkheadCeiling_ContourType.Hole) + holes.push(chiNode.contour.Clone()); + } + + let shape = new Shape(contourNode.contour, holes); + let geom = new ShapeBufferGeometry(shape.Shape, 30); + + geom.applyMatrix4(shape.Outline.Curve.OCSNoClone); + + { + const indices = Array.from(geom.getIndex().array); + + // 翻转面片索引的顺序 + const flippedIndices = []; + for (let i = 0; i < indices.length; i += 3) + flippedIndices.push(indices[i], indices[i + 2], indices[i + 1]); + + // 创建新的面片索引属性 + const newIndices = new BufferAttribute(new Uint16Array(flippedIndices), 1); + + // 更新面片索引属性 + geom.setIndex(newIndices); + } + + faceGeoms.push(geom); + //#endregion + } + } + //绘制底面end + + //Sweep + let i = 0; + for (; i < this._ContourData.length; i++) + { + let contour = this._ContourData[i].Contour; + + if (contour) + { + let path = this._ContourData[i].Path; + if (this._ContourData[i].ContourType === BulkheadCeiling_ContourType.Hole) + path = path.Clone().Reverse(); + + let sweepGeo = new SweepGeometry(contour, path, this._ContourData[i].ShapeMaterialSlotData); + + this._GemoIdMap.set(sweepGeo.id, i); + + this._MeshGeometry.push(sweepGeo); + + //line geo + this.GetLineGeometry(sweepGeo.edgePts); + //edge geo + let edgeGeom = new BufferGeometry().setAttribute('position', new Float32BufferAttribute(sweepGeo.edgePts, 3)); + this._EdgeGeometrys.push(edgeGeom); + + sweepGeo.edgePts = undefined; + } + } + + this._FaceGeometry = BufferGeometryUtils.MergeBufferGeometries(faceGeoms); + this._GemoIdMap.set(this._FaceGeometry.id, i); + + return this._MeshGeometry; + } + + GetLineGeometry(pts: number[]) + { + let lineGeo = new LineGeometry(); + let lineSegments = new Float32Array(pts); + var instanceBuffer = new InstancedInterleavedBuffer(lineSegments, 6, 1); + lineGeo.setAttribute('instanceStart', new InterleavedBufferAttribute(instanceBuffer, 3, 0)); + lineGeo.setAttribute('instanceEnd', new InterleavedBufferAttribute(instanceBuffer, 3, 3)); + this._LineGeometry.push(lineGeo); + } + + InitDrawObject(renderType: RenderType = RenderType.Wireframe): Object3D + { + let obj = new Object3D(); + this.UpdateDrawObject(renderType, obj); + return obj; + } + + /** + * 重载:更新绘制的实体 + * @param {RenderType} renderType + * @param {Object3D} obj + */ + UpdateDrawObject(renderType: RenderType, obj: Object3D) + { + DisposeThreeObj(obj); + Object3DRemoveAll(obj); + + if (renderType === RenderType.Wireframe || renderType === RenderType.Jig) + { + for (let edgeGeo of this.EdgeGeometrys) + obj.add(new LineSegments(edgeGeo, ColorMaterial.GetLineMaterial(this.ColorIndex))); + } + else if (renderType === RenderType.Conceptual) + { + let material = ColorMaterial.GetConceptualMaterial(this.ColorIndex); + + obj.add(new Mesh(this.FaceGeometry, material)); + + for (let meshGeo of this.MeshGeometry) + { + obj.add(new Mesh(meshGeo, material)); + } + + for (let edgeGeo of this.EdgeGeometrys) + obj.add(new LineSegments(edgeGeo, ColorMaterial.GetLineMaterial(this.ColorIndex))); + } + else if (renderType === RenderType.Physical) + { + obj.add(new Mesh(this.FaceGeometry, (this.Material?.Object as PhysicalMaterialRecord)?.Material ?? this.MeshMaterial)); + + for (let meshGeo of this.MeshGeometry) + obj.add(new Mesh(meshGeo, this.GetMaterials(this._GemoIdMap.get(meshGeo.id)))); + } + // else if (renderType === RenderType.Physical2) + // { + // obj.add(new Mesh(this.FaceGeometry, (this.Material?.Object as PhysicalMaterialRecord)?.Material ?? this.MeshMaterial)); + + // for (let meshGeo of this.MeshGeometry) + // obj.add(new Mesh(meshGeo, this.GetMaterials(this._GemoIdMap.get(meshGeo.id)))); + + // for (let edgeGeo of this.EdgeGeometrys) + // obj.add(new LineSegments(edgeGeo, ColorMaterial.GetPhysical2EdgeMaterial())); + // } + else if (renderType === RenderType.Print) + { + for (let lineGeo of this.LineGeometry) + obj.add(new Line2(lineGeo, ColorMaterial.PrintLineWhiterMatrial)); + } + return obj; + } + + SetMaterial(mtl: ObjectId, intersection: Intersection) + { + let id = intersection.object["geometry"]?.id; + if (id) + { + this.WriteAllObjectRecord(); + let contourIndex = this._GemoIdMap.get(id); + if (contourIndex === undefined) + this.Material = mtl; + else + { + //因为这个索引是底部面的索引 + if (contourIndex === this._ContourData.length) + { + this.Material = mtl; + } + else + { + let contourData = this._ContourData[contourIndex]; + if (!contourData.OverWriteMaterial) + contourData.OverWriteMaterial = new Map; + + contourData.OverWriteMaterial.set(intersection.face.materialIndex, mtl); + } + } + this.Update(); + } + } + + //获取Sweep实体的材质列表 + GetMaterials(index: number): Material[] + { + let contourData = this._ContourData[index]; + return contourData.Materials.map((mtl, index) => + { + return contourData.OverWriteMaterial?.get(index)?.Object?.Material ?? mtl?.Object?.Material ?? this.MeshMaterial as Material; + }); + } + + UpdateDrawObjectMaterial(renderType: RenderType, obj: Object3D, material?: Material) + { + if (renderType === RenderType.Physical) + obj.traverse(o => + { + if (o instanceof Mesh) + { + let index = this._GemoIdMap.get(o.geometry.id); + if (index !== undefined) + { + if (Array.isArray(o.material)) + { + let materials = this.GetMaterials(index); + o.material = materials; + } + } + else + o.material = this.MeshMaterial; + } + }); + else if (renderType === RenderType.Conceptual) + { + let material = ColorMaterial.GetConceptualMaterial(this.ColorIndex); + let face = obj.children[0] as Mesh;// + face.material = material; + for (let i = 1; i < obj.children.length; i++) + { + let chiObj = obj.children[i]; + if (chiObj instanceof Mesh) + chiObj.material = material; + else if (chiObj instanceof LineSegments) + chiObj.material = ColorMaterial.GetLineMaterial(this.ColorIndex); + } + } + else if (renderType === RenderType.Wireframe) + { + for (let lineSeg of obj.children as LineSegments[]) + lineSeg.material = ColorMaterial.GetLineMaterial(this.ColorIndex); + } + } + + override UpdateDrawGeometry() + { + for (let gemo of this._MeshGeometry) + gemo.dispose(); + this._MeshGeometry = []; + + for (let gemo of this._LineGeometry) + gemo.dispose(); + this._LineGeometry = []; + + if (this._FaceGeometry) + this._FaceGeometry.dispose(); + this._FaceGeometry = undefined; + } + + GetGripPoints(): Array + { + let pts = []; + for (let data of this._ContourData) + pts.push(...data.Path.Clone().ApplyMatrix(this.OCSNoClone).GetGripPoints()); + return pts; + } + + GetStretchPoints(): Vector3[] + { + let pts: Vector3[] = []; + let lineData = (this.ContourData[0].Path as Polyline).LineData; + for (let data of lineData) + { + let p = AsVector3(data.pt).applyMatrix4(this.ContourData[0].Path.OCS).applyMatrix4(this.OCSNoClone); + pts.push(p); + } + return pts; + } + + MoveStretchPoints(indexList: Array, vec: Vector3) + { + this.WriteAllObjectRecord(); + let path = this.ContourData[0].Path; + path.ApplyMatrix(this.OCS); + path.MoveStretchPoints(indexList, vec); + path.ApplyMatrix(this.OCSInv); + this.Update(); + } + + MoveGripPoints(indexList: number[], moveVec: Vector3) + { + this.WriteAllObjectRecord(); + + for (let i = 0; i < this._ContourData.length; i++) + { + let path = this._ContourData[i].Path.Clone(); + let newIndexlist = []; + let dataIndexList = []; + let ptLength = path.GetGripPoints().length; + for (let index of indexList) + { + if (ptLength < (index + 1)) + newIndexlist.push(index - ptLength); + else + dataIndexList.push(index); + } + if (dataIndexList.length !== 0) + { + path.ApplyMatrix(this.OCS); + path.MoveGripPoints(dataIndexList, moveVec); + path.ApplyMatrix(this.OCSInv); + this.ContourData[i].Path = path; + } + + indexList = newIndexlist; + } + this.Update(); + } + + //#region -------------------------File------------------------- + //对象从文件中读取数据,初始化自身 + protected override _ReadFile(file: CADFiler) + { + let ver = file.Read(); + super._ReadFile(file); + + this.ContourData = []; + let contourDataCount = file.Read(); + for (let i = 0; i < contourDataCount; i++) + { + let data: BulkheadCeiling_ContourData = { + ContourType: null, + Path: null, + SweepShapeTempalteId: null, + Materials: [], + Contour: null, + ContourId: null, + ShapeMaterialSlotData: [], + OverWriteMaterial: null, + }; + + data.ContourType = file.Read(); + data.Contour = file.ReadObject(); + data.ContourId = file.Read(); + data.Path = file.ReadObject(); + data.SweepShapeTempalteId = file.ReadObjectId() as ObjectId; + + //覆盖材质 + let overwriteMtlSize = file.Read() as number; + if (overwriteMtlSize) data.OverWriteMaterial = new Map; + else data.OverWriteMaterial = undefined; + for (let i = 0; i < overwriteMtlSize; i++) + { + let index = file.Read(); + let mtlId = file.ReadObjectId() as ObjectId; + data.OverWriteMaterial.set(index, mtlId); + } + + //原始材质 + let mtlCount = file.Read(); + for (let i = 0; i < mtlCount; i++) + data.Materials.push(file.ReadObjectId() as ObjectId); + + //材质槽 + let materialCount = file.Read(); + data.ShapeMaterialSlotData = file.ReadArray(materialCount); + + this.ContourData.push(data); + } + + this.RelativeRoomFlatTop = file.ReadObjectId() as ObjectId; + } + + + //对象将自身数据写入到文件. + override WriteFile(file: CADFiler) + { + file.Write(1); + super.WriteFile(file); + + file.Write(this.ContourData.length); + + for (let data of this.ContourData) + { + file.Write(data.ContourType); + file.WriteObject(data.Contour); + file.Write(data.ContourId); + file.WriteObject(data.Path); + file.WriteObjectId(data.SweepShapeTempalteId); + + //覆盖材质 + if (data.OverWriteMaterial) + { + file.Write(data.OverWriteMaterial.size); + for (let [index, mtlId] of data.OverWriteMaterial) + { + file.Write(index); + file.WriteObjectId(mtlId); + } + } + else + file.Write(0); + + //原始材质 + file.Write(data.Materials.length); + for (let material of data.Materials) + file.WriteObjectId(material); + + //材质槽 + file.Write(data.ShapeMaterialSlotData.length); + for (let matData of data.ShapeMaterialSlotData) + file.Write(matData); + } + + file.WriteObjectId(this.RelativeRoomFlatTop); + } + //#endregion +} diff --git a/src/DatabaseServices/Room/Entity/Ceiling/BulkheadCeilingShapeExtendData.ts b/src/DatabaseServices/Room/Entity/Ceiling/BulkheadCeilingShapeExtendData.ts new file mode 100644 index 000000000..9a3d6ae7b --- /dev/null +++ b/src/DatabaseServices/Room/Entity/Ceiling/BulkheadCeilingShapeExtendData.ts @@ -0,0 +1,37 @@ +import { CADFiler } from "../../../CADFiler"; +import { ISerialize } from "../../../ISerialize"; + +/** + * 吊顶轮廓拓展数据(材质槽信息) (保存到服务端) + */ +export class BulkheadCeilingShapeTemplateExtendData implements ISerialize +{ + //颜色与材质信息映射(为了这个模块能正常流通,这个模块还是成为内嵌模块吧) + Color_MaterialId: Map = new Map(); + + constructor() { } + + ReadFile(file: CADFiler): void + { + let ver = file.Read(); + let size = file.Read(); + this.Color_MaterialId.clear(); + for (let i = 0; i < size; i++) + { + let color = file.Read(); + let templateId = file.Read(); + this.Color_MaterialId.set(color, templateId); + } + } + + WriteFile(file: CADFiler): void + { + file.Write(1); + file.Write(this.Color_MaterialId.size); + for (let [color, templateId] of this.Color_MaterialId) + { + file.Write(color); + file.Write(templateId); + } + } +} diff --git a/src/DatabaseServices/Room/ParseService/RoomRegionParse.ts b/src/DatabaseServices/Room/ParseService/RoomRegionParse.ts index adcd0dad4..70d81ba05 100644 --- a/src/DatabaseServices/Room/ParseService/RoomRegionParse.ts +++ b/src/DatabaseServices/Room/ParseService/RoomRegionParse.ts @@ -10,7 +10,7 @@ import { Polyline } from "../../Entity/Polyline"; import { UpdateTempPolyline } from "../Entity/Flat/RoomFlatBase"; import { RoomFlatFloor } from "../Entity/Flat/RoomFlatFloor"; import { RoomFlatTop } from "../Entity/Flat/RoomFlatTop"; -import { RoomRegion, ROOM_REGION_CURVES_KEY } from "../Entity/Region/RoomRegion"; +import { ROOM_REGION_CURVES_KEY, RoomRegion } from "../Entity/Region/RoomRegion"; import { CURVE_DIR_TYPE_KEY, CURVE_FACE_TYPE_KEY, CURVE_WALL_TYPE_KEY, RoomWallBase, WallFaceType } from "../Entity/Wall/RoomWallBase"; import { ParseRegionTextPos } from "./ParseRegionTextPos"; import { RegionReplacement } from "./RegionReplacement"; diff --git a/src/DatabaseServices/Shape2.ts b/src/DatabaseServices/Shape2.ts index e70f8a7a4..1d4111566 100644 --- a/src/DatabaseServices/Shape2.ts +++ b/src/DatabaseServices/Shape2.ts @@ -8,7 +8,8 @@ export class Shape2 extends Shape { getPoints(divisions: number = 12, optimizeArc = true): Vector2[] { - let points = [], last: Vector2; + let points: Vector2[] = [], + last: Vector2; for (let i = 0, curves = this.curves; i < curves.length; i++) { let curve = curves[i] as EllipseCurve; diff --git a/src/Editor/CommandRegister.ts b/src/Editor/CommandRegister.ts index 839277cf4..291e873c9 100644 --- a/src/Editor/CommandRegister.ts +++ b/src/Editor/CommandRegister.ts @@ -29,22 +29,22 @@ import { ChangeColor } from "../Add-on/ChangeColor"; import { ChangeColorByMaterial } from "../Add-on/ChangeColorByBoard/ChangeColorByMaterial"; import { CheckHoles } from "../Add-on/CheckHoles"; import { CheckModeling } from "../Add-on/CheckModeling"; -import { Command_ClosePt } from "../Add-on/closetest"; import { Cmd_Freeze, Cmd_UnFreeze } from "../Add-on/Cmd_Freeze"; import { Cmd_UnVisibleInRender, Cmd_VisibleInRender } from "../Add-on/Cmd_VisibleInRender"; import { CombinatAttributeBrush } from "../Add-on/CombinatAttributeBrush"; +import { FeedingCommand } from "../Add-on/CommandFeeding"; import { Command_CombineEntity } from "../Add-on/Command_CombineEntity"; import { Command_CommandPanel } from "../Add-on/Command_CommandPanel"; import { Command_Options } from "../Add-on/Command_Option"; import { Command_Purge } from "../Add-on/Command_Purge"; import { Command_SetBRXAxis } from "../Add-on/Command_SetBRXAxis"; -import { FeedingCommand } from "../Add-on/CommandFeeding"; import { Command_Conver2Polyline } from "../Add-on/Conver2Polyline"; import { Command_Copy } from "../Add-on/Copy"; import { CopyClip } from "../Add-on/CopyClip"; import { Command_CopyPoint } from "../Add-on/CopyPoint"; import { CustomUcs } from "../Add-on/CostumUCS"; import { Command_CleanCustomNumber, Command_CustomNumber } from "../Add-on/CustomNumber/Command_CustomNumber"; +import { Command_DWGDXFImport } from "../Add-on/DXFLoad"; import { DeleteCurve } from "../Add-on/DeleteCurve"; import { Command_Dist } from "../Add-on/Dist"; import { CMD_Divide } from "../Add-on/Divide"; @@ -115,7 +115,6 @@ import { DrawWineRack } from "../Add-on/DrawWineRack/DrawWineRack"; import { EditorWineRack } from "../Add-on/DrawWineRack/EditorWineRack"; import { Polyline2Winerack } from "../Add-on/DrawWineRack/Polyline2Winerack"; import { DrawCircle0 } from "../Add-on/DrawZeroCircle"; -import { Command_DWGDXFImport } from "../Add-on/DXFLoad"; import { Command_EndTempEditor } from "../Add-on/EndTempEditor"; import { Command_EntitytMoveToZ0 } from "../Add-on/EntityMoveToZ0"; import { Entsel } from "../Add-on/Entsel"; @@ -130,27 +129,25 @@ import { Command_ExportView } from "../Add-on/Export2View"; import { Command_ExportData } from "../Add-on/ExportData"; import { Command_ExportSTL } from "../Add-on/Exports/ExportSTL"; import { Command_Extend } from "../Add-on/Extends"; +import { Command_FZWL } from "../Add-on/FZWL"; import { Command_OpenHistory } from "../Add-on/File/OpenHistory"; import { OperLogs } from "../Add-on/File/OperLog"; import { CommandFillet } from "../Add-on/Fillet"; import { Command_FindBoardModelingKnife } from "../Add-on/FindBoardModelingKnife"; import { Command_Fix2DPath } from "../Add-on/Fix/Fix2DPath"; -import { Command_FZWL } from "../Add-on/FZWL"; import { Command_Group, Command_UnGroup } from "../Add-on/Group"; import { Command_HideSelected, Command_HideUnselected, Command_ShowAll, Command_SwitchDoorOrDrawer, SelectAll, ShowHideSelectPanel } from "../Add-on/HideSelected"; import { Command_Insert } from "../Add-on/Insert"; -import { Command_INsTest } from "../Add-on/instest"; import { Command_JiaJuImport } from "../Add-on/JiaJu/Import/JiaJuImport"; import { Command_Join } from "../Add-on/Join"; import { Command_KJLImport } from "../Add-on/KJL/Import/KJLImport"; -import { ClearKjlToken, KjlExport } from "../Add-on/KJL/KjlExport"; import { Command_KJLImportConfig } from "../Add-on/KJL/KJLImportConfig/KJLImportConfigTool"; +import { ClearKjlToken, KjlExport } from "../Add-on/KJL/KjlExport"; import { DrawLattice } from "../Add-on/LatticeDrawer/DrawLatticeDrawer"; import { EditorLattice } from "../Add-on/LatticeDrawer/EditorLattice"; import { Command_Length } from "../Add-on/Length"; import { Command_Lisp } from "../Add-on/Lisp"; import { DownLoadDConfig, DownloadHoleOption, UpLoadConfig, UploadHoleOption } from "../Add-on/LoadConfig"; -import { Fbx } from "../Add-on/loadfbx"; import { LookOverBoardInfos } from "../Add-on/LookOverBoardInfos/LookOverBoardInfos"; import { Command_MatchProp } from "../Add-on/MatchProp"; import { MirrorCommand } from "../Add-on/Mirror"; @@ -165,11 +162,10 @@ import { Open } from "../Add-on/Open"; import { Command_OpenCabinet } from "../Add-on/OpenCabinet/OpenCabinet"; import { PasteClip } from "../Add-on/PasteClip"; import { Pedit } from "../Add-on/Pedit"; -import { Command_PLTest } from "../Add-on/polytest"; import { Print } from "../Add-on/Print"; -import { CMD_Renderer } from "../Add-on/Renderer"; -import { Command_RenderModulesState } from "../Add-on/RenderModulesState"; import { ReOpen } from "../Add-on/ReOpen"; +import { Command_RenderModulesState } from "../Add-on/RenderModulesState"; +import { CMD_Renderer } from "../Add-on/Renderer"; import { Command_ResetCustomCommand } from "../Add-on/ResetCustomCommand"; import { Command_RestoreColor } from "../Add-on/RestoreColor"; import { Command_Reverse } from "../Add-on/Reverse"; @@ -190,8 +186,6 @@ import { Command_SendCADFileOnKf } from "../Add-on/SendCADFileOnKF"; import { SetSmoothEdge } from "../Add-on/SetSmoothEdge/SetSmoothEdge"; import { Command_ShareView } from "../Add-on/ShareView/Command_ShareView"; import { SwitchLines } from "../Add-on/ShowLines"; -import { Command_GroovesModify } from "../Add-on/showModal/GroovesModify"; -import { ShowEditorBBS } from "../Add-on/showModal/ShowModal"; import { ShowOpenDirLiens } from "../Add-on/ShowOpenDirLiens"; import { Command_ShowProcessingGroupModal } from "../Add-on/ShowProcessingGroupModal"; import { ShowRecycleBin } from "../Add-on/ShowRecycleBin"; @@ -211,18 +205,36 @@ import { ShowTemplateDesign } from "../Add-on/Template/ShowTemplateDesign"; import { ShowTopLine } from "../Add-on/Template/ShowTopline"; import { Command_SplitTemplate, Command_SplitTemplateByDir } from "../Add-on/Template/SplitTemplate"; import { Command_TemplateSearch } from "../Add-on/TemplateSearch"; +import { Command_ClosePt } from "../Add-on/closetest"; +import { Command_INsTest } from "../Add-on/instest"; +import { Fbx } from "../Add-on/loadfbx"; +import { Command_PLTest } from "../Add-on/polytest"; +import { Command_GroovesModify } from "../Add-on/showModal/GroovesModify"; +import { ShowEditorBBS } from "../Add-on/showModal/ShowModal"; // import { DrawFloor } from '../Add-on/DrawFloor'; // import { RevTarget, SaveTarget } from '../Add-on/RenderTarget'; -import { TestIntersect } from "../Add-on/test/testIntersect"; +import { TestFb } from "../Add-on/TestFb"; +import { Command_TestPointPickParse } from "../Add-on/TestPointPickParse"; +import { Text2Curve } from "../Add-on/Text2Curve"; +import { Command_ToggleUI } from "../Add-on/ToggleUI"; +import { Command_Trim } from "../Add-on/Trim"; +import { Redo, Undo } from "../Add-on/Undo"; +import { ViewChange } from "../Add-on/ViewChange"; +import { Command_FixView } from "../Add-on/ViewCtrl/FixView"; +import { EditFrame } from "../Add-on/ViewortConfig/EditFrame"; +import { EditViewport } from "../Add-on/ViewortConfig/EditViewport"; +import { OneKeyLayout } from "../Add-on/Viewport/OneKeyLayout"; +import { OneKeyPrint } from "../Add-on/Viewport/OneKeyPrint"; +import { Command_Wblock } from "../Add-on/Wblock"; +import { Command_ZoomObject, ZoomE } from "../Add-on/ZoomE"; import { Command_TestParseEdgeSealDir } from "../Add-on/test/TestParseEdgeSealDir"; import { Command_TestTape } from "../Add-on/test/TestTape"; -import { Command_Test_IsRect } from "../Add-on/testEntity/Cmd_Test_IsRect"; +import { TestIntersect } from "../Add-on/test/testIntersect"; import { Command_UpdateLight } from "../Add-on/testEntity/CMD_UpdateLight"; +import { Command_Test_IsRect } from "../Add-on/testEntity/Cmd_Test_IsRect"; import { Command_DebugTemplateAssocCount } from "../Add-on/testEntity/DebugShowTemplateAssocEntityCount"; -import { Test } from "../Add-on/testEntity/test"; import { Command_TestBoundaryBox } from "../Add-on/testEntity/TestBoundaryBox"; import { Command_TestBox } from "../Add-on/testEntity/TestBox"; -import { TestCollision } from "../Add-on/testEntity/testCollision"; import { TestTargeOnCurve } from "../Add-on/testEntity/TestCurve"; import { Command_TestDrawEdgeGeometry } from "../Add-on/testEntity/TestDrawEdgeGeometry"; import { Command_TestLoadFbx } from "../Add-on/testEntity/TestFbx"; @@ -232,25 +244,13 @@ import { Command_TestRegionParse } from "../Add-on/testEntity/TestRegionParse"; import { Command_TestSweepMaxLength } from "../Add-on/testEntity/TestSweepMaxLength"; import { Command_DeleteTemplate } from "../Add-on/testEntity/TestTemplateDelete"; import { Command_TestVPath } from "../Add-on/testEntity/TestVPath"; -import { TestFb } from "../Add-on/TestFb"; -import { Command_TestPointPickParse } from "../Add-on/TestPointPickParse"; -import { Text2Curve } from "../Add-on/Text2Curve"; -import { Command_ToggleUI } from "../Add-on/ToggleUI"; -import { Command_Trim } from "../Add-on/Trim"; +import { Test } from "../Add-on/testEntity/test"; +import { TestCollision } from "../Add-on/testEntity/testCollision"; import { Command_Curve2Polyline } from "../Add-on/twoD2threeD/Command_Curve2Polyline"; import { Command_Curve2VSBox } from "../Add-on/twoD2threeD/Command_Curve2VSBox"; import { Command_ParseBoardName } from "../Add-on/twoD2threeD/ParseBoardName"; import { Polyline2Board } from "../Add-on/twoD2threeD/Polyline2Board"; import { Rect2Board } from "../Add-on/twoD2threeD/Rect2Board"; -import { Redo, Undo } from "../Add-on/Undo"; -import { ViewChange } from "../Add-on/ViewChange"; -import { Command_FixView } from "../Add-on/ViewCtrl/FixView"; -import { EditFrame } from "../Add-on/ViewortConfig/EditFrame"; -import { EditViewport } from "../Add-on/ViewortConfig/EditViewport"; -import { OneKeyLayout } from "../Add-on/Viewport/OneKeyLayout"; -import { OneKeyPrint } from "../Add-on/Viewport/OneKeyPrint"; -import { Command_Wblock } from "../Add-on/Wblock"; -import { Command_ZoomObject, ZoomE } from "../Add-on/ZoomE"; import { CommandNames } from "../Common/CommandNames"; import { IsTest } from "../Common/Deving"; import { Command_SelectEntity } from "../Common/SelectEntity"; @@ -274,6 +274,8 @@ import { Command_TestYHSingle } from "../Nest/Test/TestYHSingle"; import { Command_TestYHWorker } from "../Nest/Test/TestYHWorker"; import { Comman_SwitchServers, Command_ChangeLayout, Command_ModuleBar, Command_PropertiesBar, Command_RightPanel, RightTabCommandMap } from "../UI/Components/CommandPanel/SystemCommand/UICpmmand"; import Command_Gallery from "../UI/Components/Gallery/command/Command_Gallery"; +import { Command_HeadCeilingContourManage } from "../UI/Components/HeadCeiling/HeadCeilingContourManageCommand"; +import { Command_HeadCeilingInfoConfigPanel, Command_HeadCeilingMaterialPanel } from "../UI/Components/HeadCeiling/HeadCeilingInfoConfigPanelCommand"; import { EOptionTabId } from "../UI/Components/Modal/OptionModal/ConfigDialog"; import { Align } from "./../Add-on/Align"; import { BuyMaterial } from "./../Add-on/BuyMaterial"; @@ -832,6 +834,11 @@ export function registerCommand() commandMachine.RegisterCommand(CommandNames.ZJPC, new Command_OneKeyDrawZJPCWindow(DrawHoleType.L, IHoleType.Window, true)); //转角飘窗 commandMachine.RegisterCommand(CommandNames.YJHM, new Command_OneKeyDrawYJHMWindow(true)); //一键画门 + + commandMachine.RegisterCommand(CommandNames.HeadCeilingContour, new Command_HeadCeilingContourManage()); //吊顶轮廓材质面板 + commandMachine.RegisterCommand(CommandNames.HeadCeilingMaterialPanel, new Command_HeadCeilingMaterialPanel()); //吊顶轮廓材质面板 + commandMachine.RegisterCommand(CommandNames.HeadCeilingInfoConfigPanel, new Command_HeadCeilingInfoConfigPanel()); //吊顶轮廓材质面板 + //SelectEntity commandMachine.RegisterCommand(CommandNames.SelectBoard, new Command_SelectEntity(Board, "请选择板:")); commandMachine.RegisterCommand(CommandNames.SelectCurve, new Command_SelectEntity(Curve, "请选择曲线:")); diff --git a/src/Editor/DbClick/DbClick.ts b/src/Editor/DbClick/DbClick.ts index 3c4ffe009..f63c17c11 100644 --- a/src/Editor/DbClick/DbClick.ts +++ b/src/Editor/DbClick/DbClick.ts @@ -18,6 +18,8 @@ import { Light } from "../../DatabaseServices/Lights/Light"; import { PointLight } from "../../DatabaseServices/Lights/PointLight"; import { RectAreaLight } from "../../DatabaseServices/Lights/RectAreaLight"; import { SpotLight } from "../../DatabaseServices/Lights/SpotLight"; +import { BulkheadCeiling } from "../../DatabaseServices/Room/Entity/Ceiling/BulkheadCeiling"; +import { RoomFlatTop } from "../../DatabaseServices/Room/Entity/Flat/RoomFlatTop"; import { RoomRegion } from "../../DatabaseServices/Room/Entity/Region/RoomRegion"; import { RoomBase } from "../../DatabaseServices/Room/Entity/RoomBase"; import { Text } from "../../DatabaseServices/Text/Text"; @@ -35,6 +37,7 @@ import { CompositeMatalPanel } from "../../UI/Components/RightPanel/CompositeMet import { RightTabId } from "../../UI/Components/RightPanel/RightPanel"; import { ToplineMetalsPanel } from "../../UI/Components/RightPanel/ToplineMetalsPanel"; import { AppToaster } from "../../UI/Components/Toaster"; +import RoomFlatTopParams from "../../UI/Components/ToolBar/ModifyModel/RoomFlatTopParams"; import { IConfigStore } from "../../UI/Store/BoardStore"; import { EntityStore } from "../../UI/Store/EntityStore"; import { compositeMetalsOptionStore, toplineMetalsStore } from "../../UI/Store/RightPanelStore/HardwareStore"; @@ -292,8 +295,19 @@ export class DbClickManager extends Singleton } }, VP_TOATER_KEY); } + else if (pickEnt instanceof BulkheadCeiling) + { + if (!pickEnt.RelativeRoomFlatTop?.Object) return; + app.Editor.ModalManage.RenderModeless(RoomFlatTopParams, { headCeilingEnt: pickEnt }); + return; + } else if (pickEnt instanceof RoomBase) { + if (pickEnt instanceof RoomFlatTop) + { + app.Editor.ModalManage.RenderModeless(RoomFlatTopParams, { roomFlatTopEnt: pickEnt }); + return; + } let rightStore = RightPanelStore.GetInstance(); rightStore.m_IsShow = true; rightStore.m_TabId = RightTabId.ModuelParams; diff --git a/src/Editor/DefaultConfig.ts b/src/Editor/DefaultConfig.ts index 7ac0d1c16..ba51d229e 100644 --- a/src/Editor/DefaultConfig.ts +++ b/src/Editor/DefaultConfig.ts @@ -14,6 +14,7 @@ import { ELatticeArrayType, ILatticeOption } from "../UI/Store/LatticeInterface" import { ForBoardNameType, IAutoDimBrsOption } from "../UI/Store/OptionInterface/AutoDimBrsOption"; import { CurtailType, IBoardBatchCurtailOption } from "../UI/Store/OptionInterface/BoardBatchCurtailOption "; import { BoardProcessOption } from "../UI/Store/OptionInterface/BoardProcessOption"; +import { BulkheadCeilingOption } from "../UI/Store/OptionInterface/BulkheadCeilingOption"; import { ClosingStripOption, StripType } from "../UI/Store/OptionInterface/ClosingStripOption"; import { BehindBoardOption, ChangeColorByBoardMaterialOption, CommonPanelConfigOption, DatalistConfigOption, IBatchModifyPanelOption, IDimStyleOption, LayerBoardOption, LayerNailOption, ModifyTextsConfigOption, RightPlaneLightOption, ShareBoardInfConfigurationOption, SideBoardOption, SingleBoardOption, TBBoardOption, VerticalBoardOption, WindowPanelConfigOption } from "../UI/Store/OptionInterface/IOptionInterface"; import { PointLightOption, RectAreaLightOption, SpotLightOption } from "../UI/Store/OptionInterface/LightConfigOption"; @@ -939,7 +940,6 @@ export const DefaultDimStyleOption: IDimStyleOption = { }; Object.freeze(DefaultDimStyleOption); - export const DefaultChangeColorByBoardMaterialOption: ChangeColorByBoardMaterialOption = { accordThickness: false, accordMaterialColor: true, @@ -957,3 +957,8 @@ export const DefaultShareBoardInfConfigurationOption: ShareBoardInfConfiguration showBom: true, }; Object.freeze(DefaultShareBoardInfConfigurationOption); + +export const DefaultBulkheadCeilingOption: BulkheadCeilingOption = { + Item: [] +}; +Object.freeze(DefaultBulkheadCeilingOption); diff --git a/src/Editor/TranstrolControl/ParsePlacePos.ts b/src/Editor/TranstrolControl/ParsePlacePos.ts index 2491fc757..d804bd806 100644 --- a/src/Editor/TranstrolControl/ParsePlacePos.ts +++ b/src/Editor/TranstrolControl/ParsePlacePos.ts @@ -8,7 +8,7 @@ import { BoxSolid } from "../../DatabaseServices/Entity/BoxSolid"; import { Curve } from "../../DatabaseServices/Entity/Curve"; import { Entity } from "../../DatabaseServices/Entity/Entity"; import { TemplateRecord } from "../../DatabaseServices/Template/TemplateRecord"; -import { equalv3, isPerpendicularityTo, ZAxis, ZAxisN, ZeroVec } from "../../Geometry/GeUtils"; +import { ZAxis, ZAxisN, ZeroVec, equalv3, isPerpendicularityTo } from "../../Geometry/GeUtils"; import { RenderType } from "../../GraphicsSystem/RenderType"; import { Raycast } from "../PointPick"; import { userConfig } from "../UserConfig"; @@ -28,6 +28,7 @@ export class ParsePlacePos { let nowPos = _Inter.point; + if (!_Inter.face) return; let normal = _Inter.face.normal.clone().transformDirection(_Inter.object.matrixWorld); //在地上 diff --git a/src/Geometry/CreatePolylinePath.ts b/src/Geometry/CreatePolylinePath.ts index 4814cfb6e..6e5ca5b75 100644 --- a/src/Geometry/CreatePolylinePath.ts +++ b/src/Geometry/CreatePolylinePath.ts @@ -1,4 +1,4 @@ -import { Shape, Vector2 } from 'three'; +import { Vector2 } from 'three'; import { Shape2 } from '../DatabaseServices/Shape2'; import { angle, equaln, equalv2, polar } from './GeUtils'; @@ -31,7 +31,7 @@ class Arc2d } //创建轮廓 通过点表和凸度 -export function CreatePolylinePath(pts: Vector2[], buls: number[]): Shape +export function CreatePolylinePath(pts: Vector2[], buls: number[]): Shape2 { let shape = new Shape2(); if (pts.length === 0) return shape; diff --git a/src/Geometry/SweepGeometry.ts b/src/Geometry/SweepGeometry.ts index eca2665f0..f0cfc9cdc 100644 --- a/src/Geometry/SweepGeometry.ts +++ b/src/Geometry/SweepGeometry.ts @@ -13,15 +13,15 @@ import { PlaneExt } from "./Plane"; export class SweepGeometry extends Geometry { edgePts: number[] = []; - constructor(contour: Polyline, path: Curve[] | Curve) + ShapeMaterialSlotData: number[];//[0,0,0,1,2,3,0] 指定多段线轮廓的材质槽索引 每个顶点指定一个材质槽位置 + constructor(contour: Polyline, path: Curve[] | Curve, ShapeMaterialSlotData?: number[]) { super(); - + this.ShapeMaterialSlotData = ShapeMaterialSlotData; if (Array.isArray(path)) this.AddShape2(contour, path); else this.AddShape(contour, path); - this.computeVertexNormals(); this.computeFaceNormals(); } @@ -155,12 +155,20 @@ export class SweepGeometry extends Geometry { let addCount = 0; //补充个数 shapePts2d[0]["_mask_"] = true; - for (let p of shapePts2d) if (p["_mask_"]) addCount++; + for (let p of shapePts2d) + if (p["_mask_"]) + { + addCount++; + + if (this.ShapeMaterialSlotData) + p["_material_index_"] = this.ShapeMaterialSlotData[addCount - 1]; + } + let sumCount = addCount + shapePts2d.length; //实际个数 - const f4 = (a: number, b: number, c: number, d: number, uvs: Vector2[]) => + const f4 = (a: number, b: number, c: number, d: number, uvs: Vector2[], materialIndex?: number) => { - let f1 = new Face3(a, b, c); - let f2 = new Face3(b, d, c); + let f1 = new Face3(a, b, c, undefined, undefined, materialIndex); + let f2 = new Face3(b, d, c, undefined, undefined, materialIndex); this.faces.push(f1, f2); this.faceVertexUvs[0].push([uvs[0].clone(), uvs[1].clone(), uvs[2].clone()], [uvs[1].clone(), uvs[3].clone(), uvs[2].clone()]); }; @@ -182,12 +190,16 @@ export class SweepGeometry extends Geometry let tempStartX = 0; + let lastMaterialIndex = undefined; for (let contourIndex = 0; contourIndex < shapePts2d.length; contourIndex++) { let p1 = pts[contourIndex]; let p2 = pts2[contourIndex]; let p2d = shapePts2d[contourIndex]; + if (p2d["_mask_"]) + lastMaterialIndex = p2d["_material_index_"] ?? lastMaterialIndex; + if (pathIndex !== verts.length - 1) if (contourIndex === 0 || p2d["_mask_"]) this.edgePts.push(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z); @@ -219,7 +231,7 @@ export class SweepGeometry extends Geometry new Vector2(v1, x3), new Vector2(v2, x4), ]; - f4(curIndex, nextIndex, curIndex2, nextIndex2, uvs); + f4(curIndex, nextIndex, curIndex2, nextIndex2, uvs, lastMaterialIndex); } this.vertices.push(p1); } diff --git a/src/UI/Components/Board/BoardModalType.ts b/src/UI/Components/Board/BoardModalType.ts index ed6c84f1d..f58d9b05f 100644 --- a/src/UI/Components/Board/BoardModalType.ts +++ b/src/UI/Components/Board/BoardModalType.ts @@ -62,4 +62,7 @@ export enum BoardModalType TemplateManage = "TemplateManage",//模板管理界面信息 DimStyleConfig = "DimStyleConfig",//标注配置 DatalistStore = "DatalistStore", //数据列表配置 + BulkheadCeiling = "BulkheadCeiling",//吊顶轮廓 + BulkheadCeilingContour = "BulkheadCeilingContour",//吊顶轮廓 + HeadCeilingProfileMaterial = "HeadCeilingProfileMaterial",//吊顶截面材质 } diff --git a/src/UI/Components/CommandPanel/CommandList.ts b/src/UI/Components/CommandPanel/CommandList.ts index a10b1460b..db915d110 100644 --- a/src/UI/Components/CommandPanel/CommandList.ts +++ b/src/UI/Components/CommandPanel/CommandList.ts @@ -2684,6 +2684,15 @@ export const CommandList: ICommand[] = [ chName: "排钻模块", chDes: "", }, + { + typeId: "module", + link: `#`, + defaultCustom: "HCC", + command: CommandNames.HeadCeilingContour, + type: "模块", + chName: "吊顶轮廓模块", + chDes: "", + }, { icon: IconEnum.DrawVSBox, typeId: "module", @@ -2912,6 +2921,14 @@ export const CommandList: ICommand[] = [ chName: "显示右侧面板(三维刀路)", chDes: "显示右侧面板(三维刀路)", }, + { + typeId: "interface", + defaultCustom: "HCMP", + command: CommandNames.HeadCeilingMaterialPanel, + type: "界面", + chName: "吊顶轮廓材质面板", + chDes: "显示吊顶轮廓材质面板", + }, { typeId: "interface", defaultCustom: "RPS", diff --git a/src/UI/Components/HeadCeiling/HeadCeiling.less b/src/UI/Components/HeadCeiling/HeadCeiling.less new file mode 100644 index 000000000..99bde7695 --- /dev/null +++ b/src/UI/Components/HeadCeiling/HeadCeiling.less @@ -0,0 +1,216 @@ +#BulkheadCeilingConfig { + .bp3-dialog-body { + width : 430px; + min-height : 495px; + padding : 10px; + overflow : auto; + max-height : 600px; + + ul { + padding: 0; + margin : 0; + + .firstLi { + height: 25px; + + :first-child { + border-radius: 5px 0px 0px 0px; + } + + :last-child { + border-radius: 0px 5px 0px 0px; + } + + .bp3-label { + line-height: 2rem; + } + } + + li { + height : 30px; + display : flex; + font-size : 13px; + text-align: center; + + .bp3-label { + margin : 0; + line-height : 2.2rem; + border-right: 1.5px solid #AAAAAA; + border-top : 1.5px solid #AAAAAA; + border-left : 1.5px solid #AAAAAA; + + &>div { + margin: 1px; + height: -webkit-fill-available; + } + } + + &>:first-child { + width : 50px; + border-right: 0px; + } + + &>:nth-child(2) { + width : 70px; + border-right: 0px + } + + &>:last-child { + width: 100%; + } + + .bp3-html-select { + margin: 1px; + + select { + height: 26px; + } + + .bp3-icon-caret-down { + top: 5px; + } + } + } + + &>:last-child { + &>:first-child { + border-radius: 0px 0px 0px 5px; + } + + &>:last-child { + border-radius: 0px 0px 5px 0px; + } + + .bp3-label { + border-bottom: 1.5px solid #AAAAAA; + } + } + + .material_detail { + display : flex; + white-space : nowrap; + justify-content: space-between; + + .detail_name{ + width : 70%; + display: flex; + + .materialName{ + width : 110px; + overflow : hidden; + text-align : left; + text-overflow: ellipsis; + } + } + + .detail_type{ + width : 100px; + display: flex; + + .materialType{ + width : 65px; + overflow : hidden; + text-align : left; + text-overflow: ellipsis; + } + } + } + + .contour_detail { + position: relative; + display : flex; + + .detail_logo { + height: 100%; + width : 38%; + + display : flex; + align-items : center; + justify-content: space-evenly; + svg { + margin : -19px; + transform: scale(0.5); + } + } + + .detail_name { + width : 62%; + display : flex; + align-items:center; + } + } + } + + .itemContour { + display : flex; + justify-content: space-between; + + &>div { + width: 100%; + } + + .bp3-button { + width : 50px; + padding : 0px; + margin : 1px 2px; + font-size : 12px; + min-height: unset; + + .bp3-button-text{ + margin-top: 2px; + } + } + } + + .contourLi { + height: 65px; + + :nth-child(1) { + display : flex; + align-items : center; + justify-content: center; + } + + .backgroudColor { + height: 28px; + width : 100%; + } + + .bp3-html-select { + .bp3-icon-caret-down { + top: 23px; + } + } + + .detail_name { + span{ + width: 65px; + } + } + + .materialName{ + width : 110px; + overflow : hidden; + text-align : left; + text-overflow: ellipsis; + } + } + } + + .bp3-dialog-footer { + .bp3-dialog-footer-actions { + justify-content: space-between; + } + + .bp3-button { + margin-left: 3px; + } + } +} + +.headCeilingContourManage{ + .bp3-dialog-body{ + width: 1000px; + height: 700px; + } +} \ No newline at end of file diff --git a/src/UI/Components/HeadCeiling/HeadCeilingContourList.tsx b/src/UI/Components/HeadCeiling/HeadCeilingContourList.tsx new file mode 100644 index 000000000..ffa159e97 --- /dev/null +++ b/src/UI/Components/HeadCeiling/HeadCeilingContourList.tsx @@ -0,0 +1,106 @@ +import { ContextMenu, Intent, Menu, MenuItem } from '@blueprintjs/core'; +import { IObservableValue } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { ToplineUrls } from '../../../Common/HostUrl'; +import { PostJson, RequestStatus } from '../../../Common/Request'; +import { inflateBase64 } from '../../../Common/inflate'; +import { CADFiler } from '../../../DatabaseServices/CADFiler'; +import { Database } from '../../../DatabaseServices/Database'; +import { Arc } from '../../../DatabaseServices/Entity/Arc'; +import { Line } from '../../../DatabaseServices/Entity/Line'; +import { Polyline } from '../../../DatabaseServices/Entity/Polyline'; +import { DataList } from '../Common/Datalist'; +import { IDirectoryProps } from '../SourceManage/CommonPanel'; + +export interface HeadCeilingListProps +{ + deleteFun?: (topline?: { topline_id; }) => void; + dataList?: any[]; + select?: (e: React.FormEvent, data: any) => void; + // draw: (id: string) => void; + getData?: () => void; + selectIds?: Set; + showInfos?: boolean; + isRename: IObservableValue; + editorCeilingContour?: (curves: (Polyline | Line | Arc)[], name?: string, currentDir?: IDirectoryProps, database?: Database) => void; + currentHeadCeilingInfo: { id: string, name: string; }; +} + +@observer +export class HeadCeilingContourList extends React.Component { + constructor(props) + { + super(props); + this.state = { + isContextMenuOpen: false + }; + } + _HandleMounseDown = (e: React.MouseEvent, tpline: any) => + { + this.props.currentHeadCeilingInfo.id = tpline.topline_id; + this.props.currentHeadCeilingInfo.name = tpline.name; + }; + + _HandleEditor = async () => + { + let data = await PostJson(ToplineUrls.detail, { topline_id: this.props.currentHeadCeilingInfo.id }); + + if (data.err_code === RequestStatus.Ok) + { + let json = inflateBase64(data.toplines.file); + let f = new CADFiler(JSON.parse(json)); + let saveDb = new Database(false, false, true); + saveDb.FileRead(f); + let curves = saveDb.ModelSpace.Entitys as (Polyline | Line | Arc)[]; + this.props.editorCeilingContour(curves, null, null, saveDb); + } + }; + + //展示右键菜单 + _ShowContextMenu = (e: React.MouseEvent, tpline) => + { + if (!tpline) return; + ContextMenu.show( + + this.props.isRename.set(true)} + /> + + { this.props.deleteFun(); }} + /> + , + { left: e.clientX, top: e.clientY }, + () => this.setState({ isContextMenuOpen: false }), + ); + this.setState({ isContextMenuOpen: true }); + + e.stopPropagation(); + e.preventDefault(); + }; + public render() + { + return ( + + ); + } +} diff --git a/src/UI/Components/HeadCeiling/HeadCeilingContourManage.tsx b/src/UI/Components/HeadCeiling/HeadCeilingContourManage.tsx new file mode 100644 index 000000000..ad8fa7429 --- /dev/null +++ b/src/UI/Components/HeadCeiling/HeadCeilingContourManage.tsx @@ -0,0 +1,483 @@ +import { Button, Classes, Intent, MenuItem } from '@blueprintjs/core'; +import { observable } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { Matrix4, Vector3 } from 'three'; +import { ViewChange } from '../../../Add-on/ViewChange'; +import { app } from '../../../ApplicationServices/Application'; +import { MaterialUrls, ToplineUrls } from '../../../Common/HostUrl'; +import { DirectoryId, PostJson, RequestStatus } from '../../../Common/Request'; +import { deflate, getPolylineSVG } from '../../../Common/SerializeMaterial'; +import { DuplicateRecordCloning } from '../../../Common/Status'; +import { GetEntity } from '../../../Common/Utils'; +import { CADFiler } from '../../../DatabaseServices/CADFiler'; +import { Contour } from '../../../DatabaseServices/Contour'; +import { Database } from '../../../DatabaseServices/Database'; +import { Arc } from '../../../DatabaseServices/Entity/Arc'; +import { Line } from '../../../DatabaseServices/Entity/Line'; +import { Polyline } from '../../../DatabaseServices/Entity/Polyline'; +import { ObjectId } from '../../../DatabaseServices/ObjectId'; +import { BulkheadCeilingShapeTemplateExtendData } from '../../../DatabaseServices/Room/Entity/Ceiling/BulkheadCeilingShapeExtendData'; +import { TemplateRecord } from '../../../DatabaseServices/Template/TemplateRecord'; +import { WblockCloneFiler } from '../../../DatabaseServices/WblockCloneFiler'; +import { CommandWrap } from '../../../Editor/CommandMachine'; +import { CommandState } from '../../../Editor/CommandState'; +import { PromptStatus } from '../../../Editor/PromptResult'; +import { TempEditor } from '../../../Editor/TempEditor'; +import { ZAxisN } from '../../../Geometry/GeUtils'; +import { HeadCeilingProfileMaterialStore, NONE_MATERIAL_ID } from '../../Store/HeadCeilingStore/HeadCeilingMaterialStore'; +import { BoardModalType } from '../Board/BoardModalType'; +import { DialogUserConfig } from '../Board/UserConfigComponent'; +import { ModalContainer, ModalHeader } from '../Modal/ModalContainer'; +import { ModalPosition } from '../Modal/ModalInterface'; +import { CommonPanel, IDirectoryProps } from '../SourceManage/CommonPanel'; +import { HandleDirComponent } from '../SourceManage/HandleDirComponent'; +import { AppToaster } from '../Toaster'; +import './HeadCeiling.less'; +import { HeadCeilingContourList } from './HeadCeilingContourList'; +import { HeadCeilingInfoConfigPanel } from './HeadCeilingInfoConfigPanel'; + + +/** + * 吊顶轮廓管理界面 + */ +@observer +export class HeadCeilingContourManage extends React.Component<{}> { + constructor(props) + { + super(props); + this.state = { + defaultDirName: "" + }; + } + _CanCreateCeilingContour = observable.box(false); + _CameraFiler: CADFiler; + _BulkheadCeilingStore = HeadCeilingProfileMaterialStore.GetInstance(); + @observable _CurrentHeadCeilingInfo = { id: "", name: "" }; + + //创建吊顶轮廓 + _CreateCeilingContour = async (name: string, currentDir: IDirectoryProps, callback: Function) => + { + if (!name.trim()) + { + AppToaster.show({ + message: "名称不能为空", + intent: Intent.DANGER, + timeout: 1000 + }); + return; + } + + if (this._CurrentHeadCeilingInfo.id) + { + await this._RenameBulkheadCeiling(name); + await callback(); + } + else + { + if (!currentDir) + { + AppToaster.show({ + message: "未知错误,请重试", + timeout: 1000 + }); + return; + } + + if (!app.Viewer.CameraCtrl.Direction.equals(new Vector3(0, 0, -1))) + { + await new ViewChange(ZAxisN, true).exec(); + AppToaster.show({ + message: "自动切换至俯视视角!", + timeout: 5000, + intent: Intent.PRIMARY, + }); + } + + app.Editor.ModalManage.ToggleShow(); + app.Editor.MaskManage.Clear(); + + //选择吊顶轮廓 + let contourEnts = await this._SelectCeilingContour(); + + app.Editor.ModalManage.ToggleShow(); + app.Editor.MaskManage.ShowMask(); + + if (contourEnts.length === 0) return; + //对选择的吊顶轮廓进行编辑后上传 + this._EditorCeilingContour(contourEnts, name, currentDir); + } + }; + + //选择吊顶轮廓 + async _SelectCeilingContour(): Promise<(Polyline | Line | Arc)[]> + { + let ents: (Polyline | Line | Arc)[] = []; + + await CommandWrap(async () => + { + let ssRes = await app.Editor.GetSelection({ Filter: { filterTypes: [Polyline, Line, Arc] } }); + if (ssRes.Status !== PromptStatus.OK) return []; + ents = ssRes.SelectSet.SelectEntityList as (Polyline | Line | Arc)[]; + + let contour = Contour.CreateContour(ents, true); + if (!contour) + { + //警告错误 无法组成封闭的轮廓 + AppToaster.show({ + message: "无法组成封闭的轮廓", + intent: Intent.DANGER, + timeout: 3000, + }); + ents = []; + } + }, "选择吊顶轮廓"); + + return ents; + }; + + //对选择的吊顶轮廓进行编辑 + _EditorCeilingContour = async (curves: (Polyline | Line | Arc)[], name?: string, currentDir?: IDirectoryProps, database?: Database) => + { + if (TempEditor.EditorIng || CommandState.CommandIng) + { + AppToaster.show({ + message: "当前正处于编辑模式下", + timeout: 3000, + intent: Intent.WARNING, + }); + return; + } + + app.Editor.ModalManage.DestoryAll(); + + TempEditor.Start(); + + if (!app.Viewer.CameraCtrl.Direction.equals(new Vector3(0, 0, -1))) + app.Viewer.CameraCtrl.LookAt(new Vector3(0, 0, -1)); + + let config = new DialogUserConfig(this._BulkheadCeilingStore, BoardModalType.HeadCeilingProfileMaterial); + await config.LoadAndInitConfig(true); + + //呼出吊顶材质对应的颜色面板 + app.Editor.ModalManage.RenderModeless( + HeadCeilingInfoConfigPanel, + { store: this._BulkheadCeilingStore, directoryId: DirectoryId.MaterialDir, configType: BoardModalType.HeadCeilingProfileMaterial, isNotUpdateStore: true, noClose: true }, + { position: ModalPosition.RightMid, canMinimize: false } + ); + + let extData = new BulkheadCeilingShapeTemplateExtendData; + if (database?.ExtendedData) + { + let f = new CADFiler(database.ExtendedData); + extData.ReadFile(f); + + await this._BulkheadCeilingStore.InitEditorMaterialItems(extData); + } + + await CommandWrap(async () => + { + let newCurves: (Polyline | Arc | Line)[] = []; + + for (let curve of curves) + { + let cu = curve.Clone(); + cu.ColorIndex = extData.Color_MaterialId.get(cu.ColorIndex); + + app.Database.ModelSpace.Append(cu); + newCurves.push(cu); + } + + app.Database.hm.lockIndex++;//禁止初始化动作被撤销 + this._CameraFiler = new CADFiler; + app.Viewer.CameraCtrl.WriteFile(this._CameraFiler); + + app.Viewer.ZoomtoEntitys(newCurves); + + AppToaster.show({ + message: this._RenderToasterMessage(name, currentDir, database), + intent: Intent.PRIMARY, + timeout: 0, + onDismiss: this._ExitEditor + }, "编辑吊顶轮廓"); + + }, "编辑吊顶轮廓"); + }; + + _RenderToasterMessage = (name: string, currentDir: IDirectoryProps, database?: Database) => + { + return ( +
+ 正在编辑吊顶轮廓,请确保轮廓为闭合多段线 +
+
+
+ ); + }; + + //退出轮廓编辑 + _ExitEditor = async () => + { + app.Editor.ModalManage.DestoryAll(); + await app.Editor.ModalManage.EndExecingCmd(); + if (!this._CameraFiler) return; + app.Viewer.CameraCtrl.ReadFile(this._CameraFiler); + TempEditor.End(); + this._CameraFiler = undefined; + app.Editor.ModalManage.RenderModal(HeadCeilingContourManage); + }; + + //上传吊顶轮廓(点击上方保存) + async _AddCeilingContourToDb(name: string, currentDir: IDirectoryProps, database?: Database): Promise + { + let finalCurve: (Polyline | Line | Arc)[] = []; + //因为临时编辑器会新建一个场景,只需要遍历这个场景内的对象就可以了 + for (let obj of app.Viewer.Scene.children) + { + if (obj.visible) + { + let en = GetEntity(obj); + + if (en && en.Id?.Object && en.Visible && !en.IsErase && (en instanceof Polyline || en instanceof Line || en instanceof Arc)) + finalCurve.push(en); + } + } + + let contour = Contour.CreateContour(finalCurve, true); + if (!contour) + { + //警告错误 无法组成封闭的轮廓 + AppToaster.show({ + message: "无法组成封闭的轮廓", + intent: Intent.DANGER, + timeout: 3000, + }); + return; + } + + //拓展数据(材质槽信息) + let extData = new BulkheadCeilingShapeTemplateExtendData(); + + for (let curve of finalCurve) + { + if (extData.Color_MaterialId.has(curve.ColorIndex)) continue; + + //根据UI面板对照获取材质id + let material_id = this._BulkheadCeilingStore.m_Option.Item[curve.ColorIndex - 1]?.example?.id; + if (material_id && material_id !== NONE_MATERIAL_ID) + { + //验证材质是否可用 + let mtlData = await PostJson(MaterialUrls.detail, { material_id: material_id.toString() }); + if (mtlData.err_code === RequestStatus.Ok) + extData.Color_MaterialId.set(curve.ColorIndex, material_id); + else + return; + } + else + extData.Color_MaterialId.set(curve.ColorIndex, NONE_MATERIAL_ID); + } + + let f = new CADFiler; + extData.WriteFile(f); + + + let tempaltes = new Set; + for (let e of finalCurve) + tempaltes.add((e.Template?.Object as TemplateRecord)?.Root?.objectId); + + if (tempaltes.size > 1) + { + let keyRes = await app.Editor.GetKeyWords({ + Msg: "选择的图形中来自不同的模块,忽略所有模块信息并继续?", + KeyWordList: [ + { + key: "1", + msg: "好" + }, + { + key: "2", + msg: "算了" + }, + ] + }); + + if (keyRes.StringResult !== "1") + return; + } + + AppToaster.show({ + message: "请点选该轮廓基点!", + timeout: 3000, + intent: Intent.PRIMARY, + }, "getPoint"); + + let res = await app.Editor.GetPoint({ + Msg: "指定基点" + }); + + if (res.Status === PromptStatus.Cancel) + return; + + let point = res.Point.negate(); + + let saveDb = new Database(false, false, true); + if (database) + { + saveDb = database; + saveDb.ModelSpace.Destroy(); + saveDb.TemplateTable.Destroy(); + saveDb.MaterialTable.Destroy(); + } + + if (tempaltes.size > 1 || [...tempaltes][0] === undefined) + { + let template = new TemplateRecord; + saveDb.TemplateTable.Add(template); + for (let e of finalCurve) + { + let newE = e.Clone().ApplyMatrix(new Matrix4().setPosition(point)); + saveDb.ModelSpace.Append(newE); + template.Objects.push(newE.Id); + } + } + else + { + let template = [...tempaltes][0]; + saveDb.WblockCloneObejcts([template.Object], saveDb.TemplateTable, new Map, DuplicateRecordCloning.Ignore, new WblockCloneFiler); + } + + saveDb.ExtendedData = f.Data; + + let logo = getPolylineSVG(contour.Curve as Polyline); + let fileJson = saveDb.FileWrite().ToString(); + + let data: { err_code: RequestStatus; }; + if (this._CurrentHeadCeilingInfo.id) + { + data = await PostJson(ToplineUrls.update, { + topline_id: this._CurrentHeadCeilingInfo.id, + logo, + file: deflate(fileJson), + zip_type: "gzip", + }); + } + else + { + data = await PostJson(ToplineUrls.create, { + dir_id: currentDir.id, + name, + logo, + file: deflate(fileJson), + zip_type: "gzip", + }); + } + + AppToaster.dismiss("编辑吊顶轮廓"); + + if (data.err_code === RequestStatus.Ok) + { + AppToaster.show({ + message: this._CurrentHeadCeilingInfo.id ? "编辑成功!" : "添加成功!", + timeout: 2000, + intent: Intent.SUCCESS, + }); + } + }; + + //吊顶轮廓重命名 + _RenameBulkheadCeiling = async (name: string) => + { + let data = await PostJson(ToplineUrls.update, { + topline_id: this._CurrentHeadCeilingInfo.id, + name + }); + if (data.code === RequestStatus.Ok) + { + AppToaster.show({ + message: "重命名成功", + timeout: 1000 + }); + } + this._CanCreateCeilingContour.set(false); + }; + + _StartCreateHeadCeilingContour = () => + { + this._CurrentHeadCeilingInfo.id = ""; + this._CurrentHeadCeilingInfo.name = ""; + this._CanCreateCeilingContour.set(true); + }; + + _RenderNav = () => + { + return ( +