CadParamPluging/Cad/BlockRawFreeForgeRoundHeadDrawer.cs

772 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 System.Collections.Generic;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using CadParamPluging.Common;
namespace CadParamPluging.Cad
{
public static class BlockRawFreeForgeRoundHeadDrawer
{
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 = "方体",
SpecialCondition = "有圆头",
ProcessMethod = "自由锻",
Btr = btr,
Style = new DrawingStyleManager(db, tr)
};
DrawBlockRawFreeForgeRoundHeadCore(context);
}
private static void DrawBlockRawFreeForgeRoundHeadCore(FeatureDrivenDrawer.DrawingContext ctx)
{
var bag = ctx.Bag;
// BoxSize1 (Width - 总长度)
// BoxSize2 (Height - 高度/直径)
var width = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxSize1);
var height = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxSize2);
if (!width.HasValue || width.Value <= 0 || !height.HasValue || height.Value <= 0)
{
return;
}
double H = height.Value;
double W = width.Value;
// 外轮廓圆弧:高度固定为 H/5
// 依据用户新需求 (2026-01-29): 黄色部分(圆弧高)是粉色部分(总高H)的1/5
double arcHeight = H / 5.0;
// 视觉比例:总宽度映射
double visualTotalW = H * 3.0; // 保持视觉宽高比约 3:1
// 绘图坐标计算 (保持居中)
double ox = ctx.Center.X - visualTotalW / 2.0; // 左边界 (圆弧最左端)
double oy = ctx.Center.Y - H / 2.0; // 底边
// 内框边界(从左圆弧弦线到右圆弧弦线)
// 注意ox 是圆弧顶点xInnerLeft 应该是弦线位置
double xInnerLeft = ox + arcHeight;
double xInnerRight = ox + visualTotalW - arcHeight;
double innerWidth = xInnerRight - xInnerLeft;
// 获取圆头处圆角半径 (BoxRoundHeadFilletRadiusMax) - 用于外侧圆角
// 依据用户需求:外侧圆角由“圆头处圆角半径”控制
var headFilletParam = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxRoundHeadFilletRadiusMax);
double headFilletR = headFilletParam.HasValue && headFilletParam.Value > 0
? headFilletParam.Value
: 0;
// 获取内框圆角参数:优先取 UnspecifiedFilletRadiusMax如果没有则取 BoxFilletRadiusMax - 用于内部剖面
var innerFilletParam = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyUnspecifiedFilletRadiusMax);
if (!innerFilletParam.HasValue || innerFilletParam.Value <= 0)
{
innerFilletParam = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxFilletRadiusMax);
}
double sectionFilletR = innerFilletParam.HasValue && innerFilletParam.Value > 0
? innerFilletParam.Value
: 0;
// 1. 绘制完整锻件外轮廓(方体有圆头 - 白色,大圆弧)
// 修正:圆弧弦线需向内缩进 headFilletR (原 logic 使用 innerFilletR),以与锻件外侧圆角起点对齐
DrawBlockRoundHeadOutline(ctx, ox, oy, visualTotalW, H, arcHeight, headFilletR);
// 2. 绘制分段式内框(左、中、右三段)以支持中间剖面区域的独立圆角
// 中间区域(剖面)作为主体,如果设置了圆角,四个角都应为圆角
// 计算视觉上的剖面宽度
// 依据用户需求尺寸3 (BoxSize3) 对应剖面的宽
var size3 = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxSize3);
double visualSectionWidth;
if (size3.HasValue && size3.Value > 0)
{
// 按比例映射VisualW / PhysicalW
double scale = visualTotalW / W;
visualSectionWidth = size3.Value * scale;
// 限制最大宽度,防止出错
if (visualSectionWidth > innerWidth * 0.95)
{
visualSectionWidth = innerWidth * 0.95;
}
}
else
{
// 降级策略
visualSectionWidth = innerWidth / 3.0;
}
// 居中布置剖面
double sectionOffset = (innerWidth - visualSectionWidth) / 2.0;
double xSectionLeft = xInnerLeft + sectionOffset;
double xSectionRight = xSectionLeft + visualSectionWidth;
// 绘制中间剖面框(带圆角)
// 使用 sectionFilletR
DrawBoxSectionContourWithFillet(ctx, xSectionLeft, xSectionRight, oy, H, sectionFilletR);
// 绘制左侧框线(连接左端圆弧和中间剖面框)
// 左端: xInnerLeft (需处理左上下角的圆角 - 使用 headFilletR)
// 右端: xSectionLeft (连接到中间框的直边)
DrawBoxSideFrame(ctx, xInnerLeft, xSectionLeft, oy, H, headFilletR, isLeft: true);
// 绘制右侧框线
// 左端: xSectionRight (连接到中间框的直边)
// 右端: xInnerRight (需处理右上下角的圆角 - 使用 headFilletR)
DrawBoxSideFrame(ctx, xSectionRight, xInnerRight, oy, H, headFilletR, isLeft: false);
// 3. 剖面填充 - 只在中间区域
// 使用 sectionFilletR
if (sectionFilletR > 0.01)
{
DrawRingSectionHatchWithFillet(ctx, xSectionLeft, xSectionRight, oy, H, sectionFilletR);
}
else
{
DrawBlockSectionHatch(ctx, xSectionLeft, xSectionRight, oy, H);
}
// 5. 零件轮廓框(黄色双点划线矩形 - 在内框内,与锻件有一定间距)
var widthPrime = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxSize1Prime);
var heightPrime = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxSize2Prime);
if (widthPrime.HasValue && widthPrime.Value > 0 && heightPrime.HasValue && heightPrime.Value > 0)
{
double partH = heightPrime.Value;
double partW = widthPrime.Value;
// 计算零件在视觉上的宽度比例
double partWidthRatio = partW / W;
double visualPartW = innerWidth * partWidthRatio;
if (visualPartW > innerWidth) visualPartW = innerWidth * 0.9;
// 零件在锻件内居中
double partOffsetX = (innerWidth - visualPartW) / 2.0;
double partOffsetY = (H - partH) / 2.0;
double xPartLeft = xInnerLeft + partOffsetX;
double yPartBottom = oy + partOffsetY;
DrawBlockPartContour(ctx, xPartLeft, yPartBottom, visualPartW, partH);
}
// 6. 宽度标注 (BoxSize1) - 位于底部
// 标注从锻件最左端到最右端 (BoxSize1 对应 锻件总宽)
{
var val = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxSize1) ?? W;
var str = ctx.OriginalBag?.GetString(FeatureDrivenDrawer.KeyBoxSize1);
var tolPlus = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxSize1TolPlus);
var tolMinus = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxSize1TolMinus);
var tolPlusStr = ctx.OriginalBag?.GetString(FeatureDrivenDrawer.KeyBoxSize1TolPlus);
var tolMinusStr = ctx.OriginalBag?.GetString(FeatureDrivenDrawer.KeyBoxSize1TolMinus);
var dimText = FeatureDrivenDrawer.BuildDimensionText(FeatureDrivenDrawer.FormatDimNumber(val, str), tolPlus, tolMinus, tolPlusStr, tolMinusStr);
// 添加零件尺寸 (Prime) 到下方,用括号包裹
var valPrime = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxSize1Prime);
if (valPrime.HasValue && valPrime.Value > 0)
{
dimText += $"\\X({FeatureDrivenDrawer.FormatDimNumber(valPrime.Value, null)})";
}
// 修正:标注需涵盖内框宽度 (矩形部分)
// 修正:引线起点改为内框边界 (xInnerLeft/Right) 和高度底部上移圆角半径,确保闭合到白色线框
// 使用 headFilletR 作为 Offset因为这是侧边框的倒角
double dimOriginY = oy + headFilletR;
AddLinearDim(
ctx,
new Point3d(xInnerLeft, dimOriginY, 0),
new Point3d(xInnerRight, dimOriginY, 0),
new Point3d((xInnerLeft + xInnerRight) / 2, oy - 25, 0),
0,
dimText);
}
// 7. 高度标注 (BoxSize2) - 位于右侧
// 标注从锻件顶部到底部
{
var val = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxSize2) ?? H;
var str = ctx.OriginalBag?.GetString(FeatureDrivenDrawer.KeyBoxSize2);
var tolPlus = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxSize2TolPlus);
var tolMinus = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxSize2TolMinus);
var tolPlusStr = ctx.OriginalBag?.GetString(FeatureDrivenDrawer.KeyBoxSize2TolPlus);
var tolMinusStr = ctx.OriginalBag?.GetString(FeatureDrivenDrawer.KeyBoxSize2TolMinus);
var dimText = FeatureDrivenDrawer.BuildDimensionText(FeatureDrivenDrawer.FormatDimNumber(val, str), tolPlus, tolMinus, tolPlusStr, tolMinusStr);
// 添加零件尺寸 (Prime) 到下方
var valPrime = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxSize2Prime);
if (valPrime.HasValue && valPrime.Value > 0)
{
dimText += $"\\X({FeatureDrivenDrawer.FormatDimNumber(valPrime.Value, null)})";
}
// 标注从圆弧最外侧开始(避免与圆弧轮廓线重叠)
double xOuterRight = ox + visualTotalW;
// 修正:标注界线起点应从圆弧顶端开始,往内缩进一个圆弧高度 arcHeight + headFilletR定位在弦线上
double xDimOrigin = xOuterRight - (arcHeight + headFilletR);
AddLinearDim(
ctx,
new Point3d(xDimOrigin, oy, 0),
new Point3d(xDimOrigin, oy + H, 0),
new Point3d(xOuterRight + 20, oy + H / 2, 0),
90,
dimText);
}
// 8. 中间矩形宽度标注 (BoxSize3) - 位于上方
// 对应剖面区域宽度
{
var val = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxSize3) ?? 0;
var str = ctx.OriginalBag?.GetString(FeatureDrivenDrawer.KeyBoxSize3);
// 只有当有值时才标注
if (val > 0)
{
var tolPlus = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxSize3TolPlus);
var tolMinus = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxSize3TolMinus);
var tolPlusStr = ctx.OriginalBag?.GetString(FeatureDrivenDrawer.KeyBoxSize3TolPlus);
var tolMinusStr = ctx.OriginalBag?.GetString(FeatureDrivenDrawer.KeyBoxSize3TolMinus);
var dimText = FeatureDrivenDrawer.BuildDimensionText(FeatureDrivenDrawer.FormatDimNumber(val, str), tolPlus, tolMinus, tolPlusStr, tolMinusStr);
// 添加零件尺寸 (Prime) 到下方
var valPrime = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeyBoxSize3Prime);
if (valPrime.HasValue && valPrime.Value > 0)
{
dimText += $"\\X({FeatureDrivenDrawer.FormatDimNumber(valPrime.Value, null)})";
}
AddLinearDim(
ctx,
new Point3d(xSectionLeft, oy + H, 0),
new Point3d(xSectionRight, oy + H, 0),
new Point3d((xSectionLeft + xSectionRight) / 2, oy + H + 15, 0),
0,
dimText);
}
}
// 9. 硬度符号 - 从剖面底部引出
var hardnessVal = bag.GetString(FeatureDrivenDrawer.KeyHardness);
if (!string.IsNullOrWhiteSpace(hardnessVal))
{
double xStart = (xSectionLeft + xSectionRight) / 2.0;
double yStart = oy;
DrawHardnessSymbol(ctx, xStart, yStart);
}
// 10. 标刻内容引线 - 从剖面顶部引出
var markingText = bag.GetString(FeatureDrivenDrawer.KeyMarkingContent);
if (!string.IsNullOrWhiteSpace(markingText))
{
double xTarget = (xSectionLeft + xSectionRight) / 2.0;
double yTarget = oy + H;
DrawSpecialHBLeaderToTop(ctx, xTarget, yTarget, markingText);
}
}
private static void DrawBlockRoundHeadOutline(FeatureDrivenDrawer.DrawingContext ctx, double ox, double oy, double totalWidth, double height, double arcHeight, double innerFilletR)
{
try
{
double H = height;
double r = innerFilletR;
double xCurrentLeft = ox + arcHeight + r;
double xCurrentRight = ox + totalWidth - arcHeight - r;
double sagitta = arcHeight + r;
double halfChord = H / 2.0;
double bulge = 0;
if (halfChord > 1e-3)
{
bulge = -(sagitta / halfChord);
}
var poly = new Polyline();
poly.AddVertexAt(0, new Point2d(xCurrentRight, oy), 0, 0, 0);
poly.AddVertexAt(1, new Point2d(xCurrentLeft, oy), bulge, 0, 0);
poly.AddVertexAt(2, new Point2d(xCurrentLeft, oy + H), 0, 0, 0);
poly.AddVertexAt(3, new Point2d(xCurrentRight, oy + H), bulge, 0, 0);
poly.Closed = true;
ctx.Style?.Apply(poly, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
}
catch { }
}
private static void DrawBoxSectionContourWithFillet(FeatureDrivenDrawer.DrawingContext ctx, double xLeft, double xRight, double yBottom, double height, double filletR)
{
var yTop = yBottom + height;
var width = xRight - xLeft;
var maxR = Math.Min(width * 0.5, height * 0.5);
var r = Math.Min(filletR, maxR);
if (r <= 0.01)
{
var poly = new Polyline();
poly.AddVertexAt(0, new Point2d(xLeft, yBottom), 0, 0, 0);
poly.AddVertexAt(1, new Point2d(xRight, yBottom), 0, 0, 0);
poly.AddVertexAt(2, new Point2d(xRight, yTop), 0, 0, 0);
poly.AddVertexAt(3, new Point2d(xLeft, yTop), 0, 0, 0);
poly.Closed = true;
ctx.Style?.Apply(poly, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
return;
}
var bulge = Math.Tan(Math.PI / 8.0);
var polyFillet = new Polyline();
polyFillet.AddVertexAt(0, new Point2d(xLeft + r, yBottom), 0, 0, 0);
polyFillet.AddVertexAt(1, new Point2d(xRight - r, yBottom), bulge, 0, 0);
polyFillet.AddVertexAt(2, new Point2d(xRight, yBottom + r), 0, 0, 0);
polyFillet.AddVertexAt(3, new Point2d(xRight, yTop - r), bulge, 0, 0);
polyFillet.AddVertexAt(4, new Point2d(xRight - r, yTop), 0, 0, 0);
polyFillet.AddVertexAt(5, new Point2d(xLeft + r, yTop), bulge, 0, 0);
polyFillet.AddVertexAt(6, new Point2d(xLeft, yTop - r), 0, 0, 0);
polyFillet.AddVertexAt(7, new Point2d(xLeft, yBottom + r), bulge, 0, 0);
polyFillet.Closed = true;
ctx.Style?.Apply(polyFillet, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(polyFillet);
ctx.Tr.AddNewlyCreatedDBObject(polyFillet, true);
}
private static void DrawBoxSideFrame(FeatureDrivenDrawer.DrawingContext ctx, double xStart, double xEnd, double yBottom, double height, double filletR, bool isLeft)
{
var yTop = yBottom + height;
var width = Math.Abs(xEnd - xStart);
if (width < 0.1) return;
var maxR = Math.Min(width * 0.5, height * 0.5);
var r = Math.Min(filletR, maxR);
var bulge = -Math.Tan(Math.PI / 8.0);
var poly = new Polyline();
if (isLeft)
{
poly.AddVertexAt(0, new Point2d(xEnd, yBottom), 0, 0, 0);
if (r > 0.01)
{
poly.AddVertexAt(1, new Point2d(xStart + r, yBottom), bulge, 0, 0);
poly.AddVertexAt(2, new Point2d(xStart, yBottom + r), 0, 0, 0);
poly.AddVertexAt(3, new Point2d(xStart, yTop - r), bulge, 0, 0);
poly.AddVertexAt(4, new Point2d(xStart + r, yTop), 0, 0, 0);
poly.AddVertexAt(5, new Point2d(xEnd, yTop), 0, 0, 0);
}
else
{
poly.AddVertexAt(1, new Point2d(xStart, yBottom), 0, 0, 0);
poly.AddVertexAt(2, new Point2d(xStart, yTop), 0, 0, 0);
poly.AddVertexAt(3, new Point2d(xEnd, yTop), 0, 0, 0);
}
poly.Closed = false;
}
else
{
poly.AddVertexAt(0, new Point2d(xStart, yTop), 0, 0, 0);
if (r > 0.01)
{
poly.AddVertexAt(1, new Point2d(xEnd - r, yTop), bulge, 0, 0);
poly.AddVertexAt(2, new Point2d(xEnd, yTop - r), 0, 0, 0);
poly.AddVertexAt(3, new Point2d(xEnd, yBottom + r), bulge, 0, 0);
poly.AddVertexAt(4, new Point2d(xEnd - r, yBottom), 0, 0, 0);
poly.AddVertexAt(5, new Point2d(xStart, yBottom), 0, 0, 0);
}
else
{
poly.AddVertexAt(1, new Point2d(xEnd, yTop), 0, 0, 0);
poly.AddVertexAt(2, new Point2d(xEnd, yBottom), 0, 0, 0);
poly.AddVertexAt(3, new Point2d(xStart, yBottom), 0, 0, 0);
}
poly.Closed = false;
}
ctx.Style?.Apply(poly, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
}
private static void DrawRingSectionHatchWithFillet(FeatureDrivenDrawer.DrawingContext ctx, double xInnerRight, double xOuterRight, double yBottom, double height, double filletR)
{
if (xOuterRight <= xInnerRight)
{
return;
}
var availableWidth = xOuterRight - xInnerRight;
var maxR = Math.Min(availableWidth * 0.5, height * 0.5);
var r = Math.Min(filletR, maxR);
if (r <= 0.01)
{
DrawBlockSectionHatch(ctx, xInnerRight, xOuterRight, yBottom, height);
return;
}
try
{
var yTop = yBottom + height;
var bulge = Math.Tan(Math.PI / 8.0);
var boundary = new Polyline();
boundary.AddVertexAt(0, new Point2d(xInnerRight + r, yBottom), 0, 0, 0);
boundary.AddVertexAt(1, new Point2d(xOuterRight - r, yBottom), bulge, 0, 0);
boundary.AddVertexAt(2, new Point2d(xOuterRight, yBottom + r), 0, 0, 0);
boundary.AddVertexAt(3, new Point2d(xOuterRight, yTop - r), bulge, 0, 0);
boundary.AddVertexAt(4, new Point2d(xOuterRight - r, yTop), 0, 0, 0);
boundary.AddVertexAt(5, new Point2d(xInnerRight + r, yTop), bulge, 0, 0);
boundary.AddVertexAt(6, new Point2d(xInnerRight, yTop - r), 0, 0, 0);
boundary.AddVertexAt(7, new Point2d(xInnerRight, yBottom + r), bulge, 0, 0);
boundary.Closed = true;
ctx.Btr.AppendEntity(boundary);
ctx.Tr.AddNewlyCreatedDBObject(boundary, true);
var hatch = new Hatch();
hatch.SetDatabaseDefaults();
hatch.Normal = new Vector3d(0, 0, 1);
hatch.Elevation = 0.0;
ctx.Btr.AppendEntity(hatch);
ctx.Tr.AddNewlyCreatedDBObject(hatch, true);
hatch.SetHatchPattern(HatchPatternType.PreDefined, "ANSI31");
hatch.PatternScale = 10;
hatch.PatternAngle = 0;
hatch.Associative = false;
ctx.Style?.Apply(hatch, DrawingStyleManager.Role.Hatch);
var ids = new ObjectIdCollection();
ids.Add(boundary.ObjectId);
hatch.AppendLoop(HatchLoopTypes.External, ids);
hatch.EvaluateHatch(true);
try
{
boundary.Erase(true);
}
catch { }
}
catch { }
}
private static void DrawBlockSectionHatch(FeatureDrivenDrawer.DrawingContext ctx, double xLeft, double xRight, double yBottom, double height)
{
if (xRight <= xLeft)
{
return;
}
try
{
var boundary = new Polyline();
boundary.AddVertexAt(0, new Point2d(xLeft, yBottom), 0, 0, 0);
boundary.AddVertexAt(1, new Point2d(xRight, yBottom), 0, 0, 0);
boundary.AddVertexAt(2, new Point2d(xRight, yBottom + height), 0, 0, 0);
boundary.AddVertexAt(3, new Point2d(xLeft, yBottom + height), 0, 0, 0);
boundary.Closed = true;
ctx.Btr.AppendEntity(boundary);
ctx.Tr.AddNewlyCreatedDBObject(boundary, true);
var hatch = new Hatch();
hatch.SetDatabaseDefaults();
hatch.Normal = new Vector3d(0, 0, 1);
hatch.Elevation = 0.0;
ctx.Btr.AppendEntity(hatch);
ctx.Tr.AddNewlyCreatedDBObject(hatch, true);
hatch.SetHatchPattern(HatchPatternType.PreDefined, "ANSI31");
hatch.PatternScale = 10;
hatch.PatternAngle = 0;
hatch.Associative = false;
ctx.Style?.Apply(hatch, DrawingStyleManager.Role.Hatch);
var ids = new ObjectIdCollection();
ids.Add(boundary.ObjectId);
hatch.AppendLoop(HatchLoopTypes.External, ids);
hatch.EvaluateHatch(true);
try
{
boundary.Erase(true);
}
catch { }
}
catch { }
}
private static void DrawBlockPartContour(FeatureDrivenDrawer.DrawingContext ctx, double x, double y, double width, double height)
{
try
{
var poly = new Polyline();
poly.AddVertexAt(0, new Point2d(x, y), 0, 0, 0);
poly.AddVertexAt(1, new Point2d(x + width, y), 0, 0, 0);
poly.AddVertexAt(2, new Point2d(x + width, y + height), 0, 0, 0);
poly.AddVertexAt(3, new Point2d(x, y + height), 0, 0, 0);
poly.Closed = true;
ctx.Style?.Apply(poly, DrawingStyleManager.Role.PartContour);
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
}
catch { }
}
private static void DrawHardnessSymbol(FeatureDrivenDrawer.DrawingContext ctx, double xStart, double yStart)
{
try
{
var p1 = new Point3d(xStart, yStart, 0);
var p2 = new Point3d(xStart + 15, yStart - 15, 0);
var p3 = new Point3d(p2.X + 10, p2.Y, 0);
var poly = new Polyline();
poly.AddVertexAt(0, new Point2d(p1.X, p1.Y), 0, 0, 0);
poly.AddVertexAt(1, new Point2d(p2.X, p2.Y), 0, 0, 0);
poly.AddVertexAt(2, new Point2d(p3.X, p3.Y), 0, 0, 0);
ctx.Style?.Apply(poly, DrawingStyleManager.Role.Dimension);
poly.ColorIndex = 3;
ctx.Btr.AppendEntity(poly);
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
double radius = 4.0;
var center = new Point3d(p3.X + radius, p3.Y, 0);
var circle = new Circle(center, Vector3d.ZAxis, radius);
circle.ColorIndex = 3;
ctx.Btr.AppendEntity(circle);
ctx.Tr.AddNewlyCreatedDBObject(circle, true);
var text = new DBText();
text.TextString = "HB";
text.Height = 3.5;
text.ColorIndex = 3;
text.HorizontalMode = TextHorizontalMode.TextCenter;
text.VerticalMode = TextVerticalMode.TextVerticalMid;
text.AlignmentPoint = center;
text.Position = center;
ctx.Btr.AppendEntity(text);
ctx.Tr.AddNewlyCreatedDBObject(text, true);
}
catch { }
}
private static void DrawSpecialHBLeaderToTop(FeatureDrivenDrawer.DrawingContext ctx, double xTarget, double yTarget, string textContent)
{
try
{
var p1 = new Point3d(xTarget, yTarget, 0);
var p2 = new Point3d(xTarget - 10, yTarget + 10, 0);
double textLen = (string.IsNullOrEmpty(textContent) ? 10 : textContent.Length) * 2.5;
if (textLen < 20) textLen = 20;
var p3 = new Point3d(p2.X - textLen, p2.Y, 0);
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 = textContent;
text.Height = 3.5;
text.ColorIndex = 7;
text.Layer = "0";
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 { }
}
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;
}
}
}