修改缩放功能
This commit is contained in:
parent
cdd9ae1f43
commit
34028c1ac6
@ -91,14 +91,125 @@ namespace CadParamPluging.Cad
|
||||
|
||||
#endregion
|
||||
|
||||
#region 预期图形尺寸计算
|
||||
|
||||
/// <summary>
|
||||
/// 预期图形尺寸
|
||||
/// </summary>
|
||||
public class ExpectedDrawingSize
|
||||
{
|
||||
public double Width { get; set; }
|
||||
public double Height { get; set; }
|
||||
public bool IsValid => Width > 0 && Height > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据参数计算预期绘制图形的尺寸(不包含标注,仅计算图形主体)
|
||||
/// </summary>
|
||||
public static ExpectedDrawingSize CalculateExpectedSize(ParamBag bag, string structuralFeature)
|
||||
{
|
||||
if (bag == null)
|
||||
{
|
||||
return new ExpectedDrawingSize();
|
||||
}
|
||||
|
||||
if (IsRing(structuralFeature))
|
||||
{
|
||||
return CalculateRingSize(bag);
|
||||
}
|
||||
if (IsDisk(structuralFeature))
|
||||
{
|
||||
return CalculateDiskSize(bag);
|
||||
}
|
||||
if (IsShaft(structuralFeature))
|
||||
{
|
||||
return CalculateShaftSize(bag);
|
||||
}
|
||||
if (IsBlock(structuralFeature))
|
||||
{
|
||||
return CalculateBlockSize(bag);
|
||||
}
|
||||
|
||||
return new ExpectedDrawingSize();
|
||||
}
|
||||
|
||||
private static ExpectedDrawingSize CalculateRingSize(ParamBag bag)
|
||||
{
|
||||
var outerDia = bag.GetDoubleOrNull(KeyOuterDiameter1) ?? 0;
|
||||
var height = bag.GetDoubleOrNull(KeyHeight1) ?? 0;
|
||||
|
||||
// 环形图形:宽度=高度参数(X方向),高度=外径(Y方向)
|
||||
// 加上标注的额外空间(约40像素每侧)
|
||||
var extraMargin = 40;
|
||||
return new ExpectedDrawingSize
|
||||
{
|
||||
Width = height + extraMargin * 2,
|
||||
Height = outerDia + extraMargin * 2
|
||||
};
|
||||
}
|
||||
|
||||
private static ExpectedDrawingSize CalculateDiskSize(ParamBag bag)
|
||||
{
|
||||
var diameter = bag.GetDoubleOrNull(KeyDiskDiameter) ?? 0;
|
||||
var height = bag.GetDoubleOrNull(KeyDiskHeight) ?? 0;
|
||||
|
||||
var extraMargin = 40;
|
||||
return new ExpectedDrawingSize
|
||||
{
|
||||
Width = diameter + extraMargin * 2,
|
||||
Height = height + extraMargin * 2
|
||||
};
|
||||
}
|
||||
|
||||
private static ExpectedDrawingSize CalculateShaftSize(ParamBag bag)
|
||||
{
|
||||
var diameter = bag.GetDoubleOrNull(KeyDiameter) ?? 0;
|
||||
var length = bag.GetDoubleOrNull(KeyLength) ?? 0;
|
||||
|
||||
var extraMargin = 40;
|
||||
return new ExpectedDrawingSize
|
||||
{
|
||||
Width = length + extraMargin * 2,
|
||||
Height = diameter + extraMargin * 2
|
||||
};
|
||||
}
|
||||
|
||||
private static ExpectedDrawingSize CalculateBlockSize(ParamBag bag)
|
||||
{
|
||||
var size1 = bag.GetDoubleOrNull(KeySize1) ?? bag.GetDoubleOrNull("Size123") ?? 0;
|
||||
var size2 = bag.GetDoubleOrNull(KeySize2) ?? size1;
|
||||
|
||||
var extraMargin = 40;
|
||||
return new ExpectedDrawingSize
|
||||
{
|
||||
Width = size1 + extraMargin * 2,
|
||||
Height = size2 + extraMargin * 2
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 主入口
|
||||
|
||||
/// <summary>
|
||||
/// 绘制图形(带缩放支持)
|
||||
/// </summary>
|
||||
/// <param name="ctx">CAD上下文</param>
|
||||
/// <param name="bag">参数包</param>
|
||||
/// <param name="deliveryStatus">交付状态</param>
|
||||
/// <param name="structuralFeature">结构特征</param>
|
||||
/// <param name="specialCondition">特殊条件</param>
|
||||
/// <param name="center">绘图中心点</param>
|
||||
/// <param name="scaleFactor">缩放比例(1.0表示不缩放)</param>
|
||||
public static void Draw(CadContext ctx, ParamBag bag, string deliveryStatus, string structuralFeature,
|
||||
string specialCondition = null, Point3d? center = null)
|
||||
string specialCondition = null, Point3d? center = null, 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 btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
|
||||
@ -106,7 +217,7 @@ namespace CadParamPluging.Cad
|
||||
var context = new DrawingContext
|
||||
{
|
||||
Ctx = ctx,
|
||||
Bag = bag,
|
||||
Bag = effectiveBag,
|
||||
Center = center ?? Point3d.Origin,
|
||||
DeliveryStatus = deliveryStatus,
|
||||
StructuralFeature = structuralFeature,
|
||||
@ -759,6 +870,78 @@ namespace CadParamPluging.Cad
|
||||
catch { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对参数包中的尺寸参数应用缩放比例
|
||||
/// </summary>
|
||||
private static ParamBag ScaleParamBag(ParamBag original, double scaleFactor)
|
||||
{
|
||||
if (original == null || scaleFactor <= 0 || scaleFactor >= 1.0)
|
||||
{
|
||||
return original;
|
||||
}
|
||||
|
||||
var scaled = new ParamBag();
|
||||
|
||||
// 需要缩放的尺寸参数Key列表
|
||||
var sizeKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
// 环形参数
|
||||
KeyOuterDiameter1, KeyInnerDiameter2, KeyHeight1,
|
||||
KeyOuterDiameter1Prime, KeyInnerDiameter2Prime, KeyHeight1Prime,
|
||||
KeyMinWallThickness,
|
||||
// 饼盘参数
|
||||
KeyDiskDiameter, KeyDiskHeight,
|
||||
// 轴杆参数
|
||||
KeyDiameter, KeyLength,
|
||||
// 方形参数
|
||||
KeySize1, KeySize2, KeySize3, "Size123",
|
||||
// 圆角参数
|
||||
KeyUnspecifiedFilletRadiusMax, KeyInnerRadiusMax, KeyRoundHeadFilletRadiusMax
|
||||
};
|
||||
|
||||
// 公差参数也需要缩放
|
||||
var toleranceKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
KeyOuterDiameter1TolPlus, KeyOuterDiameter1TolMinus,
|
||||
KeyInnerDiameter2TolPlus, KeyInnerDiameter2TolMinus,
|
||||
KeyHeight1TolPlus, KeyHeight1TolMinus,
|
||||
KeyDiskDiameterTolPlus, KeyDiskDiameterTolMinus,
|
||||
KeyDiskHeightTolPlus, KeyDiskHeightTolMinus,
|
||||
KeyDiameterTolPlus, KeyDiameterTolMinus,
|
||||
KeyLengthTolPlus, KeyLengthTolMinus,
|
||||
KeySize1TolPlus, KeySize1TolMinus,
|
||||
KeySize2TolPlus, KeySize2TolMinus,
|
||||
KeySize3TolPlus, KeySize3TolMinus
|
||||
};
|
||||
|
||||
foreach (var key in original.GetKeys())
|
||||
{
|
||||
var value = original.GetString(key);
|
||||
|
||||
if (sizeKeys.Contains(key) || toleranceKeys.Contains(key))
|
||||
{
|
||||
// 尝试解析为数值并缩放
|
||||
if (double.TryParse(value, out var numValue))
|
||||
{
|
||||
var scaledValue = numValue * scaleFactor;
|
||||
// 保留适当的小数位数
|
||||
scaled.Set(key, scaledValue.ToString("F2"));
|
||||
}
|
||||
else
|
||||
{
|
||||
scaled.Set(key, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 非尺寸参数直接复制
|
||||
scaled.Set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
return scaled;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,11 +20,12 @@ namespace CadParamPluging.Cad
|
||||
/// <param name="structuralFeature">结构特征(环形/饼盘/轴杆/方体)</param>
|
||||
/// <param name="specialCondition">特殊条件(中心冲孔/有圆头等)</param>
|
||||
/// <param name="center">绘图中心点</param>
|
||||
/// <param name="scaleFactor">缩放比例(1.0表示不缩放)</param>
|
||||
public static void Draw(CadContext ctx, ParamBag bag, string deliveryStatus, string structuralFeature,
|
||||
string specialCondition = null, Point3d? center = null)
|
||||
string specialCondition = null, Point3d? center = null, double scaleFactor = 1.0)
|
||||
{
|
||||
// 委托给特征驱动绘图引擎
|
||||
FeatureDrivenDrawer.Draw(ctx, bag, deliveryStatus, structuralFeature, specialCondition, center);
|
||||
FeatureDrivenDrawer.Draw(ctx, bag, deliveryStatus, structuralFeature, specialCondition, center, scaleFactor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -1313,5 +1313,185 @@ namespace CadParamPluging.Cad
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测白色外框(图纸边界)的范围
|
||||
/// 白色外框通常是 ColorIndex=7 的 Line 或 Polyline,构成图纸的可绘图区域
|
||||
/// </summary>
|
||||
public static Extents3d? ComputeWhiteFrameExtents(CadContext ctx)
|
||||
{
|
||||
if (ctx == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var db = ctx.Database;
|
||||
var tr = ctx.Transaction;
|
||||
|
||||
var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
|
||||
var ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
|
||||
|
||||
var allEntities = ms.Cast<ObjectId>()
|
||||
.Select(id => tr.GetObject(id, OpenMode.ForRead, false) as Entity)
|
||||
.Where(e => e != null && !e.IsErased)
|
||||
.ToList();
|
||||
|
||||
return ComputeWhiteFrameExtentsFromEntities(tr, allEntities);
|
||||
}
|
||||
|
||||
private static Extents3d? ComputeWhiteFrameExtentsFromEntities(Transaction tr, IEnumerable<Entity> entities)
|
||||
{
|
||||
Extents3d? result = null;
|
||||
|
||||
foreach (var ent in entities)
|
||||
{
|
||||
if (ent == null || ent.IsErased)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// 只处理 Line 或 Polyline
|
||||
if (!(ent is Line) && !(ent is Polyline))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查是否是白色(ColorIndex=7)
|
||||
if (!IsWhiteColor(ent, tr))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var ext = ent.GeometricExtents;
|
||||
if (result == null)
|
||||
{
|
||||
result = ext;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = new Extents3d(
|
||||
new Point3d(
|
||||
Math.Min(result.Value.MinPoint.X, ext.MinPoint.X),
|
||||
Math.Min(result.Value.MinPoint.Y, ext.MinPoint.Y),
|
||||
Math.Min(result.Value.MinPoint.Z, ext.MinPoint.Z)),
|
||||
new Point3d(
|
||||
Math.Max(result.Value.MaxPoint.X, ext.MaxPoint.X),
|
||||
Math.Max(result.Value.MaxPoint.Y, ext.MaxPoint.Y),
|
||||
Math.Max(result.Value.MaxPoint.Z, ext.MaxPoint.Z)));
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 忽略
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool IsWhiteColor(Entity ent, Transaction tr)
|
||||
{
|
||||
if (ent == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ColorIndex=7 是白色
|
||||
var colorIndex = ent.ColorIndex;
|
||||
if (colorIndex == 7)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// ColorIndex=256 表示 ByLayer,需要检查图层颜色
|
||||
if (colorIndex == 256 && tr != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var layer = tr.GetObject(ent.LayerId, OpenMode.ForRead) as LayerTableRecord;
|
||||
if (layer != null && layer.Color.ColorIndex == 7)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 忽略
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 图形尺寸检查结果
|
||||
/// </summary>
|
||||
public sealed class DrawingSizeCheckResult
|
||||
{
|
||||
public bool NeedsScaling { get; set; }
|
||||
public double ScaleFactor { get; set; } = 1.0;
|
||||
public double DrawingWidth { get; set; }
|
||||
public double DrawingHeight { get; set; }
|
||||
public double AvailableWidth { get; set; }
|
||||
public double AvailableHeight { get; set; }
|
||||
public string Message { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查图形是否会超出图纸边界,如果超出则计算缩放比例
|
||||
/// </summary>
|
||||
/// <param name="whiteFrameExtents">白色外框范围</param>
|
||||
/// <param name="drawingWidth">预期绘制图形的宽度</param>
|
||||
/// <param name="drawingHeight">预期绘制图形的高度</param>
|
||||
/// <param name="margin">边距(默认50)</param>
|
||||
/// <returns>检查结果,包含是否需要缩放和缩放比例</returns>
|
||||
public static DrawingSizeCheckResult CheckDrawingSize(Extents3d? whiteFrameExtents, double drawingWidth, double drawingHeight, double margin = 50)
|
||||
{
|
||||
var result = new DrawingSizeCheckResult
|
||||
{
|
||||
DrawingWidth = drawingWidth,
|
||||
DrawingHeight = drawingHeight
|
||||
};
|
||||
|
||||
if (!whiteFrameExtents.HasValue)
|
||||
{
|
||||
result.Message = "未检测到白色外框,跳过尺寸检查";
|
||||
return result;
|
||||
}
|
||||
|
||||
var frame = whiteFrameExtents.Value;
|
||||
var availableWidth = frame.MaxPoint.X - frame.MinPoint.X - margin * 2;
|
||||
var availableHeight = frame.MaxPoint.Y - frame.MinPoint.Y - margin * 2;
|
||||
|
||||
result.AvailableWidth = availableWidth;
|
||||
result.AvailableHeight = availableHeight;
|
||||
|
||||
if (availableWidth <= 0 || availableHeight <= 0)
|
||||
{
|
||||
result.Message = "白色外框范围无效";
|
||||
return result;
|
||||
}
|
||||
|
||||
// 计算宽度和高度的缩放比例,取较小值(等比例缩放)
|
||||
var scaleX = availableWidth / drawingWidth;
|
||||
var scaleY = availableHeight / drawingHeight;
|
||||
|
||||
if (scaleX >= 1.0 && scaleY >= 1.0)
|
||||
{
|
||||
result.NeedsScaling = false;
|
||||
result.ScaleFactor = 1.0;
|
||||
result.Message = $"图形尺寸正常,无需缩放 (图形: {drawingWidth:F1}x{drawingHeight:F1}, 可用: {availableWidth:F1}x{availableHeight:F1})";
|
||||
return result;
|
||||
}
|
||||
|
||||
// 需要缩放,取较小的比例以确保两个方向都不超出
|
||||
result.NeedsScaling = true;
|
||||
result.ScaleFactor = Math.Min(scaleX, scaleY);
|
||||
result.Message = $"图形超出边界,将等比例缩放至 {result.ScaleFactor:P1} (图形: {drawingWidth:F1}x{drawingHeight:F1}, 可用: {availableWidth:F1}x{availableHeight:F1})";
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -616,6 +616,51 @@ namespace CadParamPluging.UI
|
||||
var removeResult = TemplateDrawingService.RemoveTemplateOriginalDrawing(ctx);
|
||||
AppendLog($"已删除原有图形: 红色外框={removeResult.OuterFrameErased}, CAXA图层={removeResult.CaxaLayerErased}, 标注={removeResult.DimensionLayerErased}, 保留右上角={removeResult.DimensionLayerKept}");
|
||||
|
||||
// 检测白色外框(图纸边界)范围
|
||||
var whiteFrameExtents = TemplateDrawingService.ComputeWhiteFrameExtents(ctx);
|
||||
|
||||
// 计算预期图形尺寸
|
||||
var expectedSize = FeatureDrivenDrawer.CalculateExpectedSize(bag, tplParams.SheetSize);
|
||||
|
||||
// 检查是否会超出图纸边界
|
||||
double scaleFactor = 1.0;
|
||||
if (expectedSize.IsValid && whiteFrameExtents.HasValue)
|
||||
{
|
||||
var sizeCheck = TemplateDrawingService.CheckDrawingSize(
|
||||
whiteFrameExtents,
|
||||
expectedSize.Width,
|
||||
expectedSize.Height,
|
||||
50); // 边距50
|
||||
|
||||
AppendLog(sizeCheck.Message);
|
||||
|
||||
if (sizeCheck.NeedsScaling)
|
||||
{
|
||||
// 询问用户是否要等比例缩放
|
||||
var confirmScale = MessageBox.Show(
|
||||
this,
|
||||
$"图形尺寸超出图纸边界!\n\n" +
|
||||
$"图形尺寸: {expectedSize.Width:F1} x {expectedSize.Height:F1}\n" +
|
||||
$"可用区域: {sizeCheck.AvailableWidth:F1} x {sizeCheck.AvailableHeight:F1}\n" +
|
||||
$"建议缩放比例: {sizeCheck.ScaleFactor:P1}\n\n" +
|
||||
$"是否等比例缩小图形以适应图纸?\n" +
|
||||
$"选择【是】将自动缩放,选择【否】将按原尺寸绘制(可能超出边界)",
|
||||
"图形尺寸超出",
|
||||
MessageBoxButtons.YesNo,
|
||||
MessageBoxIcon.Warning);
|
||||
|
||||
if (confirmScale == DialogResult.Yes)
|
||||
{
|
||||
scaleFactor = sizeCheck.ScaleFactor;
|
||||
AppendLog($"将应用缩放比例: {scaleFactor:P1}");
|
||||
}
|
||||
else
|
||||
{
|
||||
AppendLog("用户选择按原尺寸绘制");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 根据模板参数绘制半剖视图,居中放置于原图纸位置
|
||||
// 使用特征驱动模式:根据参数存在性动态绘制对应特征
|
||||
HalfSectionDrawer.Draw(
|
||||
@ -624,7 +669,8 @@ namespace CadParamPluging.UI
|
||||
tplParams.ProjectType, // 交付状态
|
||||
tplParams.SheetSize, // 结构特征
|
||||
tplParams.Scale, // 特殊条件(中心冲孔/有圆头等)
|
||||
removeResult.OriginalCenter // 原图纸中心点
|
||||
removeResult.OriginalCenter, // 原图纸中心点
|
||||
scaleFactor // 缩放比例
|
||||
);
|
||||
|
||||
ctx.Commit();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user