CadParamPluging/Cad/RingMachinedRollingDrawer.cs

859 lines
37 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 System.Collections.Generic;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using CadParamPluging.Common;
namespace CadParamPluging.Cad
{
/// <summary>
/// 车加工-轧制-环形 独立绘图器
/// 物理隔离的绘图逻辑,不依赖 FeatureDrivenDrawer 的具体实现(除了部分通用工具方法)
/// </summary>
public static class RingMachinedRollingDrawer
{
#region Key常量 ( FeatureDrivenDrawer )
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 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;
}
// 调用核心绘制逻辑
// 此处传递 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;
// 轧制+车加工(示意图模式)特殊处理
if (ctx.IsMachined)
{
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 = null;
double? innerDiaPrime = null;
double? heightPrime = null;
if (ctx.IsMachined)
{
outerDiaPrime = bag.GetDoubleOrNull(KeyOuterDiameter1Prime);
innerDiaPrime = bag.GetDoubleOrNull(KeyInnerDiameter2Prime);
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: 未注圆角 ===
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 (ctx.IsMachined && 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 (ctx.IsMachined && innerDia.HasValue && innerDia.Value > 0)
{
// 指向锻件内孔右上角
DrawSpecialInnerHoleLeader(ctx, ox, oy, H, visualInnerR);
}
// === 特征9: 硬度符号 (HB) ===
// 【已移除】按用户需求,此模板不绘制红色方框中的硬度符号
// === 特征11: 粗糙度符号 (右上角) ===
var roughnessVal = bag.GetString("SurfaceRoughness");
if (!string.IsNullOrWhiteSpace(roughnessVal) && roughnessVal != "空")
{
DrawAllRoughnessSymbol(ctx, roughnessVal);
}
}
private static void DrawAllRoughnessSymbol(FeatureDrivenDrawer.DrawingContext ctx, string value)
{
try
{
// 获取整个模板右上方坐标
double maxX = 0;
double maxY = 0;
var frameExtents = TemplateDrawingService.ComputeWhiteFrameExtents(ctx?.Ctx);
if (frameExtents.HasValue)
{
maxX = frameExtents.Value.MaxPoint.X;
maxY = frameExtents.Value.MaxPoint.Y;
}
else
{
// Fallback, 以中心+200估算
maxX = ctx.Center.X + 200;
maxY = ctx.Center.Y + 200;
}
// 定位:距离右上角内缩一定边距,调整为更靠近右上角 (5.0)
double pRightX = maxX - 5.0;
double pTopY = maxY - 5.0;
double hTotal = 11.0;
double hTriangle = 5.5;
double dxTotal = hTotal * Math.Tan(30.0 * Math.PI / 180.0);
double originX = pRightX - dxTotal;
double originY = pTopY - hTotal;
var p0 = new Point3d(originX, originY, 0);
double dxTriangle = hTriangle * Math.Tan(30.0 * Math.PI / 180.0);
var p1 = new Point3d(originX - dxTriangle, originY + hTriangle, 0);
var p2 = new Point3d(originX + dxTriangle, originY + hTriangle, 0);
var p3 = new Point3d(pRightX, pTopY, 0);
var line1 = new Line(p1, p0);
var line2 = new Line(p0, p3);
var line3 = new Line(p1, p2);
line1.ColorIndex = 7; // White
line2.ColorIndex = 7;
line3.ColorIndex = 7;
ctx.Btr.AppendEntity(line1);
ctx.Tr.AddNewlyCreatedDBObject(line1, true);
ctx.Btr.AppendEntity(line2);
ctx.Tr.AddNewlyCreatedDBObject(line2, true);
ctx.Btr.AppendEntity(line3);
ctx.Tr.AddNewlyCreatedDBObject(line3, true);
// 粗糙度数值 (如1.6)
var textVal = new DBText();
textVal.TextString = value;
textVal.Height = 3.5;
textVal.ColorIndex = 7;
textVal.HorizontalMode = TextHorizontalMode.TextCenter;
textVal.VerticalMode = TextVerticalMode.TextBottom;
textVal.AlignmentPoint = new Point3d(originX, originY + hTriangle + 1.0, 0);
textVal.Position = textVal.AlignmentPoint;
ctx.Btr.AppendEntity(textVal);
ctx.Tr.AddNewlyCreatedDBObject(textVal, true);
// “所有”文本
var textAll = new DBText();
textAll.TextString = "所有";
textAll.Height = 3.5;
textAll.ColorIndex = 7;
textAll.HorizontalMode = TextHorizontalMode.TextRight;
textAll.VerticalMode = TextVerticalMode.TextVerticalMid;
// 向左偏移一点,中心对齐三角线高度
textAll.AlignmentPoint = new Point3d(p1.X - 2.0, originY + hTriangle, 0);
textAll.Position = textAll.AlignmentPoint;
ctx.Btr.AppendEntity(textAll);
ctx.Tr.AddNewlyCreatedDBObject(textAll, true);
}
catch { }
}
private static void DrawSpecialInnerHoleLeader(FeatureDrivenDrawer.DrawingContext ctx, double ox, double oy, double height, double visualInnerR)
{
try
{
// 内孔右侧X坐标 (锻件)
double xInner = ox + visualInnerR;
// 目标Y坐标锻件内孔右上角向下偏移一点 (引线不应直指角点,而是指在直线上)
double yTarget = oy + height - 5.0;
// 箭头点 (指向内孔竖线)
var p1 = new Point3d(xInner, yTarget, 0);
// 转折点 (向左上)
var p2 = new Point3d(xInner - 12, yTarget + 12, 0);
// 终点 (水平向左, 长度约35适配文字宽度 "HB5936-13")
var p3 = new Point3d(p2.X - 35, p2.Y, 0);
// 使用 Leader 实体绘制带箭头的引线
var leader = new Leader();
leader.SetDatabaseDefaults();
leader.AppendVertex(p1);
leader.AppendVertex(p2);
leader.AppendVertex(p3);
leader.HasArrowHead = true;
leader.ColorIndex = 7; // 白色
leader.Layer = "0";
ctx.Btr.AppendEntity(leader);
ctx.Tr.AddNewlyCreatedDBObject(leader, true);
// 绘制文字
var text = new DBText();
text.TextString = "HB5936-13";
text.Height = 3.5;
text.ColorIndex = 7; // 白色
text.Layer = "0";
// 文字位置:左对齐,基点为 p3 (线段最左端)
// 位于线段上方 (VerticalMode = TextBottom)
text.HorizontalMode = TextHorizontalMode.TextLeft;
text.VerticalMode = TextVerticalMode.TextBottom;
text.AlignmentPoint = new Point3d(p3.X, p3.Y + 1.0, 0);
text.Position = text.AlignmentPoint;
ctx.Btr.AppendEntity(text);
ctx.Tr.AddNewlyCreatedDBObject(text, true);
}
catch
{
// ignore
}
}
#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;
FeatureDrivenDrawer.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);
}
#endregion
#region ( FeatureDrivenDrawer )
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
}
}