diff --git a/Cad/Drawers/RingRawRollingGenerator.cs b/Cad/Drawers/RingRawRollingGenerator.cs
index a4d785d..5574070 100644
--- a/Cad/Drawers/RingRawRollingGenerator.cs
+++ b/Cad/Drawers/RingRawRollingGenerator.cs
@@ -1,11 +1,84 @@
+using System;
+using Autodesk.AutoCAD.Geometry;
using CadParamPluging.Common;
+using CadParamPluging.Domain.Models;
namespace CadParamPluging.Cad
{
- public sealed class RingRawRollingGenerator : TemplateDrawingGeneratorBase
+ public sealed class RingRawRollingGenerator : ITemplateDrawingGenerator
{
public static readonly string Key = TemplateKeyBuilder.Build("毛料态", "轧制", "环形", "无");
+ private const string MachinedStatus = "车加工";
- public override string TemplateKey => Key;
+ public string TemplateKey => Key;
+
+ public FeatureDrivenDrawer.ExpectedDrawingSize CalculateExpectedSize(ParamBag bag, TemplateParams templateParams)
+ {
+ var workingBag = CloneBagWithMachinedStatus(bag, templateParams);
+ return FeatureDrivenDrawer.CalculateExpectedSize(workingBag, templateParams?.SheetSize);
+ }
+
+ public void Draw(CadContext ctx, ParamBag bag, TemplateParams templateParams, Point3d center, double scaleFactor)
+ {
+ if (ctx == null)
+ {
+ throw new ArgumentNullException(nameof(ctx));
+ }
+
+ if (templateParams == null)
+ {
+ throw new ArgumentNullException(nameof(templateParams));
+ }
+
+ var workingBag = CloneBagWithMachinedStatus(bag, templateParams);
+ var drawParams = CreateMachinedTemplateParams(templateParams);
+
+ FeatureDrivenDrawer.DrawRingRollingWithUnspecifiedFillet(
+ ctx,
+ workingBag,
+ drawParams.ProjectType,
+ drawParams.SheetSize,
+ drawParams.Scale,
+ drawParams.DrawingType,
+ center,
+ scaleFactor);
+ }
+
+ private static ParamBag CloneBagWithMachinedStatus(ParamBag source, TemplateParams templateParams)
+ {
+ var clone = new ParamBag();
+ if (source?.Items != null)
+ {
+ foreach (var item in source.Items)
+ {
+ if (item == null)
+ {
+ continue;
+ }
+
+ clone.Items.Add(new ParamValue { Key = item.Key, Value = item.Value });
+ }
+ }
+
+ clone.Set("DeliveryStatus", MachinedStatus);
+ if (!string.IsNullOrWhiteSpace(templateParams?.DrawingType)
+ && string.IsNullOrWhiteSpace(clone.GetString("ProcessMethod")))
+ {
+ clone.Set("ProcessMethod", templateParams.DrawingType);
+ }
+
+ return clone;
+ }
+
+ private static TemplateParams CreateMachinedTemplateParams(TemplateParams templateParams)
+ {
+ return new TemplateParams
+ {
+ ProjectType = MachinedStatus,
+ DrawingType = templateParams?.DrawingType,
+ SheetSize = templateParams?.SheetSize,
+ Scale = templateParams?.Scale
+ };
+ }
}
}
diff --git a/Cad/FeatureDrivenDrawer.cs b/Cad/FeatureDrivenDrawer.cs
index 41fa3a2..009c426 100644
--- a/Cad/FeatureDrivenDrawer.cs
+++ b/Cad/FeatureDrivenDrawer.cs
@@ -312,6 +312,62 @@ namespace CadParamPluging.Cad
}
}
+ public static void DrawRingRollingWithUnspecifiedFillet(CadContext ctx, ParamBag bag, string deliveryStatus, string structuralFeature,
+ 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));
+
+ if (!IsRing(structuralFeature)
+ || string.IsNullOrWhiteSpace(processMethod)
+ || processMethod.IndexOf("轧制", StringComparison.OrdinalIgnoreCase) < 0)
+ {
+ Draw(ctx, bag, deliveryStatus, structuralFeature, specialCondition, processMethod, center, scaleFactor);
+ return;
+ }
+
+ 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 ?? Point3d.Origin,
+ DeliveryStatus = deliveryStatus,
+ StructuralFeature = structuralFeature,
+ SpecialCondition = specialCondition,
+ ProcessMethod = processMethod,
+ Btr = btr,
+ Style = new DrawingStyleManager(db, tr)
+ };
+
+ var outerDia = effectiveBag.GetDoubleOrNull(KeyOuterDiameter1);
+ var height = effectiveBag.GetDoubleOrNull(KeyHeight1);
+ if (!outerDia.HasValue || outerDia.Value <= 0 || !height.HasValue || height.Value <= 0)
+ {
+ return;
+ }
+
+ DrawRingFeaturesHalfWithUnspecifiedFillet(context, outerDia.Value, height.Value);
+ }
+
#endregion
#region 结构特征判断
@@ -383,6 +439,16 @@ namespace CadParamPluging.Cad
/// 轧制工艺 - 只画右半边图
///
private static void DrawRingFeaturesHalf(DrawingContext ctx, double outerDia, double height)
+ {
+ DrawRingFeaturesHalfCore(ctx, outerDia, height, false);
+ }
+
+ private static void DrawRingFeaturesHalfWithUnspecifiedFillet(DrawingContext ctx, double outerDia, double height)
+ {
+ DrawRingFeaturesHalfCore(ctx, outerDia, height, true);
+ }
+
+ private static void DrawRingFeaturesHalfCore(DrawingContext ctx, double outerDia, double height, bool applyUnspecifiedFillet)
{
var bag = ctx.Bag;
@@ -477,7 +543,15 @@ namespace CadParamPluging.Cad
}
// === 特征1: 锻件外轮廓 ===
- DrawForgingOuterContourHalf(ctx, ox, oy, visualOuterR, H);
+ var unspecifiedFillet = bag.GetDoubleOrNull(KeyUnspecifiedFilletRadiusMax);
+ if (applyUnspecifiedFillet && unspecifiedFillet.HasValue && unspecifiedFillet.Value > 0)
+ {
+ DrawForgingOuterContourHalf(ctx, ox, oy, visualOuterR, H, unspecifiedFillet);
+ }
+ else
+ {
+ DrawForgingOuterContourHalf(ctx, ox, oy, visualOuterR, H, null);
+ }
// === 特征1.1: 对称轴 ===
DrawRingSymmetryAxis(ctx, ox, oy, H);
@@ -508,9 +582,20 @@ namespace CadParamPluging.Cad
{
DrawInnerFilletsHalf(ctx, xInnerRight.Value, oy, H, innerRadiusMax.Value);
}
+ else if (applyUnspecifiedFillet && unspecifiedFillet.HasValue && unspecifiedFillet.Value > 0)
+ {
+ DrawInnerFilletsHalfInward(ctx, xInnerRight.Value, oy, H, unspecifiedFillet.Value);
+ }
// === 特征4.1: 剖面线 ===
- DrawRingSectionHatch(ctx, xInnerRight.Value, ox + visualOuterR, oy, H);
+ if (applyUnspecifiedFillet && unspecifiedFillet.HasValue && unspecifiedFillet.Value > 0)
+ {
+ DrawRingSectionHatchWithFillet(ctx, xInnerRight.Value, ox + visualOuterR, oy, H, unspecifiedFillet.Value);
+ }
+ else
+ {
+ DrawRingSectionHatch(ctx, xInnerRight.Value, ox + visualOuterR, oy, H);
+ }
// 剖面左侧竖线
DrawSectionInnerBoundaryBold(ctx, xInnerRight.Value, oy, H);
@@ -522,7 +607,6 @@ namespace CadParamPluging.Cad
DrawHeightDimensionHalf(ctx, ox, oy, visualOuterR, H, heightTolPlus, heightTolMinus, heightPrime);
// === 特征6: 未注圆角 ===
- var unspecifiedFillet = bag.GetDoubleOrNull(KeyUnspecifiedFilletRadiusMax);
if (unspecifiedFillet.HasValue && unspecifiedFillet.Value > 0)
{
DrawUnspecifiedFilletNote(ctx, ox, oy, H, visualOuterR, unspecifiedFillet.Value);
@@ -710,8 +794,32 @@ namespace CadParamPluging.Cad
///
/// 轧制:绘制右半边外轮廓(开口多段线)
///
- private static void DrawForgingOuterContourHalf(DrawingContext ctx, double ox, double oy, double radius, double height)
+ private static void DrawForgingOuterContourHalf(DrawingContext ctx, double ox, double oy, double radius, double height, double? filletRadius)
{
+ var rawR = filletRadius.GetValueOrDefault();
+ if (rawR > 0)
+ {
+ var maxR = Math.Min(radius * 0.5, height * 0.5);
+ var r = Math.Min(rawR, maxR);
+ if (r > 0.01)
+ {
+ var bulge = Math.Tan(Math.PI / 8.0);
+ var polyFillet = new Polyline();
+ polyFillet.AddVertexAt(0, new Point2d(ox, oy), 0, 0, 0);
+ polyFillet.AddVertexAt(1, new Point2d(ox + radius - r, oy), bulge, 0, 0);
+ polyFillet.AddVertexAt(2, new Point2d(ox + radius, oy + r), 0, 0, 0);
+ polyFillet.AddVertexAt(3, new Point2d(ox + radius, oy + height - r), bulge, 0, 0);
+ polyFillet.AddVertexAt(4, new Point2d(ox + radius - r, oy + height), 0, 0, 0);
+ polyFillet.AddVertexAt(5, new Point2d(ox, oy + height), 0, 0, 0);
+ polyFillet.Closed = false;
+
+ ctx.Style?.Apply(polyFillet, DrawingStyleManager.Role.OutlineBold);
+ ctx.Btr.AppendEntity(polyFillet);
+ ctx.Tr.AddNewlyCreatedDBObject(polyFillet, true);
+ return;
+ }
+ }
+
// 右半边轮廓:下边、右边、上边(左边开口)
var poly = new Polyline();
poly.AddVertexAt(0, new Point2d(ox, oy), 0, 0, 0); // 左下(对称轴下端)
@@ -879,6 +987,15 @@ namespace CadParamPluging.Cad
DrawFilletArc(ctx, xInnerRight - filletR, yBottom + filletR, filletR, Math.PI * 1.5, Math.PI * 2);
}
+ private static void DrawInnerFilletsHalfInward(DrawingContext ctx, double xInnerRight, double yBottom, double height, double filletR)
+ {
+ var yTop = yBottom + height;
+
+ // 仅绘制内孔右侧边界的圆角,圆角朝向剖面内部(右侧)
+ DrawFilletArc(ctx, xInnerRight + filletR, yTop - filletR, filletR, Math.PI / 2, Math.PI);
+ DrawFilletArc(ctx, xInnerRight + filletR, yBottom + filletR, filletR, Math.PI, Math.PI * 1.5);
+ }
+
///
/// 轧制:高度标注(在右侧)
///
@@ -1237,6 +1354,75 @@ namespace CadParamPluging.Cad
}
}
+ private static void DrawRingSectionHatchWithFillet(DrawingContext ctx, double xInnerRight, double xOuterRight, double yBottom, double height, double filletR)
+ {
+ if (xOuterRight <= xInnerRight)
+ {
+ return;
+ }
+
+ var availableWidth = xOuterRight - xInnerRight;
+ var maxR = Math.Min(availableWidth * 0.5, height * 0.5);
+ var r = Math.Min(filletR, maxR);
+ if (r <= 0.01)
+ {
+ DrawRingSectionHatch(ctx, xInnerRight, xOuterRight, yBottom, height);
+ return;
+ }
+
+ try
+ {
+ var yTop = yBottom + height;
+ var bulge = Math.Tan(Math.PI / 8.0);
+
+ var boundary = new Polyline();
+ boundary.AddVertexAt(0, new Point2d(xInnerRight + r, yBottom), 0, 0, 0);
+ boundary.AddVertexAt(1, new Point2d(xOuterRight - r, yBottom), bulge, 0, 0);
+ boundary.AddVertexAt(2, new Point2d(xOuterRight, yBottom + r), 0, 0, 0);
+ boundary.AddVertexAt(3, new Point2d(xOuterRight, yTop - r), bulge, 0, 0);
+ boundary.AddVertexAt(4, new Point2d(xOuterRight - r, yTop), 0, 0, 0);
+ boundary.AddVertexAt(5, new Point2d(xInnerRight + r, yTop), bulge, 0, 0);
+ boundary.AddVertexAt(6, new Point2d(xInnerRight, yTop - r), 0, 0, 0);
+ boundary.AddVertexAt(7, new Point2d(xInnerRight, yBottom + r), bulge, 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
+ }
+ }
+
private static string FormatDimNumber(double value, string rawInput = null)
{
try