diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/AllRevitCategories.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/AllRevitCategories.cs index cb51ab0a0f..14edc8539f 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/AllRevitCategories.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/AllRevitCategories.cs @@ -36,27 +36,45 @@ public IRevitCategoryInfo GetRevitCategoryInfo(Base @base) return elementType; } - var matchingType = revitDocumentAggregateCache - .GetOrInitializeWithDefaultFactory() - .GetAllObjects() - .Where(catInfo => catInfo.ElementTypeType == typeof(T) && catInfo.BuiltInCategories.Count == 0) - .FirstOrDefault(); + IRevitCategoryInfo matchingType; + + if (revitDocumentAggregateCache is null) + { + matchingType = elementType; + } + else + { + matchingType = revitDocumentAggregateCache + .GetOrInitializeWithDefaultFactory() + .GetAllObjects() + .Where(catInfo => catInfo.ElementTypeType == typeof(T) && catInfo.BuiltInCategories.Count == 0) + .FirstOrDefault(); + } if (matchingType != null) { return matchingType; } - var categoryInfo = revitDocumentAggregateCache - .GetOrInitializeWithDefaultFactory() - .GetOrAdd( - typeof(T).Name, - () => - { - return new RevitCategoryInfo(typeof(T).Name, null, typeof(T), new List()); - }, - out _ - ); + IRevitCategoryInfo categoryInfo; + + if (revitDocumentAggregateCache is null) + { + categoryInfo = new RevitCategoryInfo(typeof(T).Name, null, typeof(T), new List()); + } + else + { + categoryInfo = revitDocumentAggregateCache + .GetOrInitializeWithDefaultFactory() + .GetOrAdd( + typeof(T).Name, + () => + { + return new RevitCategoryInfo(typeof(T).Name, null, typeof(T), new List()); + }, + out _ + ); + } return categoryInfo; } @@ -128,30 +146,26 @@ public IRevitCategoryInfo GetRevitCategoryInfo(string categoryName) } categoryName = CategoryNameFormatted(categoryName); - var revitCategoryInfoCache = revitDocumentAggregateCache.GetOrInitializeWithDefaultFactory(); - categoryInfo = revitCategoryInfoCache.TryGet(categoryName); - if (categoryInfo != null) + IRevitObjectCache revitCategoryInfoCache; + if (revitDocumentAggregateCache is not null) { - return categoryInfo; - } + revitCategoryInfoCache = revitDocumentAggregateCache.GetOrInitializeWithDefaultFactory(); - 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 @@ -173,29 +187,43 @@ public IRevitCategoryInfo GetRevitCategoryInfo(string categoryName) // pre 2.16 we're passing the "category" string else { - var revitCat = revitDocumentAggregateCache - .GetOrInitializeWithDefaultFactory() - .TryGet(unformattedCatName); - - if (revitCat == null) + if (revitDocumentAggregateCache is null) { return null; } + else + { + var revitCat = revitDocumentAggregateCache + .GetOrInitializeWithDefaultFactory() + .TryGet(unformattedCatName); - bic = Categories.GetBuiltInCategory(revitCat); - formattedName = CategoryNameFormatted(unformattedCatName); + if (revitCat == null) + { + return null; + } + + bic = Categories.GetBuiltInCategory(revitCat); + formattedName = CategoryNameFormatted(unformattedCatName); + } } - return revitDocumentAggregateCache - .GetOrInitializeWithDefaultFactory() - .GetOrAdd( - formattedName, - () => - { - return new RevitCategoryInfo(formattedName, null, null, new List { bic }); - }, - out _ - ); + if (revitDocumentAggregateCache is null) + { + return new RevitCategoryInfo(formattedName, null, null, new List { bic }); + } + else + { + return revitDocumentAggregateCache + .GetOrInitializeWithDefaultFactory() + .GetOrAdd( + formattedName, + () => + { + return new RevitCategoryInfo(formattedName, null, null, new List { bic }); + }, + out _ + ); + } } private static string CategoryNameFormatted(string name) diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/ConversionUtils.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/ConversionUtils.cs index 5aae514f7a..307cca0e29 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/ConversionUtils.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/ConversionUtils.cs @@ -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(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(out _) + .GetOrAdd(paramInternalName, CreateParamData, out _); + } return paramData.GetParameterObjectWithValue(rp.GetValue(paramData.Definition, unitTypeId)); } @@ -450,9 +457,16 @@ ForgeTypeId unitTypeId return null; } - return revitDocumentAggregateCache - .GetOrInitializeEmptyCacheOfType(out _) - .GetOrAdd(unitTypeId.ToUniqueString(), () => unitTypeId.GetSymbol(), out _); + if (revitDocumentAggregateCache is null) + { + return unitTypeId.GetSymbol(); + } + else + { + return revitDocumentAggregateCache + .GetOrInitializeEmptyCacheOfType(out _) + .GetOrAdd(unitTypeId.ToUniqueString(), () => unitTypeId.GetSymbol(), out _); + } } /// diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.cs index 337f32a2f4..4c9a38d3f4 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/ConverterRevit.cs @@ -1,3 +1,4 @@ +#nullable enable using System; using System.Collections.Generic; using System.Linq; @@ -109,7 +110,7 @@ public ConverterRevit() Report.Log($"Using converter: {Name} v{ver}"); } - private IRevitDocumentAggregateCache revitDocumentAggregateCache; + private IRevitDocumentAggregateCache? revitDocumentAggregateCache; private IConvertedObjectsCache receivedObjectsCache; private TransactionManager transactionManager; diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertWall.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertWall.cs index ef493e7fa9..73033b0442 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertWall.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/PartialClasses/ConvertWall.cs @@ -264,19 +264,33 @@ private IEnumerable GetSubsetOfElementsInView(BuiltInCategory categor return children; } - var allSubelementsInView = revitDocumentAggregateCache - .GetOrInitializeEmptyCacheOfType>(out _) - .GetOrAdd( - category.ToString(), - () => - { - using var filter = new ElementCategoryFilter(category); - using var collector = new FilteredElementCollector(Doc, ViewSpecificOptions.View.Id); + var allSubelementsInView = new HashSet(); + + if (revitDocumentAggregateCache is null) + { + var filter = new ElementCategoryFilter(category); + var collector = new FilteredElementCollector(Doc, ViewSpecificOptions.View.Id); - return new HashSet(collector.WhereElementIsNotElementType().WherePasses(filter).ToElementIds()); - }, - out _ + allSubelementsInView = new HashSet( + collector.WhereElementIsNotElementType().WherePasses(filter).ToElementIds() ); + } + else + { + allSubelementsInView = revitDocumentAggregateCache + .GetOrInitializeEmptyCacheOfType>(out _) + .GetOrAdd( + category.ToString(), + () => + { + using var filter = new ElementCategoryFilter(category); + using var collector = new FilteredElementCollector(Doc, ViewSpecificOptions.View.Id); + + return new HashSet(collector.WhereElementIsNotElementType().WherePasses(filter).ToElementIds()); + }, + out _ + ); + } return children.Where(allSubelementsInView.Contains); } diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/RevitElementTypeUtils.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/RevitElementTypeUtils.cs index f6ce277023..43678de1c8 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/RevitElementTypeUtils.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/RevitElementTypeUtils.cs @@ -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(element); + + if (revitDocumentAggregateCache is null) + { + return default; + } + var types = revitDocumentAggregateCache .GetOrInitializeWithDefaultFactory>() .GetOrAddGroupOfTypes(typeInfo);