diff --git a/Cad/FeatureDrivenDrawer.cs b/Cad/FeatureDrivenDrawer.cs
index 009c426..dcd12cb 100644
--- a/Cad/FeatureDrivenDrawer.cs
+++ b/Cad/FeatureDrivenDrawer.cs
@@ -544,12 +544,14 @@ namespace CadParamPluging.Cad
// === 特征1: 锻件外轮廓 ===
var unspecifiedFillet = bag.GetDoubleOrNull(KeyUnspecifiedFilletRadiusMax);
- if (applyUnspecifiedFillet && unspecifiedFillet.HasValue && unspecifiedFillet.Value > 0)
- {
- DrawForgingOuterContourHalf(ctx, ox, oy, visualOuterR, H, unspecifiedFillet);
- }
- else
+
+ // 判断是否有圆角
+ bool hasUnspecifiedFillet = applyUnspecifiedFillet && unspecifiedFillet.HasValue && unspecifiedFillet.Value > 0;
+
+ if (!hasUnspecifiedFillet)
{
+ // 只有在非圆角模式下才绘制单独的外轮廓
+ // 在圆角模式下,整个实体轮廓由后面的 DrawRingSectionContourWithFillet 统一绘制
DrawForgingOuterContourHalf(ctx, ox, oy, visualOuterR, H, null);
}
@@ -562,7 +564,7 @@ namespace CadParamPluging.Cad
// 传入 visualOuterR 用于画线,传入 outerDia 用于文本
DrawOuterDiameterDimensionHalf(ctx, ox, oy, visualOuterR, H, outerDia, outerTolPlus, outerTolMinus, outerDiaPrime);
- // === 特征3: 内孔/内径 ===
+ // === 特征3: 内孔/内径 ===
double? xInnerRight = null;
if (innerDia.HasValue && innerDia.Value > 0 && innerDia.Value < outerDia)
{
@@ -572,39 +574,62 @@ namespace CadParamPluging.Cad
var innerTolPlus = bag.GetDoubleOrNull(KeyInnerDiameter2TolPlus);
var innerTolMinus = bag.GetDoubleOrNull(KeyInnerDiameter2TolMinus);
- DrawInnerHoleHalf(ctx, ox, xInnerRight.Value, oy, H);
- // 传入 raw innerDia for text
- DrawInnerDiameterDimensionHalf(ctx, ox, xInnerRight.Value, oy, H, innerDia.Value, innerTolPlus, innerTolMinus, innerDiaPrime);
+ // 判断是否有圆角 (hasUnspecifiedFillet already declared above)
+ if (hasUnspecifiedFillet)
+ {
+ // 计算圆角半径逻辑,与 DrawRingSectionContourWithFillet 保持一致
+ var sectionWidth = visualOuterR * 2.0; // Wait, section width is visualOuterR - visualInnerRight? No.
+ // Calculate visual width for section
+ var sWidth = (ox + visualOuterR) - (ox + visualInnerR);
+ var maxR = Math.Min(sWidth * 0.5, H * 0.5);
+ var rawR = unspecifiedFillet.Value;
+ var r = Math.Min(rawR, maxR);
+ double dimOffset = (r > 0.01) ? r : 0.0;
- // === 特征4: 内径圆角 ===
- var innerRadiusMax = bag.GetDoubleOrNull(KeyInnerRadiusMax);
- if (innerRadiusMax.HasValue && innerRadiusMax.Value > 0 && ctx.IsCenterPunched)
- {
- DrawInnerFilletsHalf(ctx, xInnerRight.Value, oy, H, innerRadiusMax.Value);
- }
- else if (applyUnspecifiedFillet && unspecifiedFillet.HasValue && unspecifiedFillet.Value > 0)
- {
- DrawInnerFilletsHalfInward(ctx, xInnerRight.Value, oy, H, unspecifiedFillet.Value);
- }
+ // 新逻辑:如果启用了圆角,直接绘制一个闭合的圆角矩形作为实体轮廓
+ // 替代原来分散的 外轮廓 + 内孔竖线 + 圆角 的画法,解决直角残留和不平滑问题
+ DrawRingSectionContourWithFillet(ctx, xInnerRight.Value, ox + visualOuterR, oy, H, unspecifiedFillet.Value);
+
+ // 补充:绘制连接中轴线到实体内边缘的上下两条横线(内孔顶底面)
+ DrawHoleHorizontalLines(ctx, ox, xInnerRight.Value, oy, H, unspecifiedFillet.Value);
- // === 特征4.1: 剖面线 ===
- if (applyUnspecifiedFillet && unspecifiedFillet.HasValue && unspecifiedFillet.Value > 0)
- {
+ // 标注依然需要
+ // 用户反馈:下边的标注线在竖直方向上不要闭合(保持在底边水平),不要高于白色底部边框
+ // 所以这里恢复 offset 为 0
+ DrawInnerDiameterDimensionHalf(ctx, ox, xInnerRight.Value, oy, H, innerDia.Value, innerTolPlus, innerTolMinus, innerDiaPrime, 0.0);
+
+ // 剖面填充
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);
+
DrawRingSectionHatch(ctx, xInnerRight.Value, ox + visualOuterR, oy, H);
+
+ // 剖面左侧竖线
+ DrawSectionInnerBoundaryBold(ctx, xInnerRight.Value, oy, H);
}
-
- // 剖面左侧竖线
- DrawSectionInnerBoundaryBold(ctx, xInnerRight.Value, oy, H);
}
// === 特征5: 高度标注 ===
var heightTolPlus = bag.GetDoubleOrNull(KeyHeight1TolPlus);
var heightTolMinus = bag.GetDoubleOrNull(KeyHeight1TolMinus);
- DrawHeightDimensionHalf(ctx, ox, oy, visualOuterR, H, heightTolPlus, heightTolMinus, heightPrime);
+
+ // 计算高度标注的内缩进量(针对圆角闭合)
+ // 使标注界线的起点X坐标向内缩进 r,从而搭在圆角的切点上,而Y坐标保持不变(与锻件顶底对齐)
+ double heightDimIndentX = 0.0;
+ if (hasUnspecifiedFillet)
+ {
+ var sWidth = (ox + visualOuterR) - (ox + visualInnerR);
+ 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 (unspecifiedFillet.HasValue && unspecifiedFillet.Value > 0)
@@ -616,7 +641,8 @@ namespace CadParamPluging.Cad
var minWallThickness = bag.GetDoubleOrNull(KeyMinWallThickness);
if (minWallThickness.HasValue && minWallThickness.Value > 0 && xInnerRight.HasValue)
{
- DrawMinWallThicknessNote(ctx, xInnerRight.Value, ox + visualOuterR, oy, minWallThickness.Value);
+ // 用户反馈:下边标注线不要偏移,恢复为0
+ DrawMinWallThicknessNote(ctx, xInnerRight.Value, ox + visualOuterR, oy, minWallThickness.Value, 0.0);
}
// === 特征8: 零件轮廓(车加工态,右半边) ===
@@ -642,6 +668,8 @@ namespace CadParamPluging.Cad
// 高度方向没有示意图扭曲,直接使用物理高度
var scaledHeightPrime = heightPrime.Value;
+ // 恢复绘制零件轮廓(无论是否有圆角)
+ // 用户确认剖面中需要显示零件生成部分,之前的屏蔽是误判
DrawPartContourHalf(ctx, ox, oy, H, scaledOuterDiaPrime, scaledInnerDiaPrime, scaledHeightPrime);
}
@@ -658,6 +686,112 @@ namespace CadParamPluging.Cad
}
+
+ ///
+ /// 轧制:绘制带圆角的实体闭合轮廓(圆角多段线)
+ /// 替代原来分散的外轮廓线和内孔边界线
+ ///
+ private static void DrawRingSectionContourWithFillet(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); // 90度圆弧的凸度
+
+ // 逆时针绘制圆角矩形
+ // 顺序:左下圆弧 -> 右下圆弧 -> 右上圆弧 -> 左上圆弧
+
+ // 下方边:从左下到右下
+ // 起点 (xLeft + r, yBottom) -> 直线 -> (xRight - r, yBottom) -> 圆弧 -> (xRight, yBottom + r)
+
+ var polyFillet = new Polyline();
+
+ // 1. 下边直线段起点
+ polyFillet.AddVertexAt(0, new Point2d(xLeft + r, yBottom), 0, 0, 0);
+
+ // 2. 右下角圆弧起点
+ polyFillet.AddVertexAt(1, new Point2d(xRight - r, yBottom), bulge, 0, 0);
+
+ // 3. 右边直线段起点 (圆弧终点)
+ polyFillet.AddVertexAt(2, new Point2d(xRight, yBottom + r), 0, 0, 0);
+
+ // 4. 右上角圆弧起点
+ polyFillet.AddVertexAt(3, new Point2d(xRight, yTop - r), bulge, 0, 0);
+
+ // 5. 上边直线段起点 (圆弧终点)
+ polyFillet.AddVertexAt(4, new Point2d(xRight - r, yTop), 0, 0, 0);
+
+ // 6. 左上角圆弧起点
+ polyFillet.AddVertexAt(5, new Point2d(xLeft + r, yTop), bulge, 0, 0);
+
+ // 7. 左边直线段起点 (圆弧终点)
+ polyFillet.AddVertexAt(6, new Point2d(xLeft, yTop - r), 0, 0, 0);
+
+ // 8. 左下角圆弧起点
+ 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 DrawHoleHorizontalLines(DrawingContext ctx, double xAxis, double xSectionLeft, double yBottom, double height, double filletR)
+ {
+ var yTop = yBottom + height;
+
+ // 计算延伸量:为了与圆角闭合,横线需要延伸到圆角圆心的X坐标处
+ // 或者简单点,让它延伸到 (xSectionLeft + r),即圆角的结束位置
+ var width = 200.0; // dummy big enough width for calculation
+ var maxR = Math.Min(width * 0.5, height * 0.5);
+ var r = Math.Min(filletR, maxR);
+
+ // 如果圆角很小,就不用延伸太远,但考虑到视觉闭合,应该延伸到 xSectionLeft 就够了?
+ // 不, 截图显示圆角导致内孔竖直边向内缩进,所以横线必须向右延伸穿过圆角区域,连接到实体。
+ // 圆角起点的X坐标是 xSectionLeft,圆角终点的X坐标是 xSectionLeft + r
+ // 实际上,横线应该连接到圆角圆弧的切点?不,横线是顶面/底面,所以应该连接到 (xSectionLeft + r)
+
+ double xTarget = xSectionLeft;
+ if (r > 0.01)
+ {
+ xTarget = xSectionLeft + r;
+ }
+
+ // Bottom line
+ var line1 = new Line(new Point3d(xAxis, yBottom, 0), new Point3d(xTarget, yBottom, 0));
+ ctx.Style?.Apply(line1, DrawingStyleManager.Role.OutlineBold);
+ ctx.Btr.AppendEntity(line1);
+ ctx.Tr.AddNewlyCreatedDBObject(line1, true);
+
+ // Top line
+ var line2 = new Line(new Point3d(xAxis, yTop, 0), new Point3d(xTarget, yTop, 0));
+ ctx.Style?.Apply(line2, DrawingStyleManager.Role.OutlineBold);
+ ctx.Btr.AppendEntity(line2);
+ ctx.Tr.AddNewlyCreatedDBObject(line2, true);
+ }
+
///
/// 自由锻工艺 - 画全图
///
@@ -937,7 +1071,7 @@ namespace CadParamPluging.Cad
/// 轧制:内径标注(从对称轴到右边内孔,放到下方并与最小壁厚标注共线)
///
private static void DrawInnerDiameterDimensionHalf(DrawingContext ctx, double oxAxis, double xInnerRight, double yBottom, double height,
- double diameter, double? tolPlus, double? tolMinus, double? diameterPrime)
+ double diameter, double? tolPlus, double? tolMinus, double? diameterPrime, double offsetY = 0)
{
// Use OriginalBag for text display
var diameterVal = ctx.OriginalBag?.GetDoubleOrNull(KeyInnerDiameter2) ?? diameter;
@@ -965,8 +1099,8 @@ namespace CadParamPluging.Cad
var dimLineY = yBottom - 10;
AddLinearDim(
ctx,
- new Point3d(oxAxis, yBottom, 0),
- new Point3d(xInnerRight, yBottom, 0),
+ new Point3d(oxAxis, yBottom, 0), // 对称轴点不需要偏移,因为它是中心线
+ new Point3d(xInnerRight, yBottom + offsetY, 0), // 内孔点需要偏移以避开圆角空隙
new Point3d(oxAxis + innerRadius / 2, dimLineY, 0),
0,
dimText,
@@ -998,9 +1132,10 @@ namespace CadParamPluging.Cad
///
/// 轧制:高度标注(在右侧)
+ /// indentX: 界线起点向内横向缩进量(配合圆角使用,使界线起于圆角切点)
///
private static void DrawHeightDimensionHalf(DrawingContext ctx, double ox, double oy, double radius,
- double height, double? tolPlus, double? tolMinus, double? heightPrime)
+ double height, double? tolPlus, double? tolMinus, double? heightPrime, double indentX = 0)
{
// Use OriginalBag for text display
var heightVal = ctx.OriginalBag?.GetDoubleOrNull(KeyHeight1) ?? height;
@@ -1022,10 +1157,17 @@ namespace CadParamPluging.Cad
? baseText + $"\\X({FormatDimNumber(heightPrimeVal.Value)})"
: baseText;
+ // 界线起点:
+ // 下端: (ox + radius - indentX, oy)
+ // 上端: (ox + radius - indentX, oy + height)
+ // 这样保持了高度(Y)不变,和白色横线对齐,但X方向向内缩进搭在圆角顶点上
+
+ var xLine = ox + radius - indentX;
+
AddLinearDim(
ctx,
- new Point3d(ox + radius, oy, 0),
- new Point3d(ox + radius, oy + height, 0),
+ new Point3d(xLine, oy, 0),
+ new Point3d(xLine, oy + height, 0),
new Point3d(ox + radius + 20, oy + height / 2, 0),
90,
dimText);
@@ -1250,14 +1392,14 @@ namespace CadParamPluging.Cad
}
}
- private static void DrawMinWallThicknessNote(DrawingContext ctx, double xInnerRight, double xOuterRight, double yBottom, double thickness)
+ private static void DrawMinWallThicknessNote(DrawingContext ctx, double xInnerRight, double xOuterRight, double yBottom, double thickness, double offsetY = 0)
{
var val = ctx.OriginalBag?.GetDoubleOrNull(KeyMinWallThickness) ?? thickness;
var dimText = $"{FormatDimNumber(val)}min";
AddLinearDim(
ctx,
- new Point3d(xInnerRight, yBottom, 0),
- new Point3d(xOuterRight, yBottom, 0),
+ new Point3d(xInnerRight, yBottom + offsetY, 0),
+ new Point3d(xOuterRight, yBottom + offsetY, 0),
new Point3d((xInnerRight + xOuterRight) / 2, yBottom - 10, 0),
0,
dimText);