毛料态、自由锻、方体、有圆头的模板生成

This commit is contained in:
sladro 2026-01-28 14:55:25 +08:00
parent bc208a4436
commit 6b71730057
2 changed files with 604 additions and 0 deletions

View File

@ -1,4 +1,5 @@
using CadParamPluging.Common;
using CadParamPluging.Domain.Models;
namespace CadParamPluging.Cad
{
@ -7,5 +8,32 @@ namespace CadParamPluging.Cad
public static readonly string Key = TemplateKeyBuilder.Build("毛料态", "自由锻", "方体", "有圆头");
public override string TemplateKey => Key;
public override FeatureDrivenDrawer.ExpectedDrawingSize CalculateExpectedSize(ParamBag bag, TemplateParams templateParams)
{
// 复用环形逻辑的尺寸计算,因为接下来的绘图逻辑是完全复制环形的
// 映射参数BoxSize1 -> OuterDiameter1, BoxSize2 -> Height1
var width = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxSize1) ?? 0;
var height = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxSize2) ?? 0;
// 模拟 Machined + Rolling 的示意图模式计算
// 这里的模拟逻辑是直接复制 DrawRingFeaturesHalfCore 中的视觉比例逻辑
// 假设 Height * 3.0 作为视觉宽度
double activeWidth = height * 3.0;
double activeHeight = height;
var extraMargin = 60.0;
return new FeatureDrivenDrawer.ExpectedDrawingSize
{
Width = activeWidth + extraMargin * 2,
Height = activeHeight + extraMargin * 2
};
}
public override void Draw(CadContext ctx, ParamBag bag, TemplateParams templateParams, Autodesk.AutoCAD.Geometry.Point3d center, double scaleFactor)
{
// 调用独立的新绘制方法
FeatureDrivenDrawer.DrawBlockRawFreeForgeRoundHead(ctx, bag, center, scaleFactor);
}
}
}

View File

