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);
|
}
|
}
|
}
|