!2215 功能:曲线变墙增加可选内线、中线、外线画墙功能

pull/2149/MERGE
黄诗津 1 year ago committed by ChenX
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;
} }

@ -636,7 +636,7 @@ export function fastCurveInCurve2(bigCurve: Polyline | Circle, smallCurve: Curve
} }
//大曲线是否完全包含小曲线(或者重合) //大曲线是否完全包含小曲线(或者重合)
function CurveContainerCurve(bigCurve: Polyline | Circle, smallCurve: Polyline | Circle | Curve, ipts: IntersectResult[] = undefined, fuzz = COMBINE_FUZZ) export function CurveContainerCurve(bigCurve: Polyline | Circle, smallCurve: Polyline | Circle | Curve, ipts: IntersectResult[] = undefined, fuzz = COMBINE_FUZZ)
{ {
if (!ipts) if (!ipts)
ipts = bigCurve.IntersectWith2(smallCurve, IntersectOption.ExtendNone, fuzz); ipts = bigCurve.IntersectWith2(smallCurve, IntersectOption.ExtendNone, fuzz);

Loading…
Cancel
Save