Laservall_solidworks_inject/Server/SolidWorksBomDataProvider.cs

274 lines
9.8 KiB
C#
Raw Normal View History

using Laservall.Solidworks.Extension;
using Laservall.Solidworks.Model;
using Laservall.Solidworks.Windows;
using SolidWorks.Interop.sldworks;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Laservall.Solidworks.Server
{
internal sealed class SolidWorksBomDataProvider : IBomDataProvider
{
private readonly StaThreadMarshaller _marshaller;
private static readonly HashSet<string> StaticColumnProps = new HashSet<string>
{
"零件名称", "材质", "属性", "材料"
};
public SolidWorksBomDataProvider(StaThreadMarshaller marshaller)
{
_marshaller = marshaller ?? throw new ArgumentNullException(nameof(marshaller));
}
public async Task<BomLoadResult> LoadBomAsync(IProgress<BomLoadProgress> progress, CancellationToken ct)
{
return await _marshaller.InvokeAsync(async () =>
{
ModelDoc2 model = SWUtils.SwApp.ActiveDoc as ModelDoc2;
if (model == null)
{
return new BomLoadResult
{
Items = new List<BomItemModel>(),
DynamicKeys = new List<string>(),
Settings = BomSettings.Load()
};
}
Configuration config = model.ConfigurationManager.ActiveConfiguration;
var rootTree = new SwAssDocTreeModel
{
drawingNo = Path.GetFileNameWithoutExtension(model.GetPathName()),
docPath = model.GetPathName(),
configName = config?.Name ?? "",
children = new List<SwAssDocTreeModel>(),
isAss = true,
quantity = 1,
props = SWUtils.GetConfig3(model.GetPathName())
};
Component2 rootComponent = config?.GetRootComponent3(true) as Component2;
int totalCount = GetTotalComponentCount(model);
if (HasLightweightComponents(model))
{
ResolvingProgressWindow.RunWithProgress(() =>
{
SWUtils.SetAllPartResolved(model.GetPathName());
});
}
if (rootComponent != null)
{
IProgress<SwTreeLoadProgress> swProgress = null;
if (progress != null)
{
swProgress = new Progress<SwTreeLoadProgress>(p =>
{
progress.Report(new BomLoadProgress
{
Processed = p.Processed,
Total = p.Total,
CurrentName = p.CurrentName
});
});
}
var parts = await SWUtils.GetSwAssDocTreeChildrenAsync(
rootComponent, true, true, totalCount, swProgress);
rootTree.children.AddRange(parts);
}
var allItems = SWUtils.FlattenBomTree(rootTree);
var propKeys = SWUtils.CollectAllPropertyKeys(allItems);
var dynamicKeys = propKeys
.Where(k => !StaticColumnProps.Contains(k))
.OrderBy(k => k)
.ToList();
var settings = BomSettings.Load();
settings.MergeDynamicKeys(dynamicKeys);
var userAddedKeys = settings.Columns
.Where(c => c.IsUserAdded && !dynamicKeys.Contains(c.Name))
.Select(c => c.Name)
.ToList();
dynamicKeys.AddRange(userAddedKeys);
EnsurePropsKeys(allItems, dynamicKeys);
return new BomLoadResult
{
Items = allItems,
DynamicKeys = dynamicKeys,
Settings = settings
};
});
}
public SaveResult SaveChanges(List<ChangeItem> changes)
{
if (changes == null || changes.Count == 0)
{
return new SaveResult { Success = true, SavedCount = 0 };
}
return _marshaller.Invoke(() =>
{
try
{
var grouped = changes
.Where(c => !string.IsNullOrEmpty(c.DocPath) && !string.IsNullOrEmpty(c.Key))
.GroupBy(c => c.DocPath);
int savedCount = 0;
foreach (var group in grouped)
{
ModelDoc2 doc = SWUtils.OpenDocSilently(group.Key);
if (doc == null) continue;
Configuration activeConfig = doc.ConfigurationManager?.ActiveConfiguration;
CustomPropertyManager configPropMgr = activeConfig?.CustomPropertyManager;
CustomPropertyManager filePropMgr = null;
try
{
filePropMgr = doc.Extension?.get_CustomPropertyManager("");
}
catch { }
foreach (var change in group)
{
bool writtenToConfig = false;
if (configPropMgr != null)
{
var configNames = configPropMgr.GetNames() as string[];
if (configNames != null && configNames.Contains(change.Key))
{
configPropMgr.Set2(change.Key, change.Value ?? "");
writtenToConfig = true;
}
}
if (!writtenToConfig && filePropMgr != null)
{
filePropMgr.Set2(change.Key, change.Value ?? "");
}
else if (!writtenToConfig && configPropMgr != null)
{
configPropMgr.Set2(change.Key, change.Value ?? "");
}
}
doc.Save3(0, 0, 0);
savedCount++;
}
return new SaveResult { Success = true, SavedCount = savedCount };
}
catch (Exception ex)
{
return new SaveResult { Success = false, Error = ex.Message };
}
});
}
public BomSettings GetSettings()
{
return BomSettings.Load();
}
public void SaveSettings(BomSettings settings)
{
settings?.Save();
}
public List<BomItemModel> GetFlatBomItems(List<BomItemModel> allItems)
{
return allItems
.Where(i => !i.IsAssembly)
.GroupBy(i => i.DrawingNo ?? "")
.Select(g =>
{
var first = g.First();
return new BomItemModel
{
Level = 0,
LevelDisplay = "",
DrawingNo = first.DrawingNo,
ConfigName = first.ConfigName,
PartName = first.PartName,
MaterialProp = first.MaterialProp,
Material = first.Material,
Classification = first.Classification,
Quantity = g.Sum(x => x.Quantity),
IsAssembly = false,
IsOutSourcing = first.IsOutSourcing,
DocPath = first.DocPath,
Props = first.Props,
HasChildren = false,
IsExpanded = false,
IsVisible = true
};
})
.ToList();
}
private static void EnsurePropsKeys(List<BomItemModel> items, List<string> keys)
{
foreach (var item in items)
{
if (item.Props == null)
{
item.Props = new Dictionary<string, string>();
}
foreach (var key in keys)
{
if (!item.Props.ContainsKey(key))
{
item.Props[key] = "";
}
}
}
}
private static int GetTotalComponentCount(ModelDoc2 model)
{
AssemblyDoc assembly = model as AssemblyDoc;
if (assembly == null)
{
return 1;
}
object[] components = assembly.GetComponents(false) as object[];
return Math.Max((components?.Length ?? 0) + 1, 1);
}
private static bool HasLightweightComponents(ModelDoc2 model)
{
AssemblyDoc assembly = model as AssemblyDoc;
if (assembly == null) return false;
object[] components = assembly.GetComponents(false) as object[];
if (components == null) return false;
foreach (object obj in components)
{
Component2 comp = obj as Component2;
if (comp == null) continue;
int state = comp.GetSuppression();
// swComponentLightweight = 4, swComponentFullyLightweight = 8
if (state == 4 || state == 8) return true;
}
return false;
}
}
}