321 lines
15 KiB
C#
321 lines
15 KiB
C#
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));
|
||
connectingLineTop.ColorIndex = 7; // White
|
||
ctx.Btr.AppendEntity(connectingLineTop);
|
||
ctx.Tr.AddNewlyCreatedDBObject(connectingLineTop, true);
|
||
|
||
var connectingLineBottom = new Line(new Point3d(lineStart, oy, 0), new Point3d(lineEnd, oy, 0));
|
||
connectingLineBottom.ColorIndex = 7; // White
|
||
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))
|
||
{
|
||
if (xInnerRight.HasValue)
|
||
{
|
||
double xStart = (xInnerRight.Value + ox + W) / 2.0;
|
||
double yStart = oy;
|
||
FeatureDrivenDrawer.DrawHardnessSymbol(ctx, xStart, yStart);
|
||
}
|
||
else
|
||
{
|
||
FeatureDrivenDrawer.DrawHardnessSymbol(ctx, ox + W / 2.0, oy);
|
||
}
|
||
}
|
||
|
||
// 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);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|