点击匹配后可以匹配到具体的cad文件
This commit is contained in:
parent
2d5fe10812
commit
ea9e86f1ea
@ -13,19 +13,21 @@ namespace CadParamPluging.Cad
|
||||
public List<string> DeliveryStatuses { get; set; }
|
||||
public List<string> ProcessMethods { get; set; }
|
||||
public List<string> StructuralFeatures { get; set; }
|
||||
public List<string> SpecialConditions { get; set; }
|
||||
|
||||
public LayoutAnnotation()
|
||||
{
|
||||
DeliveryStatuses = new List<string>();
|
||||
ProcessMethods = new List<string>();
|
||||
StructuralFeatures = new List<string>();
|
||||
SpecialConditions = new List<string>();
|
||||
}
|
||||
}
|
||||
|
||||
public static class TemplateLayoutAnnotationExtractor
|
||||
{
|
||||
private static readonly Regex FieldRegex = new Regex(
|
||||
@"^\s*(交付状态|工艺方法|结构特征)\s*[::]\s*(.+?)\s*$",
|
||||
@"^\s*(交付状态|工艺方法|结构特征|特殊条件)\s*[::]\s*(.+?)\s*$",
|
||||
RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex MTextFormatRegex = new Regex(@"\\[A-Za-z]+[^;]*;", RegexOptions.Compiled);
|
||||
@ -101,20 +103,14 @@ namespace CadParamPluging.Cad
|
||||
{
|
||||
if (ent is DBText text)
|
||||
{
|
||||
foreach (var line in SplitLines(text.TextString))
|
||||
{
|
||||
TryParseLine(line, ann);
|
||||
}
|
||||
ParseTextBlock(text.TextString, ann);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ent is MText mt)
|
||||
{
|
||||
var plain = SimplifyMText(mt.Contents);
|
||||
foreach (var line in SplitLines(plain))
|
||||
{
|
||||
TryParseLine(line, ann);
|
||||
}
|
||||
ParseTextBlock(plain, ann);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -128,10 +124,7 @@ namespace CadParamPluging.Cad
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var line in SplitLines(att.TextString))
|
||||
{
|
||||
TryParseLine(line, ann);
|
||||
}
|
||||
ParseTextBlock(att.TextString, ann);
|
||||
}
|
||||
|
||||
// 说明文字可能在块定义内部(非属性),需要递归扫描块内容。
|
||||
@ -159,6 +152,42 @@ namespace CadParamPluging.Cad
|
||||
}
|
||||
}
|
||||
|
||||
private static void ParseTextBlock(string text, LayoutAnnotation ann)
|
||||
{
|
||||
if (ann == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var lines = SplitLines(text).ToList();
|
||||
if (lines.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var hasAnyField = false;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
if (TryParseFieldLine(line, ann))
|
||||
{
|
||||
hasAnyField = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasAnyField)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var line in lines)
|
||||
{
|
||||
if (IsSpecialConditionValueLine(line))
|
||||
{
|
||||
ann.SpecialConditions.Add(NormalizeValue(line));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<string> SplitLines(string text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
@ -191,24 +220,24 @@ namespace CadParamPluging.Cad
|
||||
return s;
|
||||
}
|
||||
|
||||
private static void TryParseLine(string line, LayoutAnnotation ann)
|
||||
private static bool TryParseFieldLine(string line, LayoutAnnotation ann)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
var m = FieldRegex.Match(line);
|
||||
if (!m.Success)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
var key = m.Groups[1].Value;
|
||||
var val = (m.Groups[2].Value ?? string.Empty).Trim();
|
||||
if (val.Length == 0)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
val = NormalizeValue(val);
|
||||
@ -224,7 +253,28 @@ namespace CadParamPluging.Cad
|
||||
case "结构特征":
|
||||
ann.StructuralFeatures.Add(val);
|
||||
break;
|
||||
case "特殊条件":
|
||||
ann.SpecialConditions.Add(val);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool IsSpecialConditionValueLine(string line)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 特殊条件“最后一行”为不带冒号的单独值,且必须在同一文本块内已出现过字段行。
|
||||
if (FieldRegex.IsMatch(line))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return line.IndexOf(':') < 0 && line.IndexOf(':') < 0;
|
||||
}
|
||||
|
||||
private static void Normalize(LayoutAnnotation ann)
|
||||
@ -232,6 +282,7 @@ namespace CadParamPluging.Cad
|
||||
ann.DeliveryStatuses = NormalizeList(ann.DeliveryStatuses);
|
||||
ann.ProcessMethods = NormalizeList(ann.ProcessMethods);
|
||||
ann.StructuralFeatures = NormalizeList(ann.StructuralFeatures);
|
||||
ann.SpecialConditions = NormalizeList(ann.SpecialConditions);
|
||||
}
|
||||
|
||||
private static string NormalizeValue(string s)
|
||||
@ -277,7 +328,8 @@ namespace CadParamPluging.Cad
|
||||
return ann != null
|
||||
&& ((ann.DeliveryStatuses != null && ann.DeliveryStatuses.Count > 0)
|
||||
|| (ann.ProcessMethods != null && ann.ProcessMethods.Count > 0)
|
||||
|| (ann.StructuralFeatures != null && ann.StructuralFeatures.Count > 0));
|
||||
|| (ann.StructuralFeatures != null && ann.StructuralFeatures.Count > 0)
|
||||
|| (ann.SpecialConditions != null && ann.SpecialConditions.Count > 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ namespace CadParamPluging.Cad
|
||||
public List<string> DeliveryStatuses { get; set; }
|
||||
public List<string> ProcessMethods { get; set; }
|
||||
public List<string> StructuralFeatures { get; set; }
|
||||
public List<string> SpecialConditions { get; set; }
|
||||
public Extents3d Window { get; set; }
|
||||
|
||||
public ModelSheetCandidate()
|
||||
@ -21,13 +22,14 @@ namespace CadParamPluging.Cad
|
||||
DeliveryStatuses = new List<string>();
|
||||
ProcessMethods = new List<string>();
|
||||
StructuralFeatures = new List<string>();
|
||||
SpecialConditions = new List<string>();
|
||||
}
|
||||
}
|
||||
|
||||
public static class TemplateModelSheetExtractor
|
||||
{
|
||||
private static readonly Regex FieldRegex = new Regex(
|
||||
@"^\s*(交付状态|工艺方法|结构特征)\s*[::]\s*(.+?)\s*$",
|
||||
@"^\s*(交付状态|工艺方法|结构特征|特殊条件)\s*[::]\s*(.+?)\s*$",
|
||||
RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex MTextFormatRegex = new Regex(@"\\[A-Za-z]+[^;]*;", RegexOptions.Compiled);
|
||||
@ -229,23 +231,81 @@ namespace CadParamPluging.Cad
|
||||
|
||||
private static void TryCollectText(string raw, Point3d pos, List<TextMatch> matches)
|
||||
{
|
||||
foreach (var line in SplitLines(raw))
|
||||
if (matches == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var lines = SplitLines(raw).ToList();
|
||||
if (lines.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var hasAnyField = false;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
if (TryParseFieldLine(line, out var field, out var value))
|
||||
{
|
||||
hasAnyField = true;
|
||||
matches.Add(new TextMatch { Field = field, Value = value, Pos = pos });
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasAnyField)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var line in lines)
|
||||
{
|
||||
if (IsSpecialConditionValueLine(line))
|
||||
{
|
||||
var v = NormalizeValue(line);
|
||||
if (v.Length == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
matches.Add(new TextMatch { Field = "特殊条件", Value = v, Pos = pos });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TryParseFieldLine(string line, out string field, out string value)
|
||||
{
|
||||
field = null;
|
||||
value = null;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var m = FieldRegex.Match(line);
|
||||
if (!m.Success)
|
||||
{
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
|
||||
var field = m.Groups[1].Value;
|
||||
var value = NormalizeValue(m.Groups[2].Value);
|
||||
if (value.Length == 0)
|
||||
field = m.Groups[1].Value;
|
||||
value = NormalizeValue(m.Groups[2].Value);
|
||||
return !string.IsNullOrWhiteSpace(field) && !string.IsNullOrWhiteSpace(value);
|
||||
}
|
||||
|
||||
private static bool IsSpecialConditionValueLine(string line)
|
||||
{
|
||||
continue;
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
matches.Add(new TextMatch { Field = field, Value = value, Pos = pos });
|
||||
if (FieldRegex.IsMatch(line))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return line.IndexOf(':') < 0 && line.IndexOf(':') < 0;
|
||||
}
|
||||
|
||||
private static IEnumerable<string> SplitLines(string text)
|
||||
@ -307,6 +367,7 @@ namespace CadParamPluging.Cad
|
||||
var delivery = cluster.Where(m => m.Field == "交付状态").Select(m => m.Value).Distinct(StringComparer.OrdinalIgnoreCase).ToList();
|
||||
var process = cluster.Where(m => m.Field == "工艺方法").Select(m => m.Value).Distinct(StringComparer.OrdinalIgnoreCase).ToList();
|
||||
var structural = cluster.Where(m => m.Field == "结构特征").Select(m => m.Value).Distinct(StringComparer.OrdinalIgnoreCase).ToList();
|
||||
var special = cluster.Where(m => m.Field == "特殊条件").Select(m => m.Value).Distinct(StringComparer.OrdinalIgnoreCase).ToList();
|
||||
|
||||
if (delivery.Count == 0 || process.Count == 0 || structural.Count == 0)
|
||||
{
|
||||
@ -325,6 +386,7 @@ namespace CadParamPluging.Cad
|
||||
DeliveryStatuses = delivery,
|
||||
ProcessMethods = process,
|
||||
StructuralFeatures = structural,
|
||||
SpecialConditions = special,
|
||||
Window = window
|
||||
});
|
||||
|
||||
|
||||
@ -200,81 +200,69 @@ namespace CadParamPluging.UI
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_selectedTemplate == null || string.IsNullOrWhiteSpace(_selectedTemplate.FilePath))
|
||||
if (_cadFilePaths == null || _cadFilePaths.Length == 0)
|
||||
{
|
||||
AppendLog("请先选择模板文件。");
|
||||
AppendLog("请先选择路径。");
|
||||
return;
|
||||
}
|
||||
|
||||
AppendLog("开始匹配图纸...");
|
||||
AppendLog("开始匹配模板...");
|
||||
|
||||
var tplParams = CollectTemplateParams();
|
||||
// 1) 优先按 Layout 匹配(适用于多布局模板)
|
||||
var layoutCandidates = TemplateLayoutAnnotationExtractor.ExtractPerLayout(_selectedTemplate.FilePath);
|
||||
var layoutMatches = layoutCandidates.Where(c => LayoutMatches(c, tplParams)).ToList();
|
||||
|
||||
if (layoutMatches.Count > 0)
|
||||
foreach (var cadPath in _cadFilePaths)
|
||||
{
|
||||
LayoutAnnotation selectedLayout;
|
||||
if (layoutMatches.Count == 1)
|
||||
if (string.IsNullOrWhiteSpace(cadPath) || !File.Exists(cadPath))
|
||||
{
|
||||
selectedLayout = layoutMatches[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!LayoutSelectForm.TrySelect(this, layoutMatches, out selectedLayout))
|
||||
{
|
||||
AppendLog("用户取消选择图纸。");
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
_selectedTemplate.LayoutName = selectedLayout.LayoutName;
|
||||
// 1) 优先按 Layout(PaperSpace) 匹配
|
||||
var layoutCandidates = TemplateLayoutAnnotationExtractor.ExtractPerLayout(cadPath);
|
||||
var layoutMatch = layoutCandidates.FirstOrDefault(c => LayoutMatches(c, tplParams));
|
||||
if (layoutMatch != null)
|
||||
{
|
||||
_selectedTemplate = new TemplateInfo
|
||||
{
|
||||
Name = Path.GetFileName(cadPath),
|
||||
FilePath = cadPath
|
||||
};
|
||||
|
||||
_selectedTemplate.LayoutName = layoutMatch.LayoutName;
|
||||
_selectedModelWindow = null;
|
||||
_selectedSheetName = selectedLayout.LayoutName;
|
||||
_lblTemplateInfo.Text = $"{_selectedTemplate.FilePath} | {selectedLayout.LayoutName}";
|
||||
AppendLog($"已匹配图纸: {selectedLayout.LayoutName}");
|
||||
_selectedSheetName = layoutMatch.LayoutName;
|
||||
|
||||
_lblTemplateInfo.Text = $"{cadPath} | {layoutMatch.LayoutName}";
|
||||
AppendLog($"匹配成功: {Path.GetFileName(cadPath)} | Layout: {layoutMatch.LayoutName}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 2) 如果 Layout 为空或未匹配,按 ModelSpace 多张图纸模式匹配
|
||||
var modelCandidates = TemplateModelSheetExtractor.ExtractCandidates(_selectedTemplate.FilePath);
|
||||
var modelMatches = modelCandidates.Where(c => ModelMatches(c, tplParams)).ToList();
|
||||
|
||||
if (modelMatches.Count == 0)
|
||||
// 2) Layout 未命中时,尝试按 ModelSpace 窗口候选匹配
|
||||
var modelCandidates = TemplateModelSheetExtractor.ExtractCandidates(cadPath);
|
||||
var modelMatch = modelCandidates.FirstOrDefault(c => ModelMatches(c, tplParams));
|
||||
if (modelMatch != null)
|
||||
{
|
||||
_selectedTemplate = new TemplateInfo
|
||||
{
|
||||
Name = Path.GetFileName(cadPath),
|
||||
FilePath = cadPath
|
||||
};
|
||||
|
||||
_selectedTemplate.LayoutName = null;
|
||||
_selectedModelWindow = modelMatch.Window;
|
||||
_selectedSheetName = modelMatch.Name;
|
||||
|
||||
_lblTemplateInfo.Text = $"{cadPath} | {modelMatch.Name}";
|
||||
AppendLog($"匹配成功: {Path.GetFileName(cadPath)} | Model: {modelMatch.Name}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_selectedTemplate = null;
|
||||
_selectedModelWindow = null;
|
||||
_selectedSheetName = null;
|
||||
_lblTemplateInfo.Text = _selectedTemplate.FilePath;
|
||||
AppendLog("未找到匹配图纸。");
|
||||
AppendLog($"候选图纸数量: {modelCandidates.Count}");
|
||||
foreach (var c in modelCandidates.Take(10))
|
||||
{
|
||||
AppendLog($"候选: {c.Name} | 交付状态={Preview(c.DeliveryStatuses)} | 工艺方法={Preview(c.ProcessMethods)} | 结构特征={Preview(c.StructuralFeatures)}");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ModelSheetCandidate selectedModel;
|
||||
if (modelMatches.Count == 1)
|
||||
{
|
||||
selectedModel = modelMatches[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ModelSheetSelectForm.TrySelect(this, modelMatches, out selectedModel))
|
||||
{
|
||||
AppendLog("用户取消选择图纸。");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_selectedTemplate.LayoutName = null;
|
||||
_selectedModelWindow = selectedModel.Window;
|
||||
_selectedSheetName = selectedModel.Name;
|
||||
_lblTemplateInfo.Text = $"{_selectedTemplate.FilePath} | {selectedModel.Name}";
|
||||
AppendLog($"已匹配图纸: {selectedModel.Name}");
|
||||
_lblTemplateInfo.Text = "未匹配模板";
|
||||
AppendLog("未找到匹配模板。");
|
||||
}
|
||||
catch (BusinessException bex)
|
||||
{
|
||||
@ -310,7 +298,8 @@ namespace CadParamPluging.UI
|
||||
|
||||
return ContainsIgnoreCase(ann.DeliveryStatuses, tplParams.ProjectType)
|
||||
&& ContainsIgnoreCase(ann.ProcessMethods, tplParams.DrawingType)
|
||||
&& ContainsIgnoreCase(ann.StructuralFeatures, tplParams.SheetSize);
|
||||
&& ContainsIgnoreCase(ann.StructuralFeatures, tplParams.SheetSize)
|
||||
&& ContainsIgnoreCase(ann.SpecialConditions, tplParams.Scale);
|
||||
}
|
||||
|
||||
private static bool ContainsIgnoreCase(System.Collections.Generic.IEnumerable<string> values, string expected)
|
||||
@ -361,7 +350,8 @@ namespace CadParamPluging.UI
|
||||
|
||||
return ContainsIgnoreCase(ann.DeliveryStatuses, tplParams.ProjectType)
|
||||
&& ContainsIgnoreCase(ann.ProcessMethods, tplParams.DrawingType)
|
||||
&& ContainsIgnoreCase(ann.StructuralFeatures, tplParams.SheetSize);
|
||||
&& ContainsIgnoreCase(ann.StructuralFeatures, tplParams.SheetSize)
|
||||
&& ContainsIgnoreCase(ann.SpecialConditions, tplParams.Scale);
|
||||
}
|
||||
|
||||
private void OnSelectTemplate()
|
||||
@ -538,7 +528,7 @@ namespace CadParamPluging.UI
|
||||
|
||||
if (_selectedTemplate == null || string.IsNullOrWhiteSpace(_selectedTemplate.FilePath))
|
||||
{
|
||||
AppendLog("请先选择模板文件。");
|
||||
AppendLog("请先选择路径并匹配模板。");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user