diff --git a/Cad/Drawers/RingRawRollingGenerator.cs b/Cad/Drawers/RingRawRollingGenerator.cs index 5574070..36ce355 100644 --- a/Cad/Drawers/RingRawRollingGenerator.cs +++ b/Cad/Drawers/RingRawRollingGenerator.cs @@ -30,18 +30,8 @@ namespace CadParamPluging.Cad throw new ArgumentNullException(nameof(templateParams)); } - var workingBag = CloneBagWithMachinedStatus(bag, templateParams); - var drawParams = CreateMachinedTemplateParams(templateParams); - - FeatureDrivenDrawer.DrawRingRollingWithUnspecifiedFillet( - ctx, - workingBag, - drawParams.ProjectType, - drawParams.SheetSize, - drawParams.Scale, - drawParams.DrawingType, - center, - scaleFactor); + // 直接调用独立 Drawer + RingRawRollingDrawer.Draw(ctx, bag, center, scaleFactor); } private static ParamBag CloneBagWithMachinedStatus(ParamBag source, TemplateParams templateParams) diff --git a/Cad/RingRawRollingDrawer.cs b/Cad/RingRawRollingDrawer.cs new file mode 100644 index 0000000..afe76aa --- /dev/null +++ b/Cad/RingRawRollingDrawer.cs @@ -0,0 +1,680 @@ +using System; +using Autodesk.AutoCAD.DatabaseServices; +using Autodesk.AutoCAD.Geometry; +using CadParamPluging.Common; + +namespace CadParamPluging.Cad +{ + /// + /// 毛料态-轧制-环形 独立绘图器 + /// + public static class RingRawRollingDrawer + { + #region 参数Key常量 + 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 KeyHardness = "Hardness"; + + 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; + } + + // 始终使用"车加工"状态对应的视觉效果(即使是毛料态,为了绘图一致性,内部也视为有车加工参数) + // 在原始Generator中,这通过CloneBagWithMachinedStatus实现。 + // 这里我们直接在Drawer内部处理,或者假设传入的bag已经是处理过的(推荐)。 + // 但为了完全独立,我们可以在这里临时设置 context 的 DeliveryStatus 为"车加工" 来触发相关视觉逻辑, + // 或者直接复制相关逻辑而不依赖 DeliveryStatus 字符串。 + // 鉴于逻辑复用,我们这里显式设置 context.DeliveryStatus 为 "车加工", + // 因为 原来的 RingRawRollingGenerator 就是这么干的。 + context.DeliveryStatus = "车加工"; + + // 调用核心绘制逻辑 + // 此处传递 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; + + // 强制启用"示意图模式"逻辑 (原 IsMachined 判断) + // 因为在 RingRawRollingGenerator 中被强制设置了 "车加工" + if (true) + { + 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 = bag.GetDoubleOrNull(KeyOuterDiameter1Prime); + double? innerDiaPrime = bag.GetDoubleOrNull(KeyInnerDiameter2Prime); + double? 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); + + FeatureDrivenDrawer.DrawHoleHorizontalLines(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: 未注圆角 === + // 针对“毛料态-轧制-环形”模板(applyUnspecifiedFillet=true),不显示此文字 + 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 (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 (innerDia.HasValue && innerDia.Value > 0) + { + var markingText = bag.GetString(KeyMarkingContent); + if (!string.IsNullOrWhiteSpace(markingText) || applyUnspecifiedFillet) + { + // 指向锻件顶部白色边框的中间位置 + var xLoopInner = ox + visualInnerR; + var xLoopOuter = ox + visualOuterR; + var xTarget = (xLoopInner + xLoopOuter) / 2.0; + var yTarget = oy + H; + + if (string.IsNullOrWhiteSpace(markingText)) + { + markingText = "HB5936-13"; + } + + FeatureDrivenDrawer.DrawSpecialHBLeaderToTop(ctx, xTarget, yTarget, markingText); + } + else + { + var scaledInnerDia = visualInnerR * 2.0; + FeatureDrivenDrawer.DrawSpecialInnerHoleLeader(ctx, ox, oy, H, scaledInnerDia); + } + } + + // === 特征9: 硬度符号 === + // 【移除】 按用户需求,“毛料态-轧制-环形”模板不应显示硬度符号? + // "将料态/轧制/环形先改为独立",且之前提到“去掉该模板的硬度标志”, + // 所以这里移除 FeatureDrivenDrawer.DrawHardnessSymbol 的调用。 + } + + #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; + } + } + + var poly = new Polyline(); + poly.AddVertexAt(0, new Point2d(ox, oy), 0, 0, 0); + poly.AddVertexAt(1, new Point2d(ox + radius, oy), 0, 0, 0); + poly.AddVertexAt(2, new Point2d(ox + radius, oy + height), 0, 0, 0); + poly.AddVertexAt(3, new Point2d(ox, oy + height), 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 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); + 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); + ctx.Btr.AppendEntity(line2); + ctx.Tr.AddNewlyCreatedDBObject(line2, 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; + + AddLinearDim( + ctx, + new Point3d(ox, oy, 0), + new Point3d(ox + radius, oy, 0), + new Point3d(ox + radius / 2, 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; + AddLinearDim( + ctx, + new Point3d(oxAxis, yBottom, 0), + new Point3d(xInnerRight, yBottom + offsetY, 0), + new Point3d(oxAxis + innerRadius / 2, 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; + + 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); + } + + 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 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 + } +} diff --git a/CadParamPluging.csproj b/CadParamPluging.csproj index da56fcc..d099111 100644 --- a/CadParamPluging.csproj +++ b/CadParamPluging.csproj @@ -86,6 +86,7 @@ +