!1893 功能:一些代码优化,包含墙洞实现

pull/1894/MERGE
ChenX 2 years ago
parent c777f4e646
commit 75cada6f6e

@ -143,3 +143,79 @@ Array [
],
]
`;
exports[`range2 1`] = `
Array [
Array [
0.5,
1,
],
Array [
0,
0.3,
],
]
`;
exports[`range2 2`] = `
Array [
Array [
0.5,
1,
],
Array [
0,
0.3,
],
]
`;
exports[`range2 3`] = `
Array [
Array [
0.8,
1,
],
Array [
0,
0.1,
],
]
`;
exports[`range2 4`] = `
Array [
Array [
0.9,
1,
],
Array [
0,
0.1,
],
]
`;
exports[`range2 5`] = `Array []`;
exports[`range2 6`] = `
Array [
Array [
0.1,
0.3,
],
Array [
0.6,
0.8,
],
]
`;
exports[`range2 7`] = `
Array [
Array [
0.1,
0.3,
],
]
`;

@ -1,4 +1,5 @@
import { InsertRangeAndUnion, RangeUnion } from "../../src/DatabaseServices/Room/ParseService/RangeUtils";
import { SubtractRange } from "../../src/Geometry/ExtrudeMeshGeomBuilder/ExtrudeEdgeGeometry2";
test('range', () =>
{
@ -31,3 +32,25 @@ test('range', () =>
expect(InsertRangeAndUnion([[0.2, 0.3], [0.4, 0.5]], 0.299999999, 0.35)).toMatchSnapshot();
});
test('range2', () =>
{
//0-1
expect(SubtractRange(0.5, 0.3, 0.3, 0.5, 1)).toMatchSnapshot();
//0-1
expect(SubtractRange(0.4, 0.3, 0.3, 0.5, 1)).toMatchSnapshot();
//[ [ 0.8, 0.1 ], [ 0.3, 0.5 ] ]
expect(SubtractRange(0.8, 0.1, 0.3, 0.5, 1)).toMatchSnapshot();
//[ 0.3, 0.10000000000000009 ] ]
expect(SubtractRange(0.8, 0.1, 0.3, 0.9, 1)).toMatchSnapshot();
expect(SubtractRange(0.8, 0.1, 0.4, 0.1, 1)).toMatchSnapshot();
expect(SubtractRange(0.1, 0.8, 0.3, 0.6, 1)).toMatchSnapshot();
expect(SubtractRange(0.1, 0.8, 0.3, 0.9, 1)).toMatchSnapshot();
});
// file.only

@ -6,7 +6,6 @@ import { RoomWallParse } from "../../src/DatabaseServices/Room/ParseService/Room
import "../Utils/jest.util";
import { LoadEntityFromFileData } from "../Utils/LoadEntity.util";
test('重叠墙分析丢失墙体', () =>
{
let d =
@ -34,14 +33,14 @@ test('测试盖子方向正确性', () =>
let walls = LoadEntityFromFileData<RoomWallLine>(d);
new RoomWallParse(true, undefined, false).Do(walls);
new RoomWallParse(true, undefined, false).Parse(walls);
for (let wall of walls)
TestLidDir(wall);
for (let wall of walls) wall.Reverse();
new RoomWallParse(true, undefined, false).Do(walls);
new RoomWallParse(true, undefined, false).Parse(walls);
for (let wall of walls)
TestLidDir(wall);
@ -54,19 +53,19 @@ test('共线墙盖子方向正确性', () =>
let walls = LoadEntityFromFileData<RoomWallLine>(d);
new RoomWallParse(true, undefined, false).Do(walls);
new RoomWallParse(true, undefined, false).Parse(walls);
for (let wall of walls)
TestLidDir(wall);
for (let wall of walls) wall.Reverse();
new RoomWallParse(true, undefined, false).Do(walls);
new RoomWallParse(true, undefined, false).Parse(walls);
for (let wall of walls)
TestLidDir(wall);
new RoomWallParse(true, undefined, false).Do([walls[0]]);
new RoomWallParse(true, undefined, false).Parse([walls[0]]);
});
function TestCurveDerv(c: Curve)
@ -76,7 +75,7 @@ function TestCurveDerv(c: Curve)
}
function TestWallCurveParse(walls: RoomWallBase[])
{
new RoomWallParse(true, undefined, false).Do(walls);
new RoomWallParse(true, undefined, false).Parse(walls);
for (let w of walls)
{
@ -130,7 +129,7 @@ test('大圆弧月牙', () =>
let walls = LoadEntityFromFileData<RoomWallArc>(d);
new RoomWallParse(true, undefined, false).Do(walls);
new RoomWallParse(true, undefined, false).Parse(walls);
TestWallCurveParse(walls);
});
@ -151,7 +150,7 @@ test('圆弧合集', () =>
let walls = LoadEntityFromFileData<RoomWallArc>(d);
new RoomWallParse(true, undefined, false).Do(walls);
new RoomWallParse(true, undefined, false).Parse(walls);
TestWallCurveParse(walls);
});
@ -187,7 +186,7 @@ test('因为面域分析导致的墙类型不对', () =>
{ "file": [2, "RoomWallLine", 1, 1, 8, 2, 146, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 25294.194645009495, -1243.0158909486802, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 25294.194645009495, -1243.0158909486802, 0, 1], 0, 120, 4540.8123335336095, 1690.993449999878, 0, 8037.34909787654, 3003.6781037037035, 0, "RoomWallArc", 1, 8, 2, 147, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 33875.59985973879, -98.25468714960243, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 33875.59985973879, -98.25468714960243, 0, 1], 0, 120, 2, 1936.89677036127, 1.8555182812506865, 4.681440295344441, true], "basePt": { "x": 29813.9186811755, "y": -2094.4402340246024, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let walls = LoadEntityFromFileData<RoomWallBase>(d);
new RoomWallParse(true, undefined, false).Do(walls);
new RoomWallParse(true, undefined, false).Parse(walls);
for (let w of walls)
{
w.LeftCurves.forEach(TestCurveType);
@ -213,10 +212,21 @@ test('墙厚度导致的破面', () =>
TestWallCurveParse(walls);
});
test('TODO:应该适当的延伸,应该合理的判断', () =>
test('不同厚度的墙合理的延伸', () =>
{
let d =
{ "file": [4, "RoomWallLine", 1, 1, 8, 2, 100, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -4214.193942419408, -1440.0043542405433, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -4214.193942419408, -1440.0043542405433, 0, 1], 0, 240, 7967.554880617505, 3146.8334229914917, 0, 6209.54639995897, 1648.7027338926612, 0, "RoomWallLine", 1, 1, 8, 2, 101, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -4214.193942419408, -1440.0043542405433, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -4214.193942419408, -1440.0043542405433, 0, 1], 0, 120, 6209.54639995897, 1648.7027338926612, 0, 4161.649025909495, 2005.5816431119943, 0, "RoomWallLine", 1, 1, 8, 2, 102, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -3647.4661029658027, -2776.6553702892907, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -3647.4661029658027, -2776.6553702892907, 0, 1], 0, 240, 4095.0486089909755, 2493.2410833026615, 0, 6075.834594752296, 1322.2148703338619, 0, "RoomWallLine", 1, 1, 8, 2, 103, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -3647.4661029658027, -2776.6553702892907, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -3647.4661029658027, -2776.6553702892907, 0, 1], 0, 120, 6075.834594752296, 1322.2148703338619, 0, 7901.571915130223, 1858.040227258869, 0], "basePt": { "x": -62.84563758389231, "y": -1557.7388499328842, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let walls = LoadEntityFromFileData<RoomWallBase>(d);
TestWallCurveParse(walls);
});
test('分裂的曲线必须保持顺序', () =>
{
let d =
{ "file": [3, "RoomWallLine", 1, 1, 8, 2, 102, false, 1, 7, 108, [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, 4905.698242144638, -91.6907730673316, 0, 4905.698242144638, 8703.733026932669, 0, "RoomWallLine", 1, 1, 8, 2, 127, 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, 3004.7210505533426, 4709.805358965871, 0, 7874.296850553343, 4709.805358965871, 0, "RoomWallLine", 1, 1, 8, 2, 137, 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, 3901.0439746724787, 2360.5634076145334, 0, 5645.054974672479, 2360.5634076145334, 0], "basePt": { "x": 3004.7210505533426, "y": -91.6907730673316, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let walls = LoadEntityFromFileData<RoomWallBase>(d);
new RoomWallParse(true, undefined, false).Parse(walls);
for (let c of walls[0].LeftCurves)
expect(c.Length).toMatchNumberSnapshot();
});

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`TODO:应该适当的延伸,应该合理的判断 1`] = `
exports[`不同厚度的墙合理的延伸 1`] = `
Array [
-1741.576246932827,
-1484.12755208,
@ -8,7 +8,7 @@ Array [
]
`;
exports[`TODO:应该适当的延伸,应该合理的判断 2`] = `
exports[`不同厚度的墙合理的延伸 2`] = `
Array [
-1774.4407143842418,
-1512.1338261176606,
@ -16,7 +16,7 @@ Array [
]
`;
exports[`TODO:应该适当的延伸,应该合理的判断 3`] = `
exports[`不同厚度的墙合理的延伸 3`] = `
Array [
-155.66614222457792,
182.66924252571152,
@ -24,7 +24,7 @@ Array [
]
`;
exports[`TODO:应该适当的延伸,应该合理的判断 4`] = `
exports[`不同厚度的墙合理的延伸 4`] = `
Array [
-2152.463399961451,
375.10121358953484,
@ -32,7 +32,7 @@ Array [
]
`;
exports[`TODO:应该适当的延伸,应该合理的判断 5`] = `
exports[`不同厚度的墙合理的延伸 5`] = `
Array [
-1943.3313481374992,
338.6566048491314,
@ -40,7 +40,7 @@ Array [
]
`;
exports[`TODO:应该适当的延伸,应该合理的判断 6`] = `
exports[`不同厚度的墙合理的延伸 6`] = `
Array [
-20.60144214795946,
-118.21835974764781,
@ -48,7 +48,7 @@ Array [
]
`;
exports[`TODO:应该适当的延伸,应该合理的判断 7`] = `
exports[`不同厚度的墙合理的延伸 7`] = `
Array [
2006.6088105074173,
-1186.2924784250126,
@ -56,7 +56,7 @@ Array [
]
`;
exports[`TODO:应该适当的延伸,应该合理的判断 8`] = `
exports[`不同厚度的墙合理的延伸 8`] = `
Array [
1954.9631610152228,
-1155.7599475125862,
@ -64,7 +64,7 @@ Array [
]
`;
exports[`TODO:应该适当的延伸,应该合理的判断 9`] = `
exports[`不同厚度的墙合理的延伸 9`] = `
Array [
-122.13846064094832,
-206.59669995491095,
@ -72,7 +72,7 @@ Array [
]
`;
exports[`TODO:应该适当的延伸,应该合理的判断 10`] = `
exports[`不同厚度的墙合理的延伸 10`] = `
Array [
1721.9488451640773,
505.36506225093467,
@ -80,7 +80,7 @@ Array [
]
`;
exports[`TODO:应该适当的延伸,应该合理的判断 11`] = `
exports[`不同厚度的墙合理的延伸 11`] = `
Array [
1929.5257955917768,
566.28565159908,
@ -88,7 +88,7 @@ Array [
]
`;
exports[`TODO:应该适当的延伸,应该合理的判断 12`] = `
exports[`不同厚度的墙合理的延伸 12`] = `
Array [
-33.7928402945563,
115.14357969433922,
@ -160,6 +160,12 @@ Array [
]
`;
exports[`分裂的曲线必须保持顺序 1`] = `"2392.25418"`;
exports[`分裂的曲线必须保持顺序 2`] = `"2229.24195"`;
exports[`分裂的曲线必须保持顺序 3`] = `"3933.92767"`;
exports[`双圆弧 1`] = `
Array [
-1868.5481692961328,

@ -34,7 +34,7 @@
"@types/flatbush": "^3.3.0",
"@types/html-webpack-plugin": "^3.2.6",
"@types/jest": "^27.4.1",
"@types/node": "^17.0.23",
"@types/node": "^17.0.29",
"@types/pako": "^1.0.3",
"@types/polylabel": "^1.0.5",
"@types/react": "17.0.44",
@ -61,7 +61,7 @@
"jest-snapshot": "^27.5.1",
"less": "^4.1.2",
"less-loader": "10.2.0",
"react-refresh": "^0.12.0",
"react-refresh": "^0.13.0",
"request": "^2.88.2",
"request-promise-native": "^1.0.9",
"required-loader": "^1.3.16",
@ -72,16 +72,16 @@
"rollup-plugin-sourcemaps": "^0.6.3",
"rollup-plugin-typescript": "^1.0.1",
"shader-loader": "^1.3.1",
"simple-git": "^3.7.0",
"simple-git": "^3.7.1",
"style-loader": "^3.3.1",
"terser-webpack-plugin": "^5.3.1",
"ts-declaration-webpack-plugin": "^1.2.3",
"ts-jest": "^27.1.4",
"ts-loader": "^9.2.8",
"ts-loader": "^9.2.9",
"ts-node": "^10.7.0",
"tsconfig-paths": "^3.14.1",
"tslib": "^2.3.1",
"typescript": "^4.6.3",
"tslib": "^2.4.0",
"typescript": "^4.6.4",
"url-loader": "^4.1.1",
"wallaby-webpack": "^3.9.16",
"webpack": "^5.72.0",
@ -95,7 +95,7 @@
"@blueprintjs/core": "^3.54.0",
"@blueprintjs/popover2": "^0.12.9",
"@blueprintjs/table": "^3.10.0",
"@jscad/modeling": "^2.9.2",
"@jscad/modeling": "^2.9.3",
"@types/react-virtualized-auto-sizer": "^1.0.1",
"@types/react-window": "^1.8.5",
"blueimp-md5": "^2.19.0",
@ -118,7 +118,7 @@
"react-rnd": "^10.3.7",
"react-split": "^2.0.14",
"react-virtualized-auto-sizer": "^1.0.6",
"react-window": "^1.8.6",
"react-window": "^1.8.7",
"stats.js": "^0.17.0",
"three": "^0.122.0",
"xaop": "^2.0.0"

@ -79,7 +79,7 @@ export class Command_DrawRectWall implements Command
if (!updateDraw) return;
new RoomWallParse(true, undefined, false).Do(walls);
new RoomWallParse(true, undefined, false).Parse(walls);
for (let wall of walls)
wall.DeferUpdate();

@ -304,7 +304,7 @@ export class Command_DrawWall implements Command
// this._parse.walls.pop();//看起来只要这样 性能会好一点(更新 不能这样 因为绘制的墙体可能不止一个)
//更新墙体的显示会更好
new RoomWallParse(false, undefined, true).Do(GetAllWalls());
new RoomWallParse(false, undefined, true).Parse(GetAllWalls());
}
};
@ -319,7 +319,7 @@ export class Command_DrawWall implements Command
this._parse = undefined;
//更新墙体的显示会更好
new RoomWallParse(false, undefined, true).Do(GetAllWalls());
new RoomWallParse(false, undefined, true).Parse(GetAllWalls());
}
};
}
@ -508,7 +508,7 @@ export class Command_DrawWallInside implements Command
{
JigUtils.End();
let walls = Polyline2Walls(pl, this._DrawDirMode, this.WallThickness);
new RoomWallParse(true, undefined, false).Do(walls);
new RoomWallParse(true, undefined, false).Parse(walls);
walls.forEach(w => JigUtils.Draw(w));
}
}

@ -15,6 +15,6 @@ export class Command_ParseRoomWall implements Command
});
if (ssRes.Status !== PromptStatus.OK) return;
let ents = ssRes.SelectSet.SelectEntityList;
new RoomWallParse(true, app.Database, false).Do(ents as RoomWallBase[]);
new RoomWallParse(true, app.Database, false).Parse(ents as RoomWallBase[]);
}
}

