Skip to content

Commit

Permalink
CNX-9775 sending revit elements via dynamo (#3495)
Browse files Browse the repository at this point in the history
* POC: nullable cache

* Remove commented out lines

* fix: Formatting

---------

Co-authored-by: Alan Rynne <[email protected]>
  • Loading branch information
oguzhankoral and AlanRynne authored Jul 1, 2024
1 parent d151cf5 commit c9e27de
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,45 @@ public IRevitCategoryInfo GetRevitCategoryInfo<T>(Base @base)
return elementType;
}

var matchingType = revitDocumentAggregateCache
.GetOrInitializeWithDefaultFactory<IRevitCategoryInfo>()
.GetAllObjects()
.Where(catInfo => catInfo.ElementTypeType == typeof(T) && catInfo.BuiltInCategories.Count == 0)
.FirstOrDefault();
IRevitCategoryInfo matchingType;

if (revitDocumentAggregateCache is null)
{
matchingType = elementType;
}
else
{
matchingType = revitDocumentAggregateCache
.GetOrInitializeWithDefaultFactory<IRevitCategoryInfo>()
.GetAllObjects()
.Where(catInfo => catInfo.ElementTypeType == typeof(T) && catInfo.BuiltInCategories.Count == 0)
.FirstOrDefault();
}

if (matchingType != null)
{
return matchingType;
}

var categoryInfo = revitDocumentAggregateCache
.GetOrInitializeWithDefaultFactory<IRevitCategoryInfo>()
.GetOrAdd(
typeof(T).Name,
() =>
{
return new RevitCategoryInfo(typeof(T).Name, null, typeof(T), new List<BuiltInCategory>());
},
out _
);
IRevitCategoryInfo categoryInfo;

if (revitDocumentAggregateCache is null)
{
categoryInfo = new RevitCategoryInfo(typeof(T).Name, null, typeof(T), new List<BuiltInCategory>());
}
else
{
categoryInfo = revitDocumentAggregateCache
.GetOrInitializeWithDefaultFactory<IRevitCategoryInfo>()
.GetOrAdd(
typeof(T).Name,
() =>
{
return new RevitCategoryInfo(typeof(T).Name, null, typeof(T), new List<BuiltInCategory>());
},
out _
);
}

return categoryInfo;
}
Expand Down Expand Up @@ -128,30 +146,26 @@ public IRevitCategoryInfo GetRevitCategoryInfo(string categoryName)
}

categoryName = CategoryNameFormatted(categoryName);
var revitCategoryInfoCache = revitDocumentAggregateCache.GetOrInitializeWithDefaultFactory<IRevitCategoryInfo>();

categoryInfo = revitCategoryInfoCache.TryGet(categoryName);
if (categoryInfo != null)
IRevitObjectCache<IRevitCategoryInfo> revitCategoryInfoCache;
if (revitDocumentAggregateCache is not null)
{
return categoryInfo;
}
revitCategoryInfoCache = revitDocumentAggregateCache.GetOrInitializeWithDefaultFactory<IRevitCategoryInfo>();

foreach (var info in revitCategoryInfoCache.GetAllObjects())
{
if (categoryName.IndexOf(info.CategoryName, StringComparison.OrdinalIgnoreCase) >= 0)
categoryInfo = revitCategoryInfoCache.TryGet(categoryName);
if (categoryInfo != null)
{
return info;
return categoryInfo;
}
foreach (var alias in info.CategoryAliases)
else
{
if (categoryName.IndexOf(alias, StringComparison.OrdinalIgnoreCase) >= 0)
{
return info;
}
return SHC.Undefined;
}
}

return SHC.Undefined;
else
{
return SHC.Undefined;
}
}
#endregion

Expand All @@ -173,29 +187,43 @@ public IRevitCategoryInfo GetRevitCategoryInfo(string categoryName)
// pre 2.16 we're passing the "category" string
else
{
var revitCat = revitDocumentAggregateCache
.GetOrInitializeWithDefaultFactory<Category>()
.TryGet(unformattedCatName);

if (revitCat == null)
if (revitDocumentAggregateCache is null)
{
return null;
}
else
{
var revitCat = revitDocumentAggregateCache
.GetOrInitializeWithDefaultFactory<Category>()
.TryGet(unformattedCatName);

bic = Categories.GetBuiltInCategory(revitCat);
formattedName = CategoryNameFormatted(unformattedCatName);
if (revitCat == null)
{
return null;
}

bic = Categories.GetBuiltInCategory(revitCat);
formattedName = CategoryNameFormatted(unformattedCatName);
}
}

return revitDocumentAggregateCache
.GetOrInitializeWithDefaultFactory<IRevitCategoryInfo>()
.GetOrAdd(
formattedName,
() =>
{
return new RevitCategoryInfo(formattedName, null, null, new List<BuiltInCategory> { bic });
},
out _
);
if (revitDocumentAggregateCache is null)
{
return new RevitCategoryInfo(formattedName, null, null, new List<BuiltInCategory> { bic });
}
else
{
return revitDocumentAggregateCache
.GetOrInitializeWithDefaultFactory<IRevitCategoryInfo>()
.GetOrAdd(
formattedName,
() =>
{
return new RevitCategoryInfo(formattedName, null, null, new List<BuiltInCategory> { bic });
},
out _
);
}
}

