修改了修图逻辑和比例填写逻辑

This commit is contained in:
sladro 2025-12-22 20:34:31 +08:00
parent 2454dffc95
commit 487e5fb3ed
5 changed files with 539 additions and 251 deletions

158
Cad/DrawingStyleManager.cs Normal file
View File

@ -0,0 +1,158 @@
using Autodesk.AutoCAD.Colors;
using Autodesk.AutoCAD.DatabaseServices;
namespace CadParamPluging.Cad
{
internal sealed class DrawingStyleManager
{
public enum Role
{
OutlineBold,
OutlineThin,
PartContour,
Centerline,
Hidden,
Hatch,
Dimension,
Text
}
private readonly Database _db;
private readonly Transaction _tr;
public DrawingStyleManager(Database db, Transaction tr)
{
_db = db;
_tr = tr;
}
public void Apply(Entity ent, Role role)
{
if (ent == null || _db == null || _tr == null)
{
return;
}
var spec = GetSpec(role);
EnsureLayer(spec.LayerName, spec.DefaultLinetypeName, spec.DefaultLineWeight, spec.DefaultColorIndex);
try { ent.Layer = spec.LayerName; } catch { }
try { ent.ColorIndex = 256; } catch { } // ByLayer
try { ent.Linetype = "ByLayer"; } catch { }
try { ent.LineWeight = LineWeight.ByLayer; } catch { }
}
private sealed class LayerSpec
{
public string LayerName { get; set; }
public string DefaultLinetypeName { get; set; }
public LineWeight DefaultLineWeight { get; set; }
public short DefaultColorIndex { get; set; }
}
private static LayerSpec GetSpec(Role role)
{
switch (role)
{
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.LineWeight025, DefaultColorIndex = 7 };
case Role.Centerline:
return new LayerSpec { LayerName = "中心线", DefaultLinetypeName = "CENTER", DefaultLineWeight = LineWeight.LineWeight025, DefaultColorIndex = 7 };
case Role.Hidden:
return new LayerSpec { LayerName = "虚线", DefaultLinetypeName = "DASHED", DefaultLineWeight = LineWeight.LineWeight025, DefaultColorIndex = 7 };
case Role.Hatch:
return new LayerSpec { LayerName = "剖面线", DefaultLinetypeName = "Continuous", DefaultLineWeight = LineWeight.LineWeight018, DefaultColorIndex = 7 };
case Role.Dimension:
return new LayerSpec { LayerName = "尺寸标注", DefaultLinetypeName = "Continuous", DefaultLineWeight = LineWeight.LineWeight018, DefaultColorIndex = 7 };
case Role.Text:
return new LayerSpec { LayerName = "文字", DefaultLinetypeName = "Continuous", DefaultLineWeight = LineWeight.LineWeight018, DefaultColorIndex = 7 };
case Role.OutlineThin:
default:
return new LayerSpec { LayerName = "细实线", DefaultLinetypeName = "Continuous", DefaultLineWeight = LineWeight.LineWeight025, DefaultColorIndex = 7 };
}
}
private void EnsureLayer(string layerName, string linetypeName, LineWeight lineWeight, short colorIndex)
{
if (string.IsNullOrWhiteSpace(layerName) || _db == null || _tr == null)
{
return;
}
try
{
EnsureLinetype(linetypeName);
var layerTbl = (LayerTable)_tr.GetObject(_db.LayerTableId, OpenMode.ForRead);
if (layerTbl.Has(layerName))
{
return;
}
layerTbl.UpgradeOpen();
var ltr = new LayerTableRecord
{
Name = layerName,
Color = Color.FromColorIndex(ColorMethod.ByAci, colorIndex),
LineWeight = lineWeight
};
try
{
if (!string.IsNullOrWhiteSpace(linetypeName))
{
var lt = (LinetypeTable)_tr.GetObject(_db.LinetypeTableId, OpenMode.ForRead);
if (lt.Has(linetypeName))
{
ltr.LinetypeObjectId = lt[linetypeName];
}
}
}
catch
{
// ignore
}
layerTbl.Add(ltr);
_tr.AddNewlyCreatedDBObject(ltr, true);
}
catch
{
// ignore
}
}
private void EnsureLinetype(string linetypeName)
{
if (string.IsNullOrWhiteSpace(linetypeName) || _db == null || _tr == null)
{
return;
}
try
{
var lt = (LinetypeTable)_tr.GetObject(_db.LinetypeTableId, OpenMode.ForRead);
if (lt.Has(linetypeName))
{
return;
}
try
{
_db.LoadLineTypeFile(linetypeName, "acad.lin");
}
catch
{
// Some linetypes may not exist in acad.lin; ignore.
}
}
catch
{
// ignore
}
}
}
}