@ -1,20 +1,28 @@
import { Intent } from '@blueprintjs/core';
import { fnNumberSort } from '@jscad/modeling/src/utils';
import { Vector3 } from 'three';
import { app } from '../../ApplicationServices/Application';
import { Draw } from '../../Common/Draw';
import { RoomHolePolyline } from '../../DatabaseServices/Room/Entity/Wall/Hole/RoomHolePolyline';
import { RoomWallBase } from "../../DatabaseServices/Room/Entity/Wall/RoomWallBase";
import { RoomWallLine } from '../../DatabaseServices/Room/Entity/Wall/RoomWallLine';
import { PlaceIHoleHelper } from '../../DatabaseServices/Room/ParseService/Hole/PlaceIHoleHelper';
import { PlaceLHoleHelper } from '../../DatabaseServices/Room/ParseService/Hole/PlaceLHoleHelper';
import { PlaceUHoleHelper } from '../../DatabaseServices/Room/ParseService/Hole/PlaceUHoleHelper';
import { RoomWallPlaceIHoleHelper } from '../../DatabaseServices/Room/ParseService/Hole/RoomWallPlaceIHoleHelper';
import { RoomWallPlaceLHoleHelper } from '../../DatabaseServices/Room/ParseService/Hole/RoomWallPlaceLHoleHelper';
import { RoomWallPlaceUHoleHelper } from '../../DatabaseServices/Room/ParseService/Hole/RoomWallPlaceUHoleHelper';
import { GetAllWalls } from '../../DatabaseServices/Room/ParseService/RoomParseUtil';
import { RoomWallParse } from '../../DatabaseServices/Room/ParseService/RoomWallParse';
import { Command } from "../../Editor/CommandMachine";
import { JigUtils } from '../../Editor/JigUtils';
import { PromptStatus } from '../../Editor/PromptResult';
import { Route, Vertice } from '../../Geometry/CurveMap';
import { equalv3, midPoint } from '../../Geometry/GeUtils';
import { HotCMD } from "../../Hot/HotCommand";
import { AppToaster } from '../../UI/Components/Toaster';
//todo: 编写一个重新找回关联关系的函数?
//todo: 编写一个裁剪墙体线的功能
@HotCMD
export class Test implements Command
{
@ -23,12 +31,12 @@ export class Test implements Command
//关闭捕捉
let bak = app.Editor.GetPointServices.snapServices.Disabled;
app.Editor.GetPointServices.snapServices.Disabled = true;
let count = 3;
let count = 4;
if (count === 2)//直线洞
{
//两点洞的时候 我们寻找可以放的下的线段区域
let helper = new PlaceIHoleHelper(GetAllWalls());
let helper = new RoomWallPlaceIHoleHelper(GetAllWalls());
if (!helper._Walls.length)
{
AppToaster.show({
@ -39,71 +47,124 @@ export class Test implements Command
return;
}
let hole: RoomWallBase;
let holeWall: RoomWallBase;//faker wall
let holeLength = 800;
await app.Editor.GetPoint({
Callback: p =>
let hole = new RoomHolePolyline;
hole.Position = new Vector3(0, 0, 800);
JigUtils.Draw(hole);
let preWall: RoomWallBase;
const UpdateHole = (p: Vector3) =>
{
let d = helper.FindBestPlace(p);
if (preWall)
{
let d = helper.FindBestPlace(p);
if (d)
{
let { wall, getParam, range } = d;
let wallLength = wall.Length;
let length = (range[1] - range[0]) * wallLength;
preWall.Holes.length = preWall.RelevancyHoles.length;
preWall.Update();
}
JigUtils.End();
if (d)
{
preWall = d.wall;
let { wall, getParam, range } = d;
let wallLength = wall.Length;
let length = (range[1] - range[0]) * wallLength;
if (length < holeLength)
if (length < holeLength)
{
holeWall = wall.Clone();
holeWall.EndPoint = getParam.GetPointAtParam(range[1]);
holeWall.StartPoint = getParam.GetPointAtParam(range[0]);
}
else
{
if ((d.cpParam - range[0]) * wallLength < holeLength * 0.5)
{
hole = wall.Clone();
hole.EndPoint = getParam.GetPointAtParam(range[1]);
hole.StartPoint = getParam.GetPointAtParam(range[0]);
JigUtils.Draw(hole);
holeWall = wall.Clone();
holeWall.EndPoint = getParam.GetPointAtParam(range[0] + holeLength / wallLength);
holeWall.StartPoint = getParam.GetPointAtParam(range[0]);
}
else if ((range[1] - d.cpParam) * wallLength < holeLength * 0.5)
{
holeWall = wall.Clone();
holeWall.EndPoint = getParam.GetPointAtParam(range[1]);
holeWall.StartPoint = getParam.GetPointAtParam(range[1] - holeLength / wallLength);
}
else
{
if ((d.cpParam - range[0]) * wallLength < holeLength * 0.5)
{
hole = wall.Clone();
hole.EndPoint = getParam.GetPointAtParam(range[0] + holeLength / wallLength);
hole.StartPoint = getParam.GetPointAtParam(range[0]);
JigUtils.Draw(hole);
}
else if ((range[1] - d.cpParam) * wallLength < holeLength * 0.5)
{
hole = wall.Clone();
hole.EndPoint = getParam.GetPointAtParam(range[1]);
hole.StartPoint = getParam.GetPointAtParam(range[1] - holeLength / wallLength);
JigUtils.Draw(hole);
}
else
{
hole = wall.Clone();
hole.EndPoint = getParam.GetPointAtParam(d.cpParam + holeLength * 0.5 / wallLength);
hole.StartPoint = getParam.GetPointAtParam(d.cpParam - holeLength * 0.5 / wallLength);
JigUtils.Draw(hole);
}
holeWall = wall.Clone();
holeWall.EndPoint = getParam.GetPointAtParam(d.cpParam + holeLength * 0.5 / wallLength);
holeWall.StartPoint = getParam.GetPointAtParam(d.cpParam - holeLength * 0.5 / wallLength);
}
}
else
let [s, e] = [holeWall.StartPoint, holeWall.EndPoint].map(p => getParam.GetParamAtPoint(p)).sort(fnNumberSort);
d.wall.Holes.push({
StartParam: s,
EndParam: e,
Bottom: 800,
Top: 1600
});
d.wall.Update();
}
else
{
preWall = undefined;
if (!holeWall)
holeWall = new RoomWallLine(new Vector3, new Vector3(holeLength));
if (holeWall)
{
if (hole)
{
let midp = midPoint(hole.StartPoint, hole.EndPoint);
hole.Move(p.clone().sub(midp));
}
let midp = midPoint(holeWall.StartPoint, holeWall.EndPoint);
holeWall.Move(p.clone().sub(midp));
}
}
//更新洞
new RoomWallParse(false, undefined, false).Parse([holeWall]);
hole.FakerWalls = [holeWall];
hole.UpdatePoints();
return d;
};
let pRes = await app.Editor.GetPoint({
Callback: UpdateHole
});
if (preWall)
{
preWall.Holes.length = preWall.RelevancyHoles.length;
preWall.Update();
}
if (pRes.Status === PromptStatus.OK)
{
let d = UpdateHole(pRes.Point);
if (d)
{
Draw(hole);
d.wall.RelevancyHoles.push(hole.Id);
}
}
}
else if (count === 3)//L型
{
//三点洞<折角洞> 我们寻找一个点,这个点连接了2个线段
let hole = new RoomHolePolyline;
hole.Position = new Vector3(0, 0, 800);
JigUtils.Draw(hole);
let jigWalls: RoomWallBase[];
let helper = new PlaceLHoleHelper();
let helper = new RoomWallPlaceLHoleHelper();
if (!helper._stands.length)
{
AppToaster.show({
@ -115,85 +176,132 @@ export class Test implements Command
}
let preV: Vertice;
let preWalls: RoomWallBase[];
await app.Editor.GetPoint({
Callback: p =>
{
let v = helper.FindBestPlace(p);
const UpdateHole = (p: Vector3) =>
{
let v = helper.FindBestPlace(p);
if (preV && v == preV) return;
preV = v;
if (preV && v == preV) return v;
preV = v;
if (v)
if (preWalls)
for (let wall of preWalls)
{
JigUtils.End();//重绘会导致性能遍地,尽量不重绘
jigWalls = [];
let breakData = RoomWallParse._CacheWallMaps[helper._standGroupIndexMap.get(v)][0];
//找到这两堵墙
let walls = v.routes.map(r =>
{
let orgCurve = breakData._SplitCurve2OrgCurveMap.get(r.curve);
let orgWall = RoomWallParse._CacheCurveWallMaps.get(orgCurve);
return orgWall.Clone();
});
wall.Holes.length = wall.RelevancyHoles.length;
hole.RelevancyWalls.push(wall.Id);
}
let [wall1, wall2] = walls;
if (equalv3(wall1.StartPoint, v.position, 1e-3))
wall1.Reverse();
if (equalv3(wall2.EndPoint, v.position, 1e-3))
wall2.Reverse();
if (v)
{
preWalls = undefined;
jigWalls = [];
let length1 = v.routes[0].length;
let length2 = v.routes[1].length;
let breakData = RoomWallParse._CacheWallMaps[helper._standGroupIndexMap.get(v)][0];
//这里看起来不大行 使用打断后的曲线 会有过长的问题 需要得到真正的可以放置的区域(但是似乎也不需要实现非常精确的放置区域,实现成本有点麻烦 干脆不做了 问题也不大)
if (length1 < 800)
wall1.StartPoint = v.routes[0].to.position;//直接用最大的
else
wall1.StartPoint = wall1.GetPointAtDistance(wall1.Length - 800);
let orgWalls: RoomWallBase[] = [];
//找到这两堵墙
let walls = v.routes.map(r =>
{
let orgCurve = breakData._SplitCurve2OrgCurveMap.get(r.curve);
let orgWall = RoomWallParse._CacheCurveWallMaps.get(orgCurve);
orgWalls.push(orgWall);
return orgWall.Clone();
});
let [wall1, wall2] = walls;
if (equalv3(wall1.StartPoint, v.position, 1e-3))
wall1.Reverse();
if (equalv3(wall2.EndPoint, v.position, 1e-3))
wall2.Reverse();
let length1 = v.routes[0].length;
let length2 = v.routes[1].length;
//这里看起来不大行 使用打断后的曲线 会有过长的问题 需要得到真正的可以放置的区域(但是似乎也不需要实现非常精确的放置区域,实现成本有点麻烦 干脆不做了 问题也不大)
if (length1 < 800)
wall1.StartPoint = v.routes[0].to.position;//直接用最大的
else
wall1.StartPoint = wall1.GetPointAtDistance(wall1.Length - 800);
if (length2 < 800)
wall2.EndPoint = v.routes[1].to.position;//直接用最大的
else
wall2.EndPoint = wall2.GetPointAtDistance(800);
if (length2 < 800)
wall2.EndPoint = v.routes[1].to.position;//直接用最大的
else
wall2.EndPoint = wall2.GetPointAtDistance(800);
jigWalls.push(wall1);
jigWalls.push(wall2);
jigWalls.push(wall1);
jigWalls.push(wall2);
new RoomWallParse(false, undefined, false).Do(jigWalls);
for (let i = 0; i < walls.length; i++)
{
let wall = walls[i];
let orgWall = orgWalls[i];
let [s, e] = [orgWall.GetParamAtPoint(wall.StartPoint), orgWall.GetParamAtPoint(wall.EndPoint)].sort(fnNumberSort);
orgWall.Holes.push({
StartParam: s,
EndParam: e,
Bottom: 800,
Top: 1600
});
orgWall.Update();
}
for (let wall of jigWalls) JigUtils.Draw(wall);
preWalls = orgWalls;
}
else
{
if (jigWalls)
{
let moveV = p.clone().sub(jigWalls[0].EndPoint);
for (let wall of jigWalls)
wall.Move(moveV);
}
else
{
if (jigWalls)
{
let moveV = p.clone().sub(jigWalls[0].EndPoint);
for (let wall of jigWalls)
wall.Move(moveV);
}
else
{
jigWalls = [
new RoomWallLine(p.clone().add(new Vector3(0, 800, 0)), p.clone()),
new RoomWallLine(p.clone(), p.clone().add(new Vector3(800, 0, 0))),
];
new RoomWallParse(false, undefined, false).Do(jigWalls);
jigWalls = [
new RoomWallLine(p.clone().add(new Vector3(0, 800, 0)), p.clone()),
new RoomWallLine(p.clone(), p.clone().add(new Vector3(800, 0, 0))),
];
for (let wall of jigWalls) JigUtils.Draw(wall);
}
}
}
new RoomWallParse(false, undefined, false).Parse(jigWalls);
hole.FakerWalls = jigWalls;
hole.UpdatePoints();
return v;
};
let pRes = await app.Editor.GetPoint({
Callback: UpdateHole
});
if (pRes.Status === PromptStatus.OK)
{
let v = UpdateHole(pRes.Point);
if (v)
{
Draw(hole);
for (let wall of preWalls)
{
wall.RelevancyHoles.push(hole.Id);
hole.RelevancyWalls.push(wall.Id);
}
}
}
else
if (preWalls)
for (let wall of preWalls)
{
wall.Holes.length = wall.RelevancyHoles.length;
wall.Update();
}
}
else if (count === 4)//U型
{
//4点洞 U型窗户 我们寻找一个线段,这个线段的首尾都连接了2个线段
let helper = new PlaceUHoleHelper();
let helper = new RoomWallPlaceUHoleHelper();
if (!helper._fb)
{
@ -205,68 +313,124 @@ export class Test implements Command
return;
}
let hole = new RoomHolePolyline;
hole.Position = new Vector3(0, 0, 800);
JigUtils.Draw(hole);
let jigWalls: RoomWallBase[];
let preR: Route;
await app.Editor.GetPoint({
Callback: p =>
{
let route = helper.FindPlace(p);
if (preR && route == preR) return;
preR = route;
let preWalls: RoomWallBase[];
if (route)
const UpdateHole = (p: Vector3) =>
{
let route = helper.FindPlace(p);
if (preR && route == preR) return route;
preR = route;
if (preWalls)
for (let wall of preWalls)
{
JigUtils.End();//重绘会导致性能遍地,尽量不重绘
wall.Holes.length = wall.RelevancyHoles.length;
wall.Update();
}
let r1 = route.from.routes.find(r => r.curve !== route.curve);
let r2 = route.to.routes.find(r => r.curve !== route.curve);
if (route)
{
let r1 = route.from.routes.find(r => r.curve !== route.curve);
let r2 = route.to.routes.find(r => r.curve !== route.curve);
let wall = helper.GetWall(route).Clone();
let wall1 = helper.GetWall(r1).Clone();
let wall2 = helper.GetWall(r2).Clone();
let orgWalls = [helper.GetWall(route), helper.GetWall(r1), helper.GetWall(r2)];
let walls = orgWalls.map(w => w.Clone());
if (!equalv3(wall1.StartPoint, route.from.position, 1e-3))
wall1.Reverse();
if (!equalv3(wall2.StartPoint, route.to.position, 1e-3))
wall2.Reverse();
let [wall, wall1, wall2] = walls;
if (r1.length > 600)
wall1.EndPoint = wall1.GetPointAtDistance(600);
else
wall1.EndPoint = r1.to.position;
if (r2.length > 600)
wall2.EndPoint = wall2.GetPointAtDistance(600);
else
wall2.EndPoint = r2.to.position;
if (!equalv3(wall.StartPoint, route.from.position, 1e-3))
wall.Reverse();
jigWalls = [wall1, wall, wall2];
if (!equalv3(wall1.EndPoint, route.from.position, 1e-3))
wall1.Reverse();
new RoomWallParse(false, undefined, false).Do(jigWalls);
if (!equalv3(wall2.StartPoint, route.to.position, 1e-3))
wall2.Reverse();
for (let wall of jigWalls) JigUtils.Draw(wall);
}
else if (jigWalls)
if (r1.length > 600)
wall1.StartPoint = wall1.GetPointAtDistance(wall1.Length - 600);
else
wall1.StartPoint = r1.to.position;
if (r2.length > 600)
wall2.EndPoint = wall2.GetPointAtDistance(600);
else
wall2.EndPoint = r2.to.position;
jigWalls = [wall1, wall, wall2];
preWalls = orgWalls;
for (let i = 0; i < orgWalls.length; i++)
{
let moveV = p.clone().sub(jigWalls[1].GetPointAtParam(0.5));
for (let wall of jigWalls)
wall.Move(moveV);
let wall = walls[i];
let orgWall = orgWalls[i];
let [s, e] = [orgWall.GetParamAtPoint(wall.StartPoint), orgWall.GetParamAtPoint(wall.EndPoint)].sort(fnNumberSort);
orgWall.Holes.push({
StartParam: s,
EndParam: e,
Bottom: 800,
Top: 1600
});
orgWall.Update();
}
}
else if (jigWalls)
{
let moveV = p.clone().sub(jigWalls[1].GetPointAtParam(0.5));
for (let wall of jigWalls)
wall.Move(moveV);
}
if (!jigWalls)
{
jigWalls = [
new RoomWallLine(p.clone().add(new Vector3(-400, 600, 0)), p.clone().add(new Vector3(-400, 0, 0))),
new RoomWallLine(p.clone().add(new Vector3(-400, 0, 0)), p.clone().add(new Vector3(400, 0, 0))),
new RoomWallLine(p.clone().add(new Vector3(400, 0, 0)), p.clone().add(new Vector3(400, 600, 0))),
];
if (!jigWalls)
{
jigWalls = [
new RoomWallLine(p.clone().add(new Vector3(-400, 600, 0)), p.clone().add(new Vector3(-400, 0, 0))),
new RoomWallLine(p.clone().add(new Vector3(-400, 0, 0)), p.clone().add(new Vector3(400, 0, 0))),
new RoomWallLine(p.clone().add(new Vector3(400, 0, 0)), p.clone().add(new Vector3(400, 600, 0))),
];
}
new RoomWallParse(false, undefined, false).Parse(jigWalls);
new RoomWallParse(false, undefined, false).Do(jigWalls);
hole.FakerWalls = jigWalls;
hole.UpdatePoints();
return route;
};
let ptRes = await app.Editor.GetPoint({
Callback: UpdateHole
});
for (let wall of jigWalls) JigUtils.Draw(wall);
if (ptRes.Status === PromptStatus.OK)
{
let route = UpdateHole(ptRes.Point);
if (route)
{
Draw(hole);
for (let wall of preWalls)
{
wall.RelevancyHoles.push(hole.Id);
hole.RelevancyWalls.push(wall.Id);
}
}
});
}
else
if (preWalls)
for (let wall of preWalls)
{
wall.Holes.length = wall.RelevancyHoles.length;
wall.Update();
}
}
app.Editor.GetPointServices.snapServices.Disabled = bak;

@ -63,7 +63,7 @@ export class CommandHistoryRecord extends CADObject
//对象写入历史记录
WriteObjectHistoryPath(obj: CADObject, history: HistorycRecord)
{
if (this._CreateObjects.has(obj))
if (!obj || this._CreateObjects.has(obj))//某些时候obj可能为空
return;
let hrs = this.GetObjectHistoryList(obj.Id);

@ -29,7 +29,7 @@ import { Polyline } from './Polyline';
@Factory
export class Arc extends Curve
{
constructor(center: Vector3 = new Vector3(), radius: number = 0.1, startAngle: number = 0.1, endAngle: number = 0, clockwise = true)
constructor(center: Vector3 = ZeroVec, radius: number = 0.1, startAngle: number = 0.1, endAngle: number = 0, clockwise = true)
{
super();
this._Matrix.setPosition(center);

@ -11,7 +11,7 @@ import { UpdateDraw } from '../../Common/Status';
import { ObjectSnapMode } from '../../Editor/ObjectSnapMode';
import { boardUVGenerator, boardUVGenerator2 } from '../../Geometry/BoardUVGenerator';
import { BufferGeometryUtils } from '../../Geometry/BufferGeometryUtils';
import { equaln, ZeroVec } from '../../Geometry/GeUtils';
import { equaln, XAxis, XAxisN, YAxis, YAxisN, ZAxis, ZeroVec } from '../../Geometry/GeUtils';
import { PointShapeUtils } from '../../Geometry/PointShapeUtils';
import { GetBoardHighSeal, GetBoardSealingCurves, HandleRectBoardSealingData } from '../../GraphicsSystem/CalcEdgeSealing';
import { RenderType } from '../../GraphicsSystem/RenderType';
@ -607,23 +607,23 @@ export class Board extends ExtrudeSolid
{
case BoardType.Layer:
roMat.makeBasis(
new Vector3(0, 1, 0),
new Vector3(-1, 0, 0),
new Vector3(0, 0, 1)
YAxis,
XAxisN,
ZAxis
);
break;
case BoardType.Vertical:
roMat.makeBasis(
new Vector3(0, 1, 0),
new Vector3(0, 0, 1),
new Vector3(1, 0, 0)
YAxis,
ZAxis,
XAxis
);
break;
case BoardType.Behind:
roMat.makeBasis(
new Vector3(1, 0, 0),
new Vector3(0, 0, 1),
new Vector3(0, -1, 0)
XAxis,
ZAxis,
YAxisN
);
}
return roMat;

@ -250,7 +250,7 @@ export class ExtrudeSolid extends Entity
}
protected ApplyMirrorMatrix(m: Matrix4)
{
const curve = this.contourCurve;
const curve = this.ContourCurve;
if (curve instanceof Polyline && !equalv3(curve.Position, ZeroVec))
{
let pts = curve.LineData;
@ -267,18 +267,18 @@ export class ExtrudeSolid extends Entity
if (equaln(Math.abs(nor.z), 1))
{
reviseMirrorMatrix(this._Matrix, 1);
if (this.contourCurve instanceof Circle)
if (curve instanceof Circle)
{
this.contourCurve.ApplyMatrix(new Matrix4().makeRotationX(Math.PI));
curve.ApplyMatrix(new Matrix4().makeRotationX(Math.PI));
}
else
{
let ocs = this.contourCurve.OCS;
let ocs = curve.OCS;
reviseMirrorMatrix(ocs, 1);
this.contourCurve.OCS = ocs;
curve.OCS = ocs;
}
this.SetContourCurve(this.contourCurve);
this.SetContourCurve(curve);
}
else if (equaln(Math.abs(nor.x), 1))
{
@ -288,18 +288,18 @@ export class ExtrudeSolid extends Entity
else
{
reviseMirrorMatrix(this._Matrix, 0);
if (this.contourCurve instanceof Circle)
if (curve instanceof Circle)
{
this.contourCurve.ApplyMatrix(new Matrix4().makeRotationY(Math.PI));
curve.ApplyMatrix(new Matrix4().makeRotationY(Math.PI));
}
else
{
let ocs = this.contourCurve.OCS;
let ocs = curve.OCS;
reviseMirrorMatrix(ocs, 0);
this.contourCurve.OCS = ocs;
curve.OCS = ocs;
}
this.SetContourCurve(this.contourCurve);
this.SetContourCurve(curve);
}
return this;

@ -201,12 +201,11 @@ export class HistoricManage extends CADObject
{
for (let rc of this._SignalCommandHistory.historyRecord)
{
for (let [id, hl] of rc.HistoryList)
for (let [id, hrs] of rc.HistoryList)
{
for (let h of hl)
{
lastRec.WriteObjectHistoryPath(id.Object, h);
}
if (id?.Object)//某些情况下可能为空
for (let hr of hrs)
lastRec.WriteObjectHistoryPath(id.Object, hr);
}
}
this._SignalCommandHistory = undefined;

@ -13,7 +13,7 @@ import { RoomBase } from "../../RoomBase";
@Factory
export class RoomHoleBase extends RoomBase
{
private _Height = 800;
protected _Height = 800;
constructor() { super(); }

@ -13,7 +13,7 @@ const TempP = new Vector3;
/**
* 线 2
* 线 2( 使RoomHolePolyline)
*/
@Factory
export class RoomHoleLine extends RoomHoleBase

@ -1,13 +1,28 @@
import { Geometry, Object3D, ShapeUtils, Vector3 } from "three";
import { AsVector3 } from "../../../../../Geometry/GeUtils";
import { Face3, Geometry, LineSegments, Mesh, Object3D, ShapeUtils, Vector2, Vector3 } from "three";
import { arrayPushArray } from "../../../../../Common/ArrayExt";
import { ColorMaterial } from "../../../../../Common/ColorPalette";
import { CreatePolylinePath } from "../../../../../Geometry/CreatePolylinePath";
import { AsVector3, equalv2 } from "../../../../../Geometry/GeUtils";
import { RenderType } from "../../../../../GraphicsSystem/RenderType";
import { Factory } from "../../../../CADFactory";
import { CADFiler } from "../../../../CADFiler";
import { CADObject } from "../../../../CADObject";
import { Curve } from "../../../../Entity/Curve";
import { Line } from "../../../../Entity/Line";
import { Polyline } from "../../../../Entity/Polyline";
import { ObjectId } from "../../../../ObjectId";
import { CreateGetCurveParam, GetLineParam } from "../../../ParseService/GetCurveParam";
import { RoomWallBase } from "../RoomWallBase";
import { RoomHoleBase } from "./RoomHoleBase";
enum HoleType
{
Door = 1,
Window = 2,
LWindow = 3,
UWindow = 4,
}
/**
* 线 U
*/
@ -16,11 +31,55 @@ export class RoomHolePolyline extends RoomHoleBase
{
//虽然使用了三维的点,但是我们实际使用的是二维的点 z总是等于0
private _Points: Vector3[] = [];
RelevancyWalls: ObjectId[] = [];//关联的墙体列表
private _FakerWalls: RoomWallBase[] = [];
public set FakerWalls(_FakerWalls: RoomWallBase[])
{
this._FakerWalls = _FakerWalls;
this.LidCurves = [];
this.Regions = [];
for (let w of this._FakerWalls)
{
arrayPushArray(this.LidCurves, w.LidCurves);
this.Regions.push(w.Region);
}
}
constructor() { super(); }
get Points() { return this._Points.map(p => p.clone().applyMatrix4(this.OCSNoClone)); }
//使用FakerWalls来更新这个洞的信息
UpdatePoints()
{
let ocsInv = this.OCSInv;
let pts: Vector3[] = [];
for (let w of this._FakerWalls)
{
pts.push(w.StartPoint.applyMatrix4(ocsInv));
}
if (this._FakerWalls.length)
pts.push(this._FakerWalls[this._FakerWalls.length - 1].EndPoint.applyMatrix4(ocsInv));
this.WriteAllObjectRecord();
this._Points = pts;
this.Update();
}
//#region Draw
LidCurves: Curve[];
Region: Polyline;
LidCurves: Curve[];//窗户的开始和结束,我们接管了这个的绘制
Regions: Polyline[];//窗户的区域,我们接管了这个的绘制(包括上面)
override UpdateDrawGeometry()
{
if (this._EdgeGeometry)
this._EdgeGeometry.dispose();
this._EdgeGeometry = undefined;
if (this._MeshGeometry)
this._MeshGeometry.dispose();
this._MeshGeometry = undefined;
}
private _EdgeGeometry: Geometry;
get EdgeGeometry()
@ -32,26 +91,52 @@ export class RoomHolePolyline extends RoomHoleBase
let inv = this.OCSInv;
let pts: Vector3[] = this._EdgeGeometry.vertices;
for (let lid of this.LidCurves)
{
//TODO:是否真的需要切换到本地坐标系 (如果我们使用墙体上的曲线,那么需要 如果我们使用本地坐标系计算曲线 则不需要)
let sp = lid.StartPoint.applyMatrix4(inv).setZ(0);
let ep = lid.EndPoint.applyMatrix4(inv).setZ(0);
pts.push(sp, sp.clone().setZ(this.Height),
ep, ep.clone().setZ(this.Height),
);
}
if (this.LidCurves)
for (let lid of this.LidCurves)
{
//TODO:是否真的需要切换到本地坐标系 (如果我们使用墙体上的曲线,那么需要 如果我们使用本地坐标系计算曲线 则不需要)
let sp = lid.StartPoint.applyMatrix4(inv).setZ(0);
let ep = lid.EndPoint.applyMatrix4(inv).setZ(0);
let rpts = this.Region.Shape.getPoints(30);
for (let i = 1; i < rpts.length; i++)
pts.push(sp, sp.clone().setZ(this._Height),
ep, ep.clone().setZ(this._Height),
);
}
if (this.Regions)
{
//TODO:是否真的需要切换到本地坐标系 (如果我们使用墙体上的曲线,那么需要 如果我们使用本地坐标系计算曲线 则不需要)
let pre = AsVector3(rpts[i - 1]).applyMatrix4(inv);
let p = AsVector3(rpts[i]).applyMatrix4(inv);
for (let region of this.Regions)
{
region.OCSNoClone.elements[14] = this._Matrix.elements[14];//我们拥有它
let lined = region.MatrixAlignTo2(this.OCSNoClone);
if (region.CloseMark && !equalv2(lined.pts[0], lined.pts[lined.pts.length - 1], 1e-4))
{
lined.pts.push(lined.pts[0]);
lined.buls.push(0);
}
pts.push(pre, p);
pts.push(pre.clone().setZ(2700), p.clone().setZ(2700));
let path = CreatePolylinePath(lined.pts, lined.buls);
let rpts = path.getPoints(30);
// let wallTopHeight = 0;
// if (this.FakerHoles[0])
// wallTopHeight = this.FakerHoles[0].Position.z + this.FakerHoles[0].Height - this.Position.z;
for (let i = 1; i < rpts.length; i++)
{
//TODO:是否真的需要切换到本地坐标系 (如果我们使用墙体上的曲线,那么需要 如果我们使用本地坐标系计算曲线 则不需要)
let pre = AsVector3(rpts[i - 1]).applyMatrix4(inv);
let p = AsVector3(rpts[i]).applyMatrix4(inv);
pts.push(pre.setZ(0), p.setZ(0));
pts.push(pre.clone().setZ(this._Height), p.clone().setZ(this._Height));
// if (wallTopHeight)
// pts.push(pre.clone().setZ(wallTopHeight), p.clone().setZ(wallTopHeight));
}
}
}
return this._EdgeGeometry;
@ -65,44 +150,146 @@ export class RoomHolePolyline extends RoomHoleBase
this._MeshGeometry = new Geometry();
let inv = this.OCSInv;
let geo = this._MeshGeometry;
let pts: Vector3[] = this._EdgeGeometry.vertices;
for (let lid of this.LidCurves)
{
//TODO:是否真的需要切换到本地坐标系 (如果我们使用墙体上的曲线,那么需要 如果我们使用本地坐标系计算曲线 则不需要)
let sp = lid.StartPoint.applyMatrix4(inv).setZ(0);
let ep = lid.EndPoint.applyMatrix4(inv).setZ(0);
}
if (this.LidCurves)
for (let lid of this.LidCurves)
{
let startIndex = geo.vertices.length;
let rpts = this.Region.Shape.getPoints(30);
let faces = ShapeUtils.triangulateShape(rpts, []);
for (let f of faces)
{
//TODO:是否真的需要切换到本地坐标系 (如果我们使用墙体上的曲线,那么需要 如果我们使用本地坐标系计算曲线 则不需要)
let p1 = lid.StartPoint.applyMatrix4(inv).setZ(0);
let p2 = lid.EndPoint.applyMatrix4(inv).setZ(0);
}
}
geo.vertices.push(p1.setZ(0), p2.setZ(0));
geo.vertices.push(p1.clone().setZ(this._Height));
geo.vertices.push(p2.clone().setZ(this._Height));
let startX = 0;
let endX = lid.Length * 1e-3;
InitDrawObject(renderType: RenderType = RenderType.Wireframe)
{
let obj = new Object3D();
let startZ = 0;
let endZ = this._Height * 1e-3;
let parse = CreateGetCurveParam(lid as Line) as GetLineParam;
geo.faces.push(
new Face3(startIndex, startIndex + 2, startIndex + 1, parse.LeftDir),
new Face3(startIndex + 1, startIndex + 2, startIndex + 3, parse.LeftDir),
);
geo.faceVertexUvs[0].push(
[new Vector2(startX, startZ), new Vector2(startX, endZ), new Vector2(endX, startZ)],
[new Vector2(endX, startZ), new Vector2(startX, endZ), new Vector2(endX, endZ)],
);
}
if (this.Regions)
for (let region of this.Regions)
{
region.OCSNoClone.elements[14] = this._Matrix.elements[14];//我们拥有它
let lined = region.MatrixAlignTo2(this.OCSNoClone);
if (region.CloseMark && !equalv2(lined.pts[0], lined.pts[lined.pts.length - 1], 1e-4))
{
lined.pts.push(lined.pts[0]);
lined.buls.push(0);
}
let path = CreatePolylinePath(lined.pts, lined.buls);
let rpts = path.getPoints(30);
let faces = ShapeUtils.triangulateShape(rpts, []);
let startIndex = geo.vertices.length;
for (let p of rpts) geo.vertices.push(new Vector3(p.x, p.y, 0));
for (let p of rpts) geo.vertices.push(new Vector3(p.x, p.y, this._Height));
let normal = this.Normal;
let normaln = normal.clone().negate();
for (let i = 0; i < faces.length; i++)
{
let [a, b, c] = faces[i];
geo.faces.push(new Face3(startIndex + a, startIndex + b, startIndex + c, normal));
let uvs = faces[i].map(index => rpts[index].clone().multiplyScalar(1e-3));
geo.faceVertexUvs[0].push(uvs);
geo.faces.push(new Face3(startIndex + rpts.length + c, startIndex + rpts.length + b, startIndex + rpts.length + a, normaln));
geo.faceVertexUvs[0].push(uvs.concat().reverse().map(v => v.clone()));
}
}
return this._MeshGeometry;
}
if (!this.LidCurves) return;
if (renderType === RenderType.Wireframe)
InitDrawObject(renderType: RenderType = RenderType.Wireframe): Object3D
{
if (renderType === RenderType.Physical)
{
let mesh = new Mesh(this.MeshGeometry, this.MeshMaterial);
mesh.castShadow = true;
mesh.receiveShadow = true;
return mesh;
}
let obj = new Object3D;
if (renderType === RenderType.Wireframe || renderType === RenderType.Jig)
{
return new LineSegments(this.EdgeGeometry, ColorMaterial.GetLineMaterial(4));
}
else if (renderType === RenderType.Conceptual)
{
let mesh = new Mesh(this.MeshGeometry, ColorMaterial.GetConceptualMaterial(this.ColorIndex));
let line = new LineSegments(this.EdgeGeometry, ColorMaterial.GetLineMaterial(this.ColorIndex));
obj.add(mesh, line);
}
return obj;
}
UpdateDrawObject(type: RenderType, obj: Object3D)
/**
* :
* @param {RenderType} renderType
* @param {Object3D} obj
*/
UpdateDrawObject(renderType: RenderType, obj: Object3D)
{
if (renderType === RenderType.Wireframe || renderType === RenderType.Jig)
{
let line = obj as LineSegments;
if (line.geometry !== this.EdgeGeometry)
{
line.geometry.dispose();
line.geometry = this.EdgeGeometry;
}
}
else if (renderType === RenderType.Conceptual)
{
let mesh = obj.children[0] as Mesh<Geometry>;
if (mesh.geometry !== this.MeshGeometry)
{
mesh.geometry.dispose();
mesh.geometry = this.MeshGeometry;
}
let line = obj.children[1] as LineSegments<Geometry>;
if (line.geometry !== this.EdgeGeometry)
{
line.geometry.dispose();
line.geometry = this.EdgeGeometry;
}
}
else if (renderType === RenderType.Physical)
{
let mesh = obj as Mesh<Geometry>;
if (mesh.geometry !== this.MeshGeometry)
{
mesh.geometry.dispose();
mesh.geometry = this.MeshGeometry;
}
}
}
//#endregion
//#region -------------------------File-------------------------

@ -3,8 +3,9 @@ import { arrayPushArray } from "../../../../Common/ArrayExt";
import { ColorMaterial } from "../../../../Common/ColorPalette";
import { ObjectSnapMode } from "../../../../Editor/ObjectSnapMode";
import { BufferGeometryUtils } from "../../../../Geometry/BufferGeometryUtils";
import { CreatePolylinePath } from "../../../../Geometry/CreatePolylinePath";
import { AsVector3, clampRad, equalv2, updateGeometry, ZeroVec } from "../../../../Geometry/GeUtils";
import { SubtractRange, Tape } from "../../../../Geometry/ExtrudeMeshGeomBuilder/ExtrudeEdgeGeometry2";
import { SplitArcParams, SplitCurveParams } from "../../../../Geometry/ExtrudeMeshGeomBuilder/SplitCurveParams";
import { AsVector2, AsVector3, clampRad, equaln, updateGeometry, ZeroVec } from "../../../../Geometry/GeUtils";
import { RenderType } from "../../../../GraphicsSystem/RenderType";
import { Factory } from "../../../CADFactory";
import { CADFiler } from "../../../CADFiler";
@ -12,7 +13,7 @@ import { Arc } from "../../../Entity/Arc";
import { Curve } from "../../../Entity/Curve";
import { Line } from "../../../Entity/Line";
import { Polyline } from "../../../Entity/Polyline";
import { LEFT_ROTATE_MTX2 } from "../../ParseService/GetCurveParam";
import { GetArcParam, GetLineParam } from "../../ParseService/GetCurveParam";
import { applyMixins, CURVE_FACE_TYPE_KEY, CURVE_MESH_NAMES, RoomWallBase, WallFaceType } from "./RoomWallBase";
import { WallSnapMode } from "./WallSnapMode";
@ -71,14 +72,14 @@ export class RoomWallArc extends RoomWallBase
//顶部线
let bakZ = curve.OCSNoClone.elements[14];
curve.OCSNoClone.elements[14] = 2700;
curve.OCSNoClone.elements[14] = this._Height;
arrayPushArray(pts, curve.GetObjectSnapPoints(snapMode, pickPoint, lastPoint, viewXform));
curve.OCSNoClone.elements[14] = bakZ;
let spep = [curve.StartPoint, curve.EndPoint];
for (let p of spep)
{
let l = new Line(p, p.clone().setZ(2700));
let l = new Line(p, p.clone().setZ(this._Height));
arrayPushArray(pts, l.GetObjectSnapPoints(snapMode, pickPoint, lastPoint, viewXform));
}
};
@ -104,7 +105,7 @@ export class RoomWallArc extends RoomWallBase
let count = pts.length;
for (let i = 0; i < count; i++)
pts.push(pts[i].clone().setZ(pts[i].z + 2700));
pts.push(pts[i].clone().setZ(pts[i].z + this._Height));
return pts;
}
MoveGripPoints(indexList: Array<number>, vec: Vector3)
@ -156,6 +157,10 @@ export class RoomWallArc extends RoomWallBase
{
if (this._EdgeGeometry) return this._EdgeGeometry;
for (let hole of this.Holes)
if (hole.StartParam > hole.EndParam)
[hole.StartParam, hole.EndParam] = [hole.EndParam, hole.StartParam];
let pts: Vector3[];
if (!this.LeftCurves)
{
@ -169,15 +174,15 @@ export class RoomWallArc extends RoomWallBase
let leftPts = left.Shape.getPoints(this.GetDrawCount()).map(AsVector3);
let rightPts = right.Shape.getPoints(this.GetDrawCount()).map(AsVector3);
let leftPts2 = leftPts.map(p => p.clone().setZ(2700));
let rightPts2 = rightPts.map(p => p.clone().setZ(2700));
let leftPts2 = leftPts.map(p => p.clone().setZ(this._Height));
let rightPts2 = rightPts.map(p => p.clone().setZ(this._Height));
pts = [
leftPts[0], leftPts[0].clone().setZ(2700),
leftPts[leftPts.length - 1], leftPts[leftPts.length - 1].clone().setZ(2700),
leftPts[0], leftPts[0].clone().setZ(this._Height),
leftPts[leftPts.length - 1], leftPts[leftPts.length - 1].clone().setZ(this._Height),
rightPts[0], rightPts[0].clone().setZ(2700),
rightPts[rightPts.length - 1], rightPts[rightPts.length - 1].clone().setZ(2700),
rightPts[0], rightPts[0].clone().setZ(this._Height),
rightPts[rightPts.length - 1], rightPts[rightPts.length - 1].clone().setZ(this._Height),
leftPts.shift()];
@ -197,7 +202,7 @@ export class RoomWallArc extends RoomWallBase
{
pts = [];
let inv = this.OCSInv;
const DrawCurve = (curve: Line | Arc) =>
const DrawCurve = (curve: Curve, _leftRanges: [number, number][], _rightRanges: [number, number][]) =>
{
if (curve instanceof Line)
{
@ -205,25 +210,81 @@ export class RoomWallArc extends RoomWallBase
let p2 = curve.EndPoint.applyMatrix4(inv);
pts.push(p1, p2);
pts.push(p1, p1.clone().setZ(2700));
pts.push(p2, p2.clone().setZ(2700));
pts.push(p1.clone().setZ(2700), p2.clone().setZ(2700));
for (let range of _leftRanges)
pts.push(p1.clone().setZ(range[0]), p1.clone().setZ(range[1]));
for (let range of _rightRanges)
pts.push(p2.clone().setZ(range[0]), p2.clone().setZ(range[1]));
pts.push(p1.clone().setZ(this._Height), p2.clone().setZ(this._Height));
}
else
else//arc
{
let cpts = curve.Shape.getPoints(this.GetDrawCount()).map(AsVector3);
let topPts = cpts.map(p => p.clone().setZ(2700));
pts.push(topPts[0]);//左上
for (let p of cpts) pts.push(p, p);//底部
topPts.reverse();
for (let p of topPts) pts.push(p, p);//顶部
pts.pop();
let topPts = cpts.map(p => p.clone().setZ(this._Height));
//底部
pts.push(cpts[0]);
for (let i = 1; i < cpts.length - 1; i++)
{
let p = cpts[i];
pts.push(p, p);
}
pts.push(cpts[cpts.length - 1]);
//顶部
pts.push(topPts[0]);
for (let i = 1; i < topPts.length - 1; i++)
{
let p = topPts[i];
pts.push(p, p);
}
pts.push(topPts[topPts.length - 1]);
//竖线
for (let range of _leftRanges)
pts.push(cpts[0].clone().setZ(range[0]), cpts[0].clone().setZ(range[1]));
for (let range of _rightRanges)
pts.push(cpts[cpts.length - 1].clone().setZ(range[0]), cpts[cpts.length - 1].clone().setZ(range[1]));
}
};
this.LeftCurves.forEach(DrawCurve);
this.RightCurves.forEach(DrawCurve);
this.LidCurves.forEach(DrawCurve);
let lidRanges: [number, number][] = [[0, this._Height]];
let leftRanges = lidRanges;
let rightRanges = lidRanges;
for (let hole of this.Holes)
{
if (hole.StartParam === 0)
{
let newLeftRanges = [];
for (let range of leftRanges)
arrayPushArray(newLeftRanges, SubtractRange(range[0], range[1], hole.Bottom, hole.Top, 1e5));
leftRanges = newLeftRanges;
}
if (hole.EndParam === 1)
{
let newRightRanges = [];
for (let range of rightRanges)
arrayPushArray(newRightRanges, SubtractRange(range[0], range[1], hole.Bottom, hole.Top, 1e5));
rightRanges = newRightRanges;
}
}
for (let i = 0; i < this.LeftCurves.length; i++)
{
let curve = this.LeftCurves[i];
DrawCurve(curve, i === 0 ? leftRanges : lidRanges, (i === this.LeftCurves.length - 1) ? rightRanges : lidRanges);
}
for (let i = 0; i < this.RightCurves.length; i++)
{
let curve = this.RightCurves[i];
DrawCurve(curve, i === 0 ? leftRanges : lidRanges, (i === this.RightCurves.length - 1) ? rightRanges : lidRanges);
}
for (let i = 0; i < this.LidCurves.length; i++)
{
let curve = this.LidCurves[i];
DrawCurve(curve, lidRanges, lidRanges);
}
}
this._EdgeGeometry = BufferGeometryUtils.CreateFromPts(pts);
@ -241,61 +302,163 @@ export class RoomWallArc extends RoomWallBase
let center = this.Center;
let inv = this.OCSInv;
let thisParam = new GetArcParam(this as unknown as Arc);
const BuildLeftFace = (curve: Curve) =>
{
if (curve[CURVE_FACE_TYPE_KEY] === WallFaceType.Outside) return;//我们暂时直接不绘制外墙 (我们应该和酷家乐一样 在视线所到之处 将整个墙隐藏 而不是只隐藏一个面)
if (curve instanceof Line)
{
let startIndex = geo.vertices.length;
let tapes = [new Tape(0, 1, 0, this._Height)];
let curveParam = new GetLineParam(curve);
let dir = curve.GetFistDeriv(0).normalize();
LEFT_ROTATE_MTX2.applyVector(dir);
if (this.Holes.length)
{
for (let hole of this.Holes)
{
let start = equaln(hole.StartParam, 0) ? 0 : curveParam.GetParamAtPoint(thisParam.GetPointAtParam(hole.StartParam));
let end = equaln(hole.EndParam, 1) ? 1 : curveParam.GetParamAtPoint(thisParam.GetPointAtParam(hole.EndParam));
if (start > end) [start, end] = [end, start];
let holeTape = new Tape(start, end, hole.Bottom, hole.Top);
let newTapes: Tape[] = [];
for (let tape of tapes)
arrayPushArray(newTapes, tape.Clip(holeTape));
tapes = newTapes;
}
}
let p1 = curve.StartPoint.applyMatrix4(inv);
let p2 = curve.EndPoint.applyMatrix4(inv);
geo.vertices.push(p1, p2);
geo.vertices.push(p1.clone().setZ(2700));
geo.vertices.push(p2.clone().setZ(2700));
for (let tape of tapes)
{
let startIndex = geo.vertices.length;
let p1 = curveParam.GetPointAtParam(tape.start).applyMatrix4(inv);
let p2 = curveParam.GetPointAtParam(tape.end).applyMatrix4(inv);
geo.vertices.push(p1.setZ(tape.bottom), p2.setZ(tape.bottom));
geo.vertices.push(p1.clone().setZ(tape.top));
geo.vertices.push(p2.clone().setZ(tape.top));
let x = curve.Length * 1e-3;
let z = 2700 * 1e-3;
let startX = curveParam.Length * 1e-3 * tape.start;
let endX = curveParam.Length * 1e-3 * tape.end;
geo.faces.push(
new Face3(startIndex, startIndex + 2, startIndex + 1, dir),
new Face3(startIndex + 1, startIndex + 2, startIndex + 3, dir),
);
let startZ = tape.bottom * 1e-3;
let endZ = tape.top * 1e-3;
geo.faceVertexUvs[0].push(
[new Vector2(), new Vector2(0, z), new Vector2(x, 0)],
[new Vector2(x, 0), new Vector2(0, z), new Vector2(x, z)],
);
geo.faces.push(
new Face3(startIndex, startIndex + 2, startIndex + 1, curveParam.LeftDir),
new Face3(startIndex + 1, startIndex + 2, startIndex + 3, curveParam.LeftDir),
);
geo.faceVertexUvs[0].push(
[new Vector2(startX, startZ), new Vector2(startX, endZ), new Vector2(endX, startZ)],
[new Vector2(endX, startZ), new Vector2(startX, endZ), new Vector2(endX, endZ)],
);
}
}
else
{
let arc = curve as Arc;
let startIndex = geo.vertices.length;
let pts = curve.Shape.getPoints(this.GetDrawCount()).map(AsVector3);
let pts2 = pts.map(p => p.clone().setZ(2700));
arrayPushArray(geo.vertices, pts);
arrayPushArray(geo.vertices, pts2);
let tapes = [new Tape(0, 1, 0, this._Height)];
let curveParam = new GetArcParam(arc);
let count = pts.length;
for (let i = 1; i < count; i++)
if (this.Holes.length)
{
let pre = i - 1;
for (let hole of this.Holes)
{
let start = equaln(hole.StartParam, 0) ? 0 : curveParam.GetParamAtPoint(thisParam.GetPointAtParam(hole.StartParam));
let end = equaln(hole.EndParam, 1) ? 1 : curveParam.GetParamAtPoint(thisParam.GetPointAtParam(hole.EndParam));
if (start > end) [start, end] = [end, start];
let holeTape = new Tape(start, end, hole.Bottom, hole.Top);
let newTapes: Tape[] = [];
for (let tape of tapes)
arrayPushArray(newTapes, tape.Clip(holeTape));
tapes = newTapes;
}
}
let dir = pts[i].clone().add(pts[pre]).multiplyScalar(0.5).sub(center).subScalar(arc.Radius);
geo.faces.push(
new Face3(startIndex + i, startIndex + pre, startIndex + pre + count, dir),
new Face3(startIndex + i + count, startIndex + i, startIndex + pre + count, dir),
);
geo.faceVertexUvs[0].push(
[new Vector2(), new Vector2(0, 0), new Vector2(0, 0)],
[new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0)],
);
if (this.Holes.length)
{
let length = arc.Length;
let params: number[] = SplitArcParams(arc);
//需要合并顶点,所以建立一个map
let cacheIndex: { [key: string]: number; } = {};
const GetIndex = (param: number, z: number) =>
{
let key = `${param}_${z}`;
let index = cacheIndex[key];
if (index === undefined)
{
index = geo.vertices.length;
cacheIndex[key] = index;
geo.vertices.push(curveParam.GetPointAtParam(param).applyMatrix4(inv).setZ(z));
}
return index;
};
for (let tapeaaaaa of tapes)
{
for (let tape of tapeaaaaa.Split(params))
{
let p1Index = GetIndex(tape.start, tape.bottom);
let p2Index = GetIndex(tape.end, tape.bottom);
let p3Index = GetIndex(tape.start, tape.top);
let p4Index = GetIndex(tape.end, tape.top);
let startX = length * 1e-3 * tape.start;
let endX = length * 1e-3 * tape.end;
let startZ = tape.bottom * 1e-3;
let endZ = tape.top * 1e-3;
let dir = arc.GetPointAtParam((tape.start + tape.end) * 0.5).applyMatrix4(inv).sub(center).subScalar(arc.Radius);
geo.faces.push(
new Face3(p1Index, p3Index, p2Index, dir),
new Face3(p2Index, p3Index, p4Index, dir),
);
geo.faceVertexUvs[0].push(
[new Vector2(startX, startZ), new Vector2(startX, endZ), new Vector2(endX, startZ)],
[new Vector2(endX, startZ), new Vector2(startX, endZ), new Vector2(endX, endZ)],
);
}
}
}
else
{
let startIndex = geo.vertices.length;
let pts = curve.Shape.getPoints(this.GetDrawCount()).map(AsVector3);
let pts2 = pts.map(p => p.clone().setZ(this._Height));
arrayPushArray(geo.vertices, pts);
arrayPushArray(geo.vertices, pts2);
let count = pts.length;
let length = curve.Length * 1e-3;
let divLength = length / pts.length;
for (let i = 1; i < count; i++)
{
let pre = i - 1;
let preX = pre * divLength;
let nowX = i * divLength;
let dir = pts[i].clone().add(pts[pre]).multiplyScalar(0.5).sub(center).subScalar(arc.Radius);
geo.faces.push(
new Face3(startIndex + i, startIndex + pre, startIndex + pre + count, dir),
new Face3(startIndex + i + count, startIndex + i, startIndex + pre + count, dir),
);
geo.faceVertexUvs[0].push(
[new Vector2(nowX, 0), new Vector2(preX, 0), new Vector2(preX, this._Height * 1e-3)],
[new Vector2(nowX, this._Height * 1e-3), new Vector2(nowX, 0), new Vector2(preX, this._Height * 1e-3)],
);
}
}
}
};
@ -305,75 +468,169 @@ export class RoomWallArc extends RoomWallBase
if (curve instanceof Line)
{
let startIndex = geo.vertices.length;
let p1 = curve.StartPoint.applyMatrix4(inv);
let p2 = curve.EndPoint.applyMatrix4(inv);
geo.vertices.push(p1, p2);
geo.vertices.push(p1.clone().setZ(2700));
geo.vertices.push(p2.clone().setZ(2700));
let dir = curve.GetFistDeriv(0).normalize();
LEFT_ROTATE_MTX2.applyVector(dir);
dir.negate();
let x = curve.Length * 1e-3;
let z = 2700 * 1e-3;
geo.faces.push(
new Face3(startIndex, startIndex + 1, startIndex + 2, dir),
new Face3(startIndex + 1, startIndex + 3, startIndex + 2, dir),
);
geo.faceVertexUvs[0].push(
[new Vector2(), new Vector2(x, 0), new Vector2(0, z)],
[new Vector2(x, 0), new Vector2(x, z), new Vector2(0, z)],
);
}
else
{
let arc = curve as Arc;
let startIndex = geo.vertices.length;
let tapes = [new Tape(0, 1, 0, this._Height)];
let curveParam = new GetLineParam(curve);
let pts = curve.Shape.getPoints(this.GetDrawCount()).map(AsVector3);
let pts2 = pts.map(p => p.clone().setZ(2700));
arrayPushArray(geo.vertices, pts);
arrayPushArray(geo.vertices, pts2);
if (this.Holes.length)
{
for (let hole of this.Holes)
{
let start = equaln(hole.StartParam, 0) ? 0 : curveParam.GetParamAtPoint(thisParam.GetPointAtParam(hole.StartParam));
let end = equaln(hole.EndParam, 1) ? 1 : curveParam.GetParamAtPoint(thisParam.GetPointAtParam(hole.EndParam));
if (start > end) [start, end] = [end, start];
let holeTape = new Tape(start, end, hole.Bottom, hole.Top);
let newTapes: Tape[] = [];
for (let tape of tapes)
arrayPushArray(newTapes, tape.Clip(holeTape));
tapes = newTapes;
}
}
let count = pts.length;
for (let i = 1; i < count; i++)
for (let tape of tapes)
{
let pre = i - 1;
let startIndex = geo.vertices.length;
let p1 = curveParam.GetPointAtParam(tape.start).applyMatrix4(inv);
let p2 = curveParam.GetPointAtParam(tape.end).applyMatrix4(inv);
geo.vertices.push(p1.setZ(tape.bottom), p2.setZ(tape.bottom));
geo.vertices.push(p1.clone().setZ(tape.top));
geo.vertices.push(p2.clone().setZ(tape.top));
let startX = curveParam.Length * 1e-3 * tape.start;
let endX = curveParam.Length * 1e-3 * tape.end;
let startZ = tape.bottom * 1e-3;
let endZ = tape.top * 1e-3;
let dir = pts[i].clone().add(pts[pre]).multiplyScalar(0.5).sub(center).subScalar(arc.Radius);
geo.faces.push(
new Face3(startIndex + pre, startIndex + i, startIndex + pre + count, dir),
new Face3(startIndex + i, startIndex + i + count, startIndex + pre + count, dir),
new Face3(startIndex, startIndex + 1, startIndex + 2, curveParam.RightDir),
new Face3(startIndex + 1, startIndex + 3, startIndex + 2, curveParam.RightDir),
);
geo.faceVertexUvs[0].push(
[new Vector2(), new Vector2(0, 0), new Vector2(0, 0)],
[new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0)],
[new Vector2(startX, startZ), new Vector2(endX, startZ), new Vector2(startX, endZ)],
[new Vector2(endX, startZ), new Vector2(endX, endZ), new Vector2(startX, endZ)],
);
}
}
else
{
let arc = curve as Arc;
let tapes = [new Tape(0, 1, 0, this._Height)];
let curveParam = new GetArcParam(arc);
if (this.Holes.length)
{
for (let hole of this.Holes)
{
let start = equaln(hole.StartParam, 0) ? 0 : curveParam.GetParamAtPoint(thisParam.GetPointAtParam(hole.StartParam));
let end = equaln(hole.EndParam, 1) ? 1 : curveParam.GetParamAtPoint(thisParam.GetPointAtParam(hole.EndParam));
if (start > end) [start, end] = [end, start];
let holeTape = new Tape(start, end, hole.Bottom, hole.Top);
let newTapes: Tape[] = [];
for (let tape of tapes)
arrayPushArray(newTapes, tape.Clip(holeTape));
tapes = newTapes;
}
let length = arc.Length;
let params: number[] = SplitArcParams(arc);
//需要合并顶点,所以建立一个map
let cacheIndex: { [key: string]: number; } = {};
const GetIndex = (param: number, z: number) =>
{
let key = `${param}_${z}`;
let index = cacheIndex[key];
if (index === undefined)
{
index = geo.vertices.length;
cacheIndex[key] = index;
geo.vertices.push(curveParam.GetPointAtParam(param).applyMatrix4(inv).setZ(z));
}
return index;
};
for (let tapeaaaaa of tapes)
{
for (let tape of tapeaaaaa.Split(params))
{
let p1Index = GetIndex(tape.start, tape.bottom);
let p2Index = GetIndex(tape.end, tape.bottom);
let p3Index = GetIndex(tape.start, tape.top);
let p4Index = GetIndex(tape.end, tape.top);
let startX = length * 1e-3 * tape.start;
let endX = length * 1e-3 * tape.end;
let startZ = tape.bottom * 1e-3;
let endZ = tape.top * 1e-3;
let dir = arc.GetPointAtParam((tape.start + tape.end) * 0.5).applyMatrix4(inv).sub(center).subScalar(arc.Radius).negate();
geo.faces.push(
new Face3(p1Index, p2Index, p3Index, dir),
new Face3(p2Index, p4Index, p3Index, dir),
);
geo.faceVertexUvs[0].push(
[new Vector2(startX, startZ), new Vector2(endX, startZ), new Vector2(startX, endZ)],
[new Vector2(endX, startZ), new Vector2(endX, endZ), new Vector2(startX, endZ)],
);
}
}
}
else
{
let arc = curve as Arc;
let startIndex = geo.vertices.length;
let pts = curve.Shape.getPoints(this.GetDrawCount()).map(AsVector3);
let pts2 = pts.map(p => p.clone().setZ(this._Height));
arrayPushArray(geo.vertices, pts);
arrayPushArray(geo.vertices, pts2);
let length = curve.Length * 1e-3;
let divLength = length / pts.length;
let count = pts.length;
for (let i = 1; i < count; i++)
{
let pre = i - 1;
let preX = pre * divLength;
let nowX = i * divLength;
let dir = pts[i].clone().add(pts[pre]).multiplyScalar(0.5).sub(center).subScalar(arc.Radius);
geo.faces.push(
new Face3(startIndex + pre, startIndex + i, startIndex + pre + count, dir),
new Face3(startIndex + i, startIndex + i + count, startIndex + pre + count, dir),
);
geo.faceVertexUvs[0].push(
[new Vector2(preX, 0), new Vector2(nowX, 0), new Vector2(preX, this._Height * 1e-3)],
[new Vector2(nowX, 0), new Vector2(nowX, this._Height * 1e-3), new Vector2(preX, this._Height * 1e-3)],
);
}
}
}
};
const BuildRegionFace = (region: Polyline) =>
{
let lined = region.MatrixAlignTo2(this.OCSNoClone);
if (region.CloseMark && !equalv2(lined.pts[0], lined.pts[lined.pts.length - 1], 1e-4))
{
lined.pts.push(lined.pts[0]);
lined.buls.push(0);
}
let path = CreatePolylinePath(lined.pts, lined.buls);
let params = SplitCurveParams(region);
let ocsInv = this.OCSInv;
let pts = params.map(param => AsVector2(region.GetPointAtParam(param).applyMatrix4(ocsInv)));
let pts = path.getPoints(this.GetDrawCount());
let faces = ShapeUtils.triangulateShape(pts, []);
//top
let startIndex = geo.vertices.length;
for (let p of pts) geo.vertices.push(new Vector3(p.x, p.y, 2700));
for (let p of pts) geo.vertices.push(new Vector3(p.x, p.y, this._Height));
for (let p of pts) geo.vertices.push(new Vector3(p.x, p.y, 0));
for (let i = 0; i < faces.length; i++)
@ -400,8 +657,8 @@ export class RoomWallArc extends RoomWallBase
// {
// startIndex = geo.vertices.length;
// geo.vertices.push(AsVector3(pre), AsVector3(p));
// geo.vertices.push(AsVector3(pre).setZ(2700));
// geo.vertices.push(AsVector3(p).setZ(2700));
// geo.vertices.push(AsVector3(pre).setZ(this._Height));
// geo.vertices.push(AsVector3(p).setZ(this._Height));
// LEFT_ROTATE_MTX2.applyVector(tempV);
// tempV.negate();

@ -8,6 +8,7 @@ import { Arc } from "../../../Entity/Arc";
import { Curve } from "../../../Entity/Curve";
import { Line } from "../../../Entity/Line";
import { Polyline } from "../../../Entity/Polyline";
import { ObjectId } from "../../../ObjectId";
import { RoomBase } from "../RoomBase";
import { WallSnapMode } from "./WallSnapMode";
@ -20,19 +21,36 @@ export enum WallFaceType
Outside = 2,//外墙
}
interface HoleData
{
StartParam: number;
EndParam: number;
Bottom: number;
Top: number;
}
@Factory
export abstract class RoomWallBase extends RoomBase
{
static SnapMode: WallSnapMode = WallSnapMode.All;
private _Thickness = 120;
RelevancyHoles: ObjectId[] = [];
Holes: HoleData[] = [];
//中心轴线
get CenterAxisCurve(): Arc | Line { return; }
protected _Thickness = 120;
protected _Height = 2700;
//从曲线更新墙体
UpdateCurve(cu: Curve) { }
get Height()
{
return this._Height;
}
set Height(_newHeight)
{
if (_newHeight <= 0.1 || equaln(this._Height, _newHeight)) return;
this.WriteAllObjectRecord();
this._Height = _newHeight;
this.Update();
}
get Thickness() { return this._Thickness; }
set Thickness(t: number)
@ -43,6 +61,13 @@ export abstract class RoomWallBase extends RoomBase
this.Update();
}
//中心轴线
get CenterAxisCurve(): Arc | Line { return; }
//从曲线更新墙体
UpdateCurve(cu: Curve) { }
//绘制相关
LeftCurves: (Arc | Line)[];
RightCurves: (Arc | Line)[];

@ -5,13 +5,14 @@ import { EntityUpdateWrap } from "../../../../Common/EntityUpdateWrap";
import { ObjectSnapMode } from "../../../../Editor/ObjectSnapMode";
import { Box3Ext } from "../../../../Geometry/Box";
import { BufferGeometryUtils } from "../../../../Geometry/BufferGeometryUtils";
import { equalv3, midPoint, MoveMatrix, ZeroVec } from "../../../../Geometry/GeUtils";
import { equaln, equalv3, midPoint, MoveMatrix, ZeroVec } from "../../../../Geometry/GeUtils";
import { RenderType } from "../../../../GraphicsSystem/RenderType";
import { SubtractRange, Tape } from "../../../../ueapi";
import { Factory } from "../../../CADFactory";
import { CADFiler } from "../../../CADFiler";
import { Curve } from "../../../Entity/Curve";
import { Line } from "../../../Entity/Line";
import { GetLineParam, LEFT_ROTATE_MTX2 } from "../../ParseService/GetCurveParam";
import { GetLineParam } from "../../ParseService/GetCurveParam";
import { applyMixins, CURVE_FACE_TYPE_KEY, RoomWallBase, WallFaceType } from "./RoomWallBase";
import { WallSnapMode } from "./WallSnapMode";
@ -118,7 +119,7 @@ export class RoomWallLine extends RoomWallBase
//顶部线
let bakZ = curve.OCSNoClone.elements[14];
curve.OCSNoClone.elements[14] = 2700;
curve.OCSNoClone.elements[14] = this._Height;
arrayPushArray(pts, curve.GetObjectSnapPoints(snapMode, pickPoint, lastPoint, viewXform));
curve.OCSNoClone.elements[14] = bakZ;
@ -127,14 +128,14 @@ export class RoomWallLine extends RoomWallBase
//@ts-ignore
SnapTempLine._StartPoint.copy(curve._StartPoint);
//@ts-ignore
SnapTempLine._EndPoint.copy(curve._StartPoint).setZ(2700);
SnapTempLine._EndPoint.copy(curve._StartPoint).setZ(this._Height);
arrayPushArray(pts, SnapTempLine.GetObjectSnapPoints(snapMode, pickPoint, lastPoint, viewXform));
//@ts-ignore
SnapTempLine._StartPoint.copy(curve._EndPoint);
//@ts-ignore
SnapTempLine._EndPoint.copy(curve._EndPoint).setZ(2700);
SnapTempLine._EndPoint.copy(curve._EndPoint).setZ(this._Height);
arrayPushArray(pts, SnapTempLine.GetObjectSnapPoints(snapMode, pickPoint, lastPoint, viewXform));
};
@ -157,7 +158,7 @@ export class RoomWallLine extends RoomWallBase
for (let i = 0; i < 3; i++)
{
let p = pts[i].clone();
pts.push(p.setZ(p.z + 2700));
pts.push(p.setZ(p.z + this._Height));
}
return pts;
}
@ -227,6 +228,10 @@ export class RoomWallLine extends RoomWallBase
{
if (this._EdgeGeometry) return this._EdgeGeometry;
for (let hole of this.Holes)
if (hole.StartParam > hole.EndParam)
[hole.StartParam, hole.EndParam] = [hole.EndParam, hole.StartParam];
let pts: Vector3[];
if (!this.LeftCurves)
{
@ -240,7 +245,7 @@ export class RoomWallLine extends RoomWallBase
let p3 = parse.OffsetPoint(this._EndPoint.clone(), this.Thickness * 0.5);//left
let p4 = parse.OffsetPoint(this._EndPoint.clone(), this.Thickness * -0.5);//right
let [pz1, pz2, pz3, pz4] = [p1, p2, p3, p4].map(p => p.clone().setZ(2700));
let [pz1, pz2, pz3, pz4] = [p1, p2, p3, p4].map(p => p.clone().setZ(this._Height));
pts = [p1, p2, p2, p4, p4, p3, p3, p1,
pz1, pz2, pz2, pz4, pz4, pz3, pz3, pz1,
@ -255,7 +260,7 @@ export class RoomWallLine extends RoomWallBase
{
pts = [];
let inv = this.OCSInv;
const DrawCurve = (curve: Curve) =>
const DrawCurve = (curve: Curve, _leftRanges: [number, number][], _rightRanges: [number, number][]) =>
{
if (curve instanceof Line)
{
@ -263,14 +268,52 @@ export class RoomWallLine extends RoomWallBase
let p2 = curve.EndPoint.applyMatrix4(inv);
pts.push(p1, p2);
pts.push(p1, p1.clone().setZ(2700));
pts.push(p2, p2.clone().setZ(2700));
pts.push(p1.clone().setZ(2700), p2.clone().setZ(2700));
for (let range of _leftRanges)
pts.push(p1.clone().setZ(range[0]), p1.clone().setZ(range[1]));
for (let range of _rightRanges)
pts.push(p2.clone().setZ(range[0]), p2.clone().setZ(range[1]));
pts.push(p1.clone().setZ(this._Height), p2.clone().setZ(this._Height));
}
};
this.LeftCurves.forEach(DrawCurve);
this.RightCurves.forEach(DrawCurve);
this.LidCurves.forEach(DrawCurve);
let lidRanges: [number, number][] = [[0, this._Height]];
let leftRanges = lidRanges;
let rightRanges = lidRanges;
for (let hole of this.Holes)
{
if (hole.StartParam === 0)
{
let newLeftRanges = [];
for (let range of leftRanges)
arrayPushArray(newLeftRanges, SubtractRange(range[0], range[1], hole.Bottom, hole.Top, 1e5));
leftRanges = newLeftRanges;
}
if (hole.EndParam === 1)
{
let newRightRanges = [];
for (let range of rightRanges)
arrayPushArray(newRightRanges, SubtractRange(range[0], range[1], hole.Bottom, hole.Top, 1e5));
rightRanges = newRightRanges;
}
}
for (let i = 0; i < this.LeftCurves.length; i++)
{
let curve = this.LeftCurves[i];
DrawCurve(curve, i === 0 ? leftRanges : lidRanges, (i === this.LeftCurves.length - 1) ? rightRanges : lidRanges);
}
for (let i = 0; i < this.RightCurves.length; i++)
{
let curve = this.RightCurves[i];
DrawCurve(curve, i === 0 ? leftRanges : lidRanges, (i === this.RightCurves.length - 1) ? rightRanges : lidRanges);
}
for (let i = 0; i < this.LidCurves.length; i++)
{
let curve = this.LidCurves[i];
DrawCurve(curve, lidRanges, lidRanges);
}
}
this._EdgeGeometry = BufferGeometryUtils.CreateFromPts(pts ?? []);
@ -301,7 +344,7 @@ export class RoomWallLine extends RoomWallBase
let p3 = parse.OffsetPoint(this._EndPoint.clone(), this.Thickness * 0.5);//left
let p4 = parse.OffsetPoint(this._EndPoint.clone(), this.Thickness * -0.5);//right
let [pz1, pz2, pz3, pz4] = [p1, p2, p3, p4].map(p => p.clone().setZ(2700));
let [pz1, pz2, pz3, pz4] = [p1, p2, p3, p4].map(p => p.clone().setZ(this._Height));
geo.vertices.push(p1, p2, p3, p4, pz1, pz2, pz3, pz4);
@ -329,7 +372,7 @@ export class RoomWallLine extends RoomWallBase
//x
let x = parse.Length * 1e-3;
let y = this.Thickness * 1e-3;
let z = 2700 * 1e-3;
let z = this._Height * 1e-3;
geo.faceVertexUvs[0].push(
//floor
[new Vector2(0, 0), new Vector2(x, 0), new Vector2(0, y)],
@ -357,32 +400,63 @@ export class RoomWallLine extends RoomWallBase
else
{
let inv = this.OCSInv;
let thisParam = new GetLineParam(this as unknown as Line);
const BuildLeftFace = (curve: Curve) =>
{
if (curve[CURVE_FACE_TYPE_KEY] === WallFaceType.Outside) return;//我们暂时直接不绘制外墙 (我们应该和酷家乐一样 在视线所到之处 将整个墙隐藏 而不是只隐藏一个面)
if (curve instanceof Line)
{
let startIndex = geo.vertices.length;
let p1 = curve.StartPoint.applyMatrix4(inv);
let p2 = curve.EndPoint.applyMatrix4(inv);
geo.vertices.push(p1, p2);
geo.vertices.push(p1.clone().setZ(2700));
geo.vertices.push(p2.clone().setZ(2700));
let x = curve.Length * 1e-3;
let z = 2700 * 1e-3;
geo.faces.push(
new Face3(startIndex, startIndex + 2, startIndex + 1, parse.LeftDir),
new Face3(startIndex + 1, startIndex + 2, startIndex + 3, parse.LeftDir),
);
geo.faceVertexUvs[0].push(
[new Vector2(), new Vector2(0, z), new Vector2(x, 0)],
[new Vector2(x, 0), new Vector2(0, z), new Vector2(x, z)],
);
let tapes = [new Tape(0, 1, 0, this._Height)];
let curveParam = new GetLineParam(curve);
if (this.Holes.length)
{
for (let hole of this.Holes)
{
let start = equaln(hole.StartParam, 0) ? 0 : curveParam.GetParamAtPoint(thisParam.GetPointAtParam(hole.StartParam));
let end = equaln(hole.EndParam, 1) ? 1 : curveParam.GetParamAtPoint(thisParam.GetPointAtParam(hole.EndParam));
if (start > end) [start, end] = [end, start];
start = Math.max(0, start);
end = Math.min(1, end);
if (start >= end) continue;
let holeTape = new Tape(start, end, hole.Bottom, hole.Top);
let newTapes: Tape[] = [];
for (let tape of tapes)
arrayPushArray(newTapes, tape.Clip(holeTape));
tapes = newTapes;
}
}
for (let tape of tapes)
{
let startIndex = geo.vertices.length;
let p1 = curveParam.GetPointAtParam(tape.start).applyMatrix4(inv);
let p2 = curveParam.GetPointAtParam(tape.end).applyMatrix4(inv);
geo.vertices.push(p1.setZ(tape.bottom), p2.setZ(tape.bottom));
geo.vertices.push(p1.clone().setZ(tape.top));
geo.vertices.push(p2.clone().setZ(tape.top));
let startX = curveParam.Length * 1e-3 * tape.start;
let endX = curveParam.Length * 1e-3 * tape.end;
let startZ = tape.bottom * 1e-3;
let endZ = tape.top * 1e-3;
geo.faces.push(
new Face3(startIndex, startIndex + 2, startIndex + 1, parse.LeftDir),
new Face3(startIndex + 1, startIndex + 2, startIndex + 3, parse.LeftDir),
);
geo.faceVertexUvs[0].push(
[new Vector2(startX, startZ), new Vector2(startX, endZ), new Vector2(endX, startZ)],
[new Vector2(endX, startZ), new Vector2(startX, endZ), new Vector2(endX, endZ)],
);
}
}
};
const BuildRightFace = (curve: Curve) =>
@ -391,30 +465,52 @@ export class RoomWallLine extends RoomWallBase
if (curve instanceof Line)
{
let startIndex = geo.vertices.length;
let p1 = curve.StartPoint.applyMatrix4(inv);
let p2 = curve.EndPoint.applyMatrix4(inv);
geo.vertices.push(p1, p2);
geo.vertices.push(p1.clone().setZ(2700));
geo.vertices.push(p2.clone().setZ(2700));
let dir = curve.GetFistDeriv(0).normalize();
LEFT_ROTATE_MTX2.applyVector(dir);
dir.negate();
let x = curve.Length * 1e-3;
let z = 2700 * 1e-3;
geo.faces.push(
new Face3(startIndex, startIndex + 1, startIndex + 2, dir),
new Face3(startIndex + 1, startIndex + 3, startIndex + 2, dir),
);
geo.faceVertexUvs[0].push(
[new Vector2(), new Vector2(x, 0), new Vector2(0, z)],
[new Vector2(x, 0), new Vector2(x, z), new Vector2(0, z)],
);
let tapes = [new Tape(0, 1, 0, this._Height)];
let curveParam = new GetLineParam(curve);
if (this.Holes.length)
{
for (let hole of this.Holes)
{
let start = equaln(hole.StartParam, 0) ? 0 : curveParam.GetParamAtPoint(thisParam.GetPointAtParam(hole.StartParam));
let end = equaln(hole.EndParam, 1) ? 1 : curveParam.GetParamAtPoint(thisParam.GetPointAtParam(hole.EndParam));
if (start > end) [start, end] = [end, start];
let holeTape = new Tape(start, end, hole.Bottom, hole.Top);
let newTapes: Tape[] = [];
for (let tape of tapes)
arrayPushArray(newTapes, tape.Clip(holeTape));
tapes = newTapes;
}
}
for (let tape of tapes)
{
let startIndex = geo.vertices.length;
let p1 = curveParam.GetPointAtParam(tape.start).applyMatrix4(inv);
let p2 = curveParam.GetPointAtParam(tape.end).applyMatrix4(inv);
geo.vertices.push(p1.setZ(tape.bottom), p2.setZ(tape.bottom));
geo.vertices.push(p1.clone().setZ(tape.top));
geo.vertices.push(p2.clone().setZ(tape.top));
let startX = curveParam.Length * 1e-3 * tape.start;
let endX = curveParam.Length * 1e-3 * tape.end;
let startZ = tape.bottom * 1e-3;
let endZ = tape.top * 1e-3;
geo.faces.push(
new Face3(startIndex, startIndex + 1, startIndex + 2, curveParam.RightDir),
new Face3(startIndex + 1, startIndex + 3, startIndex + 2, curveParam.RightDir),
);
geo.faceVertexUvs[0].push(
[new Vector2(startX, startZ), new Vector2(endX, startZ), new Vector2(startX, endZ)],
[new Vector2(endX, startZ), new Vector2(endX, endZ), new Vector2(startX, endZ)],
);
}
}
};
this.LeftCurves.forEach(BuildLeftFace);
@ -433,7 +529,7 @@ export class RoomWallLine extends RoomWallBase
//top
let startIndex = geo.vertices.length;
for (let p of pts) geo.vertices.push(new Vector3(p.x, p.y, 2700));
for (let p of pts) geo.vertices.push(new Vector3(p.x, p.y, this._Height));
for (let p of pts) geo.vertices.push(new Vector3(p.x, p.y, 0));
for (let i = 0; i < faces.length; i++)
@ -460,8 +556,8 @@ export class RoomWallLine extends RoomWallBase
// {
// startIndex = geo.vertices.length;
// geo.vertices.push(AsVector3(pre), AsVector3(p));
// geo.vertices.push(AsVector3(pre).setZ(2700));
// geo.vertices.push(AsVector3(p).setZ(2700));
// geo.vertices.push(AsVector3(pre).setZ(this._Height));
// geo.vertices.push(AsVector3(p).setZ(this._Height));
// LEFT_ROTATE_MTX2.applyVector(tempV);
// tempV.negate();

@ -143,6 +143,10 @@ export class CurveTrimLine extends CurveTrim
if (this._TrimParams.length === 0) return [this._curve as Line];
let lines: Line[] = [];
if (this._TrimParams[0][0] !== 0)
lines.push(new Line(this.GetPointAtParam(0), this.GetPointAtParam(this._TrimParams[0][0])));
for (let i = 0; i < this._TrimParams.length - 1; i++)
{
let param1 = this._TrimParams[i][1];
@ -150,9 +154,6 @@ export class CurveTrimLine extends CurveTrim
lines.push(new Line(this.GetPointAtParam(param1), this.GetPointAtParam(param2)));
}
if (this._TrimParams[0][0] !== 0)
lines.push(new Line(this.GetPointAtParam(0), this.GetPointAtParam(this._TrimParams[0][0])));
if (this._TrimParams[this._TrimParams.length - 1][1] !== 1)
lines.push(new Line(this.GetPointAtParam(this._TrimParams[this._TrimParams.length - 1][1]), this.GetPointAtParam(1)));

@ -4,7 +4,7 @@ import { RoomWallBase } from "../../Entity/Wall/RoomWallBase";
import { CreateGetCurveParam, GetCurveParam } from "../GetCurveParam";
import { InsertSortedIndex, Intersection } from '../RangeUtils';
export class PlaceIHoleHelper
export class RoomWallPlaceIHoleHelper
{
protected _ParamGets: GetCurveParam[] = [];
protected _ParamRanges: ([number, number][])[] = [];

@ -3,7 +3,7 @@ import { Vector3 } from 'three';
import { Vertice } from "../../../../Geometry/CurveMap";
import { RoomWallParse } from "../RoomWallParse";
export class PlaceLHoleHelper
export class RoomWallPlaceLHoleHelper
{
_stands: Vertice[];
_fb: Flatbush;
@ -15,6 +15,8 @@ export class PlaceLHoleHelper
FindBestPlace(p: Vector3)
{
if (!this._fb) return;
let ids = this._fb.neighbors(p.x, p.y, 50, 1000);//50个 300距离
let minDist = Infinity;

@ -4,7 +4,7 @@ import { Route } from "../../../../Geometry/CurveMap";
import { Curve } from "../../../Entity/Curve";
import { RoomWallParse } from "../RoomWallParse";
export class PlaceUHoleHelper
export class RoomWallPlaceUHoleHelper
{
constructor()
{

@ -0,0 +1,127 @@
import { Vertice } from "../../../../Geometry/CurveMap";
import { equalv3 } from "../../../../Geometry/GeUtils";
import { RoomHolePolyline } from "../../Entity/Wall/Hole/RoomHolePolyline";
import { RoomWallBase } from "../../Entity/Wall/RoomWallBase";
import { RoomWallParse } from "../RoomWallParse";
import { RoomWallPlaceIHoleHelper } from "./RoomWallPlaceIHoleHelper";
import { RoomWallPlaceLHoleHelper } from "./RoomWallPlaceLHoleHelper";
/**
*
* RoomWallParse,RoomWallParse
*/
export class RoomWallRelevancyHoleParse
{
constructor() { }
Parse(holes: RoomHolePolyline[], walls: RoomWallBase[])
{
let iparse = new RoomWallPlaceIHoleHelper(walls);//计算起点和终点所在的墙
let lparse = new RoomWallPlaceLHoleHelper();//计算中间的顶点
for (let hole of holes)
{
if (hole.IsErase) continue;
let pts = hole.Points;
if (pts.length === 0)
{
hole.Erase();
continue;
}
for (let p of pts) p.setZ(0);//如果不设置为0 找不到墙
let firstWall = iparse.FindBestPlace(pts[0]);
let lastWall = iparse.FindBestPlace(pts[pts.length - 1]);
if (!firstWall || !lastWall)
{
console.warn("找不到墙");
continue;
}
let wallSets = new Set<RoomWallBase>();
wallSets.add(firstWall.wall);
wallSets.add(lastWall.wall);
let orgWalls: RoomWallBase[] = [firstWall.wall];
let vlist: Vertice[] = [];
for (let i = 1; i < pts.length - 1; i++)
{
let v = lparse.FindBestPlace(pts[i]);
if (!v)
{
console.warn("找不到拐角点");
continue;
}
vlist.push(v);
let breakData = RoomWallParse._CacheWallMaps[lparse._standGroupIndexMap.get(v)][0];
//找到这两堵墙
let routeWalls = v.routes.map(r =>
{
let orgCurve = breakData._SplitCurve2OrgCurveMap.get(r.curve);
let orgWall = RoomWallParse._CacheCurveWallMaps.get(orgCurve);
return orgWall;
});
for (let wall of routeWalls)
if (!wallSets.has(wall))
{
wallSets.add(wall);
orgWalls.push(wall);
}
}
if (firstWall.wall !== lastWall.wall)
orgWalls.push(lastWall.wall);
if (orgWalls.length !== pts.length - 1)
{
console.log("个数不对");
continue;
}
let fakerWalls = orgWalls.map(w => w.Clone());
if (vlist.length)
if (!equalv3(fakerWalls[0].EndPoint, vlist[0].position))
fakerWalls[0].Reverse();
for (let i = 1; i < fakerWalls.length; i++)
{
let v = vlist[i - 1];
let wall = fakerWalls[i];
if (!equalv3(wall.StartPoint, v.position))
wall.Reverse();
}
fakerWalls[0].StartPoint = firstWall.getParam.GetPointAtParam(firstWall.cpParam);
fakerWalls[fakerWalls.length - 1].EndPoint = lastWall.getParam.GetPointAtParam(lastWall.cpParam);
new RoomWallParse(false, null, false).Parse(fakerWalls);
hole.FakerWalls = fakerWalls;
hole.RelevancyWalls = orgWalls.map(w => w.Id);
for (let i = 0; i < orgWalls.length; i++)
{
let wall = orgWalls[i];
let fakerWall = fakerWalls[i];
wall.Holes.push({
StartParam: wall.GetParamAtPoint(fakerWall.StartPoint),
EndParam: wall.GetParamAtPoint(fakerWall.EndPoint),
Bottom: hole.Position.z - wall.Position.z,
Top: hole.Position.z - wall.Position.z + hole.Height,
});
wall.RelevancyHoles.push(hole.Id);
wall.Update();
}
}
}
}

@ -13,7 +13,8 @@ export class RoomParse
Parse()
{
new RoomWallParse(this._ExtendsWalls, this._UpdateDb, this._IsCacheWallNodePoints).Do(this.walls);
new RoomWallParse(this._ExtendsWalls, this._UpdateDb, this._IsCacheWallNodePoints).Parse(this.walls);
return this;
}
}

@ -1,6 +1,4 @@
import { arrayRemoveDuplicateBySort } from "../../../Common/ArrayExt";
import { EntitysUpdateWrap } from "../../../Common/EntityUpdateWrap";
import { Status } from "../../../Common/Status";
import { Route } from "../../../Geometry/CurveMap";
import { RegionParse } from "../../../Geometry/RegionParse";
import { Polyline2Points } from "../../../Nest/Converter/Curves2Points";
@ -57,8 +55,7 @@ export class RoomRegionParse
let aloneWalls: RoomWallBase[] = [];
let left = new Set<Curve>();
// let right = new Set<Curve>();
let leftCurves = new Set<Curve>();
for (let wall of walls)
{
@ -71,30 +68,22 @@ export class RoomRegionParse
for (let c of wall.LeftCurves)
{
curves.push(c);
left.add(c);
leftCurves.add(c);
}
for (let c of wall.RightCurves)
{
curves.push(c);
// right.add(c);
}
for (let c of wall.LidCurves)
{
curves.push(c);
}
// arrayPushArray(curves, wall.LeftCurves);
// arrayPushArray(curves, wall.RightCurves);
// arrayPushArray(curves, wall.LidCurves);
}
let parse = new RegionParse(curves);
for (let [orgArc, arcs] of parse.ExpLineMap)
{
if (left.has(orgArc))
if (leftCurves.has(orgArc))
for (let arc of arcs)
left.add(arc);
leftCurves.add(arc);
}
let regionPolylines: Polyline[] = [];
@ -107,7 +96,7 @@ export class RoomRegionParse
// for (let i = 0; i < routes.length; i++)
// {
if (left.has(routes[0].curve))
if (leftCurves.has(routes[0].curve))
pl.ColorIndex = routes[0].isReverse ? 1 : 2;
else //if (right.has(routes[0].curve))
pl.ColorIndex = routes[0].isReverse ? 2 : 1;
@ -227,8 +216,9 @@ export class RoomRegionParse
for (let wall of walls)
{
wall.LeftCurves && arrayRemoveDuplicateBySort(wall.LeftCurves, (cu1: Curve, cu2: Curve) => cu1.Join(cu2) === Status.True);
wall.RightCurves && arrayRemoveDuplicateBySort(wall.RightCurves, (cu1: Curve, cu2: Curve) => cu1.Join(cu2) === Status.True);
// 因为我们现在没有分裂圆弧 所以我们不需要在合并线
// wall.LeftCurves && arrayRemoveDuplicateBySort(wall.LeftCurves, (cu1: Curve, cu2: Curve) => cu1.Join(cu2) === Status.True);
// wall.RightCurves && arrayRemoveDuplicateBySort(wall.RightCurves, (cu1: Curve, cu2: Curve) => cu1.Join(cu2) === Status.True);
wall.Update();
}
}

@ -61,7 +61,7 @@ export class RoomWallParse
* @param walls
* @param changeWalls ( )
*/
Do(walls: RoomWallBase[], changeWalls: RoomWallBase[] = undefined)
Parse(walls: RoomWallBase[], changeWalls: RoomWallBase[] = undefined)
{
if (this._IsCacheWallNodePoints)
{
@ -101,7 +101,7 @@ export class RoomWallParse
regionPrase.End();
}
PraseWallsFromSameFloor(walls: RoomWallBase[], changeWalls: RoomWallBase[] = undefined)
private PraseWallsFromSameFloor(walls: RoomWallBase[], changeWalls: RoomWallBase[] = undefined)
{
SHOW_PERF && console.time("尖角化+裁剪面");
//{墙}->{轴线} {轴线}->{墙}
@ -750,6 +750,7 @@ export class RoomWallParse
arrayPushArray(orgWall.LidCurves, Trim(splitCurve, offsetCurve, orgCurve[ROOM_WALL_INDEX_KEY], CurveType.EndLid));
}
//Update:2022-04-28 我们不再分裂圆弧,所以也不再需要合并线
//区域分析需要破裂的圆弧,这里暂时不合并墙(在room region parse中合并)
// for (let wall of walls)
// {

@ -380,7 +380,7 @@ class EdgeGeometryBuild
/**
*
*/
class Tape
export class Tape
{
constructor(
public start: number,
@ -1144,48 +1144,54 @@ function UnionRange(a: number, b: number, c: number, d: number, end: number): [n
return [[a1, e]];
}
// //0-1
// UnionRange(0.5, 0.3, 0.3, 0.5, 1);//?
// //0-1
// UnionRange(0.4, 0.3, 0.3, 0.5, 1);//?
// //[ [ 0.8, 0.1 ], [ 0.3, 0.5 ] ]
// UnionRange(0.8, 0.1, 0.3, 0.5, 1);//?
// //[ 0.3, 0.10000000000000009 ] ]
// UnionRange(0.8, 0.1, 0.3, 0.9, 1);//?
function SubtractRange(a: number, b: number, c: number, d: number, end: number): Range[]
/**
*
* @param orgStart (, s->end + 0->e)
* @param orgEnd
* @param clipStart
* @param clipEnd
* @param end
* @returns
*/
export function SubtractRange(orgStart: number, orgEnd: number, clipStart: number, clipEnd: number, end: number): Range[]
{
if (a < 0 || b < 0) return [];
if (a > b)
return [...SubtractRange(a, end, c, d, end), ...SubtractRange(0, b, c, d, end)];
if (c > d)
if (orgStart < 0
|| orgEnd < 0
|| orgEnd > end
|| orgStart > end
|| clipStart < 0
|| clipEnd < 0
|| clipStart > end
|| clipEnd > end) return [];
if (orgStart > orgEnd)
return SubtractRange(orgStart, end, clipStart, clipEnd, end).concat(SubtractRange(0, orgEnd, clipStart, clipEnd, end));
if (clipStart > clipEnd)
{
let arr = SubtractRange(a, b, c, end, end);
let arr = SubtractRange(orgStart, orgEnd, clipStart, end, end);
let rem: [number, number][] = [];
for (let s of arr)
rem.push(...SubtractRange(s[0], s[1], 0, d, end));
arrayPushArray(rem, SubtractRange(s[0], s[1], 0, clipEnd, end));
return rem;
}
if (c >= b || d <= a)
return [[a, b]];
if (clipStart >= orgEnd || clipEnd <= orgStart)
return [[orgStart, orgEnd]];
if (c <= a)// c1 a1 b1
if (clipStart <= orgStart)// c1 a1 b1
{
if (d >= b) return [];
return [[d, b]];
if (clipEnd >= orgEnd) return [];
return [[clipEnd, orgEnd]];
}
if (d < b)
return [[a, c], [d, b]];
return [[a, c]];
if (clipEnd < orgEnd)
return [[orgStart, clipStart], [clipEnd, orgEnd]];
return [[orgStart, clipStart]];
}
function SubtractRange2(r: Range, sr: Range, end: number): Range[]
export function SubtractRange2(r: Range, sr: Range, end: number): Range[]
{
return SubtractRange(r[0], r[1], sr[0], sr[1], end);
}
@ -1198,8 +1204,7 @@ function SubtractRanges(ranges: Range[], subRanges: Range[], end: number): Range
{
let temps: Range[] = [];
for (let r of rets)
temps.push(...SubtractRange2(r, sr, end));
arrayPushArray(temps, SubtractRange2(r, sr, end));
rets = temps;
}
return rets;

@ -59,3 +59,25 @@ export function SplitCurveParams(cu: ExtrudeContourCurve): number[]
xparams.push(cu.EndParam);
return xparams;
}
export function SplitArcParams(arc: Arc): number[]
{
let splitCount = arc.Radius / ARC_SplitLength;
splitCount = clamp(Math.floor(splitCount), Arc_MinSplitCount, ARC_MaxSplitCount);
if (splitCount === 0)
return [];
let a = Math.PI * 2 / splitCount;
let params: number[] = [];
for (let j = 0; j < splitCount; j++)
{
let param = arc.GetParamAtAngle(a * j);
if (arc.ParamOnCurve(param))
params.push(param);
}
arraySortByNumber(params);
if (params.length === 0)
return [];
return params.filter(p => p > 1e-5 && p < 9.99999);
}

@ -17,6 +17,8 @@ import { GetEntity } from '../Common/Utils';
import { Database } from '../DatabaseServices/Database';
import { Board } from '../DatabaseServices/Entity/Board';
import { Entity } from '../DatabaseServices/Entity/Entity';
import { RoomHolePolyline } from '../DatabaseServices/Room/Entity/Wall/Hole/RoomHolePolyline';
import { RoomWallRelevancyHoleParse } from '../DatabaseServices/Room/ParseService/Hole/RoomWallRelevancyHoleParse';
import { RoomParse } from '../DatabaseServices/Room/ParseService/RoomParseUtil';
import { DisposeTextShapeCache } from '../DatabaseServices/Text/Text';
import { ViewportEntity } from '../DatabaseServices/ViewportEntity';
@ -649,7 +651,9 @@ export class Viewer
let brs: Board[] = [];
let pre = Date.now();
new RoomParse(false, undefined, true).Parse();
let room = new RoomParse(false, undefined, true).Parse();
let holes = app.Database.ModelSpace.Entitys.filter(e => e instanceof RoomHolePolyline) as RoomHolePolyline[];
new RoomWallRelevancyHoleParse().Parse(holes, room.walls);
for (let index = 0; index < db.ModelSpace.Entitys.length; index++)
{

@ -6,13 +6,12 @@ import { CommandLine } from './CommandLine';
@observer
export class CommandLineContainer extends React.Component<{}, null>
{
//输出信息列表的容器
m_OutputContainer: HTMLElement;
m_CommandListContainer: HTMLElement;
_OutputContainer: HTMLElement;
_CommandListContainer: HTMLElement;
componentDidUpdate()
{
this.m_OutputContainer.scrollTop = this.m_CommandListContainer.offsetHeight;
this._OutputContainer.scrollTop = this._CommandListContainer.offsetHeight;
}
render()
{
@ -20,12 +19,12 @@ export class CommandLineContainer extends React.Component<{}, null>
<div
id="TerminalOutputArea"
className='terminal-output-area scroll flexCol'
ref={el => { this.m_OutputContainer = el; }}
ref={el => { this._OutputContainer = el; }}
style={{ display: "flex" }}
>
<div className='terminal-pusher'></div>
<div className='terminal-output'
ref={el => { this.m_CommandListContainer = el; }}
ref={el => { this._CommandListContainer = el; }}
>
{CommandStore.GetInstance().promptList.map(cmd => <CommandLine key={cmd.key} msg={cmd} />)}
</div>

@ -1,4 +1,4 @@
import { observable } from 'mobx';
import { action, observable } from 'mobx';
import { app } from '../../ApplicationServices/Application';
import { KeyWord } from '../../Common/InputState';
import { commandMachine } from '../../Editor/CommandMachine';
@ -34,7 +34,12 @@ export class CommandStore
//历史命令列表
@observable historyCmdList: string[] = [];
@observable disableInput = false;
//提示字符串 当前:
/**
*
* @param msg
*/
@action
Prompt(msg: string)
{
this.promptList.push({
@ -43,8 +48,8 @@ export class CommandStore
});
this._promptKeyIndex++;
if (this.promptList.length > 50)
this.promptList.splice(0, 20);
if (this.promptList.length >= 50)
this.promptList.splice(0, 10);
}
lastExecTime: number = 0;

@ -29,6 +29,7 @@
"./config/**/*"
],
"exclude": [
"**/*api.ts"
"**/*api.ts",
"./node_modules/**/*"
]
}

@ -34,19 +34,25 @@ async function main()
let str = await fs.readFile(index, "utf-8");
if (str.includes("wallaby已经破解")) return;
if (str.includes("破解成功!自动续订!"))
{
console.log(`${wallaby} 已经破解过了!`);
continue;
};
str = str.replace(`this.on("notification",a=>{`,
`
this.on("notification",a=>{
a.text = "破解成功!自动续订!" + a.text;
this._continueTrial();
console.log("wallaby已经破解!");
if (a.text.indexOf("continue-trial-link") || a.text.indexOf("If you would like to try Wallaby")) {
return;
}
`);
await fs.writeFile(index, str);
if (str.includes("破解成功!自动续订!"))
console.log(`${wallaby} 破解成功!`);
else
console.log(`${wallaby} 破解失败!`);
} catch (error)
{
@ -62,26 +68,33 @@ async function main()
let str = await fs.readFile(index, "utf-8");
if (str.includes("quokka已经破解")) return;
if (str.includes("破解成功!自动续订!"))
{
console.log(`${quokka} 已经破解过了!`);
continue;
};
await fs.copy(index, join(quokka, "dist/index_bak.js"));
str = str.replace(`_showNotification(e,t){`,
`
_showNotification(e,t){
t.continueTrial()
console.log("quokka已经破解!");
if ("expiredLicense" === e.id || e.expiringSoon || e.suggestProEdition) {
console.log("wallaby 没有许可或者即将到期 自动续期");
//return;//便于调试是不是试用期过了
}
e.text = "破解成功!自动续订!" + e.text;
t.continueTrial();
`);
await fs.writeFile(index, str);
if (str.includes("破解成功!自动续订!"))
console.log(`${quokka} 破解成功!`);
else
console.log(`${quokka} 破解失败!`);
} catch (error)
{
}
}
console.log("破解完成!");
}
main();

Loading…
Cancel
Save