毛料态/轧制/环形模板生成图纸优化,调整圆角方向

This commit is contained in:
sladro 2026-01-20 15:13:23 +08:00
parent b03b72654e
commit 707ad46315
2 changed files with 265 additions and 6 deletions

View File

@ -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
};
}
}
}

View File

@ -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
/// 轧制工艺 - 只画右半边图
/// </summary>
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
/// <summary>
/// 轧制:绘制右半边外轮廓(开口多段线)
/// </summary>
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);
}
/// <summary>
/// 轧制:高度标注(在右侧)
/// </summary>
@ -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