CadParamPluging/Cad/RingRawRollingDrawer.cs

746 lines
33 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

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

using System;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using CadParamPluging.Common;
namespace CadParamPluging.Cad
{
/// <summary>
/// 毛料态-轧制-环形 独立绘图器
/// </summary>
public static class RingRawRollingDrawer
{
#region Key常量
public const string KeyOuterDiameter1 = "OuterDiameter1";
public const string KeyOuterDiameter1TolPlus = "OuterDiameter1TolPlus";
public const string KeyOuterDiameter1TolMinus = "OuterDiameter1TolMinus";
public const string KeyInnerDiameter2 = "InnerDiameter2";
public const string KeyInnerDiameter2TolPlus = "InnerDiameter2TolPlus";
public const string KeyInnerDiameter2TolMinus = "InnerDiameter2TolMinus";
public const string KeyHeight1 = "Height1";
public const string KeyHeight1TolPlus = "Height1TolPlus";
public const string KeyHeight1TolMinus = "Height1TolMinus";
public const string KeyMinWallThickness = "MinWallThickness";
public const string KeyUnspecifiedFilletRadiusMax = "UnspecifiedFilletRadiusMax";
public const string KeyHardness = "Hardness";
public const string KeyOuterDiameter1Prime = "OuterDiameter1Prime";
public const string KeyInnerDiameter2Prime = "InnerDiameter2Prime";
public const string KeyHeight1Prime = "Height1Prime";
public const string KeyMarkingContent = "MarkingContent";
#endregion
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));
// 缩放处理
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;
}
var context = new FeatureDrivenDrawer.DrawingContext
{
Ctx = ctx,
Bag = effectiveBag,
OriginalBag = bag,
Center = center,
DeliveryStatus = "毛料态",
StructuralFeature = "环形",
ProcessMethod = "轧制",
Btr = btr,
Style = new DrawingStyleManager(db, tr)
};
var outerDia = effectiveBag.GetDoubleOrNull(KeyOuterDiameter1);
var height = effectiveBag.GetDoubleOrNull(KeyHeight1);
if (!outerDia.HasValue || outerDia.Value <= 0 || !height.HasValue || height.Value <= 0)
{
return;
}
// 始终使用"车加工"状态对应的视觉效果(即使是毛料态,为了绘图一致性,内部也视为有车加工参数)
// 在原始Generator中这通过CloneBagWithMachinedStatus实现。
// 这里我们直接在Drawer内部处理或者假设传入的bag已经是处理过的推荐
// 但为了完全独立,我们可以在这里临时设置 context 的 DeliveryStatus 为"车加工" 来触发相关视觉逻辑,
// 或者直接复制相关逻辑而不依赖 DeliveryStatus 字符串。
// 鉴于逻辑复用,我们这里显式设置 context.DeliveryStatus 为 "车加工"
// 因为 原来的 RingRawRollingGenerator 就是这么干的。
context.DeliveryStatus = "车加工";
// 调用核心绘制逻辑
// 此处传递 true 以启用 UnspecifiedFillet 逻辑 (与 FeatureDrivenDrawer.DrawRingRollingWithUnspecifiedFillet 保持一致)
DrawCore(context, outerDia.Value, height.Value, true);
}
private static void DrawCore(FeatureDrivenDrawer.DrawingContext ctx, double outerDia, double height, bool applyUnspecifiedFillet)
{
var bag = ctx.Bag;
// --- 几何与视觉映射计算 ---
double H = height;
double physicalOuterR = outerDia / 2.0;
double physicalInnerR = 0;
var innerDia = bag.GetDoubleOrNull(KeyInnerDiameter2);
if (innerDia.HasValue && innerDia.Value > 0)
{
physicalInnerR = innerDia.Value / 2.0;
}
// 1. 确定视觉半径
double visualOuterR = physicalOuterR;
double visualInnerR = physicalInnerR;
// 强制启用"示意图模式"逻辑 (原 IsMachined 判断)
// 因为在 RingRawRollingGenerator 中被强制设置了 "车加工"
if (true)
{
var minWallThkParam = bag.GetDoubleOrNull(KeyMinWallThickness);
if (minWallThkParam.HasValue && minWallThkParam.Value > 0)
{
visualInnerR = minWallThkParam.Value * 2.0;
visualOuterR = minWallThkParam.Value * 3.0;
}
else
{
visualOuterR = H * 3.0;
visualInnerR = visualOuterR * (2.0/3.0);
}
}
// 3. 定义半径映射函数
double MapRadius(double r)
{
if (r <= 0) return 0;
if (physicalInnerR <= 1e-6)
{
return r * (visualOuterR / physicalOuterR);
}
if (r <= physicalInnerR)
{
return r * (visualInnerR / physicalInnerR);
}
else
{
double wallScale = (visualOuterR - visualInnerR) / (physicalOuterR - physicalInnerR);
return visualInnerR + (r - physicalInnerR) * wallScale;
}
}
// --- 绘图坐标计算 ---
double ox = ctx.Center.X - visualOuterR / 2.0; // 对称轴位置
double oy = ctx.Center.Y - H / 2.0;
// 车加工态零件尺寸
double? outerDiaPrime = bag.GetDoubleOrNull(KeyOuterDiameter1Prime);
double? innerDiaPrime = bag.GetDoubleOrNull(KeyInnerDiameter2Prime);
double? heightPrime = bag.GetDoubleOrNull(KeyHeight1Prime);
// === 特征1: 锻件外轮廓 ===
var unspecifiedFillet = bag.GetDoubleOrNull(KeyUnspecifiedFilletRadiusMax);
bool hasUnspecifiedFillet = applyUnspecifiedFillet && unspecifiedFillet.HasValue && unspecifiedFillet.Value > 0;
if (!hasUnspecifiedFillet)
{
DrawForgingOuterContourHalf(ctx, ox, oy, visualOuterR, H, null);
}
// === 特征1.1: 对称轴 ===
DrawRingSymmetryAxis(ctx, ox, oy, H);
// === 特征2: 外径公差标注 ===
var outerTolPlus = bag.GetDoubleOrNull(KeyOuterDiameter1TolPlus);
var outerTolMinus = bag.GetDoubleOrNull(KeyOuterDiameter1TolMinus);
DrawOuterDiameterDimensionHalf(ctx, ox, oy, visualOuterR, H, outerDia, outerTolPlus, outerTolMinus, outerDiaPrime);
// === 特征3: 内孔/内径 ===
double? xInnerRight = null;
if (innerDia.HasValue && innerDia.Value > 0 && innerDia.Value < outerDia)
{
xInnerRight = ox + visualInnerR;
var innerTolPlus = bag.GetDoubleOrNull(KeyInnerDiameter2TolPlus);
var innerTolMinus = bag.GetDoubleOrNull(KeyInnerDiameter2TolMinus);
if (hasUnspecifiedFillet)
{
FeatureDrivenDrawer.DrawRingSectionContourWithFillet(ctx, xInnerRight.Value, ox + visualOuterR, oy, H, unspecifiedFillet.Value);
DrawHoleHorizontalLinesWithLeftExtension(ctx, ox, xInnerRight.Value, oy, H, unspecifiedFillet.Value);
var sectionWidth = (ox + visualOuterR) - (xInnerRight.Value);
var maxR = Math.Min(sectionWidth * 0.5, H * 0.5);
var r = Math.Min(unspecifiedFillet.Value, maxR);
var dimExtensionOffset = 0.0;
if (r > 0.01) dimExtensionOffset = r;
DrawInnerDiameterDimensionHalf(ctx, ox, xInnerRight.Value, oy, H, innerDia.Value, innerTolPlus, innerTolMinus, innerDiaPrime, dimExtensionOffset);
FeatureDrivenDrawer.DrawRingSectionHatchWithFillet(ctx, xInnerRight.Value, ox + visualOuterR, oy, H, unspecifiedFillet.Value);
}
else
{
DrawInnerHoleHalf(ctx, ox, xInnerRight.Value, oy, H);
DrawInnerDiameterDimensionHalf(ctx, ox, xInnerRight.Value, oy, H, innerDia.Value, innerTolPlus, innerTolMinus, innerDiaPrime);
FeatureDrivenDrawer.DrawRingSectionHatch(ctx, xInnerRight.Value, ox + visualOuterR, oy, H);
FeatureDrivenDrawer.DrawSectionInnerBoundaryBold(ctx, xInnerRight.Value, oy, H);
}
}
// === 特征5: 高度标注 ===
var heightTolPlus = bag.GetDoubleOrNull(KeyHeight1TolPlus);
var heightTolMinus = bag.GetDoubleOrNull(KeyHeight1TolMinus);
double heightDimIndentX = 0.0;
if (hasUnspecifiedFillet)
{
var sWidth = (ox + visualOuterR) - (xInnerRight.Value);
var maxR = Math.Min(sWidth * 0.5, H * 0.5);
var r = Math.Min(unspecifiedFillet.Value, maxR);
if (r > 0.01) heightDimIndentX = r;
}
DrawHeightDimensionHalf(ctx, ox, oy, visualOuterR, H, heightTolPlus, heightTolMinus, heightPrime, heightDimIndentX);
// === 特征6: 未注圆角 ===
// 针对“毛料态-轧制-环形”模板applyUnspecifiedFillet=true不显示此文字
if (!applyUnspecifiedFillet && unspecifiedFillet.HasValue && unspecifiedFillet.Value > 0)
{
FeatureDrivenDrawer.DrawUnspecifiedFilletNote(ctx, ox, oy, H, visualOuterR, unspecifiedFillet.Value);
}
// === 特征7: 最小壁厚min标注 ===
var minWallThickness = bag.GetDoubleOrNull(KeyMinWallThickness);
if (minWallThickness.HasValue && minWallThickness.Value > 0 && xInnerRight.HasValue)
{
var dimExtensionOffset = 0.0;
if (applyUnspecifiedFillet && unspecifiedFillet.HasValue)
{
var sWidth = Math.Abs((ox + visualOuterR) - (xInnerRight.Value));
var maxR = Math.Min(sWidth * 0.5, H * 0.5);
var rCalc = Math.Min(unspecifiedFillet.Value, maxR);
if (rCalc > 0.01) dimExtensionOffset = rCalc;
}
FeatureDrivenDrawer.DrawMinWallThicknessNote(ctx, xInnerRight.Value, ox + visualOuterR, oy, minWallThickness.Value, dimExtensionOffset);
}
// === 特征8: 零件轮廓(车加工态,右半边) ===
if (outerDiaPrime.HasValue && outerDiaPrime.Value > 0 && heightPrime.HasValue && heightPrime.Value > 0)
{
// 1. 外径
double physicalPartOuterR = outerDiaPrime.Value / 2.0;
double visualPartOuterR = MapRadius(physicalPartOuterR);
var scaledOuterDiaPrime = visualPartOuterR * 2.0;
// 2. 内径
double? scaledInnerDiaPrime = null;
if (innerDiaPrime.HasValue && innerDiaPrime.Value > 0)
{
double physicalPartInnerR = innerDiaPrime.Value / 2.0;
double visualPartInnerR = MapRadius(physicalPartInnerR);
scaledInnerDiaPrime = visualPartInnerR * 2.0;
}
// 3. 高度
var scaledHeightPrime = heightPrime.Value;
DrawPartContourHalf(ctx, ox, oy, H, scaledOuterDiaPrime, scaledInnerDiaPrime, scaledHeightPrime);
}
// === 特征10: 轧制+车加工 特殊引线标注 (HB5936-13) ===
if (innerDia.HasValue && innerDia.Value > 0)
{
var markingText = bag.GetString(KeyMarkingContent);
if (!string.IsNullOrWhiteSpace(markingText) || applyUnspecifiedFillet)
{
// 指向锻件顶部白色边框的中间位置
var xLoopInner = ox + visualInnerR;
var xLoopOuter = ox + visualOuterR;
var xTarget = (xLoopInner + xLoopOuter) / 2.0;
var yTarget = oy + H;
if (string.IsNullOrWhiteSpace(markingText))
{
markingText = "HB5936-13";
}
FeatureDrivenDrawer.DrawSpecialHBLeaderToTop(ctx, xTarget, yTarget, markingText);
}
else
{
var scaledInnerDia = visualInnerR * 2.0;
FeatureDrivenDrawer.DrawSpecialInnerHoleLeader(ctx, ox, oy, H, scaledInnerDia);
}
}
// === 特征9: 硬度符号 ===
var hardnessVal = bag.GetString(KeyHardness);
if (!string.IsNullOrWhiteSpace(hardnessVal) && hardnessVal != "空")
{
if (xInnerRight.HasValue)
{
double xStart = (xInnerRight.Value + ox + visualOuterR) / 2.0;
double yStart = oy;
FeatureDrivenDrawer.DrawHardnessSymbol(ctx, xStart, yStart, hardnessVal);
}
else
{
FeatureDrivenDrawer.DrawHardnessSymbol(ctx, ox + visualOuterR / 2.0, oy, hardnessVal);
}
}
}
#region
private static void DrawForgingOuterContourHalf(FeatureDrivenDrawer.DrawingContext ctx, double ox, double oy, double radius, double height, double? filletRadius)
{
var rawR = filletRadius.GetValueOrDefault();
if (rawR > 0)
{
var maxR = Math.Min(radius * 0.5, height * 0.5);
var r = Math.Min(rawR, maxR);
if (r > 0.01)
{
var bulge = Math.Tan(Math.PI / 8.0);
var polyFillet = new Polyline();
polyFillet.AddVertexAt(0, new Point2d(ox, oy), 0, 0, 0);
polyFillet.AddVertexAt(1, new Point2d(ox + radius - r, oy), bulge, 0, 0);
polyFillet.AddVertexAt(2, new Point2d(ox + radius, oy + r), 0, 0, 0);
polyFillet.AddVertexAt(3, new Point2d(ox + radius, oy + height - r), bulge, 0, 0);
polyFillet.AddVertexAt(4, new Point2d(ox + radius - r, oy + height), 0, 0, 0);
polyFillet.AddVertexAt(5, new Point2d(ox, oy + height), 0, 0, 0);
polyFillet.Closed = false;
ctx.Style?.Apply(polyFillet, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(polyFillet);
ctx.Tr.AddNewlyCreatedDBObject(polyFillet, true);
return;
}
}
DrawOpenHalfOutlineWithLeftExtension(ctx, ox, oy, radius, height);
}
private static void DrawRingSymmetryAxis(FeatureDrivenDrawer.DrawingContext ctx, double ox, double oy, double height)
{
const double extend = 5.0;
const double frameMargin = 5.0;
const double lineSpacing = 3.0;
var y0 = oy - extend;
var y1 = oy + height + extend;
try
{
var frameExtents = TemplateDrawingService.ComputeWhiteFrameExtents(ctx?.Ctx);
if (frameExtents.HasValue)
{
var frame = frameExtents.Value;
y0 = Math.Max(y0, frame.MinPoint.Y + frameMargin);
y1 = Math.Min(y1, frame.MaxPoint.Y - frameMargin);
}
}
catch { }
if (y1 <= y0)
{
y0 = oy;
y1 = oy + height;
}
var line1 = new Line(new Point3d(ox, y0, 0), new Point3d(ox, y1, 0));
ctx.Style?.Apply(line1, DrawingStyleManager.Role.BreakLine);
line1.LinetypeScale = 5.0;
ctx.Btr.AppendEntity(line1);
ctx.Tr.AddNewlyCreatedDBObject(line1, true);
var line2 = new Line(new Point3d(ox - lineSpacing, y0, 0), new Point3d(ox - lineSpacing, y1, 0));
ctx.Style?.Apply(line2, DrawingStyleManager.Role.BreakLine);
line2.LinetypeScale = 5.0;
ctx.Btr.AppendEntity(line2);
ctx.Tr.AddNewlyCreatedDBObject(line2, true);
}
private static void DrawHoleHorizontalLinesWithLeftExtension(FeatureDrivenDrawer.DrawingContext ctx, double xAxis, double xSectionLeft, double yBottom, double height, double filletR)
{
const double leftExtension = 10.0;
const double lineSpacing = 3.0;
var yTop = yBottom + height;
var maxR = Math.Min(100.0, height * 0.5);
var r = Math.Min(filletR, maxR);
var xTarget = r > 0.01 ? xSectionLeft + r : xSectionLeft;
var xLeft = xAxis - leftExtension;
DrawOutlineLine(ctx, xLeft, yBottom, xAxis - lineSpacing, yBottom);
DrawOutlineLine(ctx, xAxis, yBottom, xTarget, yBottom);
DrawOutlineLine(ctx, xLeft, yTop, xAxis - lineSpacing, yTop);
DrawOutlineLine(ctx, xAxis, yTop, xTarget, yTop);
DrawLeftCutCenterLine(ctx, xLeft, yBottom, height);
}
private static void DrawOpenHalfOutlineWithLeftExtension(FeatureDrivenDrawer.DrawingContext ctx, double ox, double oy, double radius, double height)
{
const double leftExtension = 10.0;
const double lineSpacing = 3.0;
var xLeft = ox - leftExtension;
var xBreakLeft = ox - lineSpacing;
var xRight = ox + radius;
var yTop = oy + height;
DrawOutlineLine(ctx, xLeft, oy, xBreakLeft, oy);
DrawOutlineLine(ctx, ox, oy, xRight, oy);
DrawOutlineLine(ctx, xRight, oy, xRight, yTop);
DrawOutlineLine(ctx, xRight, yTop, ox, yTop);
DrawOutlineLine(ctx, xBreakLeft, yTop, xLeft, yTop);
DrawLeftCutCenterLine(ctx, xLeft, oy, height);
}
private static void DrawOutlineLine(FeatureDrivenDrawer.DrawingContext ctx, double x1, double y1, double x2, double y2)
{
var line = new Line(new Point3d(x1, y1, 0), new Point3d(x2, y2, 0));
ctx.Style?.Apply(line, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(line);
ctx.Tr.AddNewlyCreatedDBObject(line, true);
}
private static void DrawLeftCutCenterLine(FeatureDrivenDrawer.DrawingContext ctx, double x, double yBottom, double height)
{
var yTop = yBottom + height;
var centerLine = new Line(new Point3d(x, yBottom - 5.0, 0), new Point3d(x, yTop + 5.0, 0));
ctx.Style?.Apply(centerLine, DrawingStyleManager.Role.Centerline);
centerLine.LinetypeScale = 8.0;
ctx.Btr.AppendEntity(centerLine);
ctx.Tr.AddNewlyCreatedDBObject(centerLine, true);
}
private static void DrawOuterDiameterDimensionHalf(FeatureDrivenDrawer.DrawingContext ctx, double ox, double oy, double radius, double height,
double diameter, double? tolPlus, double? tolMinus, double? diameterPrime)
{
var diameterVal = ctx.OriginalBag?.GetDoubleOrNull(KeyOuterDiameter1) ?? diameter;
var diameterStr = ctx.OriginalBag?.GetString(KeyOuterDiameter1);
var tolPlusVal = ctx.OriginalBag?.GetDoubleOrNull(KeyOuterDiameter1TolPlus) ?? tolPlus;
var tolMinusVal = ctx.OriginalBag?.GetDoubleOrNull(KeyOuterDiameter1TolMinus) ?? tolMinus;
var tolPlusStr = ctx.OriginalBag?.GetString(KeyOuterDiameter1TolPlus);
var tolMinusStr = ctx.OriginalBag?.GetString(KeyOuterDiameter1TolMinus);
var diameterPrimeVal = diameterPrime;
if (ctx.OriginalBag != null)
{
var p = ctx.OriginalBag.GetDoubleOrNull(KeyOuterDiameter1Prime);
if (p.HasValue) diameterPrimeVal = p.Value;
}
var baseText = FeatureDrivenDrawer.BuildDimensionText($"%%c{FeatureDrivenDrawer.FormatDimNumber(diameterVal, diameterStr)}", tolPlusVal, tolMinusVal, tolPlusStr, tolMinusStr);
var dimText = diameterPrimeVal.HasValue && diameterPrimeVal.Value > 0
? baseText + $"\\X(%%c{FeatureDrivenDrawer.FormatDimNumber(diameterPrimeVal.Value)})"
: baseText;
const double leftExtension = 10.0;
var xLeft = ox - leftExtension;
AddLinearDim(
ctx,
new Point3d(xLeft, oy, 0),
new Point3d(ox + radius, oy, 0),
new Point3d((xLeft + ox + radius) / 2.0, oy - 25, 0),
0,
dimText,
ApplyHalfSideDimStyle);
}
private static void DrawInnerHoleHalf(FeatureDrivenDrawer.DrawingContext ctx, double oxAxis, double xInnerRight, double yBottom, double height)
{
var yTop = yBottom + height;
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 DrawInnerDiameterDimensionHalf(FeatureDrivenDrawer.DrawingContext ctx, double oxAxis, double xInnerRight, double yBottom, double height,
double diameter, double? tolPlus, double? tolMinus, double? diameterPrime, double offsetY = 0)
{
var diameterVal = ctx.OriginalBag?.GetDoubleOrNull(KeyInnerDiameter2) ?? diameter;
var diameterStr = ctx.OriginalBag?.GetString(KeyInnerDiameter2);
var tolPlusVal = ctx.OriginalBag?.GetDoubleOrNull(KeyInnerDiameter2TolPlus) ?? tolPlus;
var tolMinusVal = ctx.OriginalBag?.GetDoubleOrNull(KeyInnerDiameter2TolMinus) ?? tolMinus;
var tolPlusStr = ctx.OriginalBag?.GetString(KeyInnerDiameter2TolPlus);
var tolMinusStr = ctx.OriginalBag?.GetString(KeyInnerDiameter2TolMinus);
var diameterPrimeVal = diameterPrime;
if (ctx.OriginalBag != null)
{
var p = ctx.OriginalBag.GetDoubleOrNull(KeyInnerDiameter2Prime);
if (p.HasValue) diameterPrimeVal = p.Value;
}
var baseText = FeatureDrivenDrawer.BuildDimensionText($"%%c{FeatureDrivenDrawer.FormatDimNumber(diameterVal, diameterStr)}", tolPlusVal, tolMinusVal, tolPlusStr, tolMinusStr);
var dimText = diameterPrimeVal.HasValue && diameterPrimeVal.Value > 0
? baseText + $"\\X(%%c{FeatureDrivenDrawer.FormatDimNumber(diameterPrimeVal.Value)})"
: baseText;
double innerRadius = xInnerRight - oxAxis;
var dimLineY = yBottom - 10;
const double leftExtension = 10.0;
var xLeft = oxAxis - leftExtension;
AddLinearDim(
ctx,
new Point3d(xLeft, yBottom, 0),
new Point3d(xInnerRight, yBottom + offsetY, 0),
new Point3d((xLeft + xInnerRight) / 2.0, dimLineY, 0),
0,
dimText,
ApplyHalfSideDimStyle);
}
private static void DrawHeightDimensionHalf(FeatureDrivenDrawer.DrawingContext ctx, double ox, double oy, double radius,
double height, double? tolPlus, double? tolMinus, double? heightPrime, double indentX = 0)
{
var heightVal = ctx.OriginalBag?.GetDoubleOrNull(KeyHeight1) ?? height;
var heightStr = ctx.OriginalBag?.GetString(KeyHeight1);
var tolPlusVal = ctx.OriginalBag?.GetDoubleOrNull(KeyHeight1TolPlus) ?? tolPlus;
var tolMinusVal = ctx.OriginalBag?.GetDoubleOrNull(KeyHeight1TolMinus) ?? tolMinus;
var tolPlusStr = ctx.OriginalBag?.GetString(KeyHeight1TolPlus);
var tolMinusStr = ctx.OriginalBag?.GetString(KeyHeight1TolMinus);
var heightPrimeVal = heightPrime;
if (ctx.OriginalBag != null)
{
var p = ctx.OriginalBag.GetDoubleOrNull(KeyHeight1Prime);
if (p.HasValue) heightPrimeVal = p.Value;
}
var baseText = FeatureDrivenDrawer.BuildDimensionText(FeatureDrivenDrawer.FormatDimNumber(heightVal, heightStr), tolPlusVal, tolMinusVal, tolPlusStr, tolMinusStr);
var dimText = heightPrimeVal.HasValue && heightPrimeVal.Value > 0
? baseText + $"\\X({FeatureDrivenDrawer.FormatDimNumber(heightPrimeVal.Value)})"
: baseText;
var xLine = ox + radius - indentX;
AddLinearDim(
ctx,
new Point3d(xLine, oy, 0),
new Point3d(xLine, oy + height, 0),
new Point3d(ox + radius + 20, oy + height / 2, 0),
90,
dimText);
}
private static void DrawPartContourHalf(FeatureDrivenDrawer.DrawingContext ctx, double ox, double oy, double forgingHeight,
double outerDiaPrime, double? innerDiaPrime, double heightPrime)
{
var Rp = outerDiaPrime / 2.0;
var h = heightPrime;
var offsetY = (forgingHeight - h) / 2.0;
var y0 = oy + offsetY;
double minX = ox;
if (innerDiaPrime.HasValue && innerDiaPrime.Value > 0)
{
minX = ox + innerDiaPrime.Value / 2.0;
}
double maxX = ox + Rp;
var polyPart = new Polyline();
polyPart.AddVertexAt(0, new Point2d(minX, y0), 0, 0, 0);
polyPart.AddVertexAt(1, new Point2d(maxX, y0), 0, 0, 0);
polyPart.AddVertexAt(2, new Point2d(maxX, y0 + h), 0, 0, 0);
polyPart.AddVertexAt(3, new Point2d(minX, y0 + h), 0, 0, 0);
polyPart.Closed = true;
ctx.Style?.Apply(polyPart, DrawingStyleManager.Role.PartContour);
ctx.Btr.AppendEntity(polyPart);
ctx.Tr.AddNewlyCreatedDBObject(polyPart, true);
}
private static void ApplyHalfSideDimStyle(Dimension dim, FeatureDrivenDrawer.DrawingContext ctx)
{
TrySetDimProp(dim, "Dimse1", true);
TrySetDimProp(dim, "Dimse2", false);
try
{
TrySetDimProp(dim, "Dimsah", true);
EnsureNoneBlock(ctx.Db, ctx.Tr);
var bt = (BlockTable)ctx.Tr.GetObject(ctx.Db.BlockTableId, OpenMode.ForRead);
if (bt.Has("_NONE"))
{
dim.Dimblk1 = bt["_NONE"];
}
}
catch { }
}
private static void EnsureNoneBlock(Database db, Transaction tr)
{
try
{
var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
if (!bt.Has("_NONE"))
{
using (var btr = new BlockTableRecord())
{
btr.Name = "_NONE";
btr.Origin = Point3d.Origin;
bt.UpgradeOpen();
bt.Add(btr);
tr.AddNewlyCreatedDBObject(btr, true);
}
}
}
catch { }
}
private static void AddLinearDim(FeatureDrivenDrawer.DrawingContext ctx, Point3d pt1, Point3d pt2, Point3d dimLinePt,
double rotationDeg, string textOverride, Action<Dimension, FeatureDrivenDrawer.DrawingContext> customizer = null)
{
try
{
var prevDb = HostApplicationServices.WorkingDatabase;
HostApplicationServices.WorkingDatabase = ctx.Db;
try
{
double rotRad = rotationDeg * Math.PI / 180.0;
var dim = new RotatedDimension(rotRad, pt1, pt2, dimLinePt, textOverride, ctx.Db.Dimstyle);
try { dim.SetDatabaseDefaults(); } catch { }
dim.ColorIndex = 3;
if (!string.IsNullOrEmpty(textOverride))
{
dim.DimensionText = textOverride;
}
try { dim.Normal = Vector3d.ZAxis; } catch { }
TryApplyDimSizeOverrides(dim);
TryApplyDimLayoutOverrides(dim);
customizer?.Invoke(dim, ctx);
ctx.Style?.Apply(dim, DrawingStyleManager.Role.Dimension);
dim.ColorIndex = 3;
ctx.Btr.AppendEntity(dim);
ctx.Tr.AddNewlyCreatedDBObject(dim, true);
try { dim.RecomputeDimensionBlock(true); } catch { }
}
finally
{
HostApplicationServices.WorkingDatabase = prevDb;
}
}
catch { }
}
private static void TryApplyDimSizeOverrides(Dimension dim)
{
if (dim == null) return;
TrySetDimProp(dim, "Dimtxt", 3.5);
TrySetDimProp(dim, "Dimasz", 2.5);
TrySetDimProp(dim, "Dimgap", 1.0);
TrySetDimProp(dim, "Dimexe", 1.0);
TrySetDimProp(dim, "Dimexo", 0.0);
TrySetDimProp(dim, "Dimtofl", true);
TrySetDimProp(dim, "Dimatfit", 3);
TrySetDimProp(dim, "Dimtad", 1);
TrySetDimProp(dim, "Dimclrd", 3);
TrySetDimProp(dim, "Dimclre", 3);
TrySetDimProp(dim, "Dimclrt", 3);
}
private static void TryApplyDimLayoutOverrides(Dimension dim)
{
if (dim == null) return;
TrySetDimProp(dim, "Dimtih", false);
TrySetDimProp(dim, "Dimtoh", false);
TrySetDimProp(dim, "Dimse1", false);
TrySetDimProp(dim, "Dimse2", false);
}
private static void TrySetDimProp(object obj, string propName, double value)
{
if (obj == null) return;
try
{
var prop = obj.GetType().GetProperty(propName);
if (prop != null && prop.CanWrite && prop.PropertyType == typeof(double))
prop.SetValue(obj, value, null);
}
catch { }
}
private static void TrySetDimProp(object obj, string propName, bool value)
{
if (obj == null) return;
try
{
var prop = obj.GetType().GetProperty(propName);
if (prop != null && prop.CanWrite && prop.PropertyType == typeof(bool))
prop.SetValue(obj, value, null);
}
catch { }
}
private static void TrySetDimProp(object obj, string propName, int value)
{
if (obj == null) return;
try
{
var prop = obj.GetType().GetProperty(propName);
if (prop != null && prop.CanWrite && prop.PropertyType == typeof(int))
prop.SetValue(obj, value, null);
}
catch { }
}
private static ParamBag ScaleParamBag(ParamBag original, double scaleFactor)
{
if (original == null || Math.Abs(scaleFactor - 1.0) < 0.000001) return original;
var newBag = new ParamBag();
foreach(var k in original.GetKeys())
{
var v = original.GetString(k);
if (k.Contains("Diameter") || k.Contains("Length") || k.Contains("Radius") || k.Contains("Prime") || k.Contains("Height") || k.Contains("Thickness") || k.Contains("Size"))
{
if (double.TryParse(v, out var d))
{
newBag.Set(k, (d * scaleFactor).ToString("0.###"));
}
else { newBag.Set(k, v); }
}
else { newBag.Set(k, v); }
}
return newBag;
}
#endregion
}
}