View File

@ -83,6 +83,8 @@ namespace CadParamPluging.Cad
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; }
@ -146,13 +148,13 @@ namespace CadParamPluging.Cad
var outerDia = bag.GetDoubleOrNull(KeyOuterDiameter1) ?? 0;
var height = bag.GetDoubleOrNull(KeyHeight1) ?? 0;
// 环形图形:宽度=高度参数X方向高度=外径Y方向
// 环形图形:宽度=外径X方向高度=高度参数Y方向
// 加上标注的额外空间约40像素每侧
var extraMargin = 40;
return new ExpectedDrawingSize
{
Width = height + extraMargin * 2,
Height = outerDia + extraMargin * 2
Width = outerDia + extraMargin * 2,
Height = height + extraMargin * 2
};
}
@ -230,7 +232,8 @@ namespace CadParamPluging.Cad
DeliveryStatus = deliveryStatus,
StructuralFeature = structuralFeature,
SpecialCondition = specialCondition,
Btr = btr
Btr = btr,
Style = new DrawingStyleManager(db, tr)
};
// 根据结构特征分发到对应绘制器
@ -306,114 +309,142 @@ namespace CadParamPluging.Cad
return; // 缺少高度,无法绘制
}
// 计算图形偏移,使其居中
double ox = ctx.Center.X - height.Value / 2.0;
double oy = ctx.Center.Y;
double R = outerDia.Value / 2.0;
// 视图方向调整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;
// 加载虚线线型
TryLoadLinetype(ctx.Db, ctx.Tr, "DASHED");
// 车加工态零件尺寸(用于括号尺寸与零件轮廓)
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, R, height.Value);
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, R, outerDia.Value, outerTolPlus, outerTolMinus);
DrawOuterDiameterDimension(ctx, ox, oy, W, outerDia.Value, outerTolPlus, outerTolMinus, outerDiaPrime);
// === 特征3: 内孔(如果有内径参数) ===
// === 特征3: 内孔/内径(如果有内径参数) ===
var innerDia = bag.GetDoubleOrNull(KeyInnerDiameter2);
if (innerDia.HasValue && innerDia.Value > 0)
double? xInnerLeft = null;
double? xInnerRight = null;
if (innerDia.HasValue && innerDia.Value > 0 && innerDia.Value < W)
{
double r = innerDia.Value / 2.0;
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, ox, oy, r, height.Value);
DrawInnerDiameterDimension(ctx, ox, oy, r, height.Value, innerDia.Value, innerTolPlus, innerTolMinus);
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, ox, oy, r, height.Value, innerRadiusMax.Value);
DrawInnerFillets(ctx, xInnerLeft.Value, xInnerRight.Value, oy, H, innerRadiusMax.Value);
}
// === 特征4.1: 剖面线(仅剖切端部区域) ===
DrawRingSectionHatch(ctx, xInnerRight.Value, ox + W, oy, H);
}
// === 特征5: 高度/长度标注 ===
// === 特征5: 高度标注 ===
var heightTolPlus = bag.GetDoubleOrNull(KeyHeight1TolPlus);
var heightTolMinus = bag.GetDoubleOrNull(KeyHeight1TolMinus);
DrawHeightDimension(ctx, ox, oy, R, height.Value, heightTolPlus, heightTolMinus);
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, R, height.Value, unspecifiedFillet.Value);
// 复用现有位置逻辑:右上角
DrawUnspecifiedFilletNote(ctx, ox, oy, H, W, unspecifiedFillet.Value);
}
// === 特征7: 最小壁厚T标注(如果有该参数) ===
// === 特征7: 最小壁厚min标注(如果有该参数) ===
var minWallThickness = bag.GetDoubleOrNull(KeyMinWallThickness);
if (minWallThickness.HasValue && minWallThickness.Value > 0 && innerDia.HasValue)
if (minWallThickness.HasValue && minWallThickness.Value > 0 && xInnerRight.HasValue)
{
DrawMinWallThicknessNote(ctx, ox, oy, R, innerDia.Value / 2.0, minWallThickness.Value);
DrawMinWallThicknessNote(ctx, xInnerRight.Value, ox + W, oy, minWallThickness.Value);
}
// === 特征8: 零件轮廓(车加工态 ===
if (ctx.IsMachined)
// === 特征8: 零件轮廓(车加工态,双点划线 ===
if (ctx.IsMachined && outerDiaPrime.HasValue && outerDiaPrime.Value > 0 && heightPrime.HasValue && heightPrime.Value > 0)
{
var outerDiaPrime = bag.GetDoubleOrNull(KeyOuterDiameter1Prime);
var innerDiaPrime = bag.GetDoubleOrNull(KeyInnerDiameter2Prime);
var heightPrime = bag.GetDoubleOrNull(KeyHeight1Prime);
if (outerDiaPrime.HasValue && outerDiaPrime.Value > 0 && heightPrime.HasValue && heightPrime.Value > 0)
{
DrawPartContour(ctx, ox, oy, height.Value, outerDiaPrime.Value, innerDiaPrime, heightPrime.Value);
}
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 R, double height)
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 - R), 0, 0, 0);
poly.AddVertexAt(1, new Point2d(ox + height, oy - R), 0, 0, 0);
poly.AddVertexAt(2, new Point2d(ox + height, oy + R), 0, 0, 0);
poly.AddVertexAt(3, new Point2d(ox, oy + R), 0, 0, 0);
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;
poly.ColorIndex = 7;
ctx.Style?.Apply(poly, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
}
private static void DrawInnerHole(DrawingContext ctx, double ox, double oy, double r, double height)
private static void DrawRingCenterline(DrawingContext ctx, double ox, double oy, double width, double height)
{
var lineTop = new Line(new Point3d(ox, oy + r, 0), new Point3d(ox + height, oy + r, 0));
lineTop.ColorIndex = 2;
lineTop.Linetype = "DASHED";
ctx.Btr.AppendEntity(lineTop);
ctx.Tr.AddNewlyCreatedDBObject(lineTop, true);
var lineBot = new Line(new Point3d(ox, oy - r, 0), new Point3d(ox + height, oy - r, 0));
lineBot.ColorIndex = 2;
lineBot.Linetype = "DASHED";
ctx.Btr.AppendEntity(lineBot);
ctx.Tr.AddNewlyCreatedDBObject(lineBot, true);
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 DrawInnerFillets(DrawingContext ctx, double ox, double oy, double r, double height, double filletR)
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, ox + filletR, oy + r - filletR, filletR, Math.PI / 2, Math.PI);
DrawFilletArc(ctx, xInnerLeft + filletR, yTop - filletR, filletR, Math.PI / 2, Math.PI);
// 左下角
DrawFilletArc(ctx, ox + filletR, oy - r + filletR, filletR, Math.PI, Math.PI * 1.5);
DrawFilletArc(ctx, xInnerLeft + filletR, yBottom + filletR, filletR, Math.PI, Math.PI * 1.5);
// 右上角
DrawFilletArc(ctx, ox + height - filletR, oy + r - filletR, filletR, 0, Math.PI / 2);
DrawFilletArc(ctx, xInnerRight - filletR, yTop - filletR, filletR, 0, Math.PI / 2);
// 右下角
DrawFilletArc(ctx, ox + height - filletR, oy - r + filletR, filletR, Math.PI * 1.5, 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)
@ -421,7 +452,7 @@ namespace CadParamPluging.Cad
try
{
var arc = new Arc(new Point3d(cx, cy, 0), r, startAngle, endAngle);
arc.ColorIndex = 7;
ctx.Style?.Apply(arc, DrawingStyleManager.Role.OutlineThin);
ctx.Btr.AppendEntity(arc);
ctx.Tr.AddNewlyCreatedDBObject(arc, true);
}
@ -431,29 +462,55 @@ namespace CadParamPluging.Cad
}
}
private static void DrawOuterDiameterDimension(DrawingContext ctx, double ox, double oy, double R,
double diameter, double? tolPlus, double? tolMinus)
private static void DrawOuterDiameterDimension(DrawingContext ctx, double ox, double oy, double width,
double diameter, double? tolPlus, double? tolMinus, double? diameterPrime)
{
var dimText = BuildDimensionText($"%%c{diameter}", tolPlus, tolMinus);
AddLinearDim(ctx, new Point3d(ox, oy + R, 0), new Point3d(ox, oy - R, 0),
new Point3d(ox - 20, oy, 0), 90, dimText);
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 ox, double oy, double r,
double height, double diameter, double? tolPlus, double? tolMinus)
private static void DrawInnerDiameterDimension(DrawingContext ctx, double xInnerLeft, double xInnerRight, double yBottom,
double diameter, double? tolPlus, double? tolMinus, double? diameterPrime)
{
var dimText = BuildDimensionText($"%%c{diameter}", tolPlus, tolMinus);
AddLinearDim(ctx, new Point3d(ox, oy + r, 0), new Point3d(ox, oy - r, 0),
new Point3d(ox + height + 20, oy, 0), 90, dimText);
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 R,
double height, double? tolPlus, double? tolMinus)
private static void DrawHeightDimension(DrawingContext ctx, double ox, double oy, double width,
double height, double? tolPlus, double? tolMinus, double? heightPrime)
{
var baseText = $"{height}min";
var dimText = BuildDimensionText(baseText, tolPlus, tolMinus);
AddLinearDim(ctx, new Point3d(ox, oy - R, 0), new Point3d(ox + height, oy - R, 0),
new Point3d(ox + height / 2, oy - R - 20, 0), 0, dimText);
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)
@ -465,7 +522,7 @@ namespace CadParamPluging.Cad
text.TextString = $"未注圆角半径R≤{filletR}";
text.Position = new Point3d(ox + height + 10, oy + R + 15, 0);
text.Height = 5;
text.ColorIndex = 7;
ctx.Style?.Apply(text, DrawingStyleManager.Role.Text);
ctx.Btr.AppendEntity(text);
ctx.Tr.AddNewlyCreatedDBObject(text, true);
}
@ -475,55 +532,75 @@ namespace CadParamPluging.Cad
}
}
private static void DrawMinWallThicknessNote(DrawingContext ctx, double ox, double oy, double R, double r, double thickness)
private static void DrawMinWallThicknessNote(DrawingContext ctx, double xInnerRight, double xOuterRight, double yBottom, double thickness)
{
// 壁厚标注线 - 在截面中间位置
try
{
// 在内外径之间画一条标注线
var midX = ox;
var midY = oy + (R + r) / 2;
var leader = new Line(new Point3d(midX, oy + r, 0), new Point3d(midX, oy + R, 0));
leader.ColorIndex = 4;
ctx.Btr.AppendEntity(leader);
ctx.Tr.AddNewlyCreatedDBObject(leader, true);
var text = new DBText();
text.TextString = $"T≥{thickness}";
text.Position = new Point3d(midX - 20, midY, 0);
text.Height = 4;
text.ColorIndex = 4;
ctx.Btr.AppendEntity(text);
ctx.Tr.AddNewlyCreatedDBObject(text, true);
}
catch
{
// 忽略
}
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, double ox, double oy, double forgingHeight,
private static void DrawPartContour(DrawingContext ctx, Point3d center,
double outerDiaPrime, double? innerDiaPrime, double heightPrime)
{
double offsetX = (forgingHeight - heightPrime) / 2.0;
double Rp = outerDiaPrime / 2.0;
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(ox + offsetX, oy - Rp), 0, 0, 0);
polyPart.AddVertexAt(1, new Point2d(ox + offsetX + heightPrime, oy - Rp), 0, 0, 0);
polyPart.AddVertexAt(2, new Point2d(ox + offsetX + heightPrime, oy + Rp), 0, 0, 0);
polyPart.AddVertexAt(3, new Point2d(ox + offsetX, oy + Rp), 0, 0, 0);
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;
polyPart.ColorIndex = 7;
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);
@ -536,25 +613,133 @@ namespace CadParamPluging.Cad
hatch.PatternScale = 0.8;
hatch.PatternAngle = 0;
hatch.Associative = false;
hatch.ColorIndex = 7;
ctx.Style?.Apply(hatch, DrawingStyleManager.Role.Hatch);
var ids = new ObjectIdCollection();
ids.Add(polyPart.ObjectId);
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;
}
// 零件外径标注
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{outerDiaPrime}");
var raw = ctx.Bag.GetString("Hardness");
if (string.IsNullOrWhiteSpace(raw))
{
return;
}
// 零件高度标注
AddLinearDim(ctx, new Point3d(ox + offsetX, oy - Rp, 0), new Point3d(ox + offsetX + heightPrime, oy - Rp, 0),
new Point3d(ox + offsetX + heightPrime / 2, oy - Rp - 10, 0), 0, $"{heightPrime}");
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
@ -584,7 +769,7 @@ namespace CadParamPluging.Cad
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;
poly.ColorIndex = 7;
ctx.Style?.Apply(poly, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
@ -631,34 +816,12 @@ namespace CadParamPluging.Cad
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;
polyPart.ColorIndex = 7;
ctx.Style?.Apply(polyPart, DrawingStyleManager.Role.PartContour);
ctx.Btr.AppendEntity(polyPart);
ctx.Tr.AddNewlyCreatedDBObject(polyPart, true);
// 填充
try
{
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;
hatch.ColorIndex = 7;
var ids = new ObjectIdCollection();
ids.Add(polyPart.ObjectId);
hatch.AppendLoop(HatchLoopTypes.External, ids);
hatch.EvaluateHatch(true);
}
catch { }
// 不再对零件轮廓整块填充剖面线
// 零件直径标注
AddLinearDim(ctx, new Point3d(ox + offsetX, oy + offsetY, 0),
@ -711,15 +874,14 @@ namespace CadParamPluging.Cad
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;
poly.ColorIndex = 7;
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));
centerLine.ColorIndex = 1;
centerLine.Linetype = "CENTER";
ctx.Style?.Apply(centerLine, DrawingStyleManager.Role.Centerline);
ctx.Btr.AppendEntity(centerLine);
ctx.Tr.AddNewlyCreatedDBObject(centerLine, true);
@ -780,7 +942,7 @@ namespace CadParamPluging.Cad
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;
poly.ColorIndex = 7;
ctx.Style?.Apply(poly, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
@ -814,7 +976,7 @@ namespace CadParamPluging.Cad
text.TextString = dim3Text;
text.Position = new Point3d(ox + width + 10, oy + height + 10, 0);
text.Height = 5;
text.ColorIndex = 7;
ctx.Style?.Apply(text, DrawingStyleManager.Role.Text);
ctx.Btr.AppendEntity(text);
ctx.Tr.AddNewlyCreatedDBObject(text, true);
}
@ -831,7 +993,7 @@ namespace CadParamPluging.Cad
text.TextString = $"未注圆角半径R≤{unspecifiedFillet.Value}";
text.Position = new Point3d(ox + width + 10, oy + height + 20, 0);
text.Height = 5;
text.ColorIndex = 7;
ctx.Style?.Apply(text, DrawingStyleManager.Role.Text);
ctx.Btr.AppendEntity(text);
ctx.Tr.AddNewlyCreatedDBObject(text, true);
}
@ -861,34 +1023,12 @@ namespace CadParamPluging.Cad
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;
polyPart.ColorIndex = 7;
ctx.Style?.Apply(polyPart, DrawingStyleManager.Role.PartContour);
ctx.Btr.AppendEntity(polyPart);
ctx.Tr.AddNewlyCreatedDBObject(polyPart, true);
// 填充
try
{
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;
hatch.ColorIndex = 7;
var ids = new ObjectIdCollection();
ids.Add(polyPart.ObjectId);
hatch.AppendLoop(HatchLoopTypes.External, ids);
hatch.EvaluateHatch(true);
}
catch { }
// 不再对零件轮廓整块填充剖面线
// 零件直径标注
AddLinearDim(ctx, new Point3d(ox + offsetX, oy + Rp, 0), new Point3d(ox + offsetX, oy - Rp, 0),
@ -929,7 +1069,7 @@ namespace CadParamPluging.Cad
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;
poly.ColorIndex = 7;
ctx.Style?.Apply(poly, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
@ -963,7 +1103,7 @@ namespace CadParamPluging.Cad
text.TextString = dim3Text;
text.Position = new Point3d(ox + width + 10, oy + height + 10, 0);
text.Height = 5;
text.ColorIndex = 7;
ctx.Style?.Apply(text, DrawingStyleManager.Role.Text);
ctx.Btr.AppendEntity(text);
ctx.Tr.AddNewlyCreatedDBObject(text, true);
}
@ -980,7 +1120,7 @@ namespace CadParamPluging.Cad
text.TextString = $"未注圆角半径R≤{unspecifiedFillet.Value}";
text.Position = new Point3d(ox + width + 10, oy + height + 20, 0);
text.Height = 5;
text.ColorIndex = 7;
ctx.Style?.Apply(text, DrawingStyleManager.Role.Text);
ctx.Btr.AppendEntity(text);
ctx.Tr.AddNewlyCreatedDBObject(text, true);
}
@ -997,7 +1137,7 @@ namespace CadParamPluging.Cad
try
{
var arcLeft = new Arc(new Point3d(ox, centerY, 0), R, Math.PI / 2, Math.PI * 1.5);
arcLeft.ColorIndex = 7;
ctx.Style?.Apply(arcLeft, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(arcLeft);
ctx.Tr.AddNewlyCreatedDBObject(arcLeft, true);
}
@ -1007,7 +1147,7 @@ namespace CadParamPluging.Cad
try
{
var arcRight = new Arc(new Point3d(ox + width, centerY, 0), R, -Math.PI / 2, Math.PI / 2);
arcRight.ColorIndex = 7;
ctx.Style?.Apply(arcRight, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(arcRight);
ctx.Tr.AddNewlyCreatedDBObject(arcRight, true);
}
@ -1037,34 +1177,12 @@ namespace CadParamPluging.Cad
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;
polyPart.ColorIndex = 7;
ctx.Style?.Apply(polyPart, DrawingStyleManager.Role.PartContour);
ctx.Btr.AppendEntity(polyPart);
ctx.Tr.AddNewlyCreatedDBObject(polyPart, true);
// 填充
try
{
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;
hatch.ColorIndex = 7;
var ids = new ObjectIdCollection();
ids.Add(polyPart.ObjectId);
hatch.AppendLoop(HatchLoopTypes.External, ids);
hatch.EvaluateHatch(true);
}
catch { }
// 不再对零件轮廓整块填充剖面线
// 零件尺寸1标注
AddLinearDim(ctx, new Point3d(ox + offsetX, oy + offsetY, 0),
@ -1085,7 +1203,7 @@ namespace CadParamPluging.Cad
text.TextString = $"深度:{partD.Value}";
text.Position = new Point3d(ox + offsetX + partW + 10, oy + offsetY + partH + 5, 0);
text.Height = 4;
text.ColorIndex = 7;
ctx.Style?.Apply(text, DrawingStyleManager.Role.Text);
ctx.Btr.AppendEntity(text);
ctx.Tr.AddNewlyCreatedDBObject(text, true);
}
@ -1134,7 +1252,7 @@ namespace CadParamPluging.Cad
{
double rotRad = rotationDeg * Math.PI / 180.0;
var dim = new RotatedDimension(rotRad, pt1, pt2, dimLinePt, textOverride, ctx.Db.Dimstyle);
dim.ColorIndex = 4;
ctx.Style?.Apply(dim, DrawingStyleManager.Role.Dimension);
ctx.Btr.AppendEntity(dim);
ctx.Tr.AddNewlyCreatedDBObject(dim, true);
}

View File

@ -77,6 +77,7 @@
<Compile Include="Common\Logger.cs" />
<Compile Include="Cad\CadContext.cs" />
<Compile Include="Cad\CadDrawingService.cs" />
<Compile Include="Cad\DrawingStyleManager.cs" />
<Compile Include="Cad\FeatureDrivenDrawer.cs" />
<Compile Include="Cad\HalfSectionDrawer.cs" />
<Compile Include="Cad\TemplateAnnotationOptionsExtractor.cs" />

View File

@ -258,6 +258,19 @@ namespace CadParamPluging.Common
Group = "备注参数"
},
new ParamDefinition
{
Key = "DrawingScale",
Label = "出图比例",
Type = ParamValueType.Enum,
Required = true,
DefaultValue = "1:1",
EnumOptions = new List<string> { "1:1", "1:2", "1:5", "1:10", "1:20" },
Hint = "单选下拉列表决定绘图缩放1:n",
Order = 10,
Group = "模板参数"
},
// --- Template key fields (also exist in panel dropdowns) ---
new ParamDefinition
{

View File

@ -513,6 +513,47 @@ namespace CadParamPluging.UI
return string.Join(", ", arr.Take(max)) + $" ... (共 {arr.Length} 项)";
}
private static double ParseScaleFactor(string raw)
{
if (string.IsNullOrWhiteSpace(raw))
{
throw new BusinessException("请填写:出图比例 (DrawingScale)");
}
var s = (raw ?? string.Empty).Trim();
s = s.Replace(" ", "").Replace("\u3000", "").Replace("", ":");
var parts = s.Split(':');
if (parts.Length != 2 || !string.Equals(parts[0], "1", StringComparison.OrdinalIgnoreCase))
{
throw new BusinessException("出图比例格式错误,应为 1:n例如 1:5");
}
if (!TryParseDouble(parts[1], out var denom) || denom < 1e-9)
{
throw new BusinessException("出图比例格式错误,应为 1:n例如 1:5");
}
if (denom < 1.0)
{
throw new BusinessException("出图比例不支持放大n 必须 >= 1");
}
return 1.0 / denom;
}
private static bool TryParseDouble(string s, out double value)
{
value = 0;
if (string.IsNullOrWhiteSpace(s))
{
return false;
}
return double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out value)
|| double.TryParse(s, NumberStyles.Float, CultureInfo.CurrentCulture, out value);
}
private void OnGenerateDrawing()
{
try
@ -616,50 +657,7 @@ namespace CadParamPluging.UI
var removeResult = TemplateDrawingService.RemoveTemplateOriginalDrawing(ctx);
AppendLog($"已删除原有图形: 红色外框={removeResult.OuterFrameErased}, CAXA图层={removeResult.CaxaLayerErased}, 标注={removeResult.DimensionLayerErased}, 保留右上角={removeResult.DimensionLayerKept}");
// 检测白色外框(图纸边界)范围
var whiteFrameExtents = TemplateDrawingService.ComputeWhiteFrameExtents(ctx);
// 计算预期图形尺寸
var expectedSize = FeatureDrivenDrawer.CalculateExpectedSize(bag, tplParams.SheetSize);
// 检查是否会超出图纸边界
double scaleFactor = 1.0;
if (expectedSize.IsValid && whiteFrameExtents.HasValue)
{
var sizeCheck = TemplateDrawingService.CheckDrawingSize(
whiteFrameExtents,
expectedSize.Width,
expectedSize.Height,
50); // 边距50
AppendLog(sizeCheck.Message);
if (sizeCheck.NeedsScaling)
{
// 询问用户是否要等比例缩放
var confirmScale = MessageBox.Show(
this,
$"图形尺寸超出图纸边界!\n\n" +
$"图形尺寸: {expectedSize.Width:F1} x {expectedSize.Height:F1}\n" +
$"可用区域: {sizeCheck.AvailableWidth:F1} x {sizeCheck.AvailableHeight:F1}\n" +
$"建议缩放比例: {sizeCheck.ScaleFactor:P1}\n\n" +
$"是否等比例缩小图形以适应图纸?\n" +
$"选择【是】将自动缩放,选择【否】将按原尺寸绘制(可能超出边界)",
"图形尺寸超出",
MessageBoxButtons.YesNo,
MessageBoxIcon.Warning);
if (confirmScale == DialogResult.Yes)
{
scaleFactor = sizeCheck.ScaleFactor;
AppendLog($"将应用缩放比例: {scaleFactor:P1}");
}
else
{
AppendLog("用户选择按原尺寸绘制");
}
}
}
var scaleFactor = ParseScaleFactor(bag.GetString("DrawingScale"));
// 根据模板参数绘制半剖视图,居中放置于原图纸位置
// 使用特征驱动模式:根据参数存在性动态绘制对应特征