diff --git a/Cad/FeatureDrivenDrawer.cs b/Cad/FeatureDrivenDrawer.cs index 8c70232..2760f03 100644 --- a/Cad/FeatureDrivenDrawer.cs +++ b/Cad/FeatureDrivenDrawer.cs @@ -82,6 +82,7 @@ namespace CadParamPluging.Cad public string DeliveryStatus { get; set; } public string StructuralFeature { get; set; } public string SpecialCondition { get; set; } + public string ProcessMethod { get; set; } internal DrawingStyleManager Style { get; set; } @@ -97,6 +98,12 @@ namespace CadParamPluging.Cad public bool HasRoundHead => !string.IsNullOrWhiteSpace(SpecialCondition) && SpecialCondition.IndexOf("有圆头", StringComparison.OrdinalIgnoreCase) >= 0; + + /// + /// 是否为轧制工艺(轧制时只画右半边图) + /// + public bool IsRolling => !string.IsNullOrWhiteSpace(ProcessMethod) + && ProcessMethod.IndexOf("轧制", StringComparison.OrdinalIgnoreCase) >= 0; } #endregion @@ -209,10 +216,11 @@ namespace CadParamPluging.Cad /// 交付状态 /// 结构特征 /// 特殊条件 + /// 工艺方法(轧制/自由锻) /// 绘图中心点 /// 缩放比例(1.0表示不缩放) public static void Draw(CadContext ctx, ParamBag bag, string deliveryStatus, string structuralFeature, - string specialCondition = null, Point3d? center = null, double scaleFactor = 1.0) + string specialCondition = null, string processMethod = null, Point3d? center = null, double scaleFactor = 1.0) { if (ctx == null) throw new ArgumentNullException(nameof(ctx)); if (bag == null) throw new ArgumentNullException(nameof(bag)); @@ -232,6 +240,7 @@ namespace CadParamPluging.Cad DeliveryStatus = deliveryStatus, StructuralFeature = structuralFeature, SpecialCondition = specialCondition, + ProcessMethod = processMethod, Btr = btr, Style = new DrawingStyleManager(db, tr) }; @@ -309,9 +318,118 @@ namespace CadParamPluging.Cad return; // 缺少高度,无法绘制 } - // 视图方向调整:X方向为直径方向(外径/内径),Y方向为高度方向 - double W = outerDia.Value; - double H = height.Value; + // 判断是轧制还是自由锻 + if (ctx.IsRolling) + { + // 轧制:只画右半边图 + DrawRingFeaturesHalf(ctx, outerDia.Value, height.Value); + } + else + { + // 自由锻:画全图 + DrawRingFeaturesFull(ctx, outerDia.Value, height.Value); + } + } + + /// + /// 轧制工艺 - 只画右半边图 + /// + private static void DrawRingFeaturesHalf(DrawingContext ctx, double outerDia, double height) + { + var bag = ctx.Bag; + double R = outerDia / 2.0; // 外半径 + double H = height; + + // 轧制时图形只画右半边,但要保持居中 + // 半图宽度为R,要居中则起点为 Center.X - R/2 + double ox = ctx.Center.X - R / 2.0; // 对称轴位置(左边界) + double oy = ctx.Center.Y - H / 2.0; + + // 车加工态零件尺寸 + double? outerDiaPrime = null; + double? innerDiaPrime = null; + double? heightPrime = null; + if (ctx.IsMachined) + { + outerDiaPrime = bag.GetDoubleOrNull(KeyOuterDiameter1Prime); + innerDiaPrime = bag.GetDoubleOrNull(KeyInnerDiameter2Prime); + heightPrime = bag.GetDoubleOrNull(KeyHeight1Prime); + } + + // === 特征1: 锻件外轮廓(右半边,三条边:下、右、上,左边开口) === + DrawForgingOuterContourHalf(ctx, ox, oy, R, H); + + // === 特征1.1: 对称轴(垂直中心线) === + DrawRingSymmetryAxis(ctx, ox, oy, H); + + // === 特征2: 外径公差标注 === + var outerTolPlus = bag.GetDoubleOrNull(KeyOuterDiameter1TolPlus); + var outerTolMinus = bag.GetDoubleOrNull(KeyOuterDiameter1TolMinus); + DrawOuterDiameterDimensionHalf(ctx, ox, oy, R, H, outerDia, outerTolPlus, outerTolMinus, outerDiaPrime); + + // === 特征3: 内孔/内径(如果有内径参数) === + var innerDia = bag.GetDoubleOrNull(KeyInnerDiameter2); + double? xInnerRight = null; + if (innerDia.HasValue && innerDia.Value > 0 && innerDia.Value < outerDia) + { + double innerR = innerDia.Value / 2.0; + xInnerRight = ox + innerR; + + var innerTolPlus = bag.GetDoubleOrNull(KeyInnerDiameter2TolPlus); + var innerTolMinus = bag.GetDoubleOrNull(KeyInnerDiameter2TolMinus); + + // 只画右侧内孔线 + DrawInnerHoleHalf(ctx, ox, xInnerRight.Value, oy, H); + DrawInnerDiameterDimensionHalf(ctx, ox, xInnerRight.Value, oy, H, innerDia.Value, innerTolPlus, innerTolMinus, innerDiaPrime); + + // === 特征4: 内径圆角(只画右侧) === + var innerRadiusMax = bag.GetDoubleOrNull(KeyInnerRadiusMax); + if (innerRadiusMax.HasValue && innerRadiusMax.Value > 0 && ctx.IsCenterPunched) + { + DrawInnerFilletsHalf(ctx, xInnerRight.Value, oy, H, innerRadiusMax.Value); + } + + // === 特征4.1: 剖面线(右半边环形截面) === + DrawRingSectionHatch(ctx, xInnerRight.Value, ox + R, oy, H); + } + + // === 特征5: 高度标注 === + var heightTolPlus = bag.GetDoubleOrNull(KeyHeight1TolPlus); + var heightTolMinus = bag.GetDoubleOrNull(KeyHeight1TolMinus); + DrawHeightDimensionHalf(ctx, ox, oy, R, H, heightTolPlus, heightTolMinus, heightPrime); + + // === 特征6: 未注圆角 === + var unspecifiedFillet = bag.GetDoubleOrNull(KeyUnspecifiedFilletRadiusMax); + if (unspecifiedFillet.HasValue && unspecifiedFillet.Value > 0) + { + DrawUnspecifiedFilletNote(ctx, ox, oy, H, R, unspecifiedFillet.Value); + } + + // === 特征7: 最小壁厚min标注 === + var minWallThickness = bag.GetDoubleOrNull(KeyMinWallThickness); + if (minWallThickness.HasValue && minWallThickness.Value > 0 && xInnerRight.HasValue) + { + DrawMinWallThicknessNote(ctx, xInnerRight.Value, ox + R, oy, minWallThickness.Value); + } + + // === 特征8: 零件轮廓(车加工态,右半边) === + if (ctx.IsMachined && outerDiaPrime.HasValue && outerDiaPrime.Value > 0 && heightPrime.HasValue && heightPrime.Value > 0) + { + DrawPartContourHalf(ctx, ox, oy, H, outerDiaPrime.Value, innerDiaPrime, heightPrime.Value); + } + + // === 特征9: 硬度符号 === + TryDrawHardnessSymbol(ctx, ox + R, oy, H); + } + + /// + /// 自由锻工艺 - 画全图 + /// + private static void DrawRingFeaturesFull(DrawingContext ctx, double outerDia, double height) + { + var bag = ctx.Bag; + double W = outerDia; + double H = height; double ox = ctx.Center.X - W / 2.0; double oy = ctx.Center.Y - H / 2.0; @@ -335,7 +453,7 @@ namespace CadParamPluging.Cad // === 特征2: 外径公差标注(如果有公差参数) === var outerTolPlus = bag.GetDoubleOrNull(KeyOuterDiameter1TolPlus); var outerTolMinus = bag.GetDoubleOrNull(KeyOuterDiameter1TolMinus); - DrawOuterDiameterDimension(ctx, ox, oy, W, outerDia.Value, outerTolPlus, outerTolMinus, outerDiaPrime); + DrawOuterDiameterDimension(ctx, ox, oy, W, outerDia, outerTolPlus, outerTolMinus, outerDiaPrime); // === 特征3: 内孔/内径(如果有内径参数) === var innerDia = bag.GetDoubleOrNull(KeyInnerDiameter2); @@ -417,6 +535,167 @@ namespace CadParamPluging.Cad ctx.Tr.AddNewlyCreatedDBObject(line, true); } + #region 轧制专用绘图方法(只画右半边) + + /// + /// 轧制:绘制右半边外轮廓(开口多段线) + /// + private static void DrawForgingOuterContourHalf(DrawingContext ctx, double ox, double oy, double radius, double height) + { + // 右半边轮廓:下边、右边、上边(左边开口) + var poly = new Polyline(); + poly.AddVertexAt(0, new Point2d(ox, oy), 0, 0, 0); // 左下(对称轴下端) + poly.AddVertexAt(1, new Point2d(ox + radius, oy), 0, 0, 0); // 右下 + poly.AddVertexAt(2, new Point2d(ox + radius, oy + height), 0, 0, 0); // 右上 + poly.AddVertexAt(3, new Point2d(ox, oy + height), 0, 0, 0); // 左上(对称轴上端) + poly.Closed = false; // 不闭合,左边开口 + + ctx.Style?.Apply(poly, DrawingStyleManager.Role.OutlineBold); + ctx.Btr.AppendEntity(poly); + ctx.Tr.AddNewlyCreatedDBObject(poly, true); + } + + /// + /// 轧制:绘制对称轴(垂直中心线) + /// + private static void DrawRingSymmetryAxis(DrawingContext ctx, double ox, double oy, double height) + { + var line = new Line(new Point3d(ox, oy - 10, 0), new Point3d(ox, oy + height + 10, 0)); + ctx.Style?.Apply(line, DrawingStyleManager.Role.Centerline); + ctx.Btr.AppendEntity(line); + ctx.Tr.AddNewlyCreatedDBObject(line, true); + } + + /// + /// 轧制:外径标注(从对称轴到右边,标注在图形下方偏内) + /// + private static void DrawOuterDiameterDimensionHalf(DrawingContext ctx, double ox, double oy, double radius, double height, + double diameter, double? tolPlus, double? tolMinus, double? diameterPrime) + { + var baseText = BuildDimensionText($"%%c{FormatDimNumber(diameter)}", tolPlus, tolMinus); + var dimText = diameterPrime.HasValue && diameterPrime.Value > 0 + ? baseText + $"\\X(%%c{FormatDimNumber(diameterPrime.Value)})" + : baseText; + + // 标注放在图形底部稍下方 + AddLinearDim( + ctx, + new Point3d(ox, oy, 0), + new Point3d(ox + radius, oy, 0), + new Point3d(ox + radius / 2, oy - 20, 0), + 0, + dimText); + } + + /// + /// 轧制:只画右侧内孔线 + /// + private static void DrawInnerHoleHalf(DrawingContext ctx, double oxAxis, double xInnerRight, double yBottom, double height) + { + var yTop = yBottom + height; + + // 只画右侧内孔竖线 + var lineRight = new Line(new Point3d(xInnerRight, yBottom, 0), new Point3d(xInnerRight, yTop, 0)); + ctx.Style?.Apply(lineRight, DrawingStyleManager.Role.Hidden); + ctx.Btr.AppendEntity(lineRight); + ctx.Tr.AddNewlyCreatedDBObject(lineRight, true); + } + + /// + /// 轧制:内径标注(从对称轴到右边内孔,标注在图形内部上方) + /// + private static void DrawInnerDiameterDimensionHalf(DrawingContext ctx, double oxAxis, double xInnerRight, double yBottom, double height, + double diameter, double? tolPlus, double? tolMinus, double? diameterPrime) + { + var baseText = BuildDimensionText($"%%c{FormatDimNumber(diameter)}", tolPlus, tolMinus); + var dimText = diameterPrime.HasValue && diameterPrime.Value > 0 + ? baseText + $"\\X(%%c{FormatDimNumber(diameterPrime.Value)})" + : baseText; + + double innerRadius = xInnerRight - oxAxis; + // 标注放在图形顶部稍上方 + AddLinearDim( + ctx, + new Point3d(oxAxis, yBottom + height, 0), + new Point3d(xInnerRight, yBottom + height, 0), + new Point3d(oxAxis + innerRadius / 2, yBottom + height + 20, 0), + 0, + dimText); + } + + /// + /// 轧制:只画右侧内径圆角 + /// + private static void DrawInnerFilletsHalf(DrawingContext ctx, double xInnerRight, double yBottom, double height, double filletR) + { + var yTop = yBottom + height; + + // 只画右侧两个圆角 + // 右上角 + DrawFilletArc(ctx, xInnerRight - filletR, yTop - filletR, filletR, 0, Math.PI / 2); + // 右下角 + DrawFilletArc(ctx, xInnerRight - filletR, yBottom + filletR, filletR, Math.PI * 1.5, Math.PI * 2); + } + + /// + /// 轧制:高度标注(在右侧) + /// + private static void DrawHeightDimensionHalf(DrawingContext ctx, double ox, double oy, double radius, + double height, double? tolPlus, double? tolMinus, double? heightPrime) + { + var baseText = BuildDimensionText(FormatDimNumber(height), tolPlus, tolMinus); + var dimText = heightPrime.HasValue && heightPrime.Value > 0 + ? baseText + $"\\X({FormatDimNumber(heightPrime.Value)})" + : baseText; + + AddLinearDim( + ctx, + new Point3d(ox + radius, oy, 0), + new Point3d(ox + radius, oy + height, 0), + new Point3d(ox + radius + 20, oy + height / 2, 0), + 90, + dimText); + } + + /// + /// 轧制:零件轮廓(右半边) + /// + private static void DrawPartContourHalf(DrawingContext ctx, double ox, double oy, double forgingHeight, + double outerDiaPrime, double? innerDiaPrime, double heightPrime) + { + var Rp = outerDiaPrime / 2.0; + var h = heightPrime; + + // 零件轮廓居中于锻件轮廓内 + var offsetY = (forgingHeight - h) / 2.0; + var y0 = oy + offsetY; + + // 右半边零件轮廓(开口) + var polyPart = new Polyline(); + polyPart.AddVertexAt(0, new Point2d(ox, y0), 0, 0, 0); + polyPart.AddVertexAt(1, new Point2d(ox + Rp, y0), 0, 0, 0); + polyPart.AddVertexAt(2, new Point2d(ox + Rp, y0 + h), 0, 0, 0); + polyPart.AddVertexAt(3, new Point2d(ox, y0 + h), 0, 0, 0); + polyPart.Closed = false; // 不闭合 + ctx.Style?.Apply(polyPart, DrawingStyleManager.Role.PartContour); + ctx.Btr.AppendEntity(polyPart); + ctx.Tr.AddNewlyCreatedDBObject(polyPart, true); + + // 右侧内径轮廓 + if (innerDiaPrime.HasValue && innerDiaPrime.Value > 0 && innerDiaPrime.Value < outerDiaPrime) + { + var xiR = ox + innerDiaPrime.Value / 2.0; + var yTop = y0 + h; + + var lineInner = new Line(new Point3d(xiR, y0, 0), new Point3d(xiR, yTop, 0)); + ctx.Style?.Apply(lineInner, DrawingStyleManager.Role.PartContour); + ctx.Btr.AppendEntity(lineInner); + ctx.Tr.AddNewlyCreatedDBObject(lineInner, true); + } + } + + #endregion + private static void DrawInnerHole(DrawingContext ctx, double xInnerLeft, double xInnerRight, double yBottom, double height) { var yTop = yBottom + height; diff --git a/Cad/HalfSectionDrawer.cs b/Cad/HalfSectionDrawer.cs index eeaeb49..3bee9de 100644 --- a/Cad/HalfSectionDrawer.cs +++ b/Cad/HalfSectionDrawer.cs @@ -19,22 +19,23 @@ namespace CadParamPluging.Cad /// 交付状态(毛料态/车加工态) /// 结构特征(环形/饼盘/轴杆/方体) /// 特殊条件(中心冲孔/有圆头等) + /// 工艺方法(轧制/自由锻) /// 绘图中心点 /// 缩放比例(1.0表示不缩放) public static void Draw(CadContext ctx, ParamBag bag, string deliveryStatus, string structuralFeature, - string specialCondition = null, Point3d? center = null, double scaleFactor = 1.0) + string specialCondition = null, string processMethod = null, Point3d? center = null, double scaleFactor = 1.0) { // 委托给特征驱动绘图引擎 - FeatureDrivenDrawer.Draw(ctx, bag, deliveryStatus, structuralFeature, specialCondition, center, scaleFactor); + FeatureDrivenDrawer.Draw(ctx, bag, deliveryStatus, structuralFeature, specialCondition, processMethod, center, scaleFactor); } /// /// 兼容旧接口 /// - [Obsolete("请使用新的 Draw 方法,支持 specialCondition 参数")] + [Obsolete("请使用新的 Draw 方法,支持 specialCondition 和 processMethod 参数")] public static void DrawLegacy(CadContext ctx, ParamBag bag, string deliveryStatus, string structuralFeature, Point3d? center = null) { - Draw(ctx, bag, deliveryStatus, structuralFeature, null, center); + Draw(ctx, bag, deliveryStatus, structuralFeature, null, null, center); } #region 旧代码保留供参考(已废弃) diff --git a/UI/ParamDrawingPanel.cs b/UI/ParamDrawingPanel.cs index 74785bd..2ba0a95 100644 --- a/UI/ParamDrawingPanel.cs +++ b/UI/ParamDrawingPanel.cs @@ -667,6 +667,7 @@ namespace CadParamPluging.UI tplParams.ProjectType, // 交付状态 tplParams.SheetSize, // 结构特征 tplParams.Scale, // 特殊条件(中心冲孔/有圆头等) + tplParams.DrawingType, // 工艺方法(轧制/自由锻) removeResult.OriginalCenter, // 原图纸中心点 scaleFactor // 缩放比例 );