diff --git a/Cad/DrawingStyleManager.cs b/Cad/DrawingStyleManager.cs new file mode 100644 index 0000000..b80937f --- /dev/null +++ b/Cad/DrawingStyleManager.cs @@ -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 + } + } + } +} diff --git a/Cad/FeatureDrivenDrawer.cs b/Cad/FeatureDrivenDrawer.cs index 4fc85f0..4d17d40 100644 --- a/Cad/FeatureDrivenDrawer.cs +++ b/Cad/FeatureDrivenDrawer.cs @@ -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(); + 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); } diff --git a/CadParamPluging.csproj b/CadParamPluging.csproj index 5445828..496bd60 100644 --- a/CadParamPluging.csproj +++ b/CadParamPluging.csproj @@ -77,6 +77,7 @@ + diff --git a/Common/ParamCatalog.cs b/Common/ParamCatalog.cs index 5315dad..b3b2509 100644 --- a/Common/ParamCatalog.cs +++ b/Common/ParamCatalog.cs @@ -258,6 +258,19 @@ namespace CadParamPluging.Common Group = "备注参数" }, + new ParamDefinition + { + Key = "DrawingScale", + Label = "出图比例", + Type = ParamValueType.Enum, + Required = true, + DefaultValue = "1:1", + EnumOptions = new List { "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 { diff --git a/UI/ParamDrawingPanel.cs b/UI/ParamDrawingPanel.cs index 47be534..74785bd 100644 --- a/UI/ParamDrawingPanel.cs +++ b/UI/ParamDrawingPanel.cs @@ -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")); // 根据模板参数绘制半剖视图,居中放置于原图纸位置 // 使用特征驱动模式:根据参数存在性动态绘制对应特征