Laservall_solidworks_inject/Extension/SWDocReader.cs

243 lines
9.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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