diff --git a/__test__/Room/RoomParse.test.ts b/__test__/Room/RoomParse.test.ts index 1e58b99ce..1ae78d71c 100644 --- a/__test__/Room/RoomParse.test.ts +++ b/__test__/Room/RoomParse.test.ts @@ -291,3 +291,13 @@ test('当墙线无法连接时,如何正确的构造补盖子', () => TestWallCurveParse(walls); }); + +test('精度导致0.02线丢失导致区域丢失', () => +{ + let d = + { "file": [7, "RoomWallLine", 1, 3, 8, 2, 113, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 120, 0, 2700, 36684.65714498695, 6147.320275722739, 0, 36684.65714498695, -51.88108393827861, 0, "RoomWallLine", 1, 3, 8, 2, 118, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 120, 0, 2700, 42738.506121433034, 6087.320275722739, 0, 36625.65714498695, 6087.320275722739, 0, "RoomWallLine", 1, 3, 8, 2, 117, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 120, 0, 2700, 42738.506121433034, 3309.5257186513045, 0, 42738.506121433034, 6087.320275722739, 0, "RoomWallLine", 1, 3, 8, 2, 122, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 120, 0, 2700, 36684.65714498695, 43.94864216606105, 0, 42738.506121433034, 3309.5257186513045, 0, "RoomWallLine", 1, 3, 8, 2, 116, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 120, 0, 2700, 47479.48970448707, 3309.5257186513045, 0, 42738.506121433034, 3309.5257186513045, 0, "RoomWallLine", 1, 3, 8, 2, 115, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 120, 0, 2700, 47479.48970448707, -51.88108393827906, 0, 47479.48970448707, 3309.5257186513045, 0, "RoomWallLine", 1, 3, 8, 2, 114, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 120, 0, 2700, 36684.65714498695, -51.88108393827861, 0, 47479.48970448707, -51.88108393827906, 0], "basePt": { "x": 36624.65714498695, "y": -111.88108393827906, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + + let walls = LoadEntityFromFileData(d); + + TestWallCurveParse(walls); +}); diff --git a/__test__/Room/__snapshots__/RoomParse.test.ts.snap b/__test__/Room/__snapshots__/RoomParse.test.ts.snap index 8d03f3ec4..53a4351f0 100644 --- a/__test__/Room/__snapshots__/RoomParse.test.ts.snap +++ b/__test__/Room/__snapshots__/RoomParse.test.ts.snap @@ -1821,3 +1821,131 @@ Array [ 0, ] `; + +exports[`精度导致0.02线丢失导致区域丢失 1`] = ` +Array [ + 0, + -5882.833669024325, + 0, +] +`; + +exports[`精度导致0.02线丢失导致区域丢失 2`] = ` +Array [ + 0, + -0.022357049821039254, + 0, +] +`; + +exports[`精度导致0.02线丢失导致区域丢失 3`] = ` +Array [ + 0, + -6259.201359661018, + 0, +] +`; + +exports[`精度导致0.02线丢失导致区域丢失 4`] = ` +Array [ + -1, + 0, + 0, +] +`; + +exports[`精度导致0.02线丢失导致区域丢失 5`] = ` +Array [ + -5933.848976446083, + 0, + 0, +] +`; + +exports[`精度导致0.02线丢失导致区域丢失 6`] = ` +Array [ + -6172.848976446083, + 0, + 0, +] +`; + +exports[`精度导致0.02线丢失导致区域丢失 7`] = ` +Array [ + 0, + 2681.9871880169153, + 0, +] +`; + +exports[`精度导致0.02线丢失导致区域丢失 8`] = ` +Array [ + 0, + 2777.7945570714346, + 0, +] +`; + +exports[`精度导致0.02线丢失导致区域丢失 9`] = ` +Array [ + 5933.848976446083, + 3200.846481007409, + 0, +] +`; + +exports[`精度导致0.02线丢失导致区域丢失 10`] = ` +Array [ + 6008.999771954339, + 3241.3844455397625, + 0, +] +`; + +exports[`精度导致0.02线丢失导致区域丢失 11`] = ` +Array [ + -4665.832787545776, + 0, + 0, +] +`; + +exports[`精度导致0.02线丢失导致区域丢失 12`] = ` +Array [ + -4740.983583054032, + 0, + 0, +] +`; + +exports[`精度导致0.02线丢失导致区域丢失 13`] = ` +Array [ + 0, + 3241.4068025895835, + 0, +] +`; + +exports[`精度导致0.02线丢失导致区域丢失 14`] = ` +Array [ + 0, + 3481.4068025895835, + 0, +] +`; + +exports[`精度导致0.02线丢失导致区域丢失 15`] = ` +Array [ + 10674.832559500115, + -4.547473508864641e-13, + 0, +] +`; + +exports[`精度导致0.02线丢失导致区域丢失 16`] = ` +Array [ + 10914.832559500115, + -4.547473508864641e-13, + 0, +] +`; diff --git a/src/Add-on/ExportData.tsx b/src/Add-on/ExportData.tsx index a65d984fa..332ca3d15 100644 --- a/src/Add-on/ExportData.tsx +++ b/src/Add-on/ExportData.tsx @@ -38,10 +38,12 @@ import { PhysicalMaterialRecord } from "../DatabaseServices/PhysicalMaterialReco import { RoomFlatBase } from '../DatabaseServices/Room/Entity/Flat/RoomFlatBase'; import { RoomHolePolyline } from '../DatabaseServices/Room/Entity/Wall/Hole/RoomHolePolyline'; import { RoomWallBase } from '../DatabaseServices/Room/Entity/Wall/RoomWallBase'; +import { RoomWallParse } from '../DatabaseServices/Room/ParseService/RoomWallParse'; import { Shape } from "../DatabaseServices/Shape"; import { TextureTableRecord } from "../DatabaseServices/Texture"; import { Command } from "../Editor/CommandMachine"; import { PromptSsgetResult, PromptStatus } from "../Editor/PromptResult"; +import { IdentityMtx4 } from '../Geometry/GeUtils'; import { Orbit } from '../Geometry/Orbit'; import { RenderType } from '../GraphicsSystem/RenderType'; import { arrayPushArray } from '../Nest/Common/ArrayExt'; @@ -149,6 +151,8 @@ export class Command_ExportData implements Command let ents = ssRes.SelectSet.SelectEntityList; ents.push(app.Database.SunLight, app.Database.HemisphereLight);//保证传递灯光参数 let d = Entitys2Data(ents); + if (ents.some(e => e instanceof RoomWallBase)) + d.Entitys.push(ConverRoomRoof2Data()); d.Clear = isClear; AppendUserInfo(d); let dstr = JSON.stringify(d); @@ -740,6 +744,23 @@ function ConverRoomFlat2Data(roomEnt: RoomFlatBase) return ed; } +function ConverRoomRoof2Data() +{ + let ed: any = {}; + ed.Id = 69; + ed.Type = "RoomRoof"; + ed.OCS = IdentityMtx4.elements; + ed.MaterialId = 71; + + let f = new CADFiler; + f.Write(RoomWallParse._CacheRoofs.length); + for (let c of RoomWallParse._CacheRoofs) + f.WriteObject(c); + + ed.Data = f.Data; + return ed; +} + //OBJ文件 const objExport = new OBJExporter; function GetOBJFileData(en: Entity): string diff --git a/src/DatabaseServices/Room/ParseService/CurveTrim.ts b/src/DatabaseServices/Room/ParseService/CurveTrim.ts index 9818b5cb5..37b3ac307 100644 --- a/src/DatabaseServices/Room/ParseService/CurveTrim.ts +++ b/src/DatabaseServices/Room/ParseService/CurveTrim.ts @@ -26,10 +26,10 @@ export class CurveTrim if (this._IsErase) return; //交点参数列表 - let iParams = this._curve.IntersectWith2(contour.Curve, IntersectOption.ExtendNone).map(p => p.thisParam).filter(p => p > 1e-4 && p < 0.9999); + let iParams = this._curve.IntersectWith2(contour.Curve, IntersectOption.ExtendNone).map(p => p.thisParam).filter(p => p > 1e-6 && p < 0.999999); iParams.push(0, 1); iParams.sort((a, b) => a - b); - arrayRemoveDuplicateBySort(iParams, (a1, a2) => equaln(a1, a2, 1e-4)); + arrayRemoveDuplicateBySort(iParams, (a1, a2) => equaln(a1, a2, 1e-6)); if (iParams.length === 2)//[0,1]全包含 或者在外部 { diff --git a/src/DatabaseServices/Room/ParseService/RoomRegionParse.ts b/src/DatabaseServices/Room/ParseService/RoomRegionParse.ts index 30560ded4..dde0ddcb1 100644 --- a/src/DatabaseServices/Room/ParseService/RoomRegionParse.ts +++ b/src/DatabaseServices/Room/ParseService/RoomRegionParse.ts @@ -80,7 +80,10 @@ export class RoomRegionParse curves.push(c); } - let parse = new RegionParse(curves); + const REGION_PARSE_NUM = 3; + const POLYLINE_JOIN_FUZZ = Math.pow(10, -REGION_PARSE_NUM); + + let parse = new RegionParse(curves, REGION_PARSE_NUM); for (let [orgArc, arcs] of parse.ExpLineMap) { @@ -95,7 +98,7 @@ export class RoomRegionParse //分析内外墙1内2外 for (let routes of parse.RegionsOutline) { - let pl = Polyline.Combine(routes.map(r => r.curve), 1e-3); + let pl = Polyline.Combine(routes.map(r => r.curve), POLYLINE_JOIN_FUZZ); // for (let i = 0; i < routes.length; i++) // { @@ -125,6 +128,8 @@ export class RoomRegionParse let cons = regionPolylines.map(pl => new ContourTreeNode(Contour.CreateContour(pl, false))); ContourTreeNode.ParseContourTree(cons); + let roofs: Polyline[] = []; + //解析 天花板区域 内空区域 for (let con of cons) { @@ -138,7 +143,9 @@ export class RoomRegionParse for (let r of routes) r.curve[CURVE_FACE_TYPE_KEY] = WallFaceType.Outside; - //未来我们需要返回这个轮廓,以便在ue中可以绘制真正的屋顶 + //我们需要返回这个轮廓,以便在ue中可以绘制真正的屋顶 + con.contour.Curve.Z = maxZ; + roofs.push(con.contour.Curve as Polyline); } else if (con.contour.Curve.ColorIndex === 1)//内空区域 { @@ -229,6 +236,8 @@ export class RoomRegionParse // wall.RightCurves && arrayRemoveDuplicateBySort(wall.RightCurves, (cu1: Curve, cu2: Curve) => cu1.Join(cu2) === Status.True); wall.Update(); } + + return roofs; } End() diff --git a/src/DatabaseServices/Room/ParseService/RoomWallParse.ts b/src/DatabaseServices/Room/ParseService/RoomWallParse.ts index 7e10f4635..2a470047b 100644 --- a/src/DatabaseServices/Room/ParseService/RoomWallParse.ts +++ b/src/DatabaseServices/Room/ParseService/RoomWallParse.ts @@ -46,6 +46,7 @@ export class RoomWallParse static _CacheWallNodePoints: Vector3[] = []; static _CacheWallMaps: [RoomWallExtendAndBreak, CurveMap][] = []; static _CacheCurveWallMaps: Map = new Map(); + static _CacheRoofs: Polyline[] = []; /** * @param [_ExtendsWalls=true] 更新墙体,在开图时不更新图纸 @@ -68,6 +69,7 @@ export class RoomWallParse RoomWallParse._CacheWallNodePoints = []; RoomWallParse._CacheWallMaps = []; RoomWallParse._CacheCurveWallMaps = new Map(); + RoomWallParse._CacheRoofs = []; } let regionPrase = new RoomRegionParse(this._UpdateDb); @@ -95,7 +97,10 @@ export class RoomWallParse for (let [, walls] of zgroupMap) { this.PraseWallsFromSameFloor(walls, changeWalls); - regionPrase.Do(walls); + let roofs = regionPrase.Do(walls); + + if (this._IsCacheWallNodePoints) + arrayPushArray(RoomWallParse._CacheRoofs, roofs); } regionPrase.End();