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 { Draw } from "../../Common/Draw";
|
||||
import { Contour, CurveContainerCurve } from "../../DatabaseServices/Contour";
|
||||
import { Arc } from "../../DatabaseServices/Entity/Arc";
|
||||
import { Curve } from "../../DatabaseServices/Entity/Curve";
|
||||
import { Line } from "../../DatabaseServices/Entity/Line";
|
||||
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
|
||||
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 { Command } from "../../Editor/CommandMachine";
|
||||
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 { WallModelKeyWords } from "./RoomEnum";
|
||||
import { WallDirMode } from "./WallDirMode";
|
||||
|
||||
export class Command_Curve2Wall implements Command
|
||||
{
|
||||
_DrawDirMode: WallDirMode = WallDirMode.Center;
|
||||
async exec()
|
||||
{
|
||||
if (!await FixDrawWallDir()) return;
|
||||
|
||||
let ssRes = await app.Editor.GetSelection({ Filter: { filterTypes: [Line, Arc, Polyline] } });
|
||||
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)
|
||||
while (true)
|
||||
{
|
||||
if (e instanceof Line)
|
||||
{
|
||||
let wall = new RoomWallLine(e.StartPoint, e.EndPoint, distRes.Distance);
|
||||
Draw(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, distRes.Distance);
|
||||
Draw(wall);
|
||||
}
|
||||
else if (e instanceof Polyline)
|
||||
let ssRes = await app.Editor.GetSelection({
|
||||
KeyWordList: [...WallModelKeyWords.filter((k, i) => i !== this._DrawDirMode)],
|
||||
Filter: { filterTypes: [Line, Arc, Polyline] }
|
||||
});
|
||||
|
||||
if (ssRes.Status === PromptStatus.OK)
|
||||
{
|
||||
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);
|
||||
Draw(wall);
|
||||
const ipts: Vector3[] = [];
|
||||
|
||||
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;
|
||||
let wall = new RoomWallArc(arc.Center, arc.Radius, arc.StartAngle, arc.EndAngle, arc.IsClockWise, distRes.Distance);
|
||||
Draw(wall);
|
||||
const curves: Curve[] = [];
|
||||
for (const { curve } of regionsOutline)
|
||||
{
|
||||
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