增加右下角分类特性参数显示

This commit is contained in:
sladro 2026-01-04 10:54:01 +08:00
parent bb4e338b4a
commit 041940be17
3 changed files with 173 additions and 2 deletions

View File

@ -897,6 +897,167 @@ namespace CadParamPluging.Cad
return string.Join(" ", parts);
}
public static int ApplyFeatureCategory(CadContext ctx, string layoutName, bool scanModelSpace, ParamBag bag)
{
if (ctx == null || bag == null)
{
return 0;
}
var category = bag.GetString("FeatureCategory");
// Logic: Is "一般件" -> show blank.
// Is "关键件"/"重要件" -> show text.
var textToShow = category;
if (string.IsNullOrWhiteSpace(textToShow) || string.Equals(textToShow, "一般件", StringComparison.OrdinalIgnoreCase))
{
textToShow = string.Empty; // Show blank
}
var db = ctx.Database;
var tr = ctx.Transaction;
var space = GetTargetSpace(tr, db, layoutName, scanModelSpace);
if (space == null) return 0;
int count = 0;
foreach (ObjectId id in space)
{
var ent = tr.GetObject(id, OpenMode.ForWrite, false) as Entity;
if (ent == null) continue;
if (ent is DBText t)
{
if (t.TextString.Contains("******"))
{
t.TextString = t.TextString.Replace("******", textToShow);
count++;
}
}
else if (ent is MText mt)
{
if (mt.Contents.Contains("******"))
{
mt.Contents = mt.Contents.Replace("******", textToShow);
count++;
}
}
else if (ent is BlockReference br)
{
foreach (ObjectId attId in br.AttributeCollection)
{
var att = tr.GetObject(attId, OpenMode.ForWrite, false) as AttributeReference;
if (att != null && att.TextString.Contains("******"))
{
att.TextString = att.TextString.Replace("******", textToShow);
count++;
}
}
}
}
// Fallback: If no placeholder found AND we have text to show (e.g. "关键件"), create it manually.
if (count == 0 && !string.IsNullOrWhiteSpace(textToShow))
{
// Try to find white frame to determine position
var spaceEntList = space.Cast<ObjectId>()
.Select(id =>
{
try { return tr.GetObject(id, OpenMode.ForRead, false) as Entity; }
catch { return null; }
})
.Where(e => e != null && !e.IsErased)
.ToList();
var frame = ComputeWhiteFrameExtentsFromEntities(tr, spaceEntList);
if (frame.HasValue)
{
var f = frame.Value;
// Strategy:
// 1. Align Right: Use f.MaxX as the right boundary anchor.
// 2. Find Table Top: Look for horizontal lines in the bottom-right quadrant to find the top of the title block.
// If found, place text above that line. If not, use a safe default from bottom.
var searchRegionMinX = f.MaxPoint.X - 200.0; // Assume title block width < 200
var searchRegionMinY = f.MinPoint.Y;
var searchRegionMaxY = f.MinPoint.Y + 150.0; // Assume title block height < 150
double tableTopY = f.MinPoint.Y + 60.0; // Default fallback (e.g. 60mm from bottom)
// Scan lines to find the highest horizontal line in this region which represents the table top
var candidatesY = new List<double>();
foreach (var ent in spaceEntList)
{
if (ent is Line ln)
{
if (ln.StartPoint.X > searchRegionMinX && ln.EndPoint.X > searchRegionMinX &&
ln.StartPoint.Y > searchRegionMinY && ln.StartPoint.Y < searchRegionMaxY &&
Math.Abs(ln.StartPoint.Y - ln.EndPoint.Y) < 1.0) // Horizontal
{
candidatesY.Add(ln.StartPoint.Y);
}
}
else if (ent is Polyline pl)
{
for (int i = 0; i < pl.NumberOfVertices; i++)
{
var pt = pl.GetPoint3dAt(i);
if (pt.X > searchRegionMinX && pt.Y > searchRegionMinY && pt.Y < searchRegionMaxY)
{
candidatesY.Add(pt.Y);
}
}
}
}
if (candidatesY.Count > 0)
{
// The "Title Block" usually consists of many lines.
// We want the top-most line of the block, but "below" the drawing area.
// Let's take the max Y found in that bottom-right corner zone.
tableTopY = candidatesY.Max();
}
// Position:
// X: f.MaxX - 5 (margin) - (TextWidth/2 treated by Attachment) => Let's use TopRight or MiddleRight alignment
// Anchor at f.MaxX - 2.0 (small margin from right border line)
// Y: tableTopY + 2.0 (small gap above the table line)
// Anchor BottomRight or BottomLeft?
// User image shows text centered in a box-like area ABOVE the table rows.
// Let's align BottomRight to (MaxX - margin, TableTop + margin)
var insertX = f.MaxPoint.X - 5.0;
var insertY = tableTopY + 2.0;
var insertPoint = new Point3d(insertX, insertY, 0);
var mt = new MText();
mt.Contents = ToMTextContents(textToShow);
mt.Location = insertPoint;
mt.TextHeight = 5.0;
mt.Attachment = AttachmentPoint.BottomRight; // Anchor at bottom-right, grows up and left
mt.Width = 0; // No wrap width, auto
mt.ColorIndex = 7;
try
{
var layerTbl = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
if (layerTbl.Has("TEXT")) mt.Layer = "TEXT";
else if (layerTbl.Has("文字")) mt.Layer = "文字";
else mt.Layer = "0";
}
catch { mt.Layer = "0"; }
space.AppendEntity(mt);
tr.AddNewlyCreatedDBObject(mt, true);
count++;
}
}
return count;
}
public static void KeepOnlyLayout(Document doc, string layoutName)
{
if (doc == null)

View File

@ -76,12 +76,12 @@ namespace CadParamPluging.Common
Key = "FeatureCategory",
Label = "特性分类",
Type = ParamValueType.Enum,
Required = false,
Required = true,
DefaultValue = "一般件",
EnumOptions = new List<string> { "一般件", "关键件", "重要件" },
Hint = "下拉列表(一般件/关键件/重要件),点选;关键件/重要件需加方框标注",
Order = 110,
Group = "备注参数"
Group = "模板参数"
},
new ParamDefinition
{

View File

@ -608,6 +608,16 @@ namespace CadParamPluging.UI
AppendLog($"已移除模板匹配参数标注文本: {removed} 处");
}
var featureCategoryCount = TemplateDrawingService.ApplyFeatureCategory(
ctx,
_selectedTemplate.LayoutName,
_selectedModelWindow.HasValue,
bag);
if (featureCategoryCount > 0)
{
AppendLog($"已更新特性分类(******: {featureCategoryCount} 处");
}
var noteResult = TemplateDrawingService.ApplyNoteTemplate(
ctx,
_selectedTemplate.LayoutName,