feat: 添加自由锻毛料圆轴和方轴的CAD绘图功能。

This commit is contained in:
sladro 2026-02-05 11:46:32 +08:00
parent 5c256c06d3
commit 91c7255a8b
2 changed files with 225 additions and 3 deletions

View File

@ -64,6 +64,10 @@ namespace CadParamPluging.Cad
double W = dia.Value;
double H = len.Value;
// 获取原始值用于判断断线(防止缩放干扰)
var originalDia = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeyDiameter);
double originalW = originalDia.HasValue ? originalDia.Value : W;
double ox = ctx.Center.X - W / 2.0;
double oy = ctx.Center.Y - H / 2.0;
@ -73,8 +77,20 @@ namespace CadParamPluging.Cad
double maxR = Math.Min(W / 2.0, H / 2.0);
if (filletR > maxR) filletR = maxR;
// 判断是否需要断线
bool needBreakLines = originalW > 150;
const double lineSpacing = 3.5;
// 1. 绘制主体轮廓 (矩形 + 圆角) - 保持原来的白色边框
DrawRectWithFillets(ctx, ox, oy, W, H, filletR, DrawingStyleManager.Role.OutlineBold);
if (needBreakLines)
{
double xBreak = ox + W / 4.0;
DrawRectWithBreak(ctx, ox, oy, W, H, filletR, xBreak, lineSpacing);
}
else
{
DrawRectWithFillets(ctx, ox, oy, W, H, filletR, DrawingStyleManager.Role.OutlineBold);
}
// 2. 绘制左右两端的弧线(向外凸出)
// 弧高设为 H/5高度的1/5确保弧高小于半弦长
@ -84,6 +100,12 @@ namespace CadParamPluging.Cad
// 3. 绘制中心线 (横向,在中间位置)
DrawHorizontalCenterLine(ctx, ctx.Center.Y, ox, ox + W);
// 4. 绘制断线 (如果需要)
if (needBreakLines)
{
DrawBreakLines(ctx, ox, oy, W, H);
}
// 3. 尺寸标注
// 3.1 直径标注 (底部)
@ -163,7 +185,16 @@ namespace CadParamPluging.Cad
double pOx = ctx.Center.X - pW / 2.0;
double pOy = ctx.Center.Y - pH / 2.0;
DrawRectOutline(ctx, pOx, pOy, pW, pH, DrawingStyleManager.Role.PartContour);
if (needBreakLines)
{
// 使用与锻件相同的断线X坐标和间距
double xBreak = ox + W / 4.0;
DrawRectOutlineWithBreak(ctx, pOx, pOy, pW, pH, xBreak, lineSpacing, DrawingStyleManager.Role.PartContour);
}
else
{
DrawRectOutline(ctx, pOx, pOy, pW, pH, DrawingStyleManager.Role.PartContour);
}
}
}
@ -300,5 +331,131 @@ namespace CadParamPluging.Cad
}
return newBag;
}
/// <summary>
/// 绘制断线(使用 BreakLine 样式:白色 PHANTOM 双点划线)
/// </summary>
private static void DrawBreakLines(FeatureDrivenDrawer.DrawingContext ctx, double ox, double oy, double width, double height)
{
const double lineSpacing = 3.5;
const double extend = 5.0;
double xBreak = ox + width / 4.0;
double y0 = oy - extend;
double y1 = oy + height + extend;
var line1 = new Line(new Point3d(xBreak, y0, 0), new Point3d(xBreak, y1, 0));
ctx.Style?.Apply(line1, DrawingStyleManager.Role.BreakLine);
ctx.Btr.AppendEntity(line1);
ctx.Tr.AddNewlyCreatedDBObject(line1, true);
var line2 = new Line(new Point3d(xBreak + lineSpacing, y0, 0), new Point3d(xBreak + lineSpacing, y1, 0));
ctx.Style?.Apply(line2, DrawingStyleManager.Role.BreakLine);
ctx.Btr.AppendEntity(line2);
ctx.Tr.AddNewlyCreatedDBObject(line2, true);
}
/// <summary>
/// 绘制带断口的矩形轮廓(在断线位置打断上下横线)
/// </summary>
private static void DrawRectWithBreak(FeatureDrivenDrawer.DrawingContext ctx, double x, double y, double w, double h, double r, double xBreak, double breakWidth)
{
// 左边竖线
var leftLine = new Line(new Point3d(x, y, 0), new Point3d(x, y + h, 0));
ctx.Style?.Apply(leftLine, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(leftLine);
ctx.Tr.AddNewlyCreatedDBObject(leftLine, true);
// 右边竖线
var rightLine = new Line(new Point3d(x + w, y, 0), new Point3d(x + w, y + h, 0));
ctx.Style?.Apply(rightLine, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(rightLine);
ctx.Tr.AddNewlyCreatedDBObject(rightLine, true);
// 底边:断开 [xBreak, xBreak + breakWidth]
// 左段
var bottomLeft = new Line(new Point3d(x, y, 0), new Point3d(xBreak, y, 0));
ctx.Style?.Apply(bottomLeft, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(bottomLeft);
ctx.Tr.AddNewlyCreatedDBObject(bottomLeft, true);
// 右段
var bottomRight = new Line(new Point3d(xBreak + breakWidth, y, 0), new Point3d(x + w, y, 0));
ctx.Style?.Apply(bottomRight, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(bottomRight);
ctx.Tr.AddNewlyCreatedDBObject(bottomRight, true);
// 顶边:断开 [xBreak, xBreak + breakWidth]
// 左段
var topLeft = new Line(new Point3d(x, y + h, 0), new Point3d(xBreak, y + h, 0));
ctx.Style?.Apply(topLeft, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(topLeft);
ctx.Tr.AddNewlyCreatedDBObject(topLeft, true);
// 右段
var topRight = new Line(new Point3d(xBreak + breakWidth, y + h, 0), new Point3d(x + w, y + h, 0));
ctx.Style?.Apply(topRight, DrawingStyleManager.Role.OutlineBold);
ctx.Btr.AppendEntity(topRight);
ctx.Tr.AddNewlyCreatedDBObject(topRight, true);
}
/// <summary>
/// 绘制带断口的零件轮廓(在断线位置打断上下横线)
/// 支持自定义 Role (通常为 PartContour)
/// </summary>
private static void DrawRectOutlineWithBreak(FeatureDrivenDrawer.DrawingContext ctx, double x, double y, double w, double h, double xBreak, double breakWidth, DrawingStyleManager.Role role)
{
// 左边竖线
var leftLine = new Line(new Point3d(x, y, 0), new Point3d(x, y + h, 0));
ctx.Style?.Apply(leftLine, role);
ctx.Btr.AppendEntity(leftLine);
ctx.Tr.AddNewlyCreatedDBObject(leftLine, true);
// 右边竖线
var rightLine = new Line(new Point3d(x + w, y, 0), new Point3d(x + w, y + h, 0));
ctx.Style?.Apply(rightLine, role);
ctx.Btr.AppendEntity(rightLine);
ctx.Tr.AddNewlyCreatedDBObject(rightLine, true);
// 底边:断开 [xBreak, xBreak + breakWidth]
// 需要判断 xBreak 是否在当前矩形范围内
// 通常零件在锻件内部,且断线位置也会穿过零件
// 我们假设断线切断了矩形(如果 xBreak < x 或 xBreak > x+w应该做特殊处理这里暂不考虑极端情况
// 左段
if (xBreak > x)
{
var bottomLeft = new Line(new Point3d(x, y, 0), new Point3d(Math.Min(xBreak, x + w), y, 0));
ctx.Style?.Apply(bottomLeft, role);
ctx.Btr.AppendEntity(bottomLeft);
ctx.Tr.AddNewlyCreatedDBObject(bottomLeft, true);
}
// 右段
if (xBreak + breakWidth < x + w)
{
var bottomRight = new Line(new Point3d(Math.Max(xBreak + breakWidth, x), y, 0), new Point3d(x + w, y, 0));
ctx.Style?.Apply(bottomRight, role);
ctx.Btr.AppendEntity(bottomRight);
ctx.Tr.AddNewlyCreatedDBObject(bottomRight, true);
}
// 顶边:断开 [xBreak, xBreak + breakWidth]
// 左段
if (xBreak > x)
{
var topLeft = new Line(new Point3d(x, y + h, 0), new Point3d(Math.Min(xBreak, x + w), y + h, 0));
ctx.Style?.Apply(topLeft, role);
ctx.Btr.AppendEntity(topLeft);
ctx.Tr.AddNewlyCreatedDBObject(topLeft, true);
}
// 右段
if (xBreak + breakWidth < x + w)
{
var topRight = new Line(new Point3d(Math.Max(xBreak + breakWidth, x), y + h, 0), new Point3d(x + w, y + h, 0));
ctx.Style?.Apply(topRight, role);
ctx.Btr.AppendEntity(topRight);
ctx.Tr.AddNewlyCreatedDBObject(topRight, true);
}
}
}
}

View File

@ -220,7 +220,15 @@ namespace CadParamPluging.Cad
double pOx = ctx.Center.X - pL / 2.0;
double pOy = ctx.Center.Y - pH / 2.0;
DrawRectOutline(ctx, pOx, pOy, pL, pH, DrawingStyleManager.Role.PartContour);
if (needBreakLines)
{
double xBreak = ox + S1 / 4.0;
DrawRectOutlineWithBreak(ctx, pOx, pOy, pL, pH, xBreak, lineSpacing, DrawingStyleManager.Role.PartContour);
}
else
{
DrawRectOutline(ctx, pOx, pOy, pL, pH, DrawingStyleManager.Role.PartContour);
}
}
}
@ -444,6 +452,63 @@ namespace CadParamPluging.Cad
ctx.Btr.AppendEntity(line);
ctx.Tr.AddNewlyCreatedDBObject(line, true);
}
/// <summary>
/// 绘制带断口的零件轮廓(在断线位置打断上下横线)
/// 支持自定义 Role (通常为 PartContour)
/// </summary>
private static void DrawRectOutlineWithBreak(FeatureDrivenDrawer.DrawingContext ctx, double x, double y, double w, double h, double xBreak, double breakWidth, DrawingStyleManager.Role role)
{
// 左边竖线
var leftLine = new Line(new Point3d(x, y, 0), new Point3d(x, y + h, 0));
ctx.Style?.Apply(leftLine, role);
ctx.Btr.AppendEntity(leftLine);
ctx.Tr.AddNewlyCreatedDBObject(leftLine, true);
// 右边竖线
var rightLine = new Line(new Point3d(x + w, y, 0), new Point3d(x + w, y + h, 0));
ctx.Style?.Apply(rightLine, role);
ctx.Btr.AppendEntity(rightLine);
ctx.Tr.AddNewlyCreatedDBObject(rightLine, true);
// 底边:断开 [xBreak, xBreak + breakWidth]
// 左段
if (xBreak > x)
{
var bottomLeft = new Line(new Point3d(x, y, 0), new Point3d(Math.Min(xBreak, x + w), y, 0));
ctx.Style?.Apply(bottomLeft, role);
ctx.Btr.AppendEntity(bottomLeft);
ctx.Tr.AddNewlyCreatedDBObject(bottomLeft, true);
}
// 右段
if (xBreak + breakWidth < x + w)
{
var bottomRight = new Line(new Point3d(Math.Max(xBreak + breakWidth, x), y, 0), new Point3d(x + w, y, 0));
ctx.Style?.Apply(bottomRight, role);
ctx.Btr.AppendEntity(bottomRight);
ctx.Tr.AddNewlyCreatedDBObject(bottomRight, true);
}
// 顶边:断开 [xBreak, xBreak + breakWidth]
// 左段
if (xBreak > x)
{
var topLeft = new Line(new Point3d(x, y + h, 0), new Point3d(Math.Min(xBreak, x + w), y + h, 0));
ctx.Style?.Apply(topLeft, role);
ctx.Btr.AppendEntity(topLeft);
ctx.Tr.AddNewlyCreatedDBObject(topLeft, true);
}
// 右段
if (xBreak + breakWidth < x + w)
{
var topRight = new Line(new Point3d(Math.Max(xBreak + breakWidth, x), y + h, 0), new Point3d(x + w, y + h, 0));
ctx.Style?.Apply(topRight, role);
ctx.Btr.AppendEntity(topRight);
ctx.Tr.AddNewlyCreatedDBObject(topRight, true);
}
}
}
}