feat: Introduce a feature-driven drawing engine with dynamic CAD entity sizing based on parameters and drawing style management.

This commit is contained in:
sladro 2026-03-26 18:33:33 +08:00
parent 7b436612f1
commit 40a2909481
3 changed files with 64 additions and 38 deletions

View File

@ -58,7 +58,7 @@ namespace CadParamPluging.Cad
case Role.OutlineBold:
return new LayerSpec { LayerName = "粗实线", DefaultLinetypeName = "Continuous", DefaultLineWeight = LineWeight.LineWeight050, DefaultColorIndex = 7 };
case Role.PartContour:
return new LayerSpec { LayerName = "双点划线", DefaultLinetypeName = "PHANTOM", DefaultLineWeight = LineWeight.LineWeight015, DefaultColorIndex = 2 };
return new LayerSpec { LayerName = "双点划线", DefaultLinetypeName = "PHANTOM", DefaultLineWeight = LineWeight.LineWeight015, DefaultColorIndex = 7 };
case Role.BreakLine:
return new LayerSpec { LayerName = "截断线", DefaultLinetypeName = "PHANTOM", DefaultLineWeight = LineWeight.LineWeight015, DefaultColorIndex = 7 };
case Role.Centerline:

View File

@ -2911,14 +2911,16 @@ namespace CadParamPluging.Cad
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
// 2. 文字和包裹圆圈
string displayTxt = string.IsNullOrWhiteSpace(hardnessVal) ? "HB" : hardnessVal;
// 2. 文字和外围圆圈 (无论硬度值是什么,只显示固定的"HB"符号)
string displayTxt = "HB";
// 估算圆圈半径基础半径至少3.5,以保证能舒适包裹"HB";长字符串相应按比例扩大
double radius = Math.Max(3.5, displayTxt.Length * 3.5 * 0.35 + 0.5);
// 放宽圆圈半径:增加到 4.5 留出适当的缝隙(留白),不再紧贴字母
double radius = 4.5;
// 设置圆心位置,位于引线终点 p3 向右偏移 radius 距离处(这样刚好圆左侧边缘直接连着引线终点)
var centerPt = new Point3d(p3.X + radius, p3.Y, 0);
// 绘制文字
// 绘制文字 (绝对居中)
var text = new DBText();
text.TextString = displayTxt;
text.Height = 3.5;
@ -2926,12 +2928,12 @@ namespace CadParamPluging.Cad
text.HorizontalMode = TextHorizontalMode.TextCenter;
text.VerticalMode = TextVerticalMode.TextVerticalMid;
text.AlignmentPoint = centerPt;
text.Position = centerPt; // TextCenter 时通常主要使用 AlignmentPoint
text.Position = centerPt;
ctx.Btr.AppendEntity(text);
ctx.Tr.AddNewlyCreatedDBObject(text, true);
// 绘制外圈圆
// 绘制固定大小的外圈圆,与文字居中贴合
var circle = new Circle();
circle.Center = centerPt;
circle.Radius = radius;

View File

