746 lines
33 KiB
C#
746 lines
33 KiB
C#
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
|
||
}
|
||
}
|