CadParamPluging/Cad/Drawers/RingRawFreeForgeNonCenterPunchDrawer.cs

321 lines
16 KiB
C#
Raw Permalink 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 Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using CadParamPluging.Common;
namespace CadParamPluging.Cad.Drawers
{
public static class RingRawFreeForgeNonCenterPunchDrawer
{
public static void Draw(CadContext ctx, ParamBag bag, Point3d center, double scaleFactor = 1.0)
{
if (ctx == null) throw new ArgumentNullException(nameof(ctx));
if (bag == null) throw new ArgumentNullException(nameof(bag));
// Apply scaling
var effectiveBag = scaleFactor < 1.0 ? ScaleParamBag(bag, scaleFactor) : bag;
var db = ctx.Database;
var tr = ctx.Transaction;
var prevDb = HostApplicationServices.WorkingDatabase;
HostApplicationServices.WorkingDatabase = db;
BlockTableRecord btr;
try
{
var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
}
finally
{
HostApplicationServices.WorkingDatabase = prevDb;
}
// Construct DrawingContext
// Note: SpecialCondition needs to NOT contain "中心冲孔"
var context = new FeatureDrivenDrawer.DrawingContext
{
Ctx = ctx,
Bag = effectiveBag,
OriginalBag = bag,
Center = center,
DeliveryStatus = "毛料态",
StructuralFeature = "环形",
SpecialCondition = "非中心冲孔",
ProcessMethod = "自由锻",
Btr = btr,
// We need to instantiate DrawingStyleManager. Accessing internal constructor via reflection or if it's internal to assembly we are fine.
// Assuming same assembly.
Style = new DrawingStyleManager(db, tr)
};
DrawCore(context);
}
private static ParamBag ScaleParamBag(ParamBag original, double scaleFactor)
{
if (original == null || scaleFactor <= 0 || (Math.Abs(scaleFactor - 1.0) < 1e-6))
{
return original;
}
var scaled = new ParamBag();
// 需要缩放的尺寸参数Key列表
var sizeKeys = new System.Collections.Generic.HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
// 环形参数
FeatureDrivenDrawer.KeyOuterDiameter1, FeatureDrivenDrawer.KeyInnerDiameter2, FeatureDrivenDrawer.KeyHeight1,
FeatureDrivenDrawer.KeyOuterDiameter1Prime, FeatureDrivenDrawer.KeyInnerDiameter2Prime, FeatureDrivenDrawer.KeyHeight1Prime,
FeatureDrivenDrawer.KeyMinWallThickness,
// 圆角参数
FeatureDrivenDrawer.KeyUnspecifiedFilletRadiusMax, FeatureDrivenDrawer.KeyInnerRadiusMax,
// 包含公差参数以保持一致性
FeatureDrivenDrawer.KeyOuterDiameter1TolPlus, FeatureDrivenDrawer.KeyOuterDiameter1TolMinus,
FeatureDrivenDrawer.KeyInnerDiameter2TolPlus, FeatureDrivenDrawer.KeyInnerDiameter2TolMinus,
FeatureDrivenDrawer.KeyHeight1TolPlus, FeatureDrivenDrawer.KeyHeight1TolMinus
};
foreach (var key in original.GetKeys())
{
var value = original.GetString(key);
if (sizeKeys.Contains(key))
{
// 尝试解析为数值并缩放
if (double.TryParse(value, out var numValue))
{
var scaledValue = numValue * scaleFactor;
// 保留适当的小数位数,避免精度问题
scaled.Set(key, scaledValue.ToString("F4"));
}
else
{
scaled.Set(key, value);
}
}
else
{
// 非尺寸参数直接复制
scaled.Set(key, value);
}
}
return scaled;
}
private static void DrawCore(FeatureDrivenDrawer.DrawingContext ctx)
{
// Logic copied from FeatureDrivenDrawer.DrawRingFeaturesFull but tailored for NonCenterPunch
var bag = ctx.Bag;
var outerDia = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyOuterDiameter1);
var height = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyHeight1);
if (!outerDia.HasValue || !height.HasValue) return;
double W = outerDia.Value;
double H = height.Value;
double ox = ctx.Center.X - W / 2.0;
double oy = ctx.Center.Y - H / 2.0;
// Unconditionally retrieve variables for Part Contour (Prime parameters)
// This ensures the yellow part contour is drawn if parameters exist, regardless of status.
var outerDiaPrime = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyOuterDiameter1Prime);
var innerDiaPrime = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyInnerDiameter2Prime);
var heightPrime = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyHeight1Prime);
/*
if (ctx.IsMachined)
{
// Previously, these were only loaded if IsMachined was true.
}
*/
// 1. Forging Section Contours (Replacing generic outer contour)
var sectionFilletR = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyUnspecifiedFilletRadiusMax) ?? 0;
// Pre-calculate inner hole parameters
var innerDia = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyInnerDiameter2);
var innerTolPlus = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyInnerDiameter2TolPlus);
var innerTolMinus = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyInnerDiameter2TolMinus);
double? xInnerLeft = null;
double? xInnerRight = null;
// Full Section: Draw Contour with Fillet for both sides
if (innerDia.HasValue && innerDia.Value > 0 && innerDia.Value < W)
{
// Do NOT draw sharp ForgingOuterContour, as it conflicts with rounded fillets.
// FeatureDrivenDrawer.DrawForgingOuterContour(ctx, ox, oy, W, H);
double xInnerLeftVal = ctx.Center.X - innerDia.Value / 2.0;
double xInnerRightVal = ctx.Center.X + innerDia.Value / 2.0;
// Draw Left Section Contour
FeatureDrivenDrawer.DrawRingSectionContourWithFillet(ctx, ox, xInnerLeftVal, oy, H, sectionFilletR);
// Draw Left Hatch (with fillet)
FeatureDrivenDrawer.DrawRingSectionHatchWithFillet(ctx, ox, xInnerLeftVal, oy, H, sectionFilletR);
// Draw Right Section Contour
FeatureDrivenDrawer.DrawRingSectionContourWithFillet(ctx, xInnerRightVal, ox + W, oy, H, sectionFilletR);
// Draw Right Hatch (with fillet)
FeatureDrivenDrawer.DrawRingSectionHatchWithFillet(ctx, xInnerRightVal, ox + W, oy, H, sectionFilletR);
// Draw Connecting Lines (Hole Back View) - Top and Bottom
// Extend into the fillet radius to connect with the flat top/bottom of the sections
double lineStart = xInnerLeftVal - sectionFilletR;
double lineEnd = xInnerRightVal + sectionFilletR;
var connectingLineTop = new Line(new Point3d(lineStart, oy + H, 0), new Point3d(lineEnd, oy + H, 0));
ctx.Style?.Apply(connectingLineTop, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(connectingLineTop);
ctx.Tr.AddNewlyCreatedDBObject(connectingLineTop, true);
var connectingLineBottom = new Line(new Point3d(lineStart, oy, 0), new Point3d(lineEnd, oy, 0));
ctx.Style?.Apply(connectingLineBottom, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(connectingLineBottom);
ctx.Tr.AddNewlyCreatedDBObject(connectingLineBottom, true);
// Adjust Inner Dim to attach to vertical wall (offset by r)
FeatureDrivenDrawer.DrawInnerDiameterDimension(ctx, xInnerLeftVal, xInnerRightVal, oy + sectionFilletR, innerDia.Value, innerTolPlus, innerTolMinus, innerDiaPrime);
// Store values for later use in dimensions/notes
xInnerRight = xInnerRightVal;
xInnerLeft = xInnerLeftVal;
}
else
{
// Fallback if no inner hole (should not happen for a ring but safe to keep)
// FeatureDrivenDrawer.DrawForgingOuterContour(ctx, ox, oy, W, H);
}
// 1.1 Centerline
// 改为竖直中心线两头超出3mm
var cx = ctx.Center.X;
var vLine = new Line(new Point3d(cx, oy - 3, 0), new Point3d(cx, oy + H + 3, 0));
ctx.Style?.Apply(vLine, DrawingStyleManager.Role.Centerline);
ctx.Btr.AppendEntity(vLine);
ctx.Tr.AddNewlyCreatedDBObject(vLine, true);
// 2. Outer Diameter Dimension
var outerTolPlus = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyOuterDiameter1TolPlus);
var outerTolMinus = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyOuterDiameter1TolMinus);
// Adjust Y by fillet radius so dimension lines attach to the vertical wall, not the rounded corner gap
FeatureDrivenDrawer.DrawOuterDiameterDimension(ctx, ox, oy + sectionFilletR, W, W, outerTolPlus, outerTolMinus, outerDiaPrime);
// 3. Inner Hole Block (REMOVED - now handled above)
/*
// declared and handled above
*/
// 5. Height Dimension
// Fix: Use OriginalBag for dimension text so it shows the real value (e.g. 43) not the scaled value (e.g. 12.28)
var displayBag = ctx.OriginalBag ?? ctx.Bag;
var displayHeightVal = displayBag.GetDoubleOrNull(FeatureDrivenDrawer.KeyHeight1) ?? H;
var displayHeightStr = displayBag.GetString(FeatureDrivenDrawer.KeyHeight1);
var heightTolPlus = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyHeight1TolPlus); // Tolerances are usually absolute or percentage? Assuming absolute, they might need scaling or not?
// Wait, if tolerances are absolute values in mm (like ±0.5), they should NOT be scaled in the text.
// But they ARE scaled in the effective bag if they were in the sizeKeys list.
// Let's check sizeKeys... Yes, TolPlus/TolMinus are in sizeKeys.
// So if we used the scaled bag's tolerance for TEXT, it would be ±0.14. The screenshot shows ±0.1429. The User input is 0.5.
// So we MUST use OriginalBag for Tolerances as well for the text.
var displayTolPlus = displayBag.GetDoubleOrNull(FeatureDrivenDrawer.KeyHeight1TolPlus);
var displayTolMinus = displayBag.GetDoubleOrNull(FeatureDrivenDrawer.KeyHeight1TolMinus);
var displayTolPlusStr = displayBag.GetString(FeatureDrivenDrawer.KeyHeight1TolPlus);
var displayTolMinusStr = displayBag.GetString(FeatureDrivenDrawer.KeyHeight1TolMinus);
var displayHeightPrime = displayBag.GetDoubleOrNull(FeatureDrivenDrawer.KeyHeight1Prime);
var heightBaseText = FeatureDrivenDrawer.BuildDimensionText(FeatureDrivenDrawer.FormatDimNumber(displayHeightVal, displayHeightStr), displayTolPlus, displayTolMinus, displayTolPlusStr, displayTolMinusStr);
var heightDimText = heightBaseText;
if (displayHeightPrime.HasValue && displayHeightPrime.Value > 0)
{
heightDimText = heightBaseText + $"\\X({FeatureDrivenDrawer.FormatDimNumber(displayHeightPrime.Value)})";
}
// Custom Height Dimension Logic to ensure "Closed" look with fillets
// Move X definition points inward by fillet radius so extension lines start from the flat face
double dimX = ox + W - sectionFilletR;
FeatureDrivenDrawer.AddLinearDim(
ctx,
new Point3d(dimX, oy, 0),
new Point3d(dimX, oy + H, 0),
new Point3d(ox + W + 25, oy + H / 2, 0),
90,
heightDimText);
// 6. Unspecified Fillet Note - User requested to remove this
/*
var unspecifiedFillet = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyUnspecifiedFilletRadiusMax);
if (unspecifiedFillet.HasValue && unspecifiedFillet.Value > 0)
{
FeatureDrivenDrawer.DrawUnspecifiedFilletNote(ctx, ox, oy, H, W, unspecifiedFillet.Value);
}
*/
// 7. Min Wall Thickness
var minWallThickness = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyMinWallThickness);
if (minWallThickness.HasValue && minWallThickness.Value > 0)
{
if (xInnerRight.HasValue)
{
var val = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeyMinWallThickness) ?? minWallThickness.Value;
var dimText = $"{FeatureDrivenDrawer.FormatDimNumber(val)}min";
FeatureDrivenDrawer.AddLinearDim(
ctx,
new Point3d(xInnerRight.Value, oy + sectionFilletR, 0),
new Point3d(ox + W, oy + sectionFilletR, 0),
new Point3d((xInnerRight.Value + ox + W) / 2, oy + sectionFilletR - 25, 0),
0,
dimText);
}
}
// 8. Part Contour (Machined Parameters present)
// Even if status is "Raw", if parameters exist, we draw the part contour as requested.
if (outerDiaPrime.HasValue && outerDiaPrime.Value > 0 && heightPrime.HasValue && heightPrime.Value > 0)
{
FeatureDrivenDrawer.DrawPartContour(ctx, ctx.Center, outerDiaPrime.Value, innerDiaPrime, heightPrime.Value);
}
// 9. Hardness Symbol
var hardnessVal = bag.GetString(FeatureDrivenDrawer.KeyHardness);
if (!string.IsNullOrWhiteSpace(hardnessVal) && hardnessVal != "空")
{
if (xInnerRight.HasValue)
{
double xStart = (xInnerRight.Value + ox + W) / 2.0;
double yStart = oy;
FeatureDrivenDrawer.DrawHardnessSymbol(ctx, xStart, yStart, hardnessVal);
}
else
{
FeatureDrivenDrawer.DrawHardnessSymbol(ctx, ox + W / 2.0, oy, hardnessVal);
}
}
// 10. Marking Content
var markingText = bag.GetString(FeatureDrivenDrawer.KeyMarkingContent);
if (!string.IsNullOrWhiteSpace(markingText))
{
if (xInnerRight.HasValue)
{
double xTarget = (xInnerRight.Value + ox + W) / 2.0;
double yTarget = oy + H;
FeatureDrivenDrawer.DrawSpecialHBLeaderToTop(ctx, xTarget, yTarget, markingText);
}
else
{
FeatureDrivenDrawer.DrawSpecialHBLeaderToTop(ctx, ox + W / 2.0, oy + H, markingText);
}
}
}
}
}