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 SpecialReadProperties = new HashSet(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; } } } }); }); } /// /// 读取属性值:先检查特殊属性,再尝试配置级,最后回退到文件级 /// 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; } /// /// 从指定的CustomPropertyManager读取属性值 /// 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; } } /// /// 读取特殊内置属性(材质、重量等) /// 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; } /// /// 获取单个属性值(保留向后兼容) /// 优先级:特殊属性 > 配置级 > 文件级 /// 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) ?? ""; } } }