372 lines
32 KiB
C#
372 lines
32 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using Autodesk.AutoCAD.DatabaseServices;
|
||
using Autodesk.AutoCAD.Geometry;
|
||
using CadParamPluging.Common;
|
||
|
||
namespace CadParamPluging.Cad
|
||
{
|
||
public static class ShaftRawFreeForgeSquareShaftDrawer
|
||
{
|
||
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)
|
||
};
|
||
|
||
DrawCore(context);
|
||
}
|
||
|
||
private static void DrawCore(FeatureDrivenDrawer.DrawingContext ctx)
|
||
{
|
||
var bag = ctx.Bag;
|
||
|
||
// Parameters
|
||
var size1 = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeySquareShaftSize1);
|
||
var size2 = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeySquareShaftSize2);
|
||
var size3 = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeySquareShaftSize3); // Optional? Assume required if provided.
|
||
|
||
if (!size1.HasValue || size1.Value <= 0 || !size2.HasValue || size2.Value <= 0)
|
||
{
|
||
// Must have at least Size 1 (Length) and Size 2 (Height/Width)
|
||
return;
|
||
}
|
||
|
||
double S1 = size1.Value; // Length
|
||
double S2 = size2.Value; // Height
|
||
double S3 = size3.HasValue && size3.Value > 0 ? size3.Value : 0; // Thickness/Width
|
||
|
||
// Calculate coordinates
|
||
// Main View (Length x Height) -> S1 x S2
|
||
// Center is geometric center of Main View?
|
||
|
||
double ox = ctx.Center.X - S1 / 2.0;
|
||
double oy = ctx.Center.Y - S2 / 2.0;
|
||
|
||
// 1. Draw Main View (S1 x S2)
|
||
var filletRParam = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeySquareShaftFilletRadiusMax);
|
||
double filletR = filletRParam.HasValue && filletRParam.Value > 0 ? filletRParam.Value : 0;
|
||
|
||
// Limit fillet
|
||
double maxR = Math.Min(S1 / 2.0, S2 / 2.0);
|
||
if (filletR > maxR) filletR = maxR;
|
||
|
||
DrawRectWithFillets(ctx, ox, oy, S1, S2, filletR);
|
||
|
||
// 2. Draw Symmetry Axis (Horizontal)
|
||
DrawSymmetryAxis(ctx, ox, oy, S1, S2);
|
||
|
||
// 3. Draw Section/Side View if S3 is present
|
||
// Position: Right of Main View
|
||
double gap = 50.0;
|
||
double sideOx = ox + S1 + gap;
|
||
|
||
if (S3 > 0)
|
||
{
|
||
// Draw Side View (S3 x S2) -> Width x Height
|
||
// Center it vertically relative to Main View
|
||
// oy is same
|
||
// But center X of side view is sideOx + S3/2
|
||
|
||
// Limit fillet for side view
|
||
double maxRSide = Math.Min(S3 / 2.0, S2 / 2.0);
|
||
double filletRSide = (filletR > maxRSide) ? maxRSide : filletR;
|
||
|
||
DrawRectWithFillets(ctx, sideOx, oy, S3, S2, filletRSide);
|
||
|
||
// Center axes for side view
|
||
// Horizontal
|
||
DrawSymmetryAxis(ctx, sideOx, oy, S3, S2);
|
||
// Vertical
|
||
DrawVerticalCenterLine(ctx, sideOx + S3 / 2.0, oy, S2);
|
||
}
|
||
|
||
// 4. Dimensions
|
||
|
||
// Size 1 (Length) - Below Main View
|
||
{
|
||
var val = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeySquareShaftSize1) ?? S1;
|
||
var tolPlus = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeySquareShaftSize1TolPlus);
|
||
var tolMinus = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeySquareShaftSize1TolMinus);
|
||
|
||
var dimText = BuildDimensionText(FormatDimNumber(val), tolPlus, tolMinus);
|
||
|
||
var valPrime = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeySquareShaftSize1Prime);
|
||
if (valPrime.HasValue && valPrime.Value > 0)
|
||
{
|
||
dimText += $"\\X({FormatDimNumber(valPrime.Value)})";
|
||
}
|
||
|
||
double dimY = oy - 20;
|
||
AddLinearDim(ctx, new Point3d(ox, oy, 0), new Point3d(ox + S1, oy, 0), new Point3d(ctx.Center.X, dimY, 0), 0, dimText);
|
||
}
|
||
|
||
// Size 2 (Height) - Right of Main View (or between views)
|
||
{
|
||
var val = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeySquareShaftSize2) ?? S2;
|
||
var tolPlus = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeySquareShaftSize2TolPlus);
|
||
var tolMinus = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeySquareShaftSize2TolMinus);
|
||
|
||
var dimText = BuildDimensionText(FormatDimNumber(val), tolPlus, tolMinus);
|
||
|
||
var valPrime = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeySquareShaftSize2Prime);
|
||
if (valPrime.HasValue && valPrime.Value > 0)
|
||
{
|
||
dimText += $"\\X({FormatDimNumber(valPrime.Value)})";
|
||
}
|
||
|
||
// If side view exists, put it between or on the far right?
|
||
// Left side is safest, or between parameters.
|
||
// Let's put it on the Left of Main View to avoid conflict with Side View
|
||
double dimX = ox - 20;
|
||
AddLinearDim(ctx, new Point3d(ox, oy, 0), new Point3d(ox, oy + S2, 0), new Point3d(dimX, ctx.Center.Y, 0), 90, dimText);
|
||
}
|
||
|
||
// Size 3 (Width) - Below Side View (if exists)
|
||
if (S3 > 0)
|
||
{
|
||
var val = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeySquareShaftSize3) ?? S3;
|
||
var tolPlus = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeySquareShaftSize3TolPlus);
|
||
var tolMinus = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeySquareShaftSize3TolMinus);
|
||
|
||
var dimText = BuildDimensionText(FormatDimNumber(val), tolPlus, tolMinus);
|
||
|
||
var valPrime = ctx.OriginalBag?.GetDoubleOrNull(FeatureDrivenDrawer.KeySquareShaftSize3Prime);
|
||
if (valPrime.HasValue && valPrime.Value > 0)
|
||
{
|
||
dimText += $"\\X({FormatDimNumber(valPrime.Value)})";
|
||
}
|
||
|
||
double dimY = oy - 20;
|
||
AddLinearDim(ctx, new Point3d(sideOx, oy, 0), new Point3d(sideOx + S3, oy, 0), new Point3d(sideOx + S3/2.0, dimY, 0), 0, dimText);
|
||
}
|
||
|
||
// Part Contour (Yellow Dashed) - Main View
|
||
var s1Prime = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeySquareShaftSize1Prime);
|
||
var s2Prime = bag.GetDoubleOrNull(FeatureDrivenDrawer.KeySquareShaftSize2Prime);
|
||
if (s1Prime.HasValue && s1Prime.Value > 0 && s2Prime.HasValue && s2Prime.Value > 0)
|
||
{
|
||
double pL = s1Prime.Value;
|
||
double pH = s2Prime.Value;
|
||
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);
|
||
}
|
||
|
||
// Note for Fillet
|
||
if (filletR > 0)
|
||
{
|
||
string note = $"未注圆角 R≤{FormatDimNumber(filletR)}";
|
||
DrawSimpleText(ctx, new Point3d(ox, oy + S2 + 10, 0), note, 3.5);
|
||
}
|
||
|
||
}
|
||
|
||
private static void DrawRectWithFillets(FeatureDrivenDrawer.DrawingContext ctx, double x, double y, double w, double h, double r)
|
||
{
|
||
var poly = new Polyline();
|
||
|
||
if (r < 0.01)
|
||
{
|
||
poly.AddVertexAt(0, new Point2d(x, y), 0, 0, 0);
|
||
poly.AddVertexAt(1, new Point2d(x + w, y), 0, 0, 0);
|
||
poly.AddVertexAt(2, new Point2d(x + w, y + h), 0, 0, 0);
|
||
poly.AddVertexAt(3, new Point2d(x, y + h), 0, 0, 0);
|
||
}
|
||
else
|
||
{
|
||
var bulge = Math.Tan(Math.PI / 8.0);
|
||
|
||
poly.AddVertexAt(0, new Point2d(x + r, y), 0, 0, 0);
|
||
poly.AddVertexAt(1, new Point2d(x + w - r, y), bulge, 0, 0);
|
||
poly.AddVertexAt(2, new Point2d(x + w, y + r), 0, 0, 0);
|
||
poly.AddVertexAt(3, new Point2d(x + w, y + h - r), bulge, 0, 0);
|
||
poly.AddVertexAt(4, new Point2d(x + w - r, y + h), 0, 0, 0);
|
||
poly.AddVertexAt(5, new Point2d(x + r, y + h), bulge, 0, 0);
|
||
poly.AddVertexAt(6, new Point2d(x, y + h - r), 0, 0, 0);
|
||
poly.AddVertexAt(7, new Point2d(x, y + r), bulge, 0, 0);
|
||
}
|
||
|
||
poly.Closed = true;
|
||
ctx.Style?.Apply(poly, DrawingStyleManager.Role.OutlineBold);
|
||
ctx.Btr.AppendEntity(poly);
|
||
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
|
||
}
|
||
|
||
private static void DrawRectOutline(FeatureDrivenDrawer.DrawingContext ctx, double x, double y, double w, double h, DrawingStyleManager.Role role)
|
||
{
|
||
var poly = new Polyline();
|
||
poly.AddVertexAt(0, new Point2d(x, y), 0, 0, 0);
|
||
poly.AddVertexAt(1, new Point2d(x + w, y), 0, 0, 0);
|
||
poly.AddVertexAt(2, new Point2d(x + w, y + h), 0, 0, 0);
|
||
poly.AddVertexAt(3, new Point2d(x, y + h), 0, 0, 0);
|
||
poly.Closed = true;
|
||
|
||
ctx.Style?.Apply(poly, role);
|
||
ctx.Btr.AppendEntity(poly);
|
||
ctx.Tr.AddNewlyCreatedDBObject(poly, true);
|
||
}
|
||
|
||
private static void DrawSymmetryAxis(FeatureDrivenDrawer.DrawingContext ctx, double x, double y, double w, double h)
|
||
{
|
||
double midY = y + h / 2.0;
|
||
double extend = w * 0.1;
|
||
if (extend > 15) extend = 15;
|
||
|
||
var line = new Line(new Point3d(x - extend, midY, 0), new Point3d(x + w + extend, midY, 0));
|
||
ctx.Style?.Apply(line, DrawingStyleManager.Role.Centerline);
|
||
ctx.Btr.AppendEntity(line);
|
||
ctx.Tr.AddNewlyCreatedDBObject(line, true);
|
||
}
|
||
|
||
private static void DrawVerticalCenterLine(FeatureDrivenDrawer.DrawingContext ctx, double midX, double y, double h)
|
||
{
|
||
double extend = h * 0.1;
|
||
if (extend > 15) extend = 15;
|
||
|
||
var line = new Line(new Point3d(midX, y - extend, 0), new Point3d(midX, y + h + extend, 0));
|
||
ctx.Style?.Apply(line, DrawingStyleManager.Role.Centerline);
|
||
ctx.Btr.AppendEntity(line);
|
||
ctx.Tr.AddNewlyCreatedDBObject(line, true);
|
||
}
|
||
|
||
private static ParamBag ScaleParamBag(ParamBag original, double scaleFactor)
|
||
{
|
||
if (original == null) return null;
|
||
if (Math.Abs(scaleFactor - 1.0) < 0.000001) return original;
|
||
var newBag = new ParamBag();
|
||
foreach(var k in original.GetKeys())
|
||
{
|
||
var v = original.GetString(k);
|
||
// Check if key is one of the Square Shaft keys
|
||
if (k.Contains("SquareShaftSize") || k.Contains("Radius") || k.Contains("Prime"))
|
||
{
|
||
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;
|
||
}
|
||
|
||
private static void AddLinearDim(FeatureDrivenDrawer.DrawingContext ctx, Point3d p1, Point3d p2, Point3d ptDim, double rot, string text)
|
||
{
|
||
try
|
||
{
|
||
var dim = new RotatedDimension();
|
||
dim.SetDatabaseDefaults();
|
||
dim.XLine1Point = p1;
|
||
dim.XLine2Point = p2;
|
||
dim.DimLinePoint = ptDim;
|
||
dim.Rotation = rot * Math.PI / 180.0;
|
||
dim.DimensionStyle = ctx.Db.Dimstyle;
|
||
dim.DimensionText = text;
|
||
dim.ColorIndex = 3;
|
||
|
||
SetDimColor(dim, "Dimclrd", 3);
|
||
SetDimColor(dim, "Dimclre", 3);
|
||
SetDimColor(dim, "Dimclrt", 3);
|
||
SetDimBool(dim, "Dimtofl", true);
|
||
|
||
ctx.Style?.Apply(dim, DrawingStyleManager.Role.Dimension);
|
||
dim.ColorIndex = 3;
|
||
|
||
ctx.Btr.AppendEntity(dim);
|
||
ctx.Tr.AddNewlyCreatedDBObject(dim, true);
|
||
}
|
||
catch {}
|
||
}
|
||
|
||
private static void DrawSimpleText(FeatureDrivenDrawer.DrawingContext ctx, Point3d pos, string text, double height)
|
||
{
|
||
try
|
||
{
|
||
var mtxt = new MText();
|
||
mtxt.SetDatabaseDefaults();
|
||
mtxt.Location = pos;
|
||
mtxt.Contents = text;
|
||
mtxt.TextHeight = height;
|
||
mtxt.Attachment = AttachmentPoint.BottomLeft;
|
||
|
||
ctx.Style?.Apply(mtxt, DrawingStyleManager.Role.Text);
|
||
ctx.Btr.AppendEntity(mtxt);
|
||
ctx.Tr.AddNewlyCreatedDBObject(mtxt, true);
|
||
}
|
||
catch {}
|
||
}
|
||
|
||
private static string FormatDimNumber(double value)
|
||
{
|
||
return value.ToString("0.###");
|
||
}
|
||
|
||
private static string BuildDimensionText(string baseText, double? tolPlus, double? tolMinus)
|
||
{
|
||
if (!tolPlus.HasValue && !tolMinus.HasValue) return baseText;
|
||
|
||
if (tolPlus.HasValue && tolMinus.HasValue && Math.Abs(Math.Abs(tolPlus.Value) - Math.Abs(tolMinus.Value)) < 0.00001)
|
||
{
|
||
return $"{baseText}%%p{Math.Abs(tolPlus.Value):0.###}";
|
||
}
|
||
|
||
string p = tolPlus.HasValue ? (tolPlus.Value >= 0 ? "+" : "") + tolPlus.Value.ToString("0.###") : "0";
|
||
string m = tolMinus.HasValue ? tolMinus.Value.ToString("0.###") : "0";
|
||
|
||
return $"{baseText}\\S{p}^{m};";
|
||
}
|
||
|
||
private static void SetDimColor(Dimension dim, string prop, int colorIndex)
|
||
{
|
||
try {
|
||
var p = dim.GetType().GetProperty(prop);
|
||
if (p != null) p.SetValue(dim, Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci, (short)colorIndex));
|
||
} catch {}
|
||
}
|
||
private static void SetDimBool(Dimension dim, string prop, bool val)
|
||
{
|
||
try { dim.GetType().GetProperty(prop)?.SetValue(dim, val); } catch {}
|
||
}
|
||
}
|
||
}
|