From 40a290948143c401ec42389b07a1d41cefbc46d5 Mon Sep 17 00:00:00 2001 From: sladro Date: Thu, 26 Mar 2026 18:33:33 +0800 Subject: [PATCH] feat: Introduce a feature-driven drawing engine with dynamic CAD entity sizing based on parameters and drawing style management. --- Cad/DrawingStyleManager.cs | 2 +- Cad/FeatureDrivenDrawer.cs | 16 +++-- Cad/ShaftRawFreeForgeSquareShaftDrawer.cs | 84 +++++++++++++++-------- 3 files changed, 64 insertions(+), 38 deletions(-) diff --git a/Cad/DrawingStyleManager.cs b/Cad/DrawingStyleManager.cs index 2cb271b..8d9cc10 100644 --- a/Cad/DrawingStyleManager.cs +++ b/Cad/DrawingStyleManager.cs @@ -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: diff --git a/Cad/FeatureDrivenDrawer.cs b/Cad/FeatureDrivenDrawer.cs index 98faa65..4efd434 100644 --- a/Cad/FeatureDrivenDrawer.cs +++ b/Cad/FeatureDrivenDrawer.cs @@ -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; diff --git a/Cad/ShaftRawFreeForgeSquareShaftDrawer.cs b/Cad/ShaftRawFreeForgeSquareShaftDrawer.cs index 1c78026..efdbfcd 100644 --- a/Cad/ShaftRawFreeForgeSquareShaftDrawer.cs +++ b/Cad/ShaftRawFreeForgeSquareShaftDrawer.cs @@ -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 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 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 segments = new List>(); + segments.Add(Tuple.Create(xf_left, xf_right)); + + if (needBreakLines) + { + var newSegs = new List>(); + 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>(); + 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 /// /// 绘制带断口的零件轮廓(在断线位置打断上下横线) - /// 支持自定义 Role (通常为 Hidden 或 PartContour) + /// 支持自定义 Role (通常为 PartContour) /// private static void DrawRectOutlineWithBreak(FeatureDrivenDrawer.DrawingContext ctx, double x, double y, double w, double h, double xBreak, double breakWidth, DrawingStyleManager.Role role) {