private static string CategoryNameFormatted(string name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -390,39 +390,46 @@ private Parameter ParameterToSpeckle(
#else
ForgeTypeId unitTypeId = null;
#endif
ParameterToSpeckleData paramData;

// Local function to create ParameterToSpeckleData
ParameterToSpeckleData CreateParamData()
{
var definition = rp.Definition;
var newParamData = new ParameterToSpeckleData()
{
Definition = definition,
InternalName = paramInternalName,
IsReadOnly = rp.IsReadOnly,
IsShared = rp.IsShared,
IsTypeParameter = isTypeParameter,
Name = definition.Name,
UnitType = definition.GetUnityTypeString(),
};
if (rp.StorageType == StorageType.Double)
{
unitTypeId = rp.GetUnitTypeId();
newParamData.UnitsSymbol = GetSymbolUnit(rp, definition, unitTypeId);
newParamData.ApplicationUnits =
unitsOverride != null ? UnitsToNative(unitsOverride).ToUniqueString() : unitTypeId.ToUniqueString();
}
return newParamData;
}

// The parameter definitions are cached using the ParameterToSpeckleData struct
// This is done because in the case of type and instance parameter there is lots of redundant data that needs to be extracted from the Revit DB
// Caching noticeably speeds up the send process
// TODO : could add some generic getOrAdd overloads to avoid creating closures
var paramData = revitDocumentAggregateCache
.GetOrInitializeEmptyCacheOfType<ParameterToSpeckleData>(out _)
.GetOrAdd(
paramInternalName,
() =>
{
var definition = rp.Definition;
var newParamData = new ParameterToSpeckleData()
{
Definition = definition,
InternalName = paramInternalName,
IsReadOnly = rp.IsReadOnly,
IsShared = rp.IsShared,
IsTypeParameter = isTypeParameter,
Name = definition.Name,
UnitType = definition.GetUnityTypeString(),
};
if (rp.StorageType == StorageType.Double)
{
unitTypeId = rp.GetUnitTypeId();
newParamData.UnitsSymbol = GetSymbolUnit(rp, definition, unitTypeId);
newParamData.ApplicationUnits =
unitsOverride != null ? UnitsToNative(unitsOverride).ToUniqueString() : unitTypeId.ToUniqueString();
}
return newParamData;
},
out _
);
if (revitDocumentAggregateCache is null)
{
paramData = CreateParamData();
}
else
{
paramData = revitDocumentAggregateCache
.GetOrInitializeEmptyCacheOfType<ParameterToSpeckleData>(out _)
.GetOrAdd(paramInternalName, CreateParamData, out _);
}

return paramData.GetParameterObjectWithValue(rp.GetValue(paramData.Definition, unitTypeId));
}
Expand Down Expand Up @@ -450,9 +457,16 @@ ForgeTypeId unitTypeId
return null;
}

return revitDocumentAggregateCache
.GetOrInitializeEmptyCacheOfType<string>(out _)
.GetOrAdd(unitTypeId.ToUniqueString(), () => unitTypeId.GetSymbol(), out _);
if (revitDocumentAggregateCache is null)
{
return unitTypeId.GetSymbol();
}
else
{
return revitDocumentAggregateCache
.GetOrInitializeEmptyCacheOfType<string>(out _)
.GetOrAdd(unitTypeId.ToUniqueString(), () => unitTypeId.GetSymbol(), out _);
}
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
Expand Down Expand Up @@ -109,7 +110,7 @@ public ConverterRevit()
Report.Log($"Using converter: {Name} v{ver}");
}

private IRevitDocumentAggregateCache revitDocumentAggregateCache;
private IRevitDocumentAggregateCache? revitDocumentAggregateCache;
private IConvertedObjectsCache<Base, Element> receivedObjectsCache;
private TransactionManager transactionManager;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,19 +264,33 @@ private IEnumerable<ElementId> GetSubsetOfElementsInView(BuiltInCategory categor
return children;
}

var allSubelementsInView = revitDocumentAggregateCache
.GetOrInitializeEmptyCacheOfType<HashSet<ElementId>>(out _)
.GetOrAdd(
category.ToString(),
() =>
{
using var filter = new ElementCategoryFilter(category);
using var collector = new FilteredElementCollector(Doc, ViewSpecificOptions.View.Id);
var allSubelementsInView = new HashSet<ElementId>();

if (revitDocumentAggregateCache is null)
{
var filter = new ElementCategoryFilter(category);
var collector = new FilteredElementCollector(Doc, ViewSpecificOptions.View.Id);

return new HashSet<ElementId>(collector.WhereElementIsNotElementType().WherePasses(filter).ToElementIds());
},
out _
allSubelementsInView = new HashSet<ElementId>(
collector.WhereElementIsNotElementType().WherePasses(filter).ToElementIds()
);
}
else
{
allSubelementsInView = revitDocumentAggregateCache
.GetOrInitializeEmptyCacheOfType<HashSet<ElementId>>(out _)
.GetOrAdd(
category.ToString(),
() =>
{
using var filter = new ElementCategoryFilter(category);
using var collector = new FilteredElementCollector(Doc, ViewSpecificOptions.View.Id);

return new HashSet<ElementId>(collector.WhereElementIsNotElementType().WherePasses(filter).ToElementIds());
},
out _
);
}

return children.Where(allSubelementsInView.Contains);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ public void SetElementFamily(Base @base, string family)
appObj.Update(logItem: $"Could not find valid incoming type for element of type \"{element.speckle_type}\"");
}
var typeInfo = AllCategories.GetRevitCategoryInfo<T>(element);

if (revitDocumentAggregateCache is null)
{
return default;
}

var types = revitDocumentAggregateCache
.GetOrInitializeWithDefaultFactory<List<ElementType>>()
.GetOrAddGroupOfTypes(typeInfo);
Expand Down

0 comments on commit c9e27de

Please sign in to comment.