diff --git a/__test__/Room/Get_RoomRegion_Walls.test.ts b/__test__/Room/Get_RoomRegion_Walls.test.ts new file mode 100644 index 000000000..990ab3102 --- /dev/null +++ b/__test__/Room/Get_RoomRegion_Walls.test.ts @@ -0,0 +1,46 @@ +import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; + +import { Database } from "../../src/DatabaseServices/Database"; +import { Curve } from "../../src/DatabaseServices/Entity/Curve"; +import { RoomRegion } from "../../src/DatabaseServices/Room/Entity/Region/RoomRegion"; +import { CURVE_DIR_TYPE_KEY, CURVE_WALL_TYPE_KEY, RoomWallBase } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallBase"; +import { RoomWallLine } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallLine"; +import { ROOM_REGION_CURVES_KEY, WallCurveDirType } from "../../src/DatabaseServices/Room/ParseService/RoomRegionParse"; +import { RoomWallParse } from "../../src/DatabaseServices/Room/ParseService/RoomWallParse"; + +// file.only + +test('分析房间和墙的关系', () => +{ + let d = + { "file": [6, "RoomWallLine", 1, 3, 8, 2, 100, 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, 240, 0, 2700, 729.5325838779954, 5977.297245098039, 0, 729.5325838779954, -183.96925490196065, 0, "RoomWallLine", 1, 3, 8, 2, 101, 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, 240, 0, 2700, 729.5325838779954, -183.96925490196065, 0, 9350.869283877995, -183.96925490196065, 0, "RoomWallLine", 1, 3, 8, 2, 102, 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, 240, 0, 2700, 9350.869283877995, -183.96925490196065, 0, 9350.869283877995, 5977.297245098039, 0, "RoomWallLine", 1, 3, 8, 2, 103, 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, 240, 0, 2700, 9350.869283877995, 5977.297245098039, 0, 729.5325838779954, 5977.297245098039, 0, "RoomWallLine", 1, 3, 8, 2, 107, 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, 240, 0, 2700, 5040.200933877995, 5977.297245098039, 0, 5040.200933877995, -183.96925490196065, 0, "RoomWallLine", 1, 3, 8, 2, 111, 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, 240, 0, 2700, 5040.200933877995, 2896.663995098039, 0, 9350.869283877995, 2896.6639950980393, 0], "basePt": { "x": 609.5325838779954, "y": -303.96925490196065, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1] }; + + let walls: RoomWallLine[] = LoadEntityFromFileData(d); + + let db = new Database; + + for (let w of walls) db.ModelSpace.Append(w); + + let parse = new RoomWallParse(true, db, false).Parse(walls); + + + for (let e of db.ModelSpace.Entitys) + { + if (e instanceof RoomRegion) + { + let roomRegion: RoomRegion = e; + + let curves = roomRegion[ROOM_REGION_CURVES_KEY] as Curve[]; + + curves.length; //? + + for (let c of curves) + { + let curve_at_wall_dir = c[CURVE_DIR_TYPE_KEY] as WallCurveDirType;//曲线在墙体内的方向 左侧 右侧 还是盖子 + console.log(curve_at_wall_dir); + let curve_at_wall = c[CURVE_WALL_TYPE_KEY] as RoomWallBase;//曲线在哪个墙体里面 + console.log(curve_at_wall.Id.Index); + } + } + } +}); diff --git a/src/DatabaseServices/Room/Entity/Wall/RoomWallBase.ts b/src/DatabaseServices/Room/Entity/Wall/RoomWallBase.ts index cbb0e1c7f..2ea8f6405 100644 --- a/src/DatabaseServices/Room/Entity/Wall/RoomWallBase.ts +++ b/src/DatabaseServices/Room/Entity/Wall/RoomWallBase.ts @@ -16,6 +16,8 @@ import { RoomHolePolyline } from "./Hole/RoomHolePolyline"; import { WallSnapMode } from "./WallSnapMode"; export const CURVE_FACE_TYPE_KEY = "__CURVE_FACE_TYPE_KEY__";//用来存储墙体类型的key +export const CURVE_DIR_TYPE_KEY = "__CURVE_DIR_TYPE_KEY__";//方向 +export const CURVE_WALL_TYPE_KEY = "__CURVE_WALL_TYPE_KEY__";//墙 export enum WallFaceType { diff --git a/src/DatabaseServices/Room/ParseService/RoomRegionParse.ts b/src/DatabaseServices/Room/ParseService/RoomRegionParse.ts index 2484c7805..40cd116c9 100644 --- a/src/DatabaseServices/Room/ParseService/RoomRegionParse.ts +++ b/src/DatabaseServices/Room/ParseService/RoomRegionParse.ts @@ -11,7 +11,7 @@ import { UpdateTempPolyline } from "../Entity/Flat/RoomFlatBase"; import { RoomFlatFloor } from "../Entity/Flat/RoomFlatFloor"; import { RoomFlatTop } from "../Entity/Flat/RoomFlatTop"; import { RoomRegion } from "../Entity/Region/RoomRegion"; -import { CURVE_FACE_TYPE_KEY, RoomWallBase, WallFaceType } from "../Entity/Wall/RoomWallBase"; +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"; @@ -26,6 +26,17 @@ import { RegionReplacement } from "./RegionReplacement"; //区域对象 (地面+天花?) +export const ROOM_REGION_CURVES_KEY = "__ROOM_REGION_CURVES_KEY__"; + + +//墙内曲线的类型 +export enum WallCurveDirType +{ + left = 0, + right = 1, + lid = 2, +} + /** * 区域分析(房间+外墙+全屋顶) @@ -72,20 +83,30 @@ export class RoomRegionParse { curves.push(c); leftCurves.add(c); + c[CURVE_DIR_TYPE_KEY] = WallCurveDirType.left; + c[CURVE_WALL_TYPE_KEY] = wall; } for (let c of wall.RightCurves) + { curves.push(c); + c[CURVE_DIR_TYPE_KEY] = WallCurveDirType.right; + c[CURVE_WALL_TYPE_KEY] = wall; + } for (let c of wall.LidCurves) + { curves.push(c); + c[CURVE_DIR_TYPE_KEY] = WallCurveDirType.lid; + c[CURVE_WALL_TYPE_KEY] = wall; + } } const REGION_PARSE_NUM = 3; const POLYLINE_JOIN_FUZZ = Math.pow(10, -REGION_PARSE_NUM); - let parse = new RegionParse(curves, REGION_PARSE_NUM); + let regParse = new RegionParse(curves, REGION_PARSE_NUM); - for (let [orgArc, arcs] of parse.ExpLineMap) + for (let [orgArc, arcs] of regParse.ExpLineMap) { if (leftCurves.has(orgArc)) for (let arc of arcs) @@ -94,9 +115,10 @@ export class RoomRegionParse let regionPolylines: Polyline[] = []; - let map = new Map(); + let regPolyline2RoutesMap = new Map();//区域轮廓多段线->墙线 映射 + //分析内外墙1内2外 - for (let routes of parse.RegionsOutline) + for (let routes of regParse.RegionsOutline) { let pl = Polyline.Combine(routes.map(r => r.curve), POLYLINE_JOIN_FUZZ); @@ -114,17 +136,27 @@ export class RoomRegionParse // TestDraw(routes[0].curve); //test regionPolylines.push(pl); - map.set(pl, routes); + regPolyline2RoutesMap.set(pl, routes); } //不可能有内部轮廓 如果有 就证明错了 - for (let routes of parse.RegionsInternal) + for (let routes of regParse.RegionsInternal) { let pl = Polyline.Combine(routes.map(r => r.curve)); pl.ColorIndex = pl.Area2 > 0 ? 3 : 4; // throw "未知错误 出现外部轮廓" } + //面域分析炸开的线和原始轮廓的关联关系 + for (let [orgArc, newArcs] of regParse.ExpLineMap) + { + for (let arc of newArcs) + { + arc[CURVE_DIR_TYPE_KEY] = orgArc[CURVE_DIR_TYPE_KEY]; + arc[CURVE_WALL_TYPE_KEY] = orgArc[CURVE_WALL_TYPE_KEY]; + } + } + let cons = regionPolylines.map(pl => new ContourTreeNode(Contour.CreateContour(pl, false))); ContourTreeNode.ParseContourTree(cons); @@ -133,7 +165,7 @@ export class RoomRegionParse //解析 天花板区域 内空区域 for (let con of cons) { - let routes = map.get(con.contour.Curve as Polyline); + let routes = regPolyline2RoutesMap.get(con.contour.Curve as Polyline); if (con.contour.Curve.ColorIndex === 2)//天花板区域(或者柱子) { if (con.Depth !== 0 || con.area < 1e6)//柱子 @@ -219,6 +251,7 @@ export class RoomRegionParse this._UpdateDb.ModelSpace.Append(floor); this._UpdateDb.ModelSpace.Append(top); let region = new RoomRegion(name, top.Id, floor.Id, floor.Area); + region[ROOM_REGION_CURVES_KEY] = routes.map(r => r.curve); region.Position = pos; this._UpdateDb.ModelSpace.Append(region); floor.RegionId = region.Id; @@ -227,8 +260,8 @@ export class RoomRegionParse } } - for (let [orgArc, arcs] of parse.ExpLineMap) - orgArc[CURVE_FACE_TYPE_KEY] = arcs[0][CURVE_FACE_TYPE_KEY]; + for (let [orgArc, arcs] of regParse.ExpLineMap) + orgArc[CURVE_FACE_TYPE_KEY] = arcs[0][CURVE_FACE_TYPE_KEY];//圆弧不可能被两个房间拥有,所以这个写法没问题 for (let wall of walls) {