@ -2874,5 +2874,581 @@ namespace CadParamPluging.Cad
}
}
/// <summary>
/// 毛料态-自由锻-方体-有圆头:独立图纸生成逻辑
/// 逻辑完全复制自“车加工-轧制-环形”,但映射了方体参数
/// </summary>
public static void DrawBlockRawFreeForgeRoundHead(CadContext ctx, ParamBag bag, Point3d center, double scaleFactor = 1.0)
{
if (ctx == null) throw new ArgumentNullException(nameof(ctx));
if (bag == null) throw new ArgumentNullException(nameof(bag));
var effectiveBag = scaleFactor < 1.0 ? ScaleParamBag(bag, scaleFactor) : bag;
var db = ctx.Database;
var tr = ctx.Transaction;
var prevDb = HostApplicationServices.WorkingDatabase;
HostApplicationServices.WorkingDatabase = db;
BlockTableRecord btr;
try
{
var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
}
finally
{
HostApplicationServices.WorkingDatabase = prevDb;
}
var context = new DrawingContext
{
Ctx = ctx,
Bag = effectiveBag,
OriginalBag = bag,
Center = center,
DeliveryStatus = "毛料态",
StructuralFeature = "方体",
SpecialCondition = "有圆头",
ProcessMethod = "自由锻",
Btr = btr,
Style = new DrawingStyleManager(db, tr)
};
DrawBlockRawFreeForgeRoundHeadCore(context);
}
private static void DrawBlockRawFreeForgeRoundHeadCore(DrawingContext ctx)
{
var bag = ctx.Bag;
// BoxSize1 (Width - 总长度)
// BoxSize2 (Height - 高度/直径)
var width = bag.GetDoubleOrNull(KeyBoxSize1);
var height = bag.GetDoubleOrNull(KeyBoxSize2);
if (!width.HasValue || width.Value <= 0 || !height.HasValue || height.Value <= 0)
{
return;
}
double H = height.Value;
double W = width.Value;
// 外轮廓圆弧:优先使用参数 BoxRoundHeadFilletRadiusMax 控制
var roundHeadRParam = bag.GetDoubleOrNull(KeyBoxRoundHeadFilletRadiusMax);
double outerArcR;
if (roundHeadRParam.HasValue && roundHeadRParam.Value > 0)
{
outerArcR = roundHeadRParam.Value;
// 限制最大半径不超过高度的一半(防止自交)
outerArcR = Math.Min(outerArcR, H / 2.0);
}
else
{
// 默认兜底固定为高度的15%作为圆弧半径
outerArcR = H * 0.15;
}
// 视觉比例:总宽度映射
double visualTotalW = H * 3.0; // 保持视觉宽高比约 3:1
// 视觉上的外轮廓圆弧半径
double visualOuterArcR = outerArcR;
// 绘图坐标计算 (保持居中)
double ox = ctx.Center.X - visualTotalW / 2.0; // 左边界
double oy = ctx.Center.Y - H / 2.0; // 底边
// 内框边界(从左圆弧结束到右圆弧开始)
double xInnerLeft = ox + visualOuterArcR;
double xInnerRight = ox + visualTotalW - visualOuterArcR;
double innerWidth = xInnerRight - xInnerLeft;
// 获取内框圆角参数:优先取 UnspecifiedFilletRadiusMax如果没有则取 BoxFilletRadiusMax
var innerFilletParam = bag.GetDoubleOrNull(KeyUnspecifiedFilletRadiusMax);
if (!innerFilletParam.HasValue || innerFilletParam.Value <= 0)
{
innerFilletParam = bag.GetDoubleOrNull(KeyBoxFilletRadiusMax);
}
double innerFilletR = innerFilletParam.HasValue && innerFilletParam.Value > 0
? innerFilletParam.Value
: 0;
// 1. 绘制完整锻件外轮廓(方体有圆头 - 白色,固定小弧度)
DrawBlockRoundHeadOutline(ctx, ox, oy, visualTotalW, H, visualOuterArcR);
// 2. 绘制分段式内框(左、中、右三段)以支持中间剖面区域的独立圆角
// 中间区域(剖面)作为主体,如果设置了圆角,四个角都应为圆角
// 计算分段坐标
double sectionWidth = innerWidth / 3.0;
double xSectionLeft = xInnerLeft + sectionWidth;
double xSectionRight = xInnerLeft + sectionWidth * 2.0;
// 绘制中间剖面框(带圆角)
// 复用 Ring 模板的 SectionContourWithFillet 逻辑绘制中间闭合框
// 注意:这里需要把 Ring 的 DrawRingSectionContourWithFillet 方法提取出来通用或者直接复制逻辑
// 为简单起见,这里直接使用类似的逻辑绘制
DrawBoxSectionContourWithFillet(ctx, xSectionLeft, xSectionRight, oy, H, innerFilletR);
// 绘制左侧框线(连接左端圆弧和中间剖面框)
// 左端: xInnerLeft (需处理左上下角的圆角 - 使用外轮廓圆角 visualOuterArcR)
// 右端: xSectionLeft (连接到中间框的直边)
// 注意DrawBoxSideFrame 仅在远端应用圆角,连接端是直的
DrawBoxSideFrame(ctx, xInnerLeft, xSectionLeft, oy, H, visualOuterArcR, isLeft: true);
// 绘制右侧框线
// 左端: xSectionRight (连接到中间框的直边)
// 右端: xInnerRight (需处理右上下角的圆角 - 使用外轮廓圆角 visualOuterArcR)
DrawBoxSideFrame(ctx, xSectionRight, xInnerRight, oy, H, visualOuterArcR, isLeft: false);
// 3. 剖面填充 - 只在中间区域
// 如果有圆角填充范围也应考虑圆角不过Hatch边界通常可以自动处理
if (innerFilletR > 0.01)
{
DrawRingSectionHatchWithFillet(ctx, xSectionLeft, xSectionRight, oy, H, innerFilletR);
}
else
{
DrawBlockSectionHatch(ctx, xSectionLeft, xSectionRight, oy, H);
}
// 4. 剖面左右边界线 -> 已包含在 DrawBoxSectionContourWithFillet 中
// 故移除 DrawSectionInnerBoundaryBold 调用
// 5. 零件轮廓框(黄色双点划线矩形 - 在内框内,与锻件有一定间距)
var widthPrime = bag.GetDoubleOrNull(KeyBoxSize1Prime);
var heightPrime = bag.GetDoubleOrNull(KeyBoxSize2Prime);
if (widthPrime.HasValue && widthPrime.Value > 0 && heightPrime.HasValue && heightPrime.Value > 0)
{
double partH = heightPrime.Value;
double partW = widthPrime.Value;
// 计算零件在视觉上的宽度比例
double partWidthRatio = partW / W;
double visualPartW = innerWidth * partWidthRatio;
if (visualPartW > innerWidth) visualPartW = innerWidth * 0.9;
// 零件在锻件内居中
double partOffsetX = (innerWidth - visualPartW) / 2.0;
double partOffsetY = (H - partH) / 2.0;
double xPartLeft = xInnerLeft + partOffsetX;
double yPartBottom = oy + partOffsetY;
DrawBlockPartContour(ctx, xPartLeft, yPartBottom, visualPartW, partH);
}
// 6. 宽度标注 (BoxSize1) - 位于底部
// 标注从锻件最左端到最右端(包括圆头)
{
var val = ctx.OriginalBag?.GetDoubleOrNull(KeyBoxSize1) ?? W;
var str = ctx.OriginalBag?.GetString(KeyBoxSize1);
var tolPlus = ctx.OriginalBag?.GetDoubleOrNull(KeyBoxSize1TolPlus);
var tolMinus = ctx.OriginalBag?.GetDoubleOrNull(KeyBoxSize1TolMinus);
var tolPlusStr = ctx.OriginalBag?.GetString(KeyBoxSize1TolPlus);
var tolMinusStr = ctx.OriginalBag?.GetString(KeyBoxSize1TolMinus);
var dimText = BuildDimensionText(FormatDimNumber(val, str), tolPlus, tolMinus, tolPlusStr, tolMinusStr);
// 标注点从内框左右边界开始(连接到矩形内框)
AddLinearDim(
ctx,
new Point3d(xInnerLeft, oy, 0),
new Point3d(xInnerRight, oy, 0),
new Point3d((xInnerLeft + xInnerRight) / 2, oy - 25, 0),
0,
dimText);
}
// 7. 高度标注 (BoxSize2) - 位于右侧
// 标注从锻件顶部到底部
{
var val = ctx.OriginalBag?.GetDoubleOrNull(KeyBoxSize2) ?? H;
var str = ctx.OriginalBag?.GetString(KeyBoxSize2);
var tolPlus = ctx.OriginalBag?.GetDoubleOrNull(KeyBoxSize2TolPlus);
var tolMinus = ctx.OriginalBag?.GetDoubleOrNull(KeyBoxSize2TolMinus);
var tolPlusStr = ctx.OriginalBag?.GetString(KeyBoxSize2TolPlus);
var tolMinusStr = ctx.OriginalBag?.GetString(KeyBoxSize2TolMinus);
var dimText = BuildDimensionText(FormatDimNumber(val, str), tolPlus, tolMinus, tolPlusStr, tolMinusStr);
// 标注从圆弧最外侧开始(避免与圆弧轮廓线重叠)
double xOuterRight = ox + visualTotalW;
// 修正:标注界线起点应向内缩进一个圆角半径 visualOuterArcR以连接到锻件顶底平直边的末端
// 否则标注界线会从包围盒的角点开始,导致与圆角轮廓之间有空隙
double xDimOrigin = xOuterRight - visualOuterArcR;
AddLinearDim(
ctx,
new Point3d(xDimOrigin, oy, 0),
new Point3d(xDimOrigin, oy + H, 0),
new Point3d(xOuterRight + 20, oy + H / 2, 0),
90,
dimText);
}
// 8. 中间矩形宽度标注(剖面区域宽度)- 第二个宽度标注,位于上方
{
var rectRealWidth = W - 2 * outerArcR; // 实际中间矩形宽度 = 总宽度 - 两端圆头
if (rectRealWidth > 0)
{
AddLinearDim(
ctx,
new Point3d(xSectionLeft, oy + H, 0),
new Point3d(xSectionRight, oy + H, 0),
new Point3d((xSectionLeft + xSectionRight) / 2, oy + H + 15, 0),
0,
FormatDimNumber(rectRealWidth, null));
}
}
// 9. 硬度符号 - 从剖面底部引出
var hardnessVal = bag.GetString(KeyHardness);
if (!string.IsNullOrWhiteSpace(hardnessVal))
{
double xStart = (xSectionLeft + xSectionRight) / 2.0;
double yStart = oy;
DrawHardnessSymbol(ctx, xStart, yStart);
}
// 10. 标刻内容引线 - 从剖面顶部引出
var markingText = bag.GetString(KeyMarkingContent);
if (!string.IsNullOrWhiteSpace(markingText))
{
double xTarget = (xSectionLeft + xSectionRight) / 2.0;
double yTarget = oy + H;
DrawSpecialHBLeaderToTop(ctx, xTarget, yTarget, markingText);
}
}
/// <summary>
/// 绘制方体零件轮廓(黄色双点划线矩形)
/// </summary>
private static void DrawBlockPartContour(DrawingContext ctx, double x, double y, double width, double height)
{
try
{
var poly = new Polyline();
poly.AddVertexAt(0, new Point2d(x, y), 0, 0, 0);
poly.AddVertexAt(1, new Point2d(x + width, y), 0, 0, 0);
poly.AddVertexAt(2, new Point2d(x + width, y + height), 0, 0, 0);
poly.AddVertexAt(3, new Point2d(x, y + height), 0, 0, 0);
poly.Closed = true;
ctx.Style?.Apply(poly, DrawingStyleManager.Role.PartContour);
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
}
catch
{
// ignore
}
}
/// <summary>
/// 绘制白色矩形内框(锻件内部区域边界,四角带圆角)
/// </summary>
private static void DrawBlockInnerFrameWithFillet(DrawingContext ctx, double x, double y, double width, double height, double filletR)
{
try
{
// 限制圆角半径不超过宽度或高度的一半
double maxR = Math.Min(width / 2.0, height / 2.0);
double r = Math.Min(filletR, maxR);
if (r <= 0.01)
{
// 没有圆角,绘制普通矩形
var poly = new Polyline();
poly.AddVertexAt(0, new Point2d(x, y), 0, 0, 0);
poly.AddVertexAt(1, new Point2d(x + width, y), 0, 0, 0);
poly.AddVertexAt(2, new Point2d(x + width, y + height), 0, 0, 0);
poly.AddVertexAt(3, new Point2d(x, y + height), 0, 0, 0);
poly.Closed = true;
ctx.Style?.Apply(poly, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
return;
}
// 绘制带圆角的矩形
// 使用 Polyline 的 bulge 值来绘制圆角
// bulge = tan(角度/4)对于90度圆角bulge = tan(22.5°) ≈ 0.414
double bulge = Math.Tan(Math.PI / 8.0);
var polyFillet = new Polyline();
// 从左下角开始,顺时针绘制(与其他模板保持一致)
// 左下角圆角起点
polyFillet.AddVertexAt(0, new Point2d(x, y + r), bulge, 0, 0); // 左下圆角
polyFillet.AddVertexAt(1, new Point2d(x + r, y), 0, 0, 0); // 左下圆角结束
// 右下角
polyFillet.AddVertexAt(2, new Point2d(x + width - r, y), bulge, 0, 0); // 右下圆角
polyFillet.AddVertexAt(3, new Point2d(x + width, y + r), 0, 0, 0); // 右下圆角结束
// 右上角
polyFillet.AddVertexAt(4, new Point2d(x + width, y + height - r), bulge, 0, 0); // 右上圆角
polyFillet.AddVertexAt(5, new Point2d(x + width - r, y + height), 0, 0, 0); // 右上圆角结束
// 左上角
polyFillet.AddVertexAt(6, new Point2d(x + r, y + height), bulge, 0, 0); // 左上圆角
polyFillet.AddVertexAt(7, new Point2d(x, y + height - r), 0, 0, 0); // 左上圆角结束
polyFillet.Closed = true;
ctx.Style?.Apply(polyFillet, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(polyFillet);
ctx.Tr.AddNewlyCreatedDBObject(polyFillet, true);
}
catch
{
// ignore
}
}
/// <summary>
/// 绘制方体有圆头的完整外轮廓
/// 结构:左圆弧 + 中间矩形顶底边 + 右圆弧(小弧度,不是半圆)
/// </summary>
private static void DrawBlockRoundHeadOutline(DrawingContext ctx, double ox, double oy, double totalWidth, double height, double arcR)
{
try
{
// 使用 Polyline 绘制外轮廓
// arcR 是圆弧部分的半径(固定小弧度)
var poly = new Polyline();
// 圆弧的 bulge 值对于90度圆角bulge = tan(22.5°) ≈ 0.414
double bulge = Math.Tan(Math.PI / 8.0);
// 左侧圆弧中心 X 坐标
double xLeftArc = ox + arcR;
// 右侧圆弧中心 X 坐标
double xRightArc = ox + totalWidth - arcR;
// 从左下开始,顺时针绘制带圆角的矩形外轮廓
// 左下角
poly.AddVertexAt(0, new Point2d(ox, oy + arcR), bulge, 0, 0); // 左下圆弧
poly.AddVertexAt(1, new Point2d(xLeftArc, oy), 0, 0, 0); // 底边开始
// 右下角
poly.AddVertexAt(2, new Point2d(xRightArc, oy), bulge, 0, 0); // 右下圆弧
poly.AddVertexAt(3, new Point2d(ox + totalWidth, oy + arcR), 0, 0, 0); // 右边开始
// 右上角
poly.AddVertexAt(4, new Point2d(ox + totalWidth, oy + height - arcR), bulge, 0, 0); // 右上圆弧
poly.AddVertexAt(5, new Point2d(xRightArc, oy + height), 0, 0, 0); // 顶边开始
// 左上角
poly.AddVertexAt(6, new Point2d(xLeftArc, oy + height), bulge, 0, 0); // 左上圆弧
poly.AddVertexAt(7, new Point2d(ox, oy + height - arcR), 0, 0, 0); // 左边开始
poly.Closed = true;
ctx.Style?.Apply(poly, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
}
catch
{
// ignore
}
}
/// <summary>
/// 绘制方体剖面填充(矩形区域的 ANSI31 网格线填充)
/// </summary>
private static void DrawBlockSectionHatch(DrawingContext ctx, double xLeft, double xRight, double yBottom, double height)
{
if (xRight <= xLeft)
{
return;
}
try
{
// 临时边界(用于剖面填充),填充后删除边界
var boundary = new Polyline();
boundary.AddVertexAt(0, new Point2d(xLeft, yBottom), 0, 0, 0);
boundary.AddVertexAt(1, new Point2d(xRight, yBottom), 0, 0, 0);
boundary.AddVertexAt(2, new Point2d(xRight, yBottom + height), 0, 0, 0);
boundary.AddVertexAt(3, new Point2d(xLeft, yBottom + height), 0, 0, 0);
boundary.Closed = true;
ctx.Btr.AppendEntity(boundary);
ctx.Tr.AddNewlyCreatedDBObject(boundary, true);
var hatch = new Hatch();
hatch.SetDatabaseDefaults();
hatch.Normal = new Vector3d(0, 0, 1);
hatch.Elevation = 0.0;
ctx.Btr.AppendEntity(hatch);
ctx.Tr.AddNewlyCreatedDBObject(hatch, true);
hatch.SetHatchPattern(HatchPatternType.PreDefined, "ANSI31");
hatch.PatternScale = 10;
hatch.PatternAngle = 0;
hatch.Associative = false;
ctx.Style?.Apply(hatch, DrawingStyleManager.Role.Hatch);
var ids = new ObjectIdCollection();
ids.Add(boundary.ObjectId);
hatch.AppendLoop(HatchLoopTypes.External, ids);
hatch.EvaluateHatch(true);
try
{
boundary.Erase(true);
}
catch
{
// ignore
}
}
catch
{
// ignore
}
}
/// <summary>
/// 绘制中间剖面框(带圆角)
/// 逻辑基本照搬 DrawRingSectionContourWithFillet
/// </summary>
private static void DrawBoxSectionContourWithFillet(DrawingContext ctx, double xLeft, double xRight, double yBottom, double height, double filletR)
{
var yTop = yBottom + height;
var width = xRight - xLeft;
// 限制圆角半径不超过尺寸的一半
var maxR = Math.Min(width * 0.5, height * 0.5);
var r = Math.Min(filletR, maxR);
if (r <= 0.01)
{
// 如果圆角太小,退化为矩形边框
var poly = new Polyline();
poly.AddVertexAt(0, new Point2d(xLeft, yBottom), 0, 0, 0);
poly.AddVertexAt(1, new Point2d(xRight, yBottom), 0, 0, 0);
poly.AddVertexAt(2, new Point2d(xRight, yTop), 0, 0, 0);
poly.AddVertexAt(3, new Point2d(xLeft, yTop), 0, 0, 0);
poly.Closed = true;
ctx.Style?.Apply(poly, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
return;
}
var bulge = Math.Tan(Math.PI / 8.0); // 90度圆弧的凸度
// 逆时针绘制圆角矩形
var polyFillet = new Polyline();
// 下方边:从左下到右下
polyFillet.AddVertexAt(0, new Point2d(xLeft + r, yBottom), 0, 0, 0);
polyFillet.AddVertexAt(1, new Point2d(xRight - r, yBottom), bulge, 0, 0);
polyFillet.AddVertexAt(2, new Point2d(xRight, yBottom + r), 0, 0, 0);
polyFillet.AddVertexAt(3, new Point2d(xRight, yTop - r), bulge, 0, 0);
polyFillet.AddVertexAt(4, new Point2d(xRight - r, yTop), 0, 0, 0);
polyFillet.AddVertexAt(5, new Point2d(xLeft + r, yTop), bulge, 0, 0);
polyFillet.AddVertexAt(6, new Point2d(xLeft, yTop - r), 0, 0, 0);
polyFillet.AddVertexAt(7, new Point2d(xLeft, yBottom + r), bulge, 0, 0);
polyFillet.Closed = true;
ctx.Style?.Apply(polyFillet, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(polyFillet);
ctx.Tr.AddNewlyCreatedDBObject(polyFillet, true);
}
/// <summary>
/// 绘制左侧或右侧的框线
/// isLeft=true: 绘制左侧部分 (xStart=xInnerLeft, xEnd=xSectionLeft)
/// isLeft=false: 绘制右侧部分 (xStart=xSectionRight, xEnd=xInnerRight)
/// </summary>
private static void DrawBoxSideFrame(DrawingContext ctx, double xStart, double xEnd, double yBottom, double height, double filletR, bool isLeft)
{
var yTop = yBottom + height;
var width = Math.Abs(xEnd - xStart);
if (width < 0.1) return;
var maxR = Math.Min(width * 0.5, height * 0.5);
var r = Math.Min(filletR, maxR);
// 路径是顺时针(CW)绘制的所以外凸圆角的Bulge应该是负值
var bulge = -Math.Tan(Math.PI / 8.0);
var poly = new Polyline();
if (isLeft)
{
// Left Frame: CW Path
// Start: Bottom-Right (connect to middle) -> Bottom-Left -> Top-Left -> Top-Right (connect to middle)
// P0: xEnd, yBottom
poly.AddVertexAt(0, new Point2d(xEnd, yBottom), 0, 0, 0);
if (r > 0.01)
{
// P1: xStart + r, yBottom (Start of Corner 1) -> Set Bulge here
poly.AddVertexAt(1, new Point2d(xStart + r, yBottom), bulge, 0, 0);
// P2: xStart, yBottom + r (End of Corner 1, Start of Vertical)
poly.AddVertexAt(2, new Point2d(xStart, yBottom + r), 0, 0, 0);
// P3: xStart, yTop - r (End of Vertical, Start of Corner 2) -> Set Bulge here
poly.AddVertexAt(3, new Point2d(xStart, yTop - r), bulge, 0, 0);
// P4: xStart + r, yTop (End of Corner 2, Start of Top Horizontal)
poly.AddVertexAt(4, new Point2d(xStart + r, yTop), 0, 0, 0);
// P5: xEnd, yTop (End)
poly.AddVertexAt(5, new Point2d(xEnd, yTop), 0, 0, 0);
}
else
{
poly.AddVertexAt(1, new Point2d(xStart, yBottom), 0, 0, 0);
poly.AddVertexAt(2, new Point2d(xStart, yTop), 0, 0, 0);
poly.AddVertexAt(3, new Point2d(xEnd, yTop), 0, 0, 0);
}
poly.Closed = false;
}
else
{
// Right Frame: CW Path
// Start: Top-Left (connect to middle) -> Top-Right -> Bottom-Right -> Bottom-Left (connect to middle)
// P0: xStart, yTop
poly.AddVertexAt(0, new Point2d(xStart, yTop), 0, 0, 0);
if (r > 0.01)
{
// P1: xEnd - r, yTop (Start of Corner 1) -> Set Bulge here
poly.AddVertexAt(1, new Point2d(xEnd - r, yTop), bulge, 0, 0);
// P2: xEnd, yTop - r (End of Corner 1, Start of Vertical)
poly.AddVertexAt(2, new Point2d(xEnd, yTop - r), 0, 0, 0);
// P3: xEnd, yBottom + r (End of Vertical, Start of Corner 2) -> Set Bulge here
poly.AddVertexAt(3, new Point2d(xEnd, yBottom + r), bulge, 0, 0);
// P4: xEnd - r, yBottom (End of Corner 2, Start of Bottom Horizontal)
poly.AddVertexAt(4, new Point2d(xEnd - r, yBottom), 0, 0, 0);
// P5: xStart, yBottom (End)
poly.AddVertexAt(5, new Point2d(xStart, yBottom), 0, 0, 0);
}
else
{
poly.AddVertexAt(1, new Point2d(xEnd, yTop), 0, 0, 0);
poly.AddVertexAt(2, new Point2d(xEnd, yBottom), 0, 0, 0);
poly.AddVertexAt(3, new Point2d(xStart, yBottom), 0, 0, 0);
}
poly.Closed = false;
}
ctx.Style?.Apply(poly, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
}
}
}