-
Notifications
You must be signed in to change notification settings - Fork 7
/
SendCollectionManager.cs
80 lines (70 loc) · 2.44 KB
/
SendCollectionManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
using Autodesk.Revit.DB;
using Speckle.Converters.Common;
using Speckle.Converters.RevitShared.Settings;
using Speckle.Sdk.Models.Collections;
namespace Speckle.Connectors.Revit.HostApp;
/// <summary>
/// Manages efficiently creating host collections for revit elements on send. Expects to be scoped per send operation.
/// </summary>
public class SendCollectionManager
{
private readonly IConverterSettingsStore<RevitConversionSettings> _converterSettings;
private readonly Dictionary<string, Collection> _collectionCache = new();
public SendCollectionManager(IConverterSettingsStore<RevitConversionSettings> converterSettings)
{
_converterSettings = converterSettings;
}
/// <summary>
/// Returns the element's host collection based on level, category and optional type. Additionally, places the host collection on the provided root object.
/// Note, it's not nice we're mutating the root object in this function.
/// </summary>
/// <param name="element"></param>
/// <param name="rootObject"></param>
/// <returns></returns>
public Collection GetAndCreateObjectHostCollection(Element element, Collection rootObject)
{
var doc = _converterSettings.Current.Document;
var path = new List<string>();
// Step 1: create path components. Currently, this is
// level > category > type
path.Add(doc.GetElement(element.LevelId) is not Level level ? "No level" : level.Name);
path.Add(element.Category?.Name ?? "No category");
var typeId = element.GetTypeId();
if (typeId != ElementId.InvalidElementId)
{
var type = doc.GetElement(typeId);
if (type != null)
{
path.Add(type.Name);
}
}
else
{
path.Add("No type");
}
string fullPathName = string.Concat(path);
if (_collectionCache.TryGetValue(fullPathName, out Collection? value))
{
return value;
}
string flatPathName = "";
Collection previousCollection = rootObject;
foreach (var pathItem in path)
{
flatPathName += pathItem;
Collection childCollection;
if (_collectionCache.TryGetValue(flatPathName, out Collection? collection))
{
childCollection = collection;
}
else
{
childCollection = new Collection(pathItem);
previousCollection.elements.Add(childCollection);
_collectionCache[flatPathName] = childCollection;
}
previousCollection = childCollection;
}
return previousCollection;
}
}