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