CadParamPluging/Cad/FeatureDrivenDrawer.cs

1362 lines
56 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using CadParamPluging.Common;
namespace CadParamPluging.Cad
{
/// <summary>
/// 特征驱动绘图引擎 - 根据参数存在性动态绘制图形
/// </summary>
public static class FeatureDrivenDrawer
{
#region Key常量
// 环形参数
public const string KeyOuterDiameter1 = "OuterDiameter1";
public const string KeyOuterDiameter1TolPlus = "OuterDiameter1TolPlus";
public const string KeyOuterDiameter1TolMinus = "OuterDiameter1TolMinus";
public const string KeyInnerDiameter2 = "InnerDiameter2";
public const string KeyInnerDiameter2TolPlus = "InnerDiameter2TolPlus";
public const string KeyInnerDiameter2TolMinus = "InnerDiameter2TolMinus";
public const string KeyHeight1 = "Height1";
public const string KeyHeight1TolPlus = "Height1TolPlus";
public const string KeyHeight1TolMinus = "Height1TolMinus";
public const string KeyMinWallThickness = "MinWallThickness";
public const string KeyUnspecifiedFilletRadiusMax = "UnspecifiedFilletRadiusMax"; // 环形未注圆角
public const string KeyInnerRadiusMax = "InnerRadiusMax"; // 内径半径R≤中心冲孔
// 环形零件尺寸(车加工态)
public const string KeyOuterDiameter1Prime = "OuterDiameter1Prime";
public const string KeyInnerDiameter2Prime = "InnerDiameter2Prime";
public const string KeyHeight1Prime = "Height1Prime";
// 饼盘参数
public const string KeyDiskDiameter = "DiskDiameter";
public const string KeyDiskDiameterTolPlus = "DiskDiameterTolPlus";
public const string KeyDiskDiameterTolMinus = "DiskDiameterTolMinus";
public const string KeyDiskHeight = "DiskHeight";
public const string KeyDiskHeightTolPlus = "DiskHeightTolPlus";
public const string KeyDiskHeightTolMinus = "DiskHeightTolMinus";
public const string KeyDiskFilletRadiusMax = "DiskFilletRadiusMax"; // 饼盘未注圆角
public const string KeyDiskDiameterPrime = "DiskDiameterPrime"; // 饼盘零件直径
public const string KeyDiskHeightPrime = "DiskHeightPrime"; // 饼盘零件高度
// 轴杆参数(圆轴)
public const string KeyDiameter = "Diameter";
public const string KeyDiameterTolPlus = "DiameterTolPlus";
public const string KeyDiameterTolMinus = "DiameterTolMinus";
public const string KeyLength = "Length";
public const string KeyLengthTolPlus = "LengthTolPlus";
public const string KeyLengthTolMinus = "LengthTolMinus";
public const string KeyShaftFilletRadiusMax = "ShaftFilletRadiusMax"; // 轴杆未注圆角
public const string KeyDiameterPrime = "DiameterPrime"; // 轴杆零件直径
public const string KeyLengthPrime = "LengthPrime"; // 轴杆零件长度
// 方体参数
public const string KeyBoxSize1 = "BoxSize1";
public const string KeyBoxSize1TolPlus = "BoxSize1TolPlus";
public const string KeyBoxSize1TolMinus = "BoxSize1TolMinus";
public const string KeyBoxSize2 = "BoxSize2";
public const string KeyBoxSize2TolPlus = "BoxSize2TolPlus";
public const string KeyBoxSize2TolMinus = "BoxSize2TolMinus";
public const string KeyBoxSize3 = "BoxSize3";
public const string KeyBoxSize3TolPlus = "BoxSize3TolPlus";
public const string KeyBoxSize3TolMinus = "BoxSize3TolMinus";
public const string KeyBoxFilletRadiusMax = "BoxFilletRadiusMax"; // 方体未注圆角
public const string KeyBoxRoundHeadFilletRadiusMax = "BoxRoundHeadFilletRadiusMax"; // 方体圆头处圆角
public const string KeyBoxSize1Prime = "BoxSize1Prime"; // 方体零件尺寸1
public const string KeyBoxSize2Prime = "BoxSize2Prime"; // 方体零件尺寸2
public const string KeyBoxSize3Prime = "BoxSize3Prime"; // 方体零件尺寸3
#endregion
#region
public class DrawingContext
{
public CadContext Ctx { get; set; }
public ParamBag Bag { get; set; }
public Point3d Center { get; set; }
public string DeliveryStatus { get; set; }
public string StructuralFeature { get; set; }
public string SpecialCondition { get; set; }
internal DrawingStyleManager Style { get; set; }
public Database Db => Ctx?.Database;
public Transaction Tr => Ctx?.Transaction;
public BlockTableRecord Btr { get; set; }
public bool IsMachined => !string.IsNullOrWhiteSpace(DeliveryStatus)
&& DeliveryStatus.IndexOf("车加工", StringComparison.OrdinalIgnoreCase) >= 0;
public bool IsCenterPunched => !string.IsNullOrWhiteSpace(SpecialCondition)
&& SpecialCondition.IndexOf("中心冲孔", StringComparison.OrdinalIgnoreCase) >= 0;
public bool HasRoundHead => !string.IsNullOrWhiteSpace(SpecialCondition)
&& SpecialCondition.IndexOf("有圆头", StringComparison.OrdinalIgnoreCase) >= 0;
}
#endregion
#region
/// <summary>
/// 预期图形尺寸
/// </summary>
public class ExpectedDrawingSize
{
public double Width { get; set; }
public double Height { get; set; }
public bool IsValid => Width > 0 && Height > 0;
}
/// <summary>
/// 根据参数计算预期绘制图形的尺寸(不包含标注,仅计算图形主体)
/// </summary>
public static ExpectedDrawingSize CalculateExpectedSize(ParamBag bag, string structuralFeature)
{
if (bag == null)
{
return new ExpectedDrawingSize();
}
if (IsRing(structuralFeature))
{
return CalculateRingSize(bag);
}
if (IsDisk(structuralFeature))
{
return CalculateDiskSize(bag);
}
if (IsShaft(structuralFeature))
{
return CalculateShaftSize(bag);
}
if (IsBlock(structuralFeature))
{
return CalculateBlockSize(bag);
}
return new ExpectedDrawingSize();
}
private static ExpectedDrawingSize CalculateRingSize(ParamBag bag)
{
var outerDia = bag.GetDoubleOrNull(KeyOuterDiameter1) ?? 0;
var height = bag.GetDoubleOrNull(KeyHeight1) ?? 0;
// 环形图形:宽度=外径X方向高度=高度参数Y方向
// 加上标注的额外空间约40像素每侧
var extraMargin = 40;
return new ExpectedDrawingSize
{
Width = outerDia + extraMargin * 2,
Height = height + extraMargin * 2
};
}
private static ExpectedDrawingSize CalculateDiskSize(ParamBag bag)
{
var diameter = bag.GetDoubleOrNull(KeyDiskDiameter) ?? 0;
var height = bag.GetDoubleOrNull(KeyDiskHeight) ?? 0;
var extraMargin = 40;
return new ExpectedDrawingSize
{
Width = diameter + extraMargin * 2,
Height = height + extraMargin * 2
};
}
private static ExpectedDrawingSize CalculateShaftSize(ParamBag bag)
{
var diameter = bag.GetDoubleOrNull(KeyDiameter) ?? 0;
var length = bag.GetDoubleOrNull(KeyLength) ?? 0;
var extraMargin = 40;
return new ExpectedDrawingSize
{
Width = length + extraMargin * 2,
Height = diameter + extraMargin * 2
};
}
private static ExpectedDrawingSize CalculateBlockSize(ParamBag bag)
{
var size1 = bag.GetDoubleOrNull(KeyBoxSize1) ?? 0;
var size2 = bag.GetDoubleOrNull(KeyBoxSize2) ?? size1;
var extraMargin = 40;
return new ExpectedDrawingSize
{
Width = size1 + extraMargin * 2,
Height = size2 + extraMargin * 2
};
}
#endregion
#region
/// <summary>
/// 绘制图形(带缩放支持)
/// </summary>
/// <param name="ctx">CAD上下文</param>
/// <param name="bag">参数包</param>
/// <param name="deliveryStatus">交付状态</param>
/// <param name="structuralFeature">结构特征</param>
/// <param name="specialCondition">特殊条件</param>
/// <param name="center">绘图中心点</param>
/// <param name="scaleFactor">缩放比例1.0表示不缩放)</param>
public static void Draw(CadContext ctx, ParamBag bag, string deliveryStatus, string structuralFeature,
string specialCondition = null, Point3d? center = null, double scaleFactor = 1.0)
{
if (ctx == null) throw new ArgumentNullException(nameof(ctx));
if (bag == null) throw new ArgumentNullException(nameof(bag));
// 如果需要缩放,创建一个缩放后的参数包
var effectiveBag = scaleFactor < 1.0 ? ScaleParamBag(bag, scaleFactor) : bag;
var db = ctx.Database;
var tr = ctx.Transaction;
var btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
var context = new DrawingContext
{
Ctx = ctx,
Bag = effectiveBag,
Center = center ?? Point3d.Origin,
DeliveryStatus = deliveryStatus,
StructuralFeature = structuralFeature,
SpecialCondition = specialCondition,
Btr = btr,
Style = new DrawingStyleManager(db, tr)
};
// 根据结构特征分发到对应绘制器
if (IsRing(structuralFeature))
{
DrawRingFeatures(context);
}
else if (IsDisk(structuralFeature))
{
DrawDiskFeatures(context);
}
else if (IsShaft(structuralFeature))
{
DrawShaftFeatures(context);
}
else if (IsBlock(structuralFeature))
{
DrawBlockFeatures(context);
}
}
#endregion
#region
private static bool IsRing(string feature)
{
return !string.IsNullOrWhiteSpace(feature)
&& feature.IndexOf("环形", StringComparison.OrdinalIgnoreCase) >= 0;
}
private static bool IsDisk(string feature)
{
return !string.IsNullOrWhiteSpace(feature)
&& (feature.IndexOf("饼盘", StringComparison.OrdinalIgnoreCase) >= 0
|| feature.IndexOf("饼", StringComparison.OrdinalIgnoreCase) >= 0
|| feature.IndexOf("盘", StringComparison.OrdinalIgnoreCase) >= 0);
}
private static bool IsShaft(string feature)
{
return !string.IsNullOrWhiteSpace(feature)
&& (feature.IndexOf("轴杆", StringComparison.OrdinalIgnoreCase) >= 0
|| feature.IndexOf("轴", StringComparison.OrdinalIgnoreCase) >= 0
|| feature.IndexOf("杆", StringComparison.OrdinalIgnoreCase) >= 0);
}
private static bool IsBlock(string feature)
{
return !string.IsNullOrWhiteSpace(feature)
&& feature.IndexOf("方体", StringComparison.OrdinalIgnoreCase) >= 0;
}
#endregion
#region -
private static void DrawRingFeatures(DrawingContext ctx)
{
var bag = ctx.Bag;
// 必需参数检测
var outerDia = bag.GetDoubleOrNull(KeyOuterDiameter1);
var height = bag.GetDoubleOrNull(KeyHeight1);
if (!outerDia.HasValue || outerDia.Value <= 0)
{
return; // 缺少外径,无法绘制
}
if (!height.HasValue || height.Value <= 0)
{
return; // 缺少高度,无法绘制
}
// 视图方向调整X方向为直径方向外径/内径Y方向为高度方向
double W = outerDia.Value;
double H = height.Value;
double ox = ctx.Center.X - W / 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: 锻件外轮廓(必绘) ===
DrawForgingOuterContour(ctx, ox, oy, W, H);
// === 特征1.1: 中心线 ===
DrawRingCenterline(ctx, ox, oy, W, H);
// === 特征2: 外径公差标注(如果有公差参数) ===
var outerTolPlus = bag.GetDoubleOrNull(KeyOuterDiameter1TolPlus);
var outerTolMinus = bag.GetDoubleOrNull(KeyOuterDiameter1TolMinus);
DrawOuterDiameterDimension(ctx, ox, oy, W, outerDia.Value, outerTolPlus, outerTolMinus, outerDiaPrime);
// === 特征3: 内孔/内径(如果有内径参数) ===
var innerDia = bag.GetDoubleOrNull(KeyInnerDiameter2);
double? xInnerLeft = null;
double? xInnerRight = null;
if (innerDia.HasValue && innerDia.Value > 0 && innerDia.Value < W)
{
xInnerLeft = ctx.Center.X - innerDia.Value / 2.0;
xInnerRight = ctx.Center.X + innerDia.Value / 2.0;
var innerTolPlus = bag.GetDoubleOrNull(KeyInnerDiameter2TolPlus);
var innerTolMinus = bag.GetDoubleOrNull(KeyInnerDiameter2TolMinus);
DrawInnerHole(ctx, xInnerLeft.Value, xInnerRight.Value, oy, H);
DrawInnerDiameterDimension(ctx, xInnerLeft.Value, xInnerRight.Value, oy, innerDia.Value, innerTolPlus, innerTolMinus, innerDiaPrime);
// === 特征4: 内径圆角如果有内径半径R参数且是中心冲孔 ===
var innerRadiusMax = bag.GetDoubleOrNull(KeyInnerRadiusMax);
if (innerRadiusMax.HasValue && innerRadiusMax.Value > 0 && ctx.IsCenterPunched)
{
DrawInnerFillets(ctx, xInnerLeft.Value, xInnerRight.Value, oy, H, innerRadiusMax.Value);
}
// === 特征4.1: 剖面线(仅剖切端部区域) ===
DrawRingSectionHatch(ctx, xInnerRight.Value, ox + W, oy, H);
}
// === 特征5: 高度标注 ===
var heightTolPlus = bag.GetDoubleOrNull(KeyHeight1TolPlus);
var heightTolMinus = bag.GetDoubleOrNull(KeyHeight1TolMinus);
DrawHeightDimension(ctx, ox, oy, W, H, heightTolPlus, heightTolMinus, heightPrime);
// === 特征6: 未注圆角(如果有该参数) ===
var unspecifiedFillet = bag.GetDoubleOrNull(KeyUnspecifiedFilletRadiusMax);
if (unspecifiedFillet.HasValue && unspecifiedFillet.Value > 0)
{
// 复用现有位置逻辑:右上角
DrawUnspecifiedFilletNote(ctx, ox, oy, H, W, unspecifiedFillet.Value);
}
// === 特征7: 最小壁厚min标注如果有该参数 ===
var minWallThickness = bag.GetDoubleOrNull(KeyMinWallThickness);
if (minWallThickness.HasValue && minWallThickness.Value > 0 && xInnerRight.HasValue)
{
DrawMinWallThicknessNote(ctx, xInnerRight.Value, ox + W, oy, minWallThickness.Value);
}
// === 特征8: 零件轮廓(车加工态,双点划线) ===
if (ctx.IsMachined && outerDiaPrime.HasValue && outerDiaPrime.Value > 0 && heightPrime.HasValue && heightPrime.Value > 0)
{
DrawPartContour(ctx, ctx.Center, outerDiaPrime.Value, innerDiaPrime, heightPrime.Value);
}
// === 特征9: 硬度符号(有要求才画) ===
TryDrawHardnessSymbol(ctx, ox + W, oy, H);
}
private static void DrawForgingOuterContour(DrawingContext ctx, double ox, double oy, double width, double height)
{
var poly = new Polyline();
poly.AddVertexAt(0, new Point2d(ox, oy), 0, 0, 0);
poly.AddVertexAt(1, new Point2d(ox + width, oy), 0, 0, 0);
poly.AddVertexAt(2, new Point2d(ox + width, oy + height), 0, 0, 0);
poly.AddVertexAt(3, new Point2d(ox, oy + height), 0, 0, 0);
poly.Closed = true;
ctx.Style?.Apply(poly, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
}
private static void DrawRingCenterline(DrawingContext ctx, double ox, double oy, double width, double height)
{
var cy = oy + height / 2.0;
var line = new Line(new Point3d(ox - 10, cy, 0), new Point3d(ox + width + 10, cy, 0));
ctx.Style?.Apply(line, DrawingStyleManager.Role.Centerline);
ctx.Btr.AppendEntity(line);
ctx.Tr.AddNewlyCreatedDBObject(line, true);
}
private static void DrawInnerHole(DrawingContext ctx, double xInnerLeft, double xInnerRight, double yBottom, double height)
{
var yTop = yBottom + height;
var lineLeft = new Line(new Point3d(xInnerLeft, yBottom, 0), new Point3d(xInnerLeft, yTop, 0));
ctx.Style?.Apply(lineLeft, DrawingStyleManager.Role.Hidden);
ctx.Btr.AppendEntity(lineLeft);
ctx.Tr.AddNewlyCreatedDBObject(lineLeft, true);
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 DrawInnerFillets(DrawingContext ctx, double xInnerLeft, double xInnerRight, double yBottom, double height, double filletR)
{
// 在内径四角绘制圆角示意
var yTop = yBottom + height;
// 左上角
DrawFilletArc(ctx, xInnerLeft + filletR, yTop - filletR, filletR, Math.PI / 2, Math.PI);
// 左下角
DrawFilletArc(ctx, xInnerLeft + filletR, yBottom + filletR, filletR, Math.PI, Math.PI * 1.5);
// 右上角
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 DrawFilletArc(DrawingContext ctx, double cx, double cy, double r, double startAngle, double endAngle)
{
try
{
var arc = new Arc(new Point3d(cx, cy, 0), r, startAngle, endAngle);
ctx.Style?.Apply(arc, DrawingStyleManager.Role.OutlineThin);
ctx.Btr.AppendEntity(arc);
ctx.Tr.AddNewlyCreatedDBObject(arc, true);
}
catch
{
// 忽略圆弧创建错误
}
}
private static void DrawOuterDiameterDimension(DrawingContext ctx, double ox, double oy, double width,
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 + width, oy, 0),
new Point3d(ox + width / 2, oy - 40, 0),
0,
dimText);
}
private static void DrawInnerDiameterDimension(DrawingContext ctx, double xInnerLeft, double xInnerRight, double yBottom,
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(xInnerLeft, yBottom, 0),
new Point3d(xInnerRight, yBottom, 0),
new Point3d((xInnerLeft + xInnerRight) / 2, yBottom - 25, 0),
0,
dimText);
}
private static void DrawHeightDimension(DrawingContext ctx, double ox, double oy, double width,
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 + width, oy, 0),
new Point3d(ox + width, oy + height, 0),
new Point3d(ox + width + 20, oy + height / 2, 0),
90,
dimText);
}
private static void DrawUnspecifiedFilletNote(DrawingContext ctx, double ox, double oy, double R, double height, double filletR)
{
// 在图纸右上角添加文字说明
try
{
var text = new DBText();
text.TextString = $"未注圆角半径R≤{filletR}";
text.Position = new Point3d(ox + height + 10, oy + R + 15, 0);
text.Height = 5;
ctx.Style?.Apply(text, DrawingStyleManager.Role.Text);
ctx.Btr.AppendEntity(text);
ctx.Tr.AddNewlyCreatedDBObject(text, true);
}
catch
{
// 忽略
}
}
private static void DrawMinWallThicknessNote(DrawingContext ctx, double xInnerRight, double xOuterRight, double yBottom, double thickness)
{
var dimText = $"{FormatDimNumber(thickness)}min";
AddLinearDim(
ctx,
new Point3d(xInnerRight, yBottom, 0),
new Point3d(xOuterRight, yBottom, 0),
new Point3d((xInnerRight + xOuterRight) / 2, yBottom - 10, 0),
0,
dimText);
}
private static void DrawPartContour(DrawingContext ctx, Point3d center,
double outerDiaPrime, double? innerDiaPrime, double heightPrime)
{
var w = outerDiaPrime;
var h = heightPrime;
var x0 = center.X - w / 2.0;
var y0 = center.Y - h / 2.0;
var polyPart = new Polyline();
polyPart.AddVertexAt(0, new Point2d(x0, y0), 0, 0, 0);
polyPart.AddVertexAt(1, new Point2d(x0 + w, y0), 0, 0, 0);
polyPart.AddVertexAt(2, new Point2d(x0 + w, y0 + h), 0, 0, 0);
polyPart.AddVertexAt(3, new Point2d(x0, y0 + h), 0, 0, 0);
polyPart.Closed = true;
ctx.Style?.Apply(polyPart, DrawingStyleManager.Role.PartContour);
ctx.Btr.AppendEntity(polyPart);
ctx.Tr.AddNewlyCreatedDBObject(polyPart, true);
// 内径(车加工态)轮廓
if (innerDiaPrime.HasValue && innerDiaPrime.Value > 0 && innerDiaPrime.Value < w)
{
var xiL = center.X - innerDiaPrime.Value / 2.0;
var xiR = center.X + innerDiaPrime.Value / 2.0;
var yTop = y0 + h;
var l1 = new Line(new Point3d(xiL, y0, 0), new Point3d(xiL, yTop, 0));
ctx.Style?.Apply(l1, DrawingStyleManager.Role.PartContour);
ctx.Btr.AppendEntity(l1);
ctx.Tr.AddNewlyCreatedDBObject(l1, true);
var l2 = new Line(new Point3d(xiR, y0, 0), new Point3d(xiR, yTop, 0));
ctx.Style?.Apply(l2, DrawingStyleManager.Role.PartContour);
ctx.Btr.AppendEntity(l2);
ctx.Tr.AddNewlyCreatedDBObject(l2, true);
}
}
private static void DrawRingSectionHatch(DrawingContext ctx, double xInnerRight, double xOuterRight, double yBottom, double height)
{
if (xOuterRight <= xInnerRight)
{
return;
}
try
{
// 临时边界(用于剖面填充),填充后删除边界
var boundary = new Polyline();
boundary.AddVertexAt(0, new Point2d(xInnerRight, yBottom), 0, 0, 0);
boundary.AddVertexAt(1, new Point2d(xOuterRight, yBottom), 0, 0, 0);
boundary.AddVertexAt(2, new Point2d(xOuterRight, yBottom + height), 0, 0, 0);
boundary.AddVertexAt(3, new Point2d(xInnerRight, yBottom + height), 0, 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 = 0.8;
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)
{
try
{
return value.ToString("0.###");
}
catch
{
return value.ToString();
}
}
private static void TryDrawHardnessSymbol(DrawingContext ctx, double xRight, double yBottom, double height)
{
if (ctx == null || ctx.Bag == null)
{
return;
}
var raw = ctx.Bag.GetString("Hardness");
if (string.IsNullOrWhiteSpace(raw))
{
return;
}
var upper = raw.Trim().ToUpperInvariant();
string symbol;
if (upper.Contains("HB"))
{
symbol = "HB";
}
else if (upper.Contains("HRC"))
{
symbol = "HRC";
}
else if (upper.Contains("HV"))
{
symbol = "HV";
}
else
{
symbol = ExtractLeadingLetters(upper);
if (string.IsNullOrWhiteSpace(symbol))
{
symbol = "HB";
}
}
try
{
var attach = new Point3d(xRight - 2, yBottom + height * 0.25, 0);
var circleCenter = new Point3d(xRight + 25, yBottom + height * 0.25, 0);
const double circleR = 6;
var leader = new Line(attach, new Point3d(circleCenter.X - circleR, circleCenter.Y, 0));
ctx.Style?.Apply(leader, DrawingStyleManager.Role.Text);
ctx.Btr.AppendEntity(leader);
ctx.Tr.AddNewlyCreatedDBObject(leader, true);
var circle = new Circle(circleCenter, new Vector3d(0, 0, 1), circleR);
ctx.Style?.Apply(circle, DrawingStyleManager.Role.Text);
ctx.Btr.AppendEntity(circle);
ctx.Tr.AddNewlyCreatedDBObject(circle, true);
var text = new DBText();
text.TextString = symbol;
text.Height = 3.5;
text.HorizontalMode = TextHorizontalMode.TextCenter;
text.VerticalMode = TextVerticalMode.TextVerticalMid;
text.AlignmentPoint = circleCenter;
text.Position = circleCenter;
ctx.Style?.Apply(text, DrawingStyleManager.Role.Text);
ctx.Btr.AppendEntity(text);
ctx.Tr.AddNewlyCreatedDBObject(text, true);
}
catch
{
// ignore
}
}
private static string ExtractLeadingLetters(string s)
{
if (string.IsNullOrEmpty(s))
{
return string.Empty;
}
var chars = new List<char>();
foreach (var c in s)
{
if (c >= 'A' && c <= 'Z')
{
chars.Add(c);
}
else
{
if (chars.Count > 0)
{
break;
}
}
}
return chars.Count == 0 ? string.Empty : new string(chars.ToArray());
}
#endregion
#region -
private static void DrawDiskFeatures(DrawingContext ctx)
{
var bag = ctx.Bag;
var diameter = bag.GetDoubleOrNull(KeyDiskDiameter);
var height = bag.GetDoubleOrNull(KeyDiskHeight);
if (!diameter.HasValue || diameter.Value <= 0) return;
if (!height.HasValue || height.Value <= 0) return;
double ox = ctx.Center.X - diameter.Value / 2.0;
double oy = ctx.Center.Y - height.Value / 2.0;
double R = diameter.Value / 2.0;
double H = height.Value;
// 绘制饼盘轮廓(俯视图为圆,侧视图为矩形)
// 这里绘制侧视图
var poly = new Polyline();
poly.AddVertexAt(0, new Point2d(ox, oy), 0, 0, 0);
poly.AddVertexAt(1, new Point2d(ox + diameter.Value, oy), 0, 0, 0);
poly.AddVertexAt(2, new Point2d(ox + diameter.Value, oy + H), 0, 0, 0);
poly.AddVertexAt(3, new Point2d(ox, oy + H), 0, 0, 0);
poly.Closed = true;
ctx.Style?.Apply(poly, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
// 直径标注
var diaTolPlus = bag.GetDoubleOrNull(KeyDiskDiameterTolPlus);
var diaTolMinus = bag.GetDoubleOrNull(KeyDiskDiameterTolMinus);
var diaDimText = BuildDimensionText($"%%c{diameter.Value}", diaTolPlus, diaTolMinus);
AddLinearDim(ctx, new Point3d(ox, oy, 0), new Point3d(ox + diameter.Value, oy, 0),
new Point3d(ctx.Center.X, oy - 20, 0), 0, diaDimText);
// 高度标注
var htTolPlus = bag.GetDoubleOrNull(KeyDiskHeightTolPlus);
var htTolMinus = bag.GetDoubleOrNull(KeyDiskHeightTolMinus);
var htDimText = BuildDimensionText($"{H}", htTolPlus, htTolMinus);
AddLinearDim(ctx, new Point3d(ox + diameter.Value, oy, 0), new Point3d(ox + diameter.Value, oy + H, 0),
new Point3d(ox + diameter.Value + 20, ctx.Center.Y, 0), 90, htDimText);
// 未注圆角使用饼盘专用Key
var unspecifiedFillet = bag.GetDoubleOrNull(KeyDiskFilletRadiusMax);
if (unspecifiedFillet.HasValue && unspecifiedFillet.Value > 0)
{
DrawUnspecifiedFilletNote(ctx, ox, oy + H, R, diameter.Value, unspecifiedFillet.Value);
}
// 零件尺寸(如果有)
var diaPrime = bag.GetDoubleOrNull(KeyDiskDiameterPrime);
var heightPrime = bag.GetDoubleOrNull(KeyDiskHeightPrime);
if (diaPrime.HasValue && diaPrime.Value > 0 && heightPrime.HasValue && heightPrime.Value > 0)
{
DrawDiskPartContour(ctx, ox, oy, diameter.Value, H, diaPrime.Value, heightPrime.Value);
}
}
private static void DrawDiskPartContour(DrawingContext ctx, double ox, double oy,
double forgingDia, double forgingH, double partDia, double partH)
{
double offsetX = (forgingDia - partDia) / 2.0;
double offsetY = (forgingH - partH) / 2.0;
var polyPart = new Polyline();
polyPart.AddVertexAt(0, new Point2d(ox + offsetX, oy + offsetY), 0, 0, 0);
polyPart.AddVertexAt(1, new Point2d(ox + offsetX + partDia, oy + offsetY), 0, 0, 0);
polyPart.AddVertexAt(2, new Point2d(ox + offsetX + partDia, oy + offsetY + partH), 0, 0, 0);
polyPart.AddVertexAt(3, new Point2d(ox + offsetX, oy + offsetY + partH), 0, 0, 0);
polyPart.Closed = true;
ctx.Style?.Apply(polyPart, DrawingStyleManager.Role.PartContour);
ctx.Btr.AppendEntity(polyPart);
ctx.Tr.AddNewlyCreatedDBObject(polyPart, true);
// 不再对零件轮廓整块填充剖面线
// 零件直径标注
AddLinearDim(ctx, new Point3d(ox + offsetX, oy + offsetY, 0),
new Point3d(ox + offsetX + partDia, oy + offsetY, 0),
new Point3d(ox + offsetX + partDia / 2, oy + offsetY - 10, 0), 0, $"%%c{partDia}");
// 零件高度标注
AddLinearDim(ctx, new Point3d(ox + offsetX + partDia, oy + offsetY, 0),
new Point3d(ox + offsetX + partDia, oy + offsetY + partH, 0),
new Point3d(ox + offsetX + partDia + 10, oy + offsetY + partH / 2, 0), 90, $"{partH}");
}
#endregion
#region -
private static void DrawShaftFeatures(DrawingContext ctx)
{
var bag = ctx.Bag;
// 圆轴使用Diameter/Length方轴使用BoxSize1/2/3
var isSquareShaft = !string.IsNullOrWhiteSpace(ctx.SpecialCondition)
&& ctx.SpecialCondition.IndexOf("方轴", StringComparison.OrdinalIgnoreCase) >= 0;
if (isSquareShaft)
{
// 方轴使用方体参数绘制
DrawSquareShaftFeatures(ctx);
return;
}
// 圆轴绘制
var diameter = bag.GetDoubleOrNull(KeyDiameter);
var length = bag.GetDoubleOrNull(KeyLength);
if (!diameter.HasValue || diameter.Value <= 0) return;
if (!length.HasValue || length.Value <= 0) return;
double ox = ctx.Center.X - length.Value / 2.0;
double oy = ctx.Center.Y;
double R = diameter.Value / 2.0;
double L = length.Value;
TryLoadLinetype(ctx.Db, ctx.Tr, "CENTER");
// 绘制轴杆轮廓(侧视图为矩形)
var poly = new Polyline();
poly.AddVertexAt(0, new Point2d(ox, oy - R), 0, 0, 0);
poly.AddVertexAt(1, new Point2d(ox + L, oy - R), 0, 0, 0);
poly.AddVertexAt(2, new Point2d(ox + L, oy + R), 0, 0, 0);
poly.AddVertexAt(3, new Point2d(ox, oy + R), 0, 0, 0);
poly.Closed = true;
ctx.Style?.Apply(poly, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
// 中心线
var centerLine = new Line(new Point3d(ox - 10, oy, 0), new Point3d(ox + L + 10, oy, 0));
ctx.Style?.Apply(centerLine, DrawingStyleManager.Role.Centerline);
ctx.Btr.AppendEntity(centerLine);
ctx.Tr.AddNewlyCreatedDBObject(centerLine, true);
// 直径标注
var diaTolPlus = bag.GetDoubleOrNull(KeyDiameterTolPlus);
var diaTolMinus = bag.GetDoubleOrNull(KeyDiameterTolMinus);
var diaDimText = BuildDimensionText($"%%c{diameter.Value}", diaTolPlus, diaTolMinus);
AddLinearDim(ctx, new Point3d(ox, oy + R, 0), new Point3d(ox, oy - R, 0),
new Point3d(ox - 20, oy, 0), 90, diaDimText);
// 长度标注
var lenTolPlus = bag.GetDoubleOrNull(KeyLengthTolPlus);
var lenTolMinus = bag.GetDoubleOrNull(KeyLengthTolMinus);
var lenDimText = BuildDimensionText($"{L}", lenTolPlus, lenTolMinus);
AddLinearDim(ctx, new Point3d(ox, oy - R, 0), new Point3d(ox + L, oy - R, 0),
new Point3d(ctx.Center.X, oy - R - 20, 0), 0, lenDimText);
// 未注圆角使用轴杆专用Key
var unspecifiedFillet = bag.GetDoubleOrNull(KeyShaftFilletRadiusMax);
if (unspecifiedFillet.HasValue && unspecifiedFillet.Value > 0)
{
DrawUnspecifiedFilletNote(ctx, ox, oy, R, L, unspecifiedFillet.Value);
}
// 零件尺寸(如果有)
var diaPrime = bag.GetDoubleOrNull(KeyDiameterPrime);
var lenPrime = bag.GetDoubleOrNull(KeyLengthPrime);
if (diaPrime.HasValue && diaPrime.Value > 0 && lenPrime.HasValue && lenPrime.Value > 0)
{
DrawShaftPartContour(ctx, ox, oy, R, L, diaPrime.Value, lenPrime.Value);
}
}
/// <summary>
/// 方轴绘制(使用方体参数)
/// </summary>
private static void DrawSquareShaftFeatures(DrawingContext ctx)
{
var bag = ctx.Bag;
var size1 = bag.GetDoubleOrNull(KeyBoxSize1);
var size2 = bag.GetDoubleOrNull(KeyBoxSize2);
var size3 = bag.GetDoubleOrNull(KeyBoxSize3);
if (!size1.HasValue || size1.Value <= 0) return;
double width = size1.Value;
double height = size2.HasValue && size2.Value > 0 ? size2.Value : size1.Value;
double depth = size3.HasValue && size3.Value > 0 ? size3.Value : 0;
double ox = ctx.Center.X - width / 2.0;
double oy = ctx.Center.Y - height / 2.0;
// 绘制正视图(矩形)
var poly = new Polyline();
poly.AddVertexAt(0, new Point2d(ox, oy), 0, 0, 0);
poly.AddVertexAt(1, new Point2d(ox + width, oy), 0, 0, 0);
poly.AddVertexAt(2, new Point2d(ox + width, oy + height), 0, 0, 0);
poly.AddVertexAt(3, new Point2d(ox, oy + height), 0, 0, 0);
poly.Closed = true;
ctx.Style?.Apply(poly, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
// 尺寸1标注
var tol1Plus = bag.GetDoubleOrNull(KeyBoxSize1TolPlus);
var tol1Minus = bag.GetDoubleOrNull(KeyBoxSize1TolMinus);
var dim1Text = BuildDimensionText($"{width}", tol1Plus, tol1Minus);
AddLinearDim(ctx, new Point3d(ox, oy, 0), new Point3d(ox + width, oy, 0),
new Point3d(ctx.Center.X, oy - 20, 0), 0, dim1Text);
// 尺寸2标注
if (size2.HasValue && size2.Value > 0)
{
var tol2Plus = bag.GetDoubleOrNull(KeyBoxSize2TolPlus);
var tol2Minus = bag.GetDoubleOrNull(KeyBoxSize2TolMinus);
var dim2Text = BuildDimensionText($"{height}", tol2Plus, tol2Minus);
AddLinearDim(ctx, new Point3d(ox + width, oy, 0), new Point3d(ox + width, oy + height, 0),
new Point3d(ox + width + 20, ctx.Center.Y, 0), 90, dim2Text);
}
// 尺寸3标注
if (depth > 0)
{
var tol3Plus = bag.GetDoubleOrNull(KeyBoxSize3TolPlus);
var tol3Minus = bag.GetDoubleOrNull(KeyBoxSize3TolMinus);
var dim3Text = BuildDimensionText($"深度:{depth}", tol3Plus, tol3Minus);
try
{
var text = new DBText();
text.TextString = dim3Text;
text.Position = new Point3d(ox + width + 10, oy + height + 10, 0);
text.Height = 5;
ctx.Style?.Apply(text, DrawingStyleManager.Role.Text);
ctx.Btr.AppendEntity(text);
ctx.Tr.AddNewlyCreatedDBObject(text, true);
}
catch { }
}
// 未注圆角使用方体专用Key
var unspecifiedFillet = bag.GetDoubleOrNull(KeyBoxFilletRadiusMax);
if (unspecifiedFillet.HasValue && unspecifiedFillet.Value > 0)
{
try
{
var text = new DBText();
text.TextString = $"未注圆角半径R≤{unspecifiedFillet.Value}";
text.Position = new Point3d(ox + width + 10, oy + height + 20, 0);
text.Height = 5;
ctx.Style?.Apply(text, DrawingStyleManager.Role.Text);
ctx.Btr.AppendEntity(text);
ctx.Tr.AddNewlyCreatedDBObject(text, true);
}
catch { }
}
// 零件尺寸
var size1Prime = bag.GetDoubleOrNull(KeyBoxSize1Prime);
var size2Prime = bag.GetDoubleOrNull(KeyBoxSize2Prime);
var size3Prime = bag.GetDoubleOrNull(KeyBoxSize3Prime);
if (size1Prime.HasValue && size1Prime.Value > 0)
{
DrawBlockPartContour(ctx, ox, oy, width, height,
size1Prime.Value, size2Prime ?? size1Prime.Value, size3Prime);
}
}
private static void DrawShaftPartContour(DrawingContext ctx, double ox, double oy,
double R, double L, double partDia, double partLen)
{
double offsetX = (L - partLen) / 2.0;
double Rp = partDia / 2.0;
var polyPart = new Polyline();
polyPart.AddVertexAt(0, new Point2d(ox + offsetX, oy - Rp), 0, 0, 0);
polyPart.AddVertexAt(1, new Point2d(ox + offsetX + partLen, oy - Rp), 0, 0, 0);
polyPart.AddVertexAt(2, new Point2d(ox + offsetX + partLen, oy + Rp), 0, 0, 0);
polyPart.AddVertexAt(3, new Point2d(ox + offsetX, oy + Rp), 0, 0, 0);
polyPart.Closed = true;
ctx.Style?.Apply(polyPart, DrawingStyleManager.Role.PartContour);
ctx.Btr.AppendEntity(polyPart);
ctx.Tr.AddNewlyCreatedDBObject(polyPart, true);
// 不再对零件轮廓整块填充剖面线
// 零件直径标注
AddLinearDim(ctx, new Point3d(ox + offsetX, oy + Rp, 0), new Point3d(ox + offsetX, oy - Rp, 0),
new Point3d(ox + offsetX - 10, oy, 0), 90, $"%%c{partDia}");
// 零件长度标注
AddLinearDim(ctx, new Point3d(ox + offsetX, oy - Rp, 0), new Point3d(ox + offsetX + partLen, oy - Rp, 0),
new Point3d(ox + offsetX + partLen / 2, oy - Rp - 10, 0), 0, $"{partLen}");
}
#endregion
#region -
private static void DrawBlockFeatures(DrawingContext ctx)
{
var bag = ctx.Bag;
// 使用方体专用参数
var size1 = bag.GetDoubleOrNull(KeyBoxSize1);
var size2 = bag.GetDoubleOrNull(KeyBoxSize2);
var size3 = bag.GetDoubleOrNull(KeyBoxSize3);
if (!size1.HasValue || size1.Value <= 0) return;
// 默认为正方形或使用size1
double width = size1.Value;
double height = size2.HasValue && size2.Value > 0 ? size2.Value : size1.Value;
double depth = size3.HasValue && size3.Value > 0 ? size3.Value : 0;
double ox = ctx.Center.X - width / 2.0;
double oy = ctx.Center.Y - height / 2.0;
// 绘制正视图(矩形)
var poly = new Polyline();
poly.AddVertexAt(0, new Point2d(ox, oy), 0, 0, 0);
poly.AddVertexAt(1, new Point2d(ox + width, oy), 0, 0, 0);
poly.AddVertexAt(2, new Point2d(ox + width, oy + height), 0, 0, 0);
poly.AddVertexAt(3, new Point2d(ox, oy + height), 0, 0, 0);
poly.Closed = true;
ctx.Style?.Apply(poly, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
// 宽度标注 (BoxSize1)
var tol1Plus = bag.GetDoubleOrNull(KeyBoxSize1TolPlus);
var tol1Minus = bag.GetDoubleOrNull(KeyBoxSize1TolMinus);
var dim1Text = BuildDimensionText($"{width}", tol1Plus, tol1Minus);
AddLinearDim(ctx, new Point3d(ox, oy, 0), new Point3d(ox + width, oy, 0),
new Point3d(ctx.Center.X, oy - 20, 0), 0, dim1Text);
// 高度标注 (BoxSize2)
if (size2.HasValue && size2.Value > 0)
{
var tol2Plus = bag.GetDoubleOrNull(KeyBoxSize2TolPlus);
var tol2Minus = bag.GetDoubleOrNull(KeyBoxSize2TolMinus);
var dim2Text = BuildDimensionText($"{height}", tol2Plus, tol2Minus);
AddLinearDim(ctx, new Point3d(ox + width, oy, 0), new Point3d(ox + width, oy + height, 0),
new Point3d(ox + width + 20, ctx.Center.Y, 0), 90, dim2Text);
}
// 深度标注 (BoxSize3) - 如果有的话,以文字形式标注
if (depth > 0)
{
var tol3Plus = bag.GetDoubleOrNull(KeyBoxSize3TolPlus);
var tol3Minus = bag.GetDoubleOrNull(KeyBoxSize3TolMinus);
var dim3Text = BuildDimensionText($"深度:{depth}", tol3Plus, tol3Minus);
try
{
var text = new DBText();
text.TextString = dim3Text;
text.Position = new Point3d(ox + width + 10, oy + height + 10, 0);
text.Height = 5;
ctx.Style?.Apply(text, DrawingStyleManager.Role.Text);
ctx.Btr.AppendEntity(text);
ctx.Tr.AddNewlyCreatedDBObject(text, true);
}
catch { }
}
// 未注圆角使用方体专用Key
var unspecifiedFillet = bag.GetDoubleOrNull(KeyBoxFilletRadiusMax);
if (unspecifiedFillet.HasValue && unspecifiedFillet.Value > 0)
{
try
{
var text = new DBText();
text.TextString = $"未注圆角半径R≤{unspecifiedFillet.Value}";
text.Position = new Point3d(ox + width + 10, oy + height + 20, 0);
text.Height = 5;
ctx.Style?.Apply(text, DrawingStyleManager.Role.Text);
ctx.Btr.AppendEntity(text);
ctx.Tr.AddNewlyCreatedDBObject(text, true);
}
catch { }
}
// 有圆头时,绘制两端半圆形圆头
if (ctx.HasRoundHead)
{
double R = height / 2.0; // 圆头半径 = 高度/2示意性
double centerY = oy + height / 2.0;
// 左端圆头(半圆)
try
{
var arcLeft = new Arc(new Point3d(ox, centerY, 0), R, Math.PI / 2, Math.PI * 1.5);
ctx.Style?.Apply(arcLeft, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(arcLeft);
ctx.Tr.AddNewlyCreatedDBObject(arcLeft, true);
}
catch { }
// 右端圆头(半圆)
try
{
var arcRight = new Arc(new Point3d(ox + width, centerY, 0), R, -Math.PI / 2, Math.PI / 2);
ctx.Style?.Apply(arcRight, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(arcRight);
ctx.Tr.AddNewlyCreatedDBObject(arcRight, true);
}
catch { }
}
// 零件尺寸
var size1Prime = bag.GetDoubleOrNull(KeyBoxSize1Prime);
var size2Prime = bag.GetDoubleOrNull(KeyBoxSize2Prime);
var size3Prime = bag.GetDoubleOrNull(KeyBoxSize3Prime);
if (size1Prime.HasValue && size1Prime.Value > 0)
{
DrawBlockPartContour(ctx, ox, oy, width, height,
size1Prime.Value, size2Prime ?? size1Prime.Value, size3Prime);
}
}
private static void DrawBlockPartContour(DrawingContext ctx, double ox, double oy,
double forgingW, double forgingH, double partW, double partH, double? partD)
{
double offsetX = (forgingW - partW) / 2.0;
double offsetY = (forgingH - partH) / 2.0;
var polyPart = new Polyline();
polyPart.AddVertexAt(0, new Point2d(ox + offsetX, oy + offsetY), 0, 0, 0);
polyPart.AddVertexAt(1, new Point2d(ox + offsetX + partW, oy + offsetY), 0, 0, 0);
polyPart.AddVertexAt(2, new Point2d(ox + offsetX + partW, oy + offsetY + partH), 0, 0, 0);
polyPart.AddVertexAt(3, new Point2d(ox + offsetX, oy + offsetY + partH), 0, 0, 0);
polyPart.Closed = true;
ctx.Style?.Apply(polyPart, DrawingStyleManager.Role.PartContour);
ctx.Btr.AppendEntity(polyPart);
ctx.Tr.AddNewlyCreatedDBObject(polyPart, true);
// 不再对零件轮廓整块填充剖面线
// 零件尺寸1标注
AddLinearDim(ctx, new Point3d(ox + offsetX, oy + offsetY, 0),
new Point3d(ox + offsetX + partW, oy + offsetY, 0),
new Point3d(ox + offsetX + partW / 2, oy + offsetY - 10, 0), 0, $"{partW}");
// 零件尺寸2标注
AddLinearDim(ctx, new Point3d(ox + offsetX + partW, oy + offsetY, 0),
new Point3d(ox + offsetX + partW, oy + offsetY + partH, 0),
new Point3d(ox + offsetX + partW + 10, oy + offsetY + partH / 2, 0), 90, $"{partH}");
// 零件尺寸3标注如果有
if (partD.HasValue && partD.Value > 0)
{
try
{
var text = new DBText();
text.TextString = $"深度:{partD.Value}";
text.Position = new Point3d(ox + offsetX + partW + 10, oy + offsetY + partH + 5, 0);
text.Height = 4;
ctx.Style?.Apply(text, DrawingStyleManager.Role.Text);
ctx.Btr.AppendEntity(text);
ctx.Tr.AddNewlyCreatedDBObject(text, true);
}
catch { }
}
}
#endregion
#region
private static string BuildDimensionText(string baseText, double? tolPlus, double? tolMinus)
{
if (!tolPlus.HasValue && !tolMinus.HasValue)
{
return baseText;
}
var result = baseText;
// 公差格式: 基本尺寸 +上差/-下差
if (tolPlus.HasValue && tolMinus.HasValue)
{
var plusStr = tolPlus.Value >= 0 ? $"+{tolPlus.Value}" : $"{tolPlus.Value}";
var minusStr = tolMinus.Value >= 0 ? $"+{tolMinus.Value}" : $"{tolMinus.Value}";
result += $"({plusStr}/{minusStr})";
}
else if (tolPlus.HasValue)
{
var plusStr = tolPlus.Value >= 0 ? $"+{tolPlus.Value}" : $"{tolPlus.Value}";
result += $"({plusStr})";
}
else if (tolMinus.HasValue)
{
var minusStr = tolMinus.Value >= 0 ? $"+{tolMinus.Value}" : $"{tolMinus.Value}";
result += $"({minusStr})";
}
return result;
}
private static void AddLinearDim(DrawingContext ctx, Point3d pt1, Point3d pt2, Point3d dimLinePt,
double rotationDeg, string textOverride)
{
try
{
double rotRad = rotationDeg * Math.PI / 180.0;
var dim = new RotatedDimension(rotRad, pt1, pt2, dimLinePt, textOverride, ctx.Db.Dimstyle);
ctx.Style?.Apply(dim, DrawingStyleManager.Role.Dimension);
ctx.Btr.AppendEntity(dim);
ctx.Tr.AddNewlyCreatedDBObject(dim, true);
}
catch
{
// 忽略标注错误
}
}
private static void TryLoadLinetype(Database db, Transaction tr, string linetypeName)
{
try
{
var linetypeTbl = (LinetypeTable)tr.GetObject(db.LinetypeTableId, OpenMode.ForRead);
if (!linetypeTbl.Has(linetypeName))
{
try
{
db.LoadLineTypeFile(linetypeName, "acad.lin");
}
catch { }
}
}
catch { }
}
/// <summary>
/// 对参数包中的尺寸参数应用缩放比例
/// </summary>
private static ParamBag ScaleParamBag(ParamBag original, double scaleFactor)
{
if (original == null || scaleFactor <= 0 || scaleFactor >= 1.0)
{
return original;
}
var scaled = new ParamBag();
// 需要缩放的尺寸参数Key列表
var sizeKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
// 环形参数
KeyOuterDiameter1, KeyInnerDiameter2, KeyHeight1,
KeyOuterDiameter1Prime, KeyInnerDiameter2Prime, KeyHeight1Prime,
KeyMinWallThickness,
// 饼盘参数
KeyDiskDiameter, KeyDiskHeight,
KeyDiskDiameterPrime, KeyDiskHeightPrime,
// 轴杆参数
KeyDiameter, KeyLength,
KeyDiameterPrime, KeyLengthPrime,
// 方体参数
KeyBoxSize1, KeyBoxSize2, KeyBoxSize3,
KeyBoxSize1Prime, KeyBoxSize2Prime, KeyBoxSize3Prime,
// 圆角参数
KeyUnspecifiedFilletRadiusMax, KeyInnerRadiusMax,
KeyDiskFilletRadiusMax, KeyShaftFilletRadiusMax,
KeyBoxFilletRadiusMax, KeyBoxRoundHeadFilletRadiusMax
};
// 公差参数也需要缩放
var toleranceKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
KeyOuterDiameter1TolPlus, KeyOuterDiameter1TolMinus,
KeyInnerDiameter2TolPlus, KeyInnerDiameter2TolMinus,
KeyHeight1TolPlus, KeyHeight1TolMinus,
KeyDiskDiameterTolPlus, KeyDiskDiameterTolMinus,
KeyDiskHeightTolPlus, KeyDiskHeightTolMinus,
KeyDiameterTolPlus, KeyDiameterTolMinus,
KeyLengthTolPlus, KeyLengthTolMinus,
KeyBoxSize1TolPlus, KeyBoxSize1TolMinus,
KeyBoxSize2TolPlus, KeyBoxSize2TolMinus,
KeyBoxSize3TolPlus, KeyBoxSize3TolMinus
};
foreach (var key in original.GetKeys())
{
var value = original.GetString(key);
if (sizeKeys.Contains(key) || toleranceKeys.Contains(key))
{
// 尝试解析为数值并缩放
if (double.TryParse(value, out var numValue))
{
var scaledValue = numValue * scaleFactor;
// 保留适当的小数位数
scaled.Set(key, scaledValue.ToString("F2"));
}
else
{
scaled.Set(key, value);
}
}
else
{
// 非尺寸参数直接复制
scaled.Set(key, value);
}
}
return scaled;
}
#endregion
}
}