243 lines
9.1 KiB
C#
243 lines
9.1 KiB
C#
using Laservall.Solidworks.Model;
|
||
using SolidWorks.Interop.sldworks;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Diagnostics;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace Laservall.Solidworks.Extension
|
||
{
|
||
public static class SWDocReader
|
||
{
|
||
// 特殊属性名称(需要通过SolidWorks内置API读取,而非自定义属性)
|
||
private static readonly HashSet<string> SpecialReadProperties = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||
{
|
||
"材质", "MATERIAL",
|
||
"重量", "MASS"
|
||
};
|
||
|
||
public static void ReadDocProperties(IModelDoc2 doc, PartPropModel partPropModel)
|
||
{
|
||
if (doc == null) return;
|
||
|
||
Configuration activeConfig = doc.ConfigurationManager?.ActiveConfiguration;
|
||
CustomPropertyManager configPropMgr = activeConfig?.CustomPropertyManager;
|
||
|
||
CustomPropertyManager filePropMgr = null;
|
||
try
|
||
{
|
||
filePropMgr = doc.Extension?.get_CustomPropertyManager("");
|
||
}
|
||
catch { }
|
||
|
||
partPropModel.GetType().GetProperties().ToList().ForEach(p =>
|
||
{
|
||
p.CustomAttributes.ToList().ForEach(attr =>
|
||
{
|
||
if (attr.AttributeType == typeof(System.ComponentModel.DisplayNameAttribute))
|
||
{
|
||
var displayName = attr.ConstructorArguments[0].Value.ToString();
|
||
|
||
string val = ReadPropertyValue(doc, configPropMgr, filePropMgr, displayName);
|
||
|
||
if (val != null)
|
||
{
|
||
switch (p.PropertyType.Name)
|
||
{
|
||
case "Double":
|
||
if (double.TryParse(val, out double d))
|
||
{
|
||
p.SetValue(partPropModel, d);
|
||
}
|
||
break;
|
||
case "Int32":
|
||
if (int.TryParse(val, out int i))
|
||
{
|
||
p.SetValue(partPropModel, i);
|
||
}
|
||
break;
|
||
case "Boolean":
|
||
// 支持 "true"/"false" 和 "1"/"0" 和 "是"/"否"
|
||
if (bool.TryParse(val, out bool b))
|
||
{
|
||
p.SetValue(partPropModel, b);
|
||
}
|
||
else if (val == "1" || string.Equals(val, "是", StringComparison.OrdinalIgnoreCase))
|
||
{
|
||
p.SetValue(partPropModel, true);
|
||
}
|
||
else if (val == "0" || string.Equals(val, "否", StringComparison.OrdinalIgnoreCase))
|
||
{
|
||
p.SetValue(partPropModel, false);
|
||
}
|
||
break;
|
||
default:
|
||
p.SetValue(partPropModel, val);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取属性值:先检查特殊属性,再尝试配置级,最后回退到文件级
|
||
/// </summary>
|
||
private static string ReadPropertyValue(
|
||
IModelDoc2 doc,
|
||
CustomPropertyManager configPropMgr,
|
||
CustomPropertyManager filePropMgr,
|
||
string propertyName)
|
||
{
|
||
// 1. 特殊属性(内置属性,通过SolidWorks API直接获取)
|
||
if (SpecialReadProperties.Contains(propertyName))
|
||
{
|
||
string specialVal = ReadSpecialProperty(doc, propertyName);
|
||
if (!string.IsNullOrEmpty(specialVal))
|
||
{
|
||
return specialVal;
|
||
}
|
||
// 特殊属性读取失败时,仍尝试从自定义属性读取(用户可能手动设置了)
|
||
}
|
||
|
||
// 2. 配置级自定义属性(优先)
|
||
if (configPropMgr != null)
|
||
{
|
||
string configVal = GetPropertyFromManager(configPropMgr, propertyName);
|
||
if (configVal != null)
|
||
{
|
||
return configVal;
|
||
}
|
||
}
|
||
|
||
// 3. 文件级自定义属性(回退)
|
||
if (filePropMgr != null)
|
||
{
|
||
string fileVal = GetPropertyFromManager(filePropMgr, propertyName);
|
||
if (fileVal != null)
|
||
{
|
||
return fileVal;
|
||
}
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 从指定的CustomPropertyManager读取属性值
|
||
/// </summary>
|
||
private static string GetPropertyFromManager(CustomPropertyManager propMgr, string propertyName)
|
||
{
|
||
try
|
||
{
|
||
int status = propMgr.Get6(propertyName, false, out string val, out string valout, out bool wasResolved, out bool _);
|
||
|
||
// status: swCustomInfoGetResult_e
|
||
// 0 = swCustomInfoGetResult_NotPresent — 属性不存在
|
||
if (status == 0)
|
||
{
|
||
return null;
|
||
}
|
||
|
||
if (wasResolved && !string.IsNullOrEmpty(valout))
|
||
{
|
||
return valout;
|
||
}
|
||
|
||
if (!string.IsNullOrEmpty(val))
|
||
{
|
||
return val;
|
||
}
|
||
|
||
return null;
|
||
}
|
||
catch
|
||
{
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取特殊内置属性(材质、重量等)
|
||
/// </summary>
|
||
private static string ReadSpecialProperty(IModelDoc2 doc, string propertyName)
|
||
{
|
||
try
|
||
{
|
||
// 材质 — 仅Part文件有材质属性
|
||
if (string.Equals(propertyName, "材质", StringComparison.OrdinalIgnoreCase)
|
||
|| string.Equals(propertyName, "MATERIAL", StringComparison.OrdinalIgnoreCase))
|
||
{
|
||
PartDoc partDoc = doc as PartDoc;
|
||
if (partDoc != null)
|
||
{
|
||
Configuration config = doc.ConfigurationManager?.ActiveConfiguration;
|
||
if (config != null)
|
||
{
|
||
string materialName = partDoc.GetMaterialPropertyName2(config.Name, out string _);
|
||
if (!string.IsNullOrEmpty(materialName))
|
||
{
|
||
return materialName;
|
||
}
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
// 重量(质量) — Part和Assembly都支持
|
||
if (string.Equals(propertyName, "重量", StringComparison.OrdinalIgnoreCase)
|
||
|| string.Equals(propertyName, "MASS", StringComparison.OrdinalIgnoreCase))
|
||
{
|
||
ModelDocExtension docExt = doc.Extension;
|
||
if (docExt != null)
|
||
{
|
||
int status = 0;
|
||
// 返回值: [CenterOfMassX, CenterOfMassY, CenterOfMassZ, Volume, Area, Mass, ...]
|
||
double[] massProps = docExt.GetMassProperties(1, ref status) as double[];
|
||
|
||
if (status == 0 && massProps != null && massProps.Length > 5)
|
||
{
|
||
double mass = massProps[5]; // 质量,单位: kg
|
||
return Math.Round(mass, 4).ToString();
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"ReadSpecialProperty({propertyName}) 异常: {ex.Message}");
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取单个属性值(保留向后兼容)
|
||
/// 优先级:特殊属性 > 配置级 > 文件级
|
||
/// </summary>
|
||
public static string GetDocProperty(IModelDoc2 model, string propertyName)
|
||
{
|
||
if (model == null)
|
||
{
|
||
return "未打开任何文档";
|
||
}
|
||
|
||
Configuration activeConfig = model.ConfigurationManager?.ActiveConfiguration;
|
||
CustomPropertyManager configPropMgr = activeConfig?.CustomPropertyManager;
|
||
|
||
CustomPropertyManager filePropMgr = null;
|
||
try
|
||
{
|
||
filePropMgr = model.Extension?.get_CustomPropertyManager("");
|
||
}
|
||
catch { }
|
||
|
||
return ReadPropertyValue(model, configPropMgr, filePropMgr, propertyName) ?? "";
|
||
}
|
||
}
|
||
}
|