From a4859edc877a899a74a8c162e215f61369428c69 Mon Sep 17 00:00:00 2001 From: sladro Date: Thu, 25 Dec 2025 16:30:06 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=85=AC=E5=B7=AE=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E5=BD=A2=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cad/FeatureDrivenDrawer.cs | 191 +++++++++++++++++++++++++++++++------ 1 file changed, 163 insertions(+), 28 deletions(-) diff --git a/Cad/FeatureDrivenDrawer.cs b/Cad/FeatureDrivenDrawer.cs index f531a82..c6ef9ac 100644 --- a/Cad/FeatureDrivenDrawer.cs +++ b/Cad/FeatureDrivenDrawer.cs @@ -636,7 +636,11 @@ namespace CadParamPluging.Cad private static void DrawOuterDiameterDimensionHalf(DrawingContext ctx, double ox, double oy, double radius, double height, double diameter, double? tolPlus, double? tolMinus, double? diameterPrime) { - var baseText = BuildDimensionText($"%%c{FormatDimNumber(diameter)}", tolPlus, tolMinus); + var diameterStr = ctx.Bag.GetString(KeyOuterDiameter1); + var tolPlusStr = ctx.Bag.GetString(KeyOuterDiameter1TolPlus); + var tolMinusStr = ctx.Bag.GetString(KeyOuterDiameter1TolMinus); + + var baseText = BuildDimensionText($"%%c{FormatDimNumber(diameter, diameterStr)}", tolPlus, tolMinus, tolPlusStr, tolMinusStr); var dimText = diameterPrime.HasValue && diameterPrime.Value > 0 ? baseText + $"\\X(%%c{FormatDimNumber(diameterPrime.Value)})" : baseText; @@ -672,7 +676,11 @@ 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) { - var baseText = BuildDimensionText($"%%c{FormatDimNumber(diameter)}", tolPlus, tolMinus); + var diameterStr = ctx.Bag.GetString(KeyInnerDiameter2); + var tolPlusStr = ctx.Bag.GetString(KeyInnerDiameter2TolPlus); + var tolMinusStr = ctx.Bag.GetString(KeyInnerDiameter2TolMinus); + + var baseText = BuildDimensionText($"%%c{FormatDimNumber(diameter, diameterStr)}", tolPlus, tolMinus, tolPlusStr, tolMinusStr); var dimText = diameterPrime.HasValue && diameterPrime.Value > 0 ? baseText + $"\\X(%%c{FormatDimNumber(diameterPrime.Value)})" : baseText; @@ -711,7 +719,11 @@ namespace CadParamPluging.Cad private static void DrawHeightDimensionHalf(DrawingContext ctx, double ox, double oy, double radius, double height, double? tolPlus, double? tolMinus, double? heightPrime) { - var baseText = BuildDimensionText(FormatDimNumber(height), tolPlus, tolMinus); + var heightStr = ctx.Bag.GetString(KeyHeight1); + var tolPlusStr = ctx.Bag.GetString(KeyHeight1TolPlus); + var tolMinusStr = ctx.Bag.GetString(KeyHeight1TolMinus); + + var baseText = BuildDimensionText(FormatDimNumber(height, heightStr), tolPlus, tolMinus, tolPlusStr, tolMinusStr); var dimText = heightPrime.HasValue && heightPrime.Value > 0 ? baseText + $"\\X({FormatDimNumber(heightPrime.Value)})" : baseText; @@ -812,7 +824,11 @@ namespace CadParamPluging.Cad private static void DrawOuterDiameterDimension(DrawingContext ctx, double ox, double oy, double width, double diameter, double? tolPlus, double? tolMinus, double? diameterPrime) { - var baseText = BuildDimensionText($"%%c{FormatDimNumber(diameter)}", tolPlus, tolMinus); + var diameterStr = ctx.Bag.GetString(KeyOuterDiameter1); + var tolPlusStr = ctx.Bag.GetString(KeyOuterDiameter1TolPlus); + var tolMinusStr = ctx.Bag.GetString(KeyOuterDiameter1TolMinus); + + var baseText = BuildDimensionText($"%%c{FormatDimNumber(diameter, diameterStr)}", tolPlus, tolMinus, tolPlusStr, tolMinusStr); var dimText = diameterPrime.HasValue && diameterPrime.Value > 0 ? baseText + $"\\X(%%c{FormatDimNumber(diameterPrime.Value)})" : baseText; @@ -829,7 +845,11 @@ namespace CadParamPluging.Cad private static void DrawInnerDiameterDimension(DrawingContext ctx, double xInnerLeft, double xInnerRight, double yBottom, double diameter, double? tolPlus, double? tolMinus, double? diameterPrime) { - var baseText = BuildDimensionText($"%%c{FormatDimNumber(diameter)}", tolPlus, tolMinus); + var diameterStr = ctx.Bag.GetString(KeyInnerDiameter2); + var tolPlusStr = ctx.Bag.GetString(KeyInnerDiameter2TolPlus); + var tolMinusStr = ctx.Bag.GetString(KeyInnerDiameter2TolMinus); + + var baseText = BuildDimensionText($"%%c{FormatDimNumber(diameter, diameterStr)}", tolPlus, tolMinus, tolPlusStr, tolMinusStr); var dimText = diameterPrime.HasValue && diameterPrime.Value > 0 ? baseText + $"\\X(%%c{FormatDimNumber(diameterPrime.Value)})" : baseText; @@ -846,7 +866,11 @@ namespace CadParamPluging.Cad private static void DrawHeightDimension(DrawingContext ctx, double ox, double oy, double width, double height, double? tolPlus, double? tolMinus, double? heightPrime) { - var baseText = BuildDimensionText(FormatDimNumber(height), tolPlus, tolMinus); + var heightStr = ctx.Bag.GetString(KeyHeight1); + var tolPlusStr = ctx.Bag.GetString(KeyHeight1TolPlus); + var tolMinusStr = ctx.Bag.GetString(KeyHeight1TolMinus); + + var baseText = BuildDimensionText(FormatDimNumber(height, heightStr), tolPlus, tolMinus, tolPlusStr, tolMinusStr); var dimText = heightPrime.HasValue && heightPrime.Value > 0 ? baseText + $"\\X({FormatDimNumber(heightPrime.Value)})" : baseText; @@ -982,11 +1006,41 @@ namespace CadParamPluging.Cad } } - private static string FormatDimNumber(double value) + private static string FormatDimNumber(double value, string rawInput = null) { try { - return value.ToString("0.###"); + // If rawInput is provided and matches the value, use its precision + if (!string.IsNullOrWhiteSpace(rawInput) && double.TryParse(rawInput, out var d) && Math.Abs(d - value) < 0.000001) + { + int decIndex = rawInput.IndexOf('.'); + int decimals = 0; + if (decIndex >= 0) + { + decimals = rawInput.Length - decIndex - 1; + } + // Format: 0.00... based on count + // If decimals is 0, format is "0" (integer) + if (decimals == 0) return value.ToString("0"); + return value.ToString("0." + new string('0', decimals)); + } + + // Fallback: auto-detect from value (strip trailing zeros) + string str = value.ToString("0.##########"); + int decimalIndex = str.IndexOf('.'); + if (decimalIndex < 0) + { + return str; // Integer, no decimal + } + + // Get number of digits after decimal + int autoDecimals = str.Length - decimalIndex - 1; + + // Construct format string + if (autoDecimals == 0) return str; + + string format = "0." + new string('0', autoDecimals); + return value.ToString(format); } catch { @@ -1124,14 +1178,22 @@ namespace CadParamPluging.Cad // 直径标注 var diaTolPlus = bag.GetDoubleOrNull(KeyDiskDiameterTolPlus); var diaTolMinus = bag.GetDoubleOrNull(KeyDiskDiameterTolMinus); - var diaDimText = BuildDimensionText($"%%c{diameter.Value}", diaTolPlus, diaTolMinus); + var diameterStr = bag.GetString(KeyDiskDiameter); + var diaTolPlusStr = bag.GetString(KeyDiskDiameterTolPlus); + var diaTolMinusStr = bag.GetString(KeyDiskDiameterTolMinus); + + var diaDimText = BuildDimensionText($"%%c{FormatDimNumber(diameter.Value, diameterStr)}", diaTolPlus, diaTolMinus, diaTolPlusStr, diaTolMinusStr); AddLinearDim(ctx, new Point3d(ox, oy, 0), new Point3d(ox + diameter.Value, oy, 0), new Point3d(ctx.Center.X, oy - 20, 0), 0, diaDimText); // 高度标注 var htTolPlus = bag.GetDoubleOrNull(KeyDiskHeightTolPlus); var htTolMinus = bag.GetDoubleOrNull(KeyDiskHeightTolMinus); - var htDimText = BuildDimensionText($"{H}", htTolPlus, htTolMinus); + var heightStr = bag.GetString(KeyDiskHeight); + var htTolPlusStr = bag.GetString(KeyDiskHeightTolPlus); + var htTolMinusStr = bag.GetString(KeyDiskHeightTolMinus); + + var htDimText = BuildDimensionText(FormatDimNumber(H, heightStr), htTolPlus, htTolMinus, htTolPlusStr, htTolMinusStr); AddLinearDim(ctx, new Point3d(ox + diameter.Value, oy, 0), new Point3d(ox + diameter.Value, oy + H, 0), new Point3d(ox + diameter.Value + 20, ctx.Center.Y, 0), 90, htDimText); @@ -1235,14 +1297,22 @@ namespace CadParamPluging.Cad // 直径标注 var diaTolPlus = bag.GetDoubleOrNull(KeyDiameterTolPlus); var diaTolMinus = bag.GetDoubleOrNull(KeyDiameterTolMinus); - var diaDimText = BuildDimensionText($"%%c{diameter.Value}", diaTolPlus, diaTolMinus); + var diameterStr = bag.GetString(KeyDiameter); + var diaTolPlusStr = bag.GetString(KeyDiameterTolPlus); + var diaTolMinusStr = bag.GetString(KeyDiameterTolMinus); + + var diaDimText = BuildDimensionText($"%%c{FormatDimNumber(diameter.Value, diameterStr)}", diaTolPlus, diaTolMinus, diaTolPlusStr, diaTolMinusStr); AddLinearDim(ctx, new Point3d(ox, oy + R, 0), new Point3d(ox, oy - R, 0), new Point3d(ox - 20, oy, 0), 90, diaDimText); // 长度标注 var lenTolPlus = bag.GetDoubleOrNull(KeyLengthTolPlus); var lenTolMinus = bag.GetDoubleOrNull(KeyLengthTolMinus); - var lenDimText = BuildDimensionText($"{L}", lenTolPlus, lenTolMinus); + var lengthStr = bag.GetString(KeyLength); + var lenTolPlusStr = bag.GetString(KeyLengthTolPlus); + var lenTolMinusStr = bag.GetString(KeyLengthTolMinus); + + var lenDimText = BuildDimensionText(FormatDimNumber(L, lengthStr), lenTolPlus, lenTolMinus, lenTolPlusStr, lenTolMinusStr); AddLinearDim(ctx, new Point3d(ox, oy - R, 0), new Point3d(ox + L, oy - R, 0), new Point3d(ctx.Center.X, oy - R - 20, 0), 0, lenDimText); @@ -1424,7 +1494,11 @@ namespace CadParamPluging.Cad // 宽度标注 (BoxSize1) var tol1Plus = bag.GetDoubleOrNull(KeyBoxSize1TolPlus); var tol1Minus = bag.GetDoubleOrNull(KeyBoxSize1TolMinus); - var dim1Text = BuildDimensionText($"{width}", tol1Plus, tol1Minus); + var widthStr = bag.GetString(KeyBoxSize1); + var tol1PlusStr = bag.GetString(KeyBoxSize1TolPlus); + var tol1MinusStr = bag.GetString(KeyBoxSize1TolMinus); + + var dim1Text = BuildDimensionText(FormatDimNumber(width, widthStr), tol1Plus, tol1Minus, tol1PlusStr, tol1MinusStr); AddLinearDim(ctx, new Point3d(ox, oy, 0), new Point3d(ox + width, oy, 0), new Point3d(ctx.Center.X, oy - 20, 0), 0, dim1Text); @@ -1433,7 +1507,11 @@ namespace CadParamPluging.Cad { var tol2Plus = bag.GetDoubleOrNull(KeyBoxSize2TolPlus); var tol2Minus = bag.GetDoubleOrNull(KeyBoxSize2TolMinus); - var dim2Text = BuildDimensionText($"{height}", tol2Plus, tol2Minus); + var heightStr = bag.GetString(KeyBoxSize2); + var tol2PlusStr = bag.GetString(KeyBoxSize2TolPlus); + var tol2MinusStr = bag.GetString(KeyBoxSize2TolMinus); + + var dim2Text = BuildDimensionText(FormatDimNumber(height, heightStr), tol2Plus, tol2Minus, tol2PlusStr, tol2MinusStr); AddLinearDim(ctx, new Point3d(ox + width, oy, 0), new Point3d(ox + width, oy + height, 0), new Point3d(ox + width + 20, ctx.Center.Y, 0), 90, dim2Text); } @@ -1443,7 +1521,11 @@ namespace CadParamPluging.Cad { var tol3Plus = bag.GetDoubleOrNull(KeyBoxSize3TolPlus); var tol3Minus = bag.GetDoubleOrNull(KeyBoxSize3TolMinus); - var dim3Text = BuildDimensionText($"深度:{depth}", tol3Plus, tol3Minus); + var depthStr = bag.GetString(KeyBoxSize3); + var tol3PlusStr = bag.GetString(KeyBoxSize3TolPlus); + var tol3MinusStr = bag.GetString(KeyBoxSize3TolMinus); + + var dim3Text = BuildDimensionText($"深度:{FormatDimNumber(depth, depthStr)}", tol3Plus, tol3Minus, tol3PlusStr, tol3MinusStr); try { var text = new DBText(); @@ -1562,17 +1644,40 @@ namespace CadParamPluging.Cad #region 辅助方法 - private static string BuildDimensionText(string baseText, double? tolPlus, double? tolMinus) + private static string BuildDimensionText(string baseText, double? tolPlus, double? tolMinus, string tolPlusStr = null, string tolMinusStr = null) { if (!tolPlus.HasValue && !tolMinus.HasValue) { return baseText; } - // 公差显示为上下并排(堆叠文本)。 - // AutoCAD MText stack: \Supper#lower; => 上下堆叠且无分隔线。 - // 这里将公差缩小到 0.7 倍以贴近常见标注样式。 - const double tolScale = 0.7; + // Check if symmetrical + // tolMinus is typically positive in parameter bag representing absolute deviation (e.g. 0.02 for -0.02) + // or negative. We check absolute values. + bool isSymmetrical = false; + if (tolPlus.HasValue && tolMinus.HasValue) + { + if (Math.Abs(Math.Abs(tolPlus.Value) - Math.Abs(tolMinus.Value)) < 0.000001) + { + // Also check if raw strings (if provided) imply different precision? + // E.g. +0.50 vs -0.5. Strictly speaking they are same value but different text. + // But for symmetrical display %%p0.50, we pick one precision (usually plus). + isSymmetrical = true; + } + } + + // Symmetric tolerance: ±Value + if (isSymmetrical) + { + var val = Math.Abs(tolPlus.Value); + // Use tolPlusStr for precision if available + return $"{baseText}%%p{FormatDimNumber(val, tolPlusStr)}"; + } + + // Deviation tolerance: Stacked + // AutoCAD MText stack: \H...x;\S...^...; (Caret ^ for tolerance style stacking without bar) + // User requested Height scale 1.0 (from property screenshot) + const double tolScale = 1.0; var plusStr = string.Empty; var minusStr = string.Empty; @@ -1580,24 +1685,46 @@ namespace CadParamPluging.Cad if (tolPlus.HasValue) { plusStr = tolPlus.Value >= 0 - ? $"+{FormatDimNumber(tolPlus.Value)}" - : $"{FormatDimNumber(tolPlus.Value)}"; + ? $"+{FormatDimNumber(tolPlus.Value, tolPlusStr)}" + : $"{FormatDimNumber(tolPlus.Value, tolPlusStr)}"; } if (tolMinus.HasValue) { - // 下偏差通常显示为负号;如果传入为正数则强制加上负号。 - minusStr = tolMinus.Value <= 0 - ? $"{FormatDimNumber(tolMinus.Value)}" - : $"-{FormatDimNumber(tolMinus.Value)}"; + // Lower deviation is usually displayed as negative number. + double vm = tolMinus.Value; + + // Use FormatDimNumber with raw string to respect input precision (e.g. "0.00" or "0") + string formattedVal = FormatDimNumber(Math.Abs(vm), tolMinusStr); + + if (Math.Abs(vm) < 0.000001) + { + // If it's zero. + // If raw string was "0", formatted is "0". + // If raw string was "0.00", formatted is "0.00". + // We just use the formatted value. + minusStr = formattedVal; + + // Exception: if it's 0, we usually don't want a negative sign. + // Unless user explicitly wrote "-0"? Unlikely. + } + else + { + // Force negative sign for lower deviation if it's not already negative in the formatted string? + // FormatDimNumber returns the number. If vm is positive in bag (abs deviation), we need minus. + minusStr = vm <= 0 + ? formattedVal + : $"-{formattedVal}"; + } } + // If we have both, stack them if (tolPlus.HasValue && tolMinus.HasValue) { - return $"{baseText}{{\\H{tolScale}x;\\S{plusStr}#{minusStr};}}"; + return $"{baseText}{{\\H{tolScale}x;\\S{plusStr}^{minusStr};}}"; } - // 只有单边公差时,仍缩小显示。 + // If only one side is present var single = tolPlus.HasValue ? plusStr : minusStr; return $"{baseText}{{\\H{tolScale}x;{single}}}"; } @@ -1688,6 +1815,11 @@ namespace CadParamPluging.Cad TrySetDimProp(dim, "Dimgap", 1.0); TrySetDimProp(dim, "Dimexe", 1.0); TrySetDimProp(dim, "Dimexo", 1.0); + + // Updated based on user request + TrySetDimProp(dim, "Dimtofl", true); // Draw dim line between ext lines + TrySetDimProp(dim, "Dimatfit", 3); // Text or Arrows (Best fit) + TrySetDimProp(dim, "Dimtad", 1); // Text Vertical: Above } private static void TryApplyDimLayoutOverrides(Dimension dim, Point3d pt1, Point3d pt2, Point3d dimLinePt, double rotRad) @@ -1706,6 +1838,8 @@ namespace CadParamPluging.Cad TrySetDimProp(dim, "Dimse2", false); // 3) 尺寸线位于尺寸(文字)上方:将文字整体移到尺寸线的“下方”(相对尺寸线法向的顺时针侧)。 + // Modified: User requested "Above" style. Dimtad=1 handles this. Manual positioning removed. + /* try { var dimtxt = TryGetDoubleProp(dim, "Dimtxt") ?? 3.5; @@ -1726,6 +1860,7 @@ namespace CadParamPluging.Cad { // ignore } + */ } private static Point3d ProjectToLineAlongNormal(Point3d p, Point3d linePoint, Vector3d normal)