@ -115,7 +115,9 @@ namespace CadParamPluging.Cad
double fy_R_tangTop = r > 0 ? (oy + S2 / 2.0) + (Rm / (Rm - r)) * ((oy + S2 - r) - (oy + S2 / 2.0)) : oy + S2;
// 1. 绘制主体轮廓 (矩形 + 平滑相切圆角) 和左右端弧线一体化
DrawShaftRoundHeadUnifiedOutline(ctx, ox, oy, S1, S2, w, r, xf_left, xf_right, fx_L_tangTop, fy_L_tangTop, fx_L_tang, fy_L_tangBot, fx_R_tangTop, fy_R_tangTop, fx_R_tang, fy_R_tangBot, needBreakLines, xBreak, lineSpacing);
double sectionOxArg = S3 > 0 ? (ox + S1 * 2.0 / 3.0 - S3 / 2.0) : 0;
double sectionWArg = S3;
DrawShaftRoundHeadUnifiedOutline(ctx, ox, oy, S1, S2, w, r, xf_left, xf_right, fx_L_tangTop, fy_L_tangTop, fx_L_tang, fy_L_tangBot, fx_R_tangTop, fy_R_tangTop, fx_R_tang, fy_R_tangBot, needBreakLines, xBreak, lineSpacing, sectionOxArg, sectionWArg);
// 2. 中心线 (贯穿左右水平方向)
double clY = oy + S2 / 2.0;
@ -253,11 +255,11 @@ namespace CadParamPluging.Cad
if (needBreakLines)
{
DrawRectOutlineWithBreak(ctx, pOx, pOy, pL, pH, xBreak, lineSpacing, DrawingStyleManager.Role.Hidden);
DrawRectOutlineWithBreak(ctx, pOx, pOy, pL, pH, xBreak, lineSpacing, DrawingStyleManager.Role.PartContour);
}
else
{
DrawRectOutline(ctx, pOx, pOy, pL, pH, DrawingStyleManager.Role.Hidden);
DrawRectOutline(ctx, pOx, pOy, pL, pH, DrawingStyleManager.Role.PartContour);
}
}
}
@ -286,7 +288,7 @@ namespace CadParamPluging.Cad
ctx.Tr.AddNewlyCreatedDBObject(line2, true);
}
private static void DrawShaftRoundHeadUnifiedOutline(FeatureDrivenDrawer.DrawingContext ctx, double ox, double oy, double W, double H, double w, double r, double xf_left, double xf_right, double fx_L_tangTop, double fy_L_tangTop, double fx_L_tangBotX, double fy_L_tangBot, double fx_R_tangTop, double fy_R_tangTop, double fx_R_tangBotX, double fy_R_tangBot, bool needBreakLines, double xBreak, double breakWidth)
private static void DrawShaftRoundHeadUnifiedOutline(FeatureDrivenDrawer.DrawingContext ctx, double ox, double oy, double W, double H, double w, double r, double xf_left, double xf_right, double fx_L_tangTop, double fy_L_tangTop, double fx_L_tangBotX, double fy_L_tangBot, double fx_R_tangTop, double fy_R_tangTop, double fx_R_tangBotX, double fy_R_tangBot, bool needBreakLines, double xBreak, double breakWidth, double sectionOx, double sectionW)
{
double Rm = (H * H) / (8.0 * w) + w / 2.0;
@ -405,32 +407,54 @@ namespace CadParamPluging.Cad
ctx.Tr.AddNewlyCreatedDBObject(rightClosureLine, true);
// -------- Horizontal Connectors --------
if (!needBreakLines)
Action<double> drawHoriz = (yLine) =>
{
var top = new Line(new Point3d(xf_left, oy + H, 0), new Point3d(xf_right, oy + H, 0));
var bot = new Line(new Point3d(xf_left, oy, 0), new Point3d(xf_right, oy, 0));
ctx.Style?.Apply(top, DrawingStyleManager.Role.OutlineBold);
ctx.Style?.Apply(bot, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(top);
ctx.Btr.AppendEntity(bot);
ctx.Tr.AddNewlyCreatedDBObject(top, true);
ctx.Tr.AddNewlyCreatedDBObject(bot, true);
}
else
var segments = new List<Tuple<double, double>>();
segments.Add(Tuple.Create(xf_left, xf_right));
if (needBreakLines)
{
var tL = new Line(new Point3d(xf_left, oy + H, 0), new Point3d(xBreak, oy + H, 0));
var tR = new Line(new Point3d(xBreak + breakWidth, oy + H, 0), new Point3d(xf_right, oy + H, 0));
var bL = new Line(new Point3d(xf_left, oy, 0), new Point3d(xBreak, oy, 0));
var bR = new Line(new Point3d(xBreak + breakWidth, oy, 0), new Point3d(xf_right, oy, 0));
ctx.Style?.Apply(tL, DrawingStyleManager.Role.OutlineBold);
ctx.Style?.Apply(tR, DrawingStyleManager.Role.OutlineBold);
ctx.Style?.Apply(bL, DrawingStyleManager.Role.OutlineBold);
ctx.Style?.Apply(bR, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(tL); ctx.Tr.AddNewlyCreatedDBObject(tL, true);
ctx.Btr.AppendEntity(tR); ctx.Tr.AddNewlyCreatedDBObject(tR, true);
ctx.Btr.AppendEntity(bL); ctx.Tr.AddNewlyCreatedDBObject(bL, true);
ctx.Btr.AppendEntity(bR); ctx.Tr.AddNewlyCreatedDBObject(bR, true);
var newSegs = new List<Tuple<double, double>>();
foreach(var seg in segments)
{
if (xBreak > seg.Item1 && (xBreak + breakWidth) < seg.Item2)
{
newSegs.Add(Tuple.Create(seg.Item1, xBreak));
newSegs.Add(Tuple.Create(xBreak + breakWidth, seg.Item2));
}
else newSegs.Add(seg);
}
segments = newSegs;
}
if (sectionW > 0)
{
var newSegs = new List<Tuple<double, double>>();
foreach(var seg in segments)
{
if (sectionOx > seg.Item1 && (sectionOx + sectionW) < seg.Item2)
{
newSegs.Add(Tuple.Create(seg.Item1, sectionOx));
newSegs.Add(Tuple.Create(sectionOx + sectionW, seg.Item2));
}
else newSegs.Add(seg);
}
segments = newSegs;
}
foreach(var seg in segments)
{
if (seg.Item2 > seg.Item1 + 0.01) {
var l = new Line(new Point3d(seg.Item1, yLine, 0), new Point3d(seg.Item2, yLine, 0));
ctx.Style?.Apply(l, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(l);
ctx.Tr.AddNewlyCreatedDBObject(l, true);
}
}
};
drawHoriz(oy + H); // top
drawHoriz(oy); // bot
}
private static void DrawHeadFilletRadiusLeader(FeatureDrivenDrawer.DrawingContext ctx, double cx, double cy, double r)
@ -608,7 +632,7 @@ namespace CadParamPluging.Cad
/// <summary>
/// 绘制带断口的零件轮廓(在断线位置打断上下横线)
/// 支持自定义 Role (通常为 Hidden 或 PartContour)
/// 支持自定义 Role (通常为 PartContour)
/// </summary>
private static void DrawRectOutlineWithBreak(FeatureDrivenDrawer.DrawingContext ctx, double x, double y, double w, double h, double xBreak, double breakWidth, DrawingStyleManager.Role role)
{