mirror of https://gitee.com/cf-fz/WebCAD.git
!2215 功能:曲线变墙增加可选内线、中线、外线画墙功能
parent
8c701b83ca
commit
8577c8992a
@ -1,59 +1,223 @@
|
|||||||
|
import { Vector3 } from "three";
|
||||||
import { app } from "../../ApplicationServices/Application";
|
import { app } from "../../ApplicationServices/Application";
|
||||||
import { Draw } from "../../Common/Draw";
|
import { Draw } from "../../Common/Draw";
|
||||||
|
import { Contour, CurveContainerCurve } from "../../DatabaseServices/Contour";
|
||||||
import { Arc } from "../../DatabaseServices/Entity/Arc";
|
import { Arc } from "../../DatabaseServices/Entity/Arc";
|
||||||
|
import { Curve } from "../../DatabaseServices/Entity/Curve";
|
||||||
import { Line } from "../../DatabaseServices/Entity/Line";
|
import { Line } from "../../DatabaseServices/Entity/Line";
|
||||||
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
|
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
|
||||||
import { RoomWallArc } from "../../DatabaseServices/Room/Entity/Wall/RoomWallArc";
|
import { RoomWallArc } from "../../DatabaseServices/Room/Entity/Wall/RoomWallArc";
|
||||||
|
import { RoomWallBase } from "../../DatabaseServices/Room/Entity/Wall/RoomWallBase";
|
||||||
import { RoomWallLine } from "../../DatabaseServices/Room/Entity/Wall/RoomWallLine";
|
import { RoomWallLine } from "../../DatabaseServices/Room/Entity/Wall/RoomWallLine";
|
||||||
import { Command } from "../../Editor/CommandMachine";
|
import { Command } from "../../Editor/CommandMachine";
|
||||||
import { PromptStatus } from "../../Editor/PromptResult";
|
import { PromptStatus } from "../../Editor/PromptResult";
|
||||||
|
import { CurveIntersection2 } from "../../Geometry/CurveIntersection";
|
||||||
|
import { RegionParse } from "../../Geometry/RegionParse";
|
||||||
|
import { IntersectOption } from "../../GraphicsSystem/IntersectWith";
|
||||||
import { FixDrawWallDir } from "./FixDrawWallDir";
|
import { FixDrawWallDir } from "./FixDrawWallDir";
|
||||||
|
import { WallModelKeyWords } from "./RoomEnum";
|
||||||
|
import { WallDirMode } from "./WallDirMode";
|
||||||
|
|
||||||
export class Command_Curve2Wall implements Command
|
export class Command_Curve2Wall implements Command
|
||||||
{
|
{
|
||||||
|
_DrawDirMode: WallDirMode = WallDirMode.Center;
|
||||||
async exec()
|
async exec()
|
||||||
{
|
{
|
||||||
if (!await FixDrawWallDir()) return;
|
if (!await FixDrawWallDir()) return;
|
||||||
|
|
||||||
let ssRes = await app.Editor.GetSelection({ Filter: { filterTypes: [Line, Arc, Polyline] } });
|
while (true)
|
||||||
if (ssRes.Status !== PromptStatus.OK) return;
|
|
||||||
let ents = ssRes.SelectSet.SelectEntityList;
|
|
||||||
|
|
||||||
let distRes = await app.Editor.GetDistance({ Msg: "输入墙体厚度:", Default: 240 });
|
|
||||||
if (distRes.Status !== PromptStatus.OK) return;
|
|
||||||
|
|
||||||
for (let e of ents)
|
|
||||||
{
|
{
|
||||||
if (e instanceof Line)
|
let ssRes = await app.Editor.GetSelection({
|
||||||
{
|
KeyWordList: [...WallModelKeyWords.filter((k, i) => i !== this._DrawDirMode)],
|
||||||
let wall = new RoomWallLine(e.StartPoint, e.EndPoint, distRes.Distance);
|
Filter: { filterTypes: [Line, Arc, Polyline] }
|
||||||
Draw(wall);
|
});
|
||||||
}
|
|
||||||
else if (e instanceof Arc)
|
if (ssRes.Status === PromptStatus.OK)
|
||||||
{
|
|
||||||
let arc = e as Arc;
|
|
||||||
let wall = new RoomWallArc(arc.Center, arc.Radius, arc.StartAngle, arc.EndAngle, arc.IsClockWise, distRes.Distance);
|
|
||||||
Draw(wall);
|
|
||||||
}
|
|
||||||
else if (e instanceof Polyline)
|
|
||||||
{
|
{
|
||||||
for (let cu of e.Explode())
|
const selectEntity = ssRes.SelectSet.SelectEntityList; //选中的所有实体
|
||||||
|
let distRes = await app.Editor.GetDistance({ Msg: "输入墙体厚度:", Default: 240 });
|
||||||
|
if (distRes.Status !== PromptStatus.OK) return;
|
||||||
|
const wallThickness = distRes.Distance;
|
||||||
|
|
||||||
|
let walls: RoomWallBase[];
|
||||||
|
if (this._DrawDirMode === WallDirMode.Center)
|
||||||
|
{
|
||||||
|
walls = CreateWalls(selectEntity as Curve[], wallThickness); //收集要画的墙
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (cu instanceof Line)
|
let entClone = selectEntity.map(en => en.Clone()) as Curve[];
|
||||||
|
let intersect = new CurveIntersection2(entClone, false, IntersectOption.ExtendNone);
|
||||||
|
|
||||||
|
const curves: Curve[] = []; //打断后曲线集合
|
||||||
|
//打断曲线
|
||||||
|
for (const [cu, pmap] of intersect.intersect)
|
||||||
{
|
{
|
||||||
let wall = new RoomWallLine(cu.StartPoint, cu.EndPoint, distRes.Distance);
|
const ipts: Vector3[] = [];
|
||||||
Draw(wall);
|
|
||||||
|
for (const [, pts] of pmap)
|
||||||
|
{
|
||||||
|
ipts.push(...pts);
|
||||||
|
}
|
||||||
|
|
||||||
|
const cus: Curve[] = ipts.length > 0 ? cu.GetSplitCurvesByPts(ipts) : [cu];
|
||||||
|
|
||||||
|
for (const c of cus)
|
||||||
|
{
|
||||||
|
curves.push(...(c instanceof Polyline ? c.Explode() : [c]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
let parse = new RegionParse(curves); //分析外轮廓
|
||||||
|
|
||||||
|
const outlinePolylines: Polyline[] = []; //外轮廓多段线集合
|
||||||
|
const outlineCurves: Curve[] = []; //外轮廓曲线集合
|
||||||
|
let inlineCurves: Curve[] = []; //外轮廓以外曲线集合
|
||||||
|
|
||||||
|
for (const regionsOutline of parse.RegionsOutline)
|
||||||
{
|
{
|
||||||
let arc = cu as Arc;
|
const curves: Curve[] = [];
|
||||||
let wall = new RoomWallArc(arc.Center, arc.Radius, arc.StartAngle, arc.EndAngle, arc.IsClockWise, distRes.Distance);
|
for (const { curve } of regionsOutline)
|
||||||
Draw(wall);
|
{
|
||||||
|
curves.push(curve);
|
||||||
|
}
|
||||||
|
outlineCurves.push(...curves);
|
||||||
|
const polyline: Polyline = Contour.CreateContour(curves, false)?.Curve as Polyline;
|
||||||
|
outlinePolylines.push(polyline);
|
||||||
}
|
}
|
||||||
|
//TODO外轮廓筛选判断是否有嵌套
|
||||||
|
|
||||||
|
inlineCurves = curves.filter((cu2: Curve) => !outlineCurves.includes(cu2));
|
||||||
|
|
||||||
|
const curves2: Curve[] = []; //要画的曲线
|
||||||
|
const outlineGroupMap = new Map<Polyline, Curve[]>(); //轮廓内的直线分组映射
|
||||||
|
for (const pl of outlinePolylines)
|
||||||
|
{
|
||||||
|
let cus = [];
|
||||||
|
for (const cu of inlineCurves)
|
||||||
|
{
|
||||||
|
if (CurveContainerCurve(pl, cu))
|
||||||
|
{
|
||||||
|
cus.push(cu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
curves2.push(...cus);
|
||||||
|
outlineGroupMap.set(pl, cus);
|
||||||
|
}
|
||||||
|
|
||||||
|
const offectOutlinePolylines: Polyline[] = [];
|
||||||
|
const offsetDistance = (this._DrawDirMode === WallDirMode.Inside) ? (wallThickness / 2) : (-wallThickness / 2);
|
||||||
|
for (const pl of outlinePolylines)
|
||||||
|
{
|
||||||
|
const offectPl = pl.GetOffsetCurves(offsetDistance)[0];
|
||||||
|
offectOutlinePolylines.push(offectPl);
|
||||||
|
for (const cu of outlineGroupMap.get(pl))
|
||||||
|
{
|
||||||
|
const sp = cu.StartPoint;
|
||||||
|
const ep = cu.EndPoint;
|
||||||
|
if (this._DrawDirMode === WallDirMode.Inside)
|
||||||
|
{
|
||||||
|
const ipts = pl.IntersectWith2(cu, IntersectOption.ExtendNone);
|
||||||
|
const ipts2 = offectPl.IntersectWith2(cu, IntersectOption.ExtendBoth);
|
||||||
|
if (ipts.length === 1)
|
||||||
|
{
|
||||||
|
for (const { pt } of ipts2)
|
||||||
|
{
|
||||||
|
const param = cu.GetParamAtPoint(pt);
|
||||||
|
if (pl.PtOnCurve(sp) && param < 0 || pl.PtOnCurve(ep) && param > 1)
|
||||||
|
{
|
||||||
|
cu.Extend(param);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ipts.length === 2 && ipts2.length === 2)
|
||||||
|
{
|
||||||
|
cu.Extend(cu.GetParamAtPoint(ipts2[0].pt));
|
||||||
|
cu.Extend(cu.GetParamAtPoint(ipts2[1].pt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const ipts2 = offectPl.IntersectWith2(cu, IntersectOption.ExtendNone);
|
||||||
|
if (ipts2.length === 1)
|
||||||
|
{
|
||||||
|
const { pt, argParam } = ipts2[0];
|
||||||
|
if (sp.distanceTo(pt) < ep.distanceTo(pt))
|
||||||
|
cu.StartPoint = cu.GetPointAtParam(argParam);
|
||||||
|
else
|
||||||
|
cu.EndPoint = cu.GetPointAtParam(argParam);
|
||||||
|
}
|
||||||
|
else if (ipts2.length === 2)
|
||||||
|
{
|
||||||
|
const point1 = cu.GetPointAtParam(ipts2[0].argParam);
|
||||||
|
const point2 = cu.GetPointAtParam(ipts2[1].argParam);
|
||||||
|
|
||||||
|
cu.StartPoint = point1;
|
||||||
|
cu.EndPoint = point2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
curves2.push(...offectOutlinePolylines);
|
||||||
|
walls = CreateWalls(curves2, wallThickness); //收集要画的墙
|
||||||
}
|
}
|
||||||
|
for (const ent of selectEntity)
|
||||||
|
ent.Erase();
|
||||||
|
|
||||||
|
if (walls.length)
|
||||||
|
walls.forEach(wall => Draw(wall));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (ssRes.Status === PromptStatus.Keyword)
|
||||||
|
{
|
||||||
|
if (ssRes.StringResult === "Z")
|
||||||
|
this._DrawDirMode = WallDirMode.Center;
|
||||||
|
else if (ssRes.StringResult === "N")
|
||||||
|
this._DrawDirMode = WallDirMode.Inside;
|
||||||
|
else if (ssRes.StringResult === "W")
|
||||||
|
this._DrawDirMode = WallDirMode.Outside;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
e.Erase();
|
function CreateWalls(curves: Curve[], wallThickness: number)
|
||||||
|
{
|
||||||
|
const walls = [];
|
||||||
|
for (let e of curves)
|
||||||
|
{
|
||||||
|
if (e instanceof Line)
|
||||||
|
{
|
||||||
|
let wall = new RoomWallLine(e.StartPoint, e.EndPoint, wallThickness);
|
||||||
|
walls.push(wall);
|
||||||
|
}
|
||||||
|
else if (e instanceof Arc)
|
||||||
|
{
|
||||||
|
let arc = e as Arc;
|
||||||
|
let wall = new RoomWallArc(arc.Center, arc.Radius, arc.StartAngle, arc.EndAngle, arc.IsClockWise, wallThickness);
|
||||||
|
walls.push(wall);
|
||||||
|
}
|
||||||
|
else if (e instanceof Polyline)
|
||||||
|
{
|
||||||
|
for (let cu of e.Explode())
|
||||||
|
{
|
||||||
|
if (cu instanceof Line)
|
||||||
|
{
|
||||||
|
let wall = new RoomWallLine(cu.StartPoint, cu.EndPoint, wallThickness);
|
||||||
|
walls.push(wall);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
let arc = cu as Arc;
|
||||||
|
let wall = new RoomWallArc(arc.Center, arc.Radius, arc.StartAngle, arc.EndAngle, arc.IsClockWise, wallThickness);
|
||||||
|
walls.push(wall);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return walls;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in new issue