chr
2024-08-12 e9d7a5ef4c17e4804fb988dd193ff7d1fa36d52b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using PdmSwPlugin.Common.Entity;
using SolidWorks.Interop.sldworks;
 
namespace PdmSwPlugin.Common.Util
{
    /// <summary>
    /// 工程图属性读取和写的操作类
    /// </summary>
    public class EngineeringDrawingPropertiesClass
    {
        /// <summary>
        /// 预定义的属性的名称
        /// </summary>
        public static string[] PredefinedProperties = new string[]
        {
            "加工件类型",
            "材料",
            "热处理",
            "表面处理",
            "编码",
            "物料名称",
            "版本",
            "设计日期",
            "审核日期",
            "设计",
            "审核"
        };
 
        /// <summary>
        /// 从工程图的第一个视图里读出所有的注解及其位置的值
        /// </summary>
        /// <param name="modelDoc">工程图文档</param>
        /// <returns>失败返回空,否则返回所有的 NoteAndPos</returns>
        private static List<NoteAndPos> ReadOutAllNotesAndPositions(ModelDoc2 modelDoc)
        {
            if (modelDoc == null)
                return null;
            DrawingDoc drawingDoc = modelDoc as DrawingDoc;
            View view = drawingDoc.GetFirstView();
            if (view == null)
                return null;
            List<NoteAndPos> allNotesInfo = new List<NoteAndPos>();
            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;
        }
 
        /// <summary>
        /// 得到两个属性名中间的 NoteAndPos 对象,也就是左边属性名的属性值
        /// </summary>
        /// <param name="all">所有的NoteAndPos 对象们</param>
        /// <param name="leftPropertyName">左边的属性名</param>
        /// <param name="rightPropertyName">右边的属性名</param>
        /// <returns>左边的属性名对应的属性值的NoteAndPos 对象</returns>
        private static NoteAndPos GetNoteAndPosBetween(IEnumerable<NoteAndPos> 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;
        }
 
        /// <summary>
        /// 从工程图的第一个视图的注解里读出指定的属性的值
        ///  图纸的属性应该只在第一个视图里,所以不用循环所有的视图了
        /// </summary>
        /// <param name="modelDoc">工程图文档</param>
        /// <param name="propertiesToRead">要读取的属性的名称,建议使用 PredefinedProperties,也可以自定义</param>
        /// <returns>失败返回空,否则返回指定属性的值,可能某些属性并没有值</returns>
        private static Dictionary<string, NoteAndPos> ReadValuesOfProperties(ModelDoc2 modelDoc, IEnumerable<string> propertiesToRead)
        {
            if (modelDoc == null || propertiesToRead == null || propertiesToRead.Count() <= 0)
                return null;
            List<NoteAndPos> allNotesInfo = ReadOutAllNotesAndPositions(modelDoc);
            if (allNotesInfo == null || allNotesInfo.Count <= 0)
                return null;
 
            Dictionary<string, NoteAndPos> propertiesNameAndValue = new Dictionary<string, NoteAndPos>();
            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<NoteAndPos> 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;
        }
 
        /// <summary>
        /// 从工程图的第一个视图的注解里读出指定的属性的值
        ///  图纸的属性应该只在第一个视图里,所以不用循环所有的视图了
        /// </summary>
        /// <param name="modelDoc">工程图文档</param>
        /// <param name="propertiesToRead">要读取的属性的名称,建议使用 PredefinedProperties,也可以自定义</param>
        /// <returns>失败返回空,否则返回指定属性的值,可能某些属性并没有值得</returns>
        public static NameValueCollection ReadViaNotesAtFirstView(ModelDoc2 modelDoc, IEnumerable<string> propertiesToRead)
        {
            Dictionary<string, NoteAndPos> allNotes = ReadValuesOfProperties(modelDoc, propertiesToRead);
            if (allNotes == null)
                return null;
            NameValueCollection propertiesNameAndValue = new NameValueCollection();
            foreach (KeyValuePair<string, NoteAndPos> noteInfo in allNotes)
            {
                if (noteInfo.Value == null)
                    propertiesNameAndValue[noteInfo.Key] = "无";
                else
                    propertiesNameAndValue[noteInfo.Key] = noteInfo.Value.TrippedText;
            }
            return propertiesNameAndValue;
        }
 
        /// <summary>
        /// 从工程图的第一个视图的注解里写入一个指定的属性的值
        ///  图纸的属性应该只在第一个视图里,所以不用循环所有的视图了
        /// </summary>
        /// <param name="modelDoc">工程图文档</param>
        /// <param name="propertyName">要写入的属性的名称,只能使用 PredefinedProperties 中的一个</param>
        /// <param name="propertyValue">要写入的属性的值</param>
        /// <returns>成功与否</returns>
        private static bool SetViaAnnotationsAtFirstView(ModelDoc2 modelDoc, string propertyName, string propertyValue)
        {
            List<string> propertyNames = new List<string>();
            propertyNames.Add(propertyName);
            Dictionary<string, NoteAndPos> 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;
        }
 
        /// <summary>
        /// 往工程图里写入设计人的姓名,不保存
        /// </summary>
        /// <param name="modelDoc">工程图文档</param>
        /// <param name="designer">设计人的名字</param>
        /// <returns>成功与否</returns>
        public static bool SetDesigner(ModelDoc2 modelDoc, string designer)
        {
            return SetViaAnnotationsAtFirstView(modelDoc, PredefinedProperties[9], designer);
        }
    }
}