Laservall_solidworks_inject/Extension/SWDocReader.cs

243 lines
9.1 KiB
C#
Raw Permalink Normal View History

using Laservall.Solidworks.Model;
2025-10-10 13:22:56 +08:00
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)
2025-10-10 13:22:56 +08:00
{
"材质", "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 =>
2025-10-10 13:22:56 +08:00
{
p.CustomAttributes.ToList().ForEach(attr =>
2025-10-10 13:22:56 +08:00
{
if (attr.AttributeType == typeof(System.ComponentModel.DisplayNameAttribute))
2025-10-10 13:22:56 +08:00
{
var displayName = attr.ConstructorArguments[0].Value.ToString();
string val = ReadPropertyValue(doc, configPropMgr, filePropMgr, displayName);
if (val != null)
2025-10-10 13:22:56 +08:00
{
switch (p.PropertyType.Name)
2025-10-10 13:22:56 +08:00
{
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;
2025-10-10 13:22:56 +08:00
}
}
}
2025-10-10 13:22:56 +08:00
});
});
2025-10-10 13:22:56 +08:00
}
2025-10-10 13:22:56 +08:00
/// <summary>
/// 读取属性值:先检查特殊属性,再尝试配置级,最后回退到文件级
2025-10-10 13:22:56 +08:00
/// </summary>
private static string ReadPropertyValue(
IModelDoc2 doc,
CustomPropertyManager configPropMgr,
CustomPropertyManager filePropMgr,
string propertyName)
2025-10-10 13:22:56 +08:00
{
// 1. 特殊属性内置属性通过SolidWorks API直接获取
if (SpecialReadProperties.Contains(propertyName))
2025-10-10 13:22:56 +08:00
{
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;
}
2025-10-10 13:22:56 +08:00
}
// 3. 文件级自定义属性(回退)
if (filePropMgr != null)
2025-10-10 13:22:56 +08:00
{
string fileVal = GetPropertyFromManager(filePropMgr, propertyName);
if (fileVal != null)
{
return fileVal;
}
}
2025-10-10 13:22:56 +08:00
return null;
}
2025-10-10 13:22:56 +08:00
/// <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))
2025-10-10 13:22:56 +08:00
{
return valout;
}
if (!string.IsNullOrEmpty(val))
2025-10-10 13:22:56 +08:00
{
return val;
}
return null;
}
catch
{
return null;
2025-10-10 13:22:56 +08:00
}
}
/// <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) ?? "";
}
2025-10-10 13:22:56 +08:00
}
}