using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using PdmSwPlugin.Common.Entity; using SolidWorks.Interop.sldworks; namespace PdmSwPlugin.Common.Util { /// /// 工程图属性读取和写的操作类 /// public class EngineeringDrawingPropertiesClass { /// /// 预定义的属性的名称 /// public static string[] PredefinedProperties = new string[] { "加工件类型", "材料", "热处理", "表面处理", "编码", "物料名称", "版本", "设计日期", "审核日期", "设计", "审核" }; /// /// 从工程图的第一个视图里读出所有的注解及其位置的值 /// /// 工程图文档 /// 失败返回空,否则返回所有的 NoteAndPos private static List ReadOutAllNotesAndPositions(ModelDoc2 modelDoc) { if (modelDoc == null) return null; DrawingDoc drawingDoc = modelDoc as DrawingDoc; View view = drawingDoc.GetFirstView(); if (view == null) return null; List allNotesInfo = new List(); try { Note note = view.GetFirstNote(); while (note != null) { // 循环得到所有的注解的位置信息 string text = note.GetText(); double[] pos = note.GetTextPoint2(); allNotesInfo.Add(new NoteAndPos() { OriginalText = text, // 原始文本 TrippedText = text.Replace(" ", string.Empty), // 图纸上的属性名称中间可能有空格,所以要去掉 X = pos[0], Y = pos[1], RawNote = note }); note = note.GetNext(); } } catch { } return allNotesInfo; } /// /// 得到两个属性名中间的 NoteAndPos 对象,也就是左边属性名的属性值 /// /// 所有的NoteAndPos 对象们 /// 左边的属性名 /// 右边的属性名 /// 左边的属性名对应的属性值的NoteAndPos 对象 private static NoteAndPos GetNoteAndPosBetween(IEnumerable all, string leftPropertyName, string rightPropertyName) { if (all == null || all.Count() <= 2 || string.IsNullOrEmpty(leftPropertyName) || string.IsNullOrEmpty(rightPropertyName)) return null; NoteAndPos leftNoteAndPos = all.FirstOrDefault(x => x.TrippedText == leftPropertyName); NoteAndPos rightNoteAndPos = all.FirstOrDefault(x => x.TrippedText == rightPropertyName); if (leftNoteAndPos == null || rightNoteAndPos == null) return null; double minY = leftNoteAndPos.Y * 0.9; double maxY = leftNoteAndPos.Y * 1.1; double minX = leftNoteAndPos.X + (rightNoteAndPos.X - leftNoteAndPos.X) / 3; // 左边的属性名,其宽度至少有两者宽度的三分之一吧? NoteAndPos theOne = all.FirstOrDefault(x => x.X > minX && x.X < rightNoteAndPos.X && x.Y > minY && x.Y < maxY); return theOne; } /// /// 从工程图的第一个视图的注解里读出指定的属性的值 /// 图纸的属性应该只在第一个视图里,所以不用循环所有的视图了 /// /// 工程图文档 /// 要读取的属性的名称,建议使用 PredefinedProperties,也可以自定义 /// 失败返回空,否则返回指定属性的值,可能某些属性并没有值 private static Dictionary ReadValuesOfProperties(ModelDoc2 modelDoc, IEnumerable propertiesToRead) { if (modelDoc == null || propertiesToRead == null || propertiesToRead.Count() <= 0) return null; List allNotesInfo = ReadOutAllNotesAndPositions(modelDoc); if (allNotesInfo == null || allNotesInfo.Count <= 0) return null; Dictionary propertiesNameAndValue = new Dictionary(); foreach (string propertyName in propertiesToRead) { bool setAlready = false; NoteAndPos propertyNameNoteAndPos = null; try { propertyNameNoteAndPos = allNotesInfo.FirstOrDefault(x => x.TrippedText == propertyName); } catch { } if (propertyNameNoteAndPos != null) { double minX = propertyNameNoteAndPos.X + 0.009; // 属性名至少有 1 厘米宽,考虑到偏差,设置为 0.9 厘米宽 double minY = propertyNameNoteAndPos.Y * 0.9; double maxY = propertyNameNoteAndPos.Y * 1.1; IEnumerable allRightOnes = allNotesInfo.Where(x => x.X > minX && x.Y > minY && x.Y < maxY); if (allRightOnes != null && allRightOnes.Count() > 0) { double minimumX = allRightOnes.Select(x => x.X).Min(); NoteAndPos neighboredRightOne = allRightOnes.FirstOrDefault(x => x.X == minimumX); if (neighboredRightOne != null) { if (string.IsNullOrEmpty(neighboredRightOne.TrippedText)) neighboredRightOne.TrippedText = "无"; propertiesNameAndValue[propertyName] = neighboredRightOne; setAlready = true; } } } if (!setAlready) propertiesNameAndValue[propertyName] = null; } return propertiesNameAndValue; } /// /// 从工程图的第一个视图的注解里读出指定的属性的值 /// 图纸的属性应该只在第一个视图里,所以不用循环所有的视图了 /// /// 工程图文档 /// 要读取的属性的名称,建议使用 PredefinedProperties,也可以自定义 /// 失败返回空,否则返回指定属性的值,可能某些属性并没有值得 public static NameValueCollection ReadViaNotesAtFirstView(ModelDoc2 modelDoc, IEnumerable propertiesToRead) { Dictionary allNotes = ReadValuesOfProperties(modelDoc, propertiesToRead); if (allNotes == null) return null; NameValueCollection propertiesNameAndValue = new NameValueCollection(); foreach (KeyValuePair noteInfo in allNotes) { if (noteInfo.Value == null) propertiesNameAndValue[noteInfo.Key] = "无"; else propertiesNameAndValue[noteInfo.Key] = noteInfo.Value.TrippedText; } return propertiesNameAndValue; } /// /// 从工程图的第一个视图的注解里写入一个指定的属性的值 /// 图纸的属性应该只在第一个视图里,所以不用循环所有的视图了 /// /// 工程图文档 /// 要写入的属性的名称,只能使用 PredefinedProperties 中的一个 /// 要写入的属性的值 /// 成功与否 private static bool SetViaAnnotationsAtFirstView(ModelDoc2 modelDoc, string propertyName, string propertyValue) { List propertyNames = new List(); propertyNames.Add(propertyName); Dictionary allNotes = ReadValuesOfProperties(modelDoc, propertyNames); if (allNotes != null) { if (allNotes[propertyName] != null) { allNotes[propertyName].RawNote.SetText(propertyValue); } } /*Note rightNote; Note theNote = (modelDoc, propertyName, out rightNote); if (theNote == null && rightNote == null) return false; rightNote.SetText(propertyValue);*/ return true; } /// /// 往工程图里写入设计人的姓名,不保存 /// /// 工程图文档 /// 设计人的名字 /// 成功与否 public static bool SetDesigner(ModelDoc2 modelDoc, string designer) { return SetViaAnnotationsAtFirstView(modelDoc, PredefinedProperties[9], designer); } } }