feat: 新增 CAD 模板图纸服务,用于打开模板、清理匹配参数标注,并提供相关 UI 和字典辅助功能。

This commit is contained in:
sladro 2026-02-28 08:49:42 +08:00
parent ed86f19c48
commit ad9968f622
4 changed files with 74 additions and 14 deletions

View File

@ -48,16 +48,25 @@ namespace CadParamPluging.Cad
// XRecord 本质上是一个 ResultBuffer 链表
// 我们使用 DxfCode.Text (1000) 来存储 key=value 字符串
var rb = new ResultBuffer();
// serialize user inputs into a single text block
var fullString = "";
foreach (var item in bag.Items)
{
if (!string.IsNullOrWhiteSpace(item.Key))
{
// 格式: Key=Value
// 也可以分开存储,但简单的 Key=Value 字符串更紧凑
string entry = $"{item.Key}={item.Value ?? string.Empty}";
rb.Add(new TypedValue((int)DxfCode.Text, entry));
fullString += $"{item.Key}={item.Value ?? string.Empty}\n";
}
}
// DxfCode.Text has a 255-character limit in AutoCAD ResultBuffer.
// We use code 301 (XTextString) and chunk the string to support any length.
var temp = fullString;
while (temp.Length > 0)
{
var chunk = temp.Length > 250 ? temp.Substring(0, 250) : temp;
rb.Add(new TypedValue(301, chunk)); // 301 = DxfCode.XTextString
temp = temp.Length > 250 ? temp.Substring(250) : "";
}
try
{
@ -114,6 +123,35 @@ namespace CadParamPluging.Cad
return bag;
}
var sb = new System.Text.StringBuilder();
bool hasCode301 = false;
// Read chunks from new format
foreach (var tv in rb)
{
if (tv.TypeCode == 301)
{
hasCode301 = true;
if (tv.Value is string s)
{
sb.Append(s);
}
}
}
if (hasCode301)
{
var fullText = sb.ToString();
foreach (var line in fullText.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries))
{
var parts = line.Split(new[] { '=' }, 2);
if (parts.Length == 2) bag.Set(parts[0], parts[1]);
else if (parts.Length == 1) bag.Set(parts[0], "");
}
return bag;
}
// Fallback to read from old Code 1 format
foreach (var tv in rb)
{
if (tv.TypeCode == (int)DxfCode.Text)

View File

@ -288,8 +288,17 @@ namespace CadParamPluging.Cad
var dict = (DBDictionary)tr.GetObject(ent.ExtensionDictionary, OpenMode.ForWrite);
const string DictName = "CadParamPluging_NoteData";
// XRecord
var rb = new ResultBuffer(new TypedValue((int)DxfCode.Text, template));
// XRecord limits text to 255 characters per element.
// Split string into 250 character chunks using DxfCode.XTextString (301)
var rb = new ResultBuffer();
var temp = template;
while (temp.Length > 0)
{
var chunk = temp.Length > 250 ? temp.Substring(0, 250) : temp;
rb.Add(new TypedValue(301, chunk)); // 301 = DxfCode.XTextString
temp = temp.Length > 250 ? temp.Substring(250) : "";
}
var xrec = new Xrecord { Data = rb };
if (dict.Contains(DictName))
@ -319,6 +328,20 @@ namespace CadParamPluging.Cad
var rb = xrec.Data;
if (rb == null) return null;
var sb = new System.Text.StringBuilder();
bool hasCode301 = false;
foreach (var tv in rb)
{
if (tv.TypeCode == 301)
{
hasCode301 = true;
if (tv.Value is string s) sb.Append(s);
}
}
if (hasCode301) return sb.ToString();
// Fallback for old code format
foreach (var tv in rb)
{
if (tv.TypeCode == (int)DxfCode.Text)
@ -457,7 +480,7 @@ namespace CadParamPluging.Cad
Func<string, string> getValueW = (k) =>
{
var val = bag.GetString(k);
if (k != null && (k.StartsWith("Hardness", StringComparison.OrdinalIgnoreCase) || k.StartsWith("MarkingContent", StringComparison.OrdinalIgnoreCase)))
if (k != null && k.StartsWith("MarkingContent", StringComparison.OrdinalIgnoreCase))
{
if (bag.GetString(k + "_ShowInNote") == "0") return "__SKIP_NOTE__";
}

View File

@ -248,8 +248,8 @@ namespace CadParamPluging.Common
}
else if (string.Equals(val, "空", StringComparison.OrdinalIgnoreCase))
{
// Exception: MarkingContent (标刻内容) should NOT cause line skip
if (key == null || !key.StartsWith("MarkingContent", StringComparison.OrdinalIgnoreCase))
// Exception: MarkingContent (标刻内容) and Hardness (硬度) should NOT cause line skip
if (key == null || !(key.StartsWith("MarkingContent", StringComparison.OrdinalIgnoreCase) || key.StartsWith("Hardness", StringComparison.OrdinalIgnoreCase)))
{
shouldSkip = true;
}
@ -303,9 +303,9 @@ namespace CadParamPluging.Common
// Handle "空" value
if (string.Equals(v, "空", StringComparison.OrdinalIgnoreCase))
{
if (string.Equals(key, "MarkingContent", StringComparison.OrdinalIgnoreCase))
if (key != null && (key.StartsWith("MarkingContent", StringComparison.OrdinalIgnoreCase) || key.StartsWith("Hardness", StringComparison.OrdinalIgnoreCase)))
{
// MarkingContent -> render empty string
// MarkingContent / Hardness -> render empty string
// (Separators will be cleaned up later)
}
else

View File

@ -427,8 +427,7 @@ namespace CadParamPluging.UI
}
Control finalCtrl = ctrl;
if (string.Equals(def.Key, "Hardness", StringComparison.OrdinalIgnoreCase) ||
string.Equals(def.Key, "MarkingContent", StringComparison.OrdinalIgnoreCase))
if (string.Equals(def.Key, "MarkingContent", StringComparison.OrdinalIgnoreCase))
{
var flow = new FlowLayoutPanel
{
@ -657,7 +656,7 @@ namespace CadParamPluging.UI
Func<string, string> getValueW = (k) =>
{
var val = tempBag.GetString(k);
if (k != null && (k.StartsWith("Hardness", StringComparison.OrdinalIgnoreCase) || k.StartsWith("MarkingContent", StringComparison.OrdinalIgnoreCase)))
if (k != null && k.StartsWith("MarkingContent", StringComparison.OrdinalIgnoreCase))
{
if (tempBag.GetString(k + "_ShowInNote") == "0") return "__SKIP_NOTE__";
}