diff --git a/All.sln b/All.sln
index ff3a26c713..1365d9e652 100644
--- a/All.sln
+++ b/All.sln
@@ -557,6 +557,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{B1324D25
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Converters.Revit2023.Tests", "DUI3-DX\Converters\Revit\Speckle.Converters.Revit2023.Tests\Speckle.Converters.Revit2023.Tests.csproj", "{AEC26A0B-25F3-4544-A9D6-A427BFF79250}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Converters.Common.Tests", "DUI3-DX\Sdk\Speckle.Converters.Common.Tests\Speckle.Converters.Common.Tests.csproj", "{95E23A97-E5EA-4506-A52C-D3DA9012DA02}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug Mac|Any CPU = Debug Mac|Any CPU
@@ -2807,6 +2809,22 @@ Global
{AEC26A0B-25F3-4544-A9D6-A427BFF79250}.Release|Any CPU.Build.0 = Release|Any CPU
{AEC26A0B-25F3-4544-A9D6-A427BFF79250}.Release|x64.ActiveCfg = Release|Any CPU
{AEC26A0B-25F3-4544-A9D6-A427BFF79250}.Release|x64.Build.0 = Release|Any CPU
+ {95E23A97-E5EA-4506-A52C-D3DA9012DA02}.Debug Mac|Any CPU.ActiveCfg = Debug|Any CPU
+ {95E23A97-E5EA-4506-A52C-D3DA9012DA02}.Debug Mac|Any CPU.Build.0 = Debug|Any CPU
+ {95E23A97-E5EA-4506-A52C-D3DA9012DA02}.Debug Mac|x64.ActiveCfg = Debug|Any CPU
+ {95E23A97-E5EA-4506-A52C-D3DA9012DA02}.Debug Mac|x64.Build.0 = Debug|Any CPU
+ {95E23A97-E5EA-4506-A52C-D3DA9012DA02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {95E23A97-E5EA-4506-A52C-D3DA9012DA02}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {95E23A97-E5EA-4506-A52C-D3DA9012DA02}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {95E23A97-E5EA-4506-A52C-D3DA9012DA02}.Debug|x64.Build.0 = Debug|Any CPU
+ {95E23A97-E5EA-4506-A52C-D3DA9012DA02}.Release Mac|Any CPU.ActiveCfg = Debug|Any CPU
+ {95E23A97-E5EA-4506-A52C-D3DA9012DA02}.Release Mac|Any CPU.Build.0 = Debug|Any CPU
+ {95E23A97-E5EA-4506-A52C-D3DA9012DA02}.Release Mac|x64.ActiveCfg = Debug|Any CPU
+ {95E23A97-E5EA-4506-A52C-D3DA9012DA02}.Release Mac|x64.Build.0 = Debug|Any CPU
+ {95E23A97-E5EA-4506-A52C-D3DA9012DA02}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {95E23A97-E5EA-4506-A52C-D3DA9012DA02}.Release|Any CPU.Build.0 = Release|Any CPU
+ {95E23A97-E5EA-4506-A52C-D3DA9012DA02}.Release|x64.ActiveCfg = Release|Any CPU
+ {95E23A97-E5EA-4506-A52C-D3DA9012DA02}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -3019,6 +3037,7 @@ Global
{F06E4C37-4076-4272-9CA6-FB505E02CD31} = {BE521908-7944-46F3-98BF-B47D34509934}
{E1C43415-3200-45F4-8BF9-A4DD7D7F2ED6} = {D92751C8-1039-4005-90B2-913E55E0B8BD}
{AEC26A0B-25F3-4544-A9D6-A427BFF79250} = {D92751C8-1039-4005-90B2-913E55E0B8BD}
+ {95E23A97-E5EA-4506-A52C-D3DA9012DA02} = {2E00592E-558D-492D-88F9-3ECEE4C0C7DA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {1D43D91B-4F01-4A78-8250-CC6F9BD93A14}
diff --git a/Core/Core/Core.csproj b/Core/Core/Core.csproj
index 275dcc12cc..caaa2ab93a 100644
--- a/Core/Core/Core.csproj
+++ b/Core/Core/Core.csproj
@@ -51,7 +51,6 @@
-
diff --git a/DUI3-DX.slnf b/DUI3-DX.slnf
index 80e74b0b65..483d0c9d43 100644
--- a/DUI3-DX.slnf
+++ b/DUI3-DX.slnf
@@ -30,6 +30,7 @@
"DUI3-DX\\Sdk\\Speckle.Autofac\\Speckle.Autofac.csproj",
"DUI3-DX\\Sdk\\Speckle.Connectors.Utils\\Speckle.Connectors.Utils.csproj",
"DUI3-DX\\Sdk\\Speckle.Converters.Common.DependencyInjection\\Speckle.Converters.Common.DependencyInjection.csproj",
+ "DUI3-DX\\Sdk\\Speckle.Converters.Common.Tests\\Speckle.Converters.Common.Tests.csproj",
"DUI3-DX\\Sdk\\Speckle.Converters.Common\\Speckle.Converters.Common.csproj",
"Objects\\Objects\\Objects.csproj",
"Objects\\Tests\\Objects.Tests.Unit\\Objects.Tests.Unit.csproj"
diff --git a/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/ArcGISSelectionBinding.cs b/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/ArcGISSelectionBinding.cs
index ddc096b629..157bad2797 100644
--- a/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/ArcGISSelectionBinding.cs
+++ b/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/ArcGISSelectionBinding.cs
@@ -7,8 +7,8 @@ namespace Speckle.Connectors.ArcGIS.Bindings;
public class ArcGISSelectionBinding : ISelectionBinding
{
- public string Name { get; } = "selectionBinding";
- public IBridge Parent { get; set; }
+ public string Name => "selectionBinding";
+ public IBridge Parent { get; }
public ArcGISSelectionBinding(IBridge parent)
{
@@ -22,7 +22,7 @@ public ArcGISSelectionBinding(IBridge parent)
private void OnSelectionChanged(MapViewEventArgs args)
{
SelectionInfo selInfo = GetSelection();
- Parent?.Send(SelectionBindingEvents.SET_SELECTION, selInfo);
+ Parent.Send(SelectionBindingEvents.SET_SELECTION, selInfo);
}
public SelectionInfo GetSelection()
diff --git a/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/BasicConnectorBinding.cs b/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/BasicConnectorBinding.cs
index dd2fa19efa..649691a526 100644
--- a/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/BasicConnectorBinding.cs
+++ b/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/BasicConnectorBinding.cs
@@ -163,7 +163,10 @@ private void SelectMapMembersInTOC(List mapMembers)
{
if (member is Layer layer)
{
- layers.Add(layer);
+ if (member is not GroupLayer) // group layer selection clears other layers selection
+ {
+ layers.Add(layer);
+ }
}
else if (member is StandaloneTable table)
{
diff --git a/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Operations/Receive/HostObjectBuilder.cs b/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Operations/Receive/HostObjectBuilder.cs
index a681f5317a..e3a3b6300e 100644
--- a/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Operations/Receive/HostObjectBuilder.cs
+++ b/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Operations/Receive/HostObjectBuilder.cs
@@ -70,7 +70,7 @@ CancellationToken cancellationToken
{
if (IsGISType(obj))
{
- string nestedLayerPath = $"{string.Join("\\", path)}\\{((Collection)obj).name}";
+ string nestedLayerPath = $"{string.Join("\\", path)}";
string datasetId = (string)_converter.Convert(obj);
conversionTracker[ctx] = new ObjectConversionTracker(obj, nestedLayerPath, datasetId);
}
@@ -92,10 +92,17 @@ CancellationToken cancellationToken
onOperationProgressed?.Invoke("Writing to Database", null);
_nonGisFeaturesUtils.WriteGeometriesToDatasets(conversionTracker);
+ // Create main group layer
+ Dictionary createdLayerGroups = new();
+ Map map = _contextStack.Current.Document.Map;
+ GroupLayer groupLayer = LayerFactory.Instance.CreateGroupLayer(map, 0, $"{projectName}: {modelName}");
+ createdLayerGroups["Basic Speckle Group"] = groupLayer; // key doesn't really matter here
+
// 3. add layer and tables to the Table Of Content
int bakeCount = 0;
Dictionary bakedMapMembers = new();
onOperationProgressed?.Invoke("Adding to Map", bakeCount);
+
foreach (var item in conversionTracker)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -120,7 +127,7 @@ CancellationToken cancellationToken
else
{
// add layer and layer URI to tracker
- MapMember mapMember = AddDatasetsToMap(trackerItem);
+ MapMember mapMember = AddDatasetsToMap(trackerItem, createdLayerGroups);
trackerItem.AddConvertedMapMember(mapMember);
trackerItem.AddLayerURI(mapMember.URI);
conversionTracker[item.Key] = trackerItem;
@@ -133,6 +140,7 @@ CancellationToken cancellationToken
}
onOperationProgressed?.Invoke("Adding to Map", (double)++bakeCount / conversionTracker.Count);
}
+ bakedObjectIds.AddRange(createdLayerGroups.Values.Select(x => x.URI));
// TODO: validated a correct set regarding bakedobject ids
return new(bakedObjectIds, results);
@@ -160,13 +168,21 @@ private void AddResultsFromTracker(ObjectConversionTracker trackerItem, List createdLayerGroups
+ )
{
+ // get layer details
string? datasetId = trackerItem.DatasetId; // should not ne null here
+ Uri uri = new($"{_contextStack.Current.Document.SpeckleDatabasePath.AbsolutePath.Replace('/', '\\')}\\{datasetId}");
string nestedLayerName = trackerItem.NestedLayerName;
- Uri uri = new($"{_contextStack.Current.Document.SpeckleDatabasePath.AbsolutePath.Replace('/', '\\')}\\{datasetId}");
- Map map = _contextStack.Current.Document.Map;
+ // add group for the current layer
+ string shortName = nestedLayerName.Split("\\")[^1];
+ string nestedLayerPath = string.Join("\\", nestedLayerName.Split("\\").SkipLast(1));
+
+ GroupLayer groupLayer = CreateNestedGroupLayer(nestedLayerPath, createdLayerGroups);
// Most of the Speckle-written datasets will be containing geometry and added as Layers
// although, some datasets might be just tables (e.g. native GIS Tables, in the future maybe Revit schedules etc.
@@ -174,23 +190,55 @@ private MapMember AddDatasetsToMap(ObjectConversionTracker trackerItem)
// expensive, than assuming by default that it's a layer with geometry (which in most cases it's expected to be)
try
{
- var layer = LayerFactory.Instance.CreateLayer(uri, map, layerName: nestedLayerName);
+ var layer = LayerFactory.Instance.CreateLayer(uri, groupLayer, layerName: shortName);
+ layer.SetExpanded(true);
return layer;
}
catch (ArgumentException)
{
- var table = StandaloneTableFactory.Instance.CreateStandaloneTable(uri, map, tableName: nestedLayerName);
+ var table = StandaloneTableFactory.Instance.CreateStandaloneTable(uri, groupLayer, tableName: shortName);
return table;
}
}
+ private GroupLayer CreateNestedGroupLayer(string nestedLayerPath, Dictionary createdLayerGroups)
+ {
+ GroupLayer lastGroup = createdLayerGroups.FirstOrDefault().Value;
+ if (lastGroup == null) // if layer not found
+ {
+ throw new InvalidOperationException("Speckle Layer Group not found");
+ }
+
+ // iterate through each nested level
+ string createdGroupPath = "";
+ var allPathElements = nestedLayerPath.Split("\\").Where(x => !string.IsNullOrEmpty(x));
+ foreach (string pathElement in allPathElements)
+ {
+ createdGroupPath += "\\" + pathElement;
+ if (createdLayerGroups.TryGetValue(createdGroupPath, out var existingGroupLayer))
+ {
+ lastGroup = existingGroupLayer;
+ }
+ else
+ {
+ // create new GroupLayer under last found Group, named with last pathElement
+ lastGroup = LayerFactory.Instance.CreateGroupLayer(lastGroup, 0, pathElement);
+ lastGroup.SetExpanded(true);
+ }
+ createdLayerGroups[createdGroupPath] = lastGroup;
+ }
+ return lastGroup;
+ }
+
[Pure]
private static string[] GetLayerPath(TraversalContext context)
{
string[] collectionBasedPath = context.GetAscendantOfType().Select(c => c.name).ToArray();
string[] reverseOrderPath =
collectionBasedPath.Length != 0 ? collectionBasedPath : context.GetPropertyPath().ToArray();
- return reverseOrderPath.Reverse().ToArray();
+
+ var originalPath = reverseOrderPath.Reverse().ToArray();
+ return originalPath.Where(x => !string.IsNullOrEmpty(x)).ToArray();
}
[Pure]
diff --git a/DUI3-DX/Connectors/Autocad/Speckle.Connectors.AutocadShared/Bindings/AutocadSelectionBinding.cs b/DUI3-DX/Connectors/Autocad/Speckle.Connectors.AutocadShared/Bindings/AutocadSelectionBinding.cs
index b52fcba337..1da7250ceb 100644
--- a/DUI3-DX/Connectors/Autocad/Speckle.Connectors.AutocadShared/Bindings/AutocadSelectionBinding.cs
+++ b/DUI3-DX/Connectors/Autocad/Speckle.Connectors.AutocadShared/Bindings/AutocadSelectionBinding.cs
@@ -9,10 +9,8 @@ public class AutocadSelectionBinding : ISelectionBinding
{
private const string SELECTION_EVENT = "setSelection";
- private readonly List _visitedDocuments = new();
-
- public string Name { get; set; } = "selectionBinding";
-
+ private readonly HashSet _visitedDocuments = new();
+ public string Name => "selectionBinding";
public IBridge Parent { get; }
public AutocadSelectionBinding(IBridge parent)
@@ -26,9 +24,9 @@ public AutocadSelectionBinding(IBridge parent)
Application.DocumentManager.DocumentActivated += (sender, e) => OnDocumentChanged(e.Document);
}
- private void OnDocumentChanged(Document document) => TryRegisterDocumentForSelection(document);
+ private void OnDocumentChanged(Document? document) => TryRegisterDocumentForSelection(document);
- private void TryRegisterDocumentForSelection(Document document)
+ private void TryRegisterDocumentForSelection(Document? document)
{
if (document == null)
{
@@ -49,13 +47,13 @@ private void TryRegisterDocumentForSelection(Document document)
private void OnSelectionChanged()
{
SelectionInfo selInfo = GetSelection();
- Parent?.Send(SELECTION_EVENT, selInfo);
+ Parent.Send(SELECTION_EVENT, selInfo);
}
public SelectionInfo GetSelection()
{
// POC: Will be addressed to move it into AutocadContext! https://spockle.atlassian.net/browse/CNX-9319
- Document doc = Application.DocumentManager.MdiActiveDocument;
+ Document? doc = Application.DocumentManager.MdiActiveDocument;
List objs = new();
List objectTypes = new();
if (doc != null)
diff --git a/DUI3-DX/Connectors/Autocad/Speckle.Connectors.AutocadShared/Bindings/AutocadSendBinding.cs b/DUI3-DX/Connectors/Autocad/Speckle.Connectors.AutocadShared/Bindings/AutocadSendBinding.cs
index 296dd64359..8ebb187279 100644
--- a/DUI3-DX/Connectors/Autocad/Speckle.Connectors.AutocadShared/Bindings/AutocadSendBinding.cs
+++ b/DUI3-DX/Connectors/Autocad/Speckle.Connectors.AutocadShared/Bindings/AutocadSendBinding.cs
@@ -18,7 +18,7 @@ namespace Speckle.Connectors.Autocad.Bindings;
public sealed class AutocadSendBinding : ISendBinding
{
- public string Name { get; } = "sendBinding";
+ public string Name => "sendBinding";
public SendBindingUICommands Commands { get; }
public IBridge Parent { get; }
diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitBaseBinding.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitBaseBinding.cs
index 7e1e0afdec..566cc9c41a 100644
--- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitBaseBinding.cs
+++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitBaseBinding.cs
@@ -8,13 +8,13 @@ namespace Speckle.Connectors.Revit.Bindings;
internal abstract class RevitBaseBinding : IBinding
{
// POC: name and bridge might be better for them to be protected props?
- public string Name { get; protected set; }
- public IBridge Parent { get; protected set; }
+ public string Name { get; }
+ public IBridge Parent { get; }
protected readonly DocumentModelStore Store;
protected readonly RevitContext RevitContext;
- public RevitBaseBinding(string name, DocumentModelStore store, IBridge bridge, RevitContext revitContext)
+ protected RevitBaseBinding(string name, DocumentModelStore store, IBridge bridge, RevitContext revitContext)
{
Name = name;
Parent = bridge;
diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Send/RevitRootObjectBuilder.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Send/RevitRootObjectBuilder.cs
index 6652aad320..417478e952 100644
--- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Send/RevitRootObjectBuilder.cs
+++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Send/RevitRootObjectBuilder.cs
@@ -72,12 +72,14 @@ public RootObjectBuilderResult Build(
var countProgress = 0; // because for(int i = 0; ...) loops are so last year
var cacheHitCount = 0;
List results = new(revitElements.Count);
+ var path = new string[2];
foreach (Element revitElement in revitElements)
{
ct.ThrowIfCancellationRequested();
var cat = revitElement.Category.Name;
- var path = new[] { doc.GetElement(revitElement.LevelId) is not Level level ? "No level" : level.Name, cat };
+ path[0] = doc.GetElement(revitElement.LevelId) is not Level level ? "No level" : level.Name;
+ path[1] = cat;
var collection = GetAndCreateObjectHostCollection(path);
var applicationId = revitElement.Id.ToString();
diff --git a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoBasicConnectorBinding.cs b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoBasicConnectorBinding.cs
index 4154665c7b..1ceb31b69a 100644
--- a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoBasicConnectorBinding.cs
+++ b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoBasicConnectorBinding.cs
@@ -14,8 +14,8 @@ namespace Speckle.Connectors.Rhino7.Bindings;
public class RhinoBasicConnectorBinding : IBasicConnectorBinding
{
- public string Name { get; set; } = "baseBinding";
- public IBridge Parent { get; set; }
+ public string Name => "baseBinding";
+ public IBridge Parent { get; }
public BasicConnectorBindingCommands Commands { get; }
private readonly DocumentModelStore _store;
diff --git a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoReceiveBinding.cs b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoReceiveBinding.cs
index 0314a0f78f..951ff40f6f 100644
--- a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoReceiveBinding.cs
+++ b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoReceiveBinding.cs
@@ -12,8 +12,8 @@ namespace Speckle.Connectors.Rhino7.Bindings;
public class RhinoReceiveBinding : IReceiveBinding
{
- public string Name { get; set; } = "receiveBinding";
- public IBridge Parent { get; set; }
+ public string Name => "receiveBinding";
+ public IBridge Parent { get; }
private readonly CancellationManager _cancellationManager;
private readonly DocumentModelStore _store;
diff --git a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoSendBinding.cs b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoSendBinding.cs
index 8f8594f193..b2c2ab1a20 100644
--- a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoSendBinding.cs
+++ b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoSendBinding.cs
@@ -18,9 +18,9 @@ namespace Speckle.Connectors.Rhino7.Bindings;
public sealed class RhinoSendBinding : ISendBinding
{
- public string Name { get; } = "sendBinding";
+ public string Name => "sendBinding";
public SendBindingUICommands Commands { get; }
- public IBridge Parent { get; set; }
+ public IBridge Parent { get; }
private readonly DocumentModelStore _store;
private readonly RhinoIdleManager _idleManager;
diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3.DependencyInjection/ArcGISConverterModule.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3.DependencyInjection/ArcGISConverterModule.cs
index 30a739310b..88d26d8166 100644
--- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3.DependencyInjection/ArcGISConverterModule.cs
+++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3.DependencyInjection/ArcGISConverterModule.cs
@@ -11,7 +11,7 @@ public class ArcGISConverterModule : ISpeckleModule
public void Load(SpeckleContainerBuilder builder)
{
//don't need a host specific RootToSpeckleConverter
- builder.AddConverterCommon();
+ builder.AddConverterCommon();
// most things should be InstancePerLifetimeScope so we get one per operation
builder.AddScoped();
builder.AddScoped();
diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.DependencyInjection/RevitConverterModule.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.DependencyInjection/RevitConverterModule.cs
index 533baf679e..1c7eae1e2f 100644
--- a/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.DependencyInjection/RevitConverterModule.cs
+++ b/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.DependencyInjection/RevitConverterModule.cs
@@ -14,6 +14,7 @@ public class RevitConverterModule : ISpeckleModule
public void Load(SpeckleContainerBuilder builder)
{
builder.AddConverterCommon();
+ builder.ScanAssemblyOfType();
// POC: do we need ToSpeckleScalingService as is, do we need to interface it out?
builder.AddScoped();
@@ -28,5 +29,6 @@ public void Load(SpeckleContainerBuilder builder)
builder.AddScoped();
builder.AddScoped();
builder.AddScoped();
+ builder.AddScoped();
}
}
diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.DependencyInjection/Speckle.Converters.Revit2023.DependencyInjection.csproj b/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.DependencyInjection/Speckle.Converters.Revit2023.DependencyInjection.csproj
index 8458d1fdaa..ae4703a46f 100644
--- a/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.DependencyInjection/Speckle.Converters.Revit2023.DependencyInjection.csproj
+++ b/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.DependencyInjection/Speckle.Converters.Revit2023.DependencyInjection.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.Tests/Speckle.Converters.Revit2023.Tests.csproj b/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.Tests/Speckle.Converters.Revit2023.Tests.csproj
index 23e43c993c..296350ca71 100644
--- a/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.Tests/Speckle.Converters.Revit2023.Tests.csproj
+++ b/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.Tests/Speckle.Converters.Revit2023.Tests.csproj
@@ -14,7 +14,7 @@
-
+
diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.Tests/XyzConversionToPointTests.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.Tests/XyzConversionToPointTests.cs
new file mode 100644
index 0000000000..dee5979761
--- /dev/null
+++ b/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.Tests/XyzConversionToPointTests.cs
@@ -0,0 +1,61 @@
+using FluentAssertions;
+using Moq;
+using NUnit.Framework;
+using Objects;
+using Speckle.Converters.Common;
+using Speckle.Converters.Common.Objects;
+using Speckle.Converters.RevitShared.Services;
+using Speckle.Converters.RevitShared.ToSpeckle;
+using Speckle.Revit.Interfaces;
+
+namespace Speckle.Converters.Revit2023.Tests;
+
+public class XyzConversionToPointTests
+{
+ private readonly MockRepository _repository = new(MockBehavior.Strict);
+
+ private readonly Mock> _revitConversionContextStack;
+ private readonly Mock _scalingServiceToSpeckle;
+
+ public XyzConversionToPointTests()
+ {
+ _revitConversionContextStack = _repository.Create>();
+ _scalingServiceToSpeckle = _repository.Create();
+ }
+
+ [TearDown]
+ public void Verify() => _repository.VerifyAll();
+
+ [Test]
+ public void Convert_Point()
+ {
+ var x = 3.1;
+ var y = 3.2;
+ var z = 3.3;
+ var xScaled = 4.1;
+ var yScaled = 4.2;
+ var zScaled = 4.3;
+ var xyz = _repository.Create();
+ xyz.Setup(x => x.X).Returns(x);
+ xyz.Setup(x => x.Y).Returns(y);
+ xyz.Setup(x => x.Z).Returns(z);
+
+ var units = "units";
+ var conversionContext = _repository.Create>();
+ conversionContext.Setup(x => x.SpeckleUnits).Returns(units);
+
+ _scalingServiceToSpeckle.Setup(a => a.ScaleLength(x)).Returns(xScaled);
+ _scalingServiceToSpeckle.Setup(a => a.ScaleLength(y)).Returns(yScaled);
+ _scalingServiceToSpeckle.Setup(a => a.ScaleLength(z)).Returns(zScaled);
+
+ _revitConversionContextStack.Setup(x => x.Current).Returns(conversionContext.Object);
+
+ var converter = new XyzConversionToPoint(_scalingServiceToSpeckle.Object, _revitConversionContextStack.Object);
+ var point = converter.Convert(xyz.Object);
+
+ point.x.Should().Be(xScaled);
+ point.y.Should().Be(yScaled);
+ point.z.Should().Be(zScaled);
+ point.units.Should().Be(units);
+ }
+}
diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.Tests/packages.lock.json b/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.Tests/packages.lock.json
index 6fdd69eb66..256510d436 100644
--- a/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.Tests/packages.lock.json
+++ b/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.Tests/packages.lock.json
@@ -65,9 +65,9 @@
},
"Speckle.Revit2023.Interfaces": {
"type": "Direct",
- "requested": "[0.1.1-preview.0.23, )",
- "resolved": "0.1.1-preview.0.23",
- "contentHash": "H66I9JRUGt1l1YS8aOdniRPDOixRPqua9puGrhGnTEKJ26kVlgkM3FpKfdAMFea4hf03hdqhnFVmNEwgA6mPHA=="
+ "requested": "[0.1.1-preview.0.24, )",
+ "resolved": "0.1.1-preview.0.24",
+ "contentHash": "BSVpOUJc9g6ISrw8GxvtkglTlITpHEDYNOhxv1ZPbckBsI0yO36JiphhQV4q57ERqD9PpCozUJkVhlCaxWeS6A=="
},
"Castle.Core": {
"type": "Transitive",
@@ -251,14 +251,6 @@
"Serilog": "2.4.0"
}
},
- "Serilog.Enrichers.GlobalLogContext": {
- "type": "Transitive",
- "resolved": "3.0.0",
- "contentHash": "IIZcj5mAUVhIl/NTA+YI2KC+sPDzcwvs0ZMHH42jsPfl1a4LVX7ohVpw5UK+e3GxuV3Nv239Il5oM2peUIl44g==",
- "dependencies": {
- "Serilog": "2.12.0"
- }
- },
"Serilog.Exceptions": {
"type": "Transitive",
"resolved": "8.4.0",
@@ -499,7 +491,7 @@
"dependencies": {
"Speckle.Autofac": "[2.0.999-local, )",
"Speckle.Objects": "[2.0.999-local, )",
- "Speckle.Revit2023.Interfaces": "[0.1.1-preview.0.23, )"
+ "Speckle.Revit2023.Interfaces": "[0.1.1-preview.0.24, )"
}
},
"speckle.converters.common.dependencyinjection": {
@@ -513,7 +505,7 @@
"type": "Project",
"dependencies": {
"Speckle.Converters.Common": "[2.0.999-local, )",
- "Speckle.Revit2023.Interfaces": "[0.1.1-preview.0.23, )"
+ "Speckle.Revit2023.Interfaces": "[0.1.1-preview.0.24, )"
}
},
"Speckle.Core": {
@@ -529,7 +521,6 @@
"Sentry.Serilog": "[3.33.0, )",
"Serilog": "[2.12.0, )",
"Serilog.Enrichers.ClientInfo": "[1.3.0, )",
- "Serilog.Enrichers.GlobalLogContext": "[3.0.0, )",
"Serilog.Exceptions": "[8.4.0, )",
"Serilog.Sinks.Console": "[4.1.0, )",
"Serilog.Sinks.Seq": "[5.2.2, )",
diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023/Speckle.Converters.Revit2023.csproj b/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023/Speckle.Converters.Revit2023.csproj
index f2fe665f57..01dc874c3f 100644
--- a/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023/Speckle.Converters.Revit2023.csproj
+++ b/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023/Speckle.Converters.Revit2023.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/DisplayValueExtractor.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/DisplayValueExtractor.cs
index 83cd6a4dd6..9dd899678a 100644
--- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/DisplayValueExtractor.cs
+++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/DisplayValueExtractor.cs
@@ -103,7 +103,7 @@ List solids
//options = ViewSpecificOptions ?? options ?? new Options() { DetailLevel = DetailLevelSetting };
options ??= _revitOptionsFactory.Create(RevitViewDetailLevel.Fine);
- IRevitGeometryElement geom;
+ IRevitGeometryElement? geom;
try
{
geom = element.GetGeometry(options);
diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/IParameterValueExtractor.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/IParameterValueExtractor.cs
new file mode 100644
index 0000000000..7366b0d055
--- /dev/null
+++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/IParameterValueExtractor.cs
@@ -0,0 +1,34 @@
+using System.Diagnostics.CodeAnalysis;
+using Speckle.Revit.Interfaces;
+
+namespace Speckle.Converters.RevitShared.Helpers;
+
+//not auto because of NotNullWhen
+public interface IParameterValueExtractor
+{
+ object? GetValue(IRevitParameter parameter);
+ double GetValueAsDouble(IRevitElement element, RevitBuiltInParameter builtInParameter);
+ bool TryGetValueAsDouble(
+ IRevitElement element,
+ RevitBuiltInParameter builtInParameter,
+ [NotNullWhen(true)] out double? value
+ );
+ int GetValueAsInt(IRevitElement element, RevitBuiltInParameter builtInParameter);
+ bool? GetValueAsBool(IRevitElement element, RevitBuiltInParameter builtInParameter);
+ string? GetValueAsString(IRevitElement element, RevitBuiltInParameter builtInParameter);
+ IRevitElementId GetValueAsElementId(IRevitElement element, RevitBuiltInParameter builtInParameter);
+ bool TryGetValueAsElementId(
+ IRevitElement element,
+ RevitBuiltInParameter builtInParameter,
+ out IRevitElementId? elementId
+ );
+ IRevitElementId? GetValueAsElementId(IRevitParameter parameter);
+ IRevitLevel GetValueAsRevitLevel(IRevitElement element, RevitBuiltInParameter builtInParameter);
+ bool TryGetValueAsRevitLevel(
+ IRevitElement element,
+ RevitBuiltInParameter builtInParameter,
+ [NotNullWhen(true)] out IRevitLevel? revitLevel
+ );
+ Dictionary GetAllRemainingParams(IRevitElement revitElement);
+ void RemoveUniqueId(string uniqueId);
+}
diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/ParameterValueExtractor.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/ParameterValueExtractor.cs
index b5218980fd..2f5a71a853 100644
--- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/ParameterValueExtractor.cs
+++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/ParameterValueExtractor.cs
@@ -2,7 +2,6 @@
using Speckle.Converters.Common;
using Speckle.Converters.RevitShared.Extensions;
using Speckle.Converters.RevitShared.Services;
-using Speckle.InterfaceGenerator;
using Speckle.Revit.Interfaces;
namespace Speckle.Converters.RevitShared.Helpers;
@@ -11,7 +10,7 @@ namespace Speckle.Converters.RevitShared.Helpers;
// really if we have to edit a switch statement...
// maybe also better as an extension method, but maybe is fine?
// POC: there are a lot of public methods here. Maybe consider consolodating
-[GenerateAutoInterface]
+
public class ParameterValueExtractor : IParameterValueExtractor
{
private readonly IScalingServiceToSpeckle _scalingService;
@@ -160,7 +159,7 @@ public bool TryGetValueAsElementId(
return GetValueGeneric(parameter, RevitStorageType.ElementId, (p) => p.AsElementId());
}
- public IRevitLevel? GetValueAsRevitLevel(IRevitElement element, RevitBuiltInParameter builtInParameter)
+ public IRevitLevel GetValueAsRevitLevel(IRevitElement element, RevitBuiltInParameter builtInParameter)
{
if (!TryGetValueAsElementId(element, builtInParameter, out var elementId))
{
@@ -168,7 +167,24 @@ public bool TryGetValueAsElementId(
}
var paramElement = element.Document.GetElement(elementId);
- return paramElement?.ToLevel();
+ return (paramElement?.ToLevel()).NotNull();
+ }
+
+ public bool TryGetValueAsRevitLevel(
+ IRevitElement element,
+ RevitBuiltInParameter builtInParameter,
+ [NotNullWhen(true)] out IRevitLevel? revitLevel
+ )
+ {
+ if (!TryGetValueAsElementId(element, builtInParameter, out var elementId))
+ {
+ revitLevel = null;
+ return false;
+ }
+
+ var paramElement = element.Document.GetElement(elementId);
+ revitLevel = paramElement?.ToLevel();
+ return revitLevel is not null;
}
private TResult? GetValueGeneric(
diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/BeamConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/BeamConversionToSpeckle.cs
index 8c7d36aea1..59f790664f 100644
--- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/BeamConversionToSpeckle.cs
+++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/BeamConversionToSpeckle.cs
@@ -1,4 +1,4 @@
-using Objects;
+using Objects;
using Speckle.Converters.Common;
using Speckle.Converters.Common.Objects;
using Speckle.Converters.RevitShared.Helpers;
@@ -58,7 +58,7 @@ public SOBR.RevitBeam Convert(IRevitFamilyInstance target)
target,
RevitBuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM
);
- speckleBeam.level = _levelConverter.Convert(level.NotNull());
+ speckleBeam.level = _levelConverter.Convert(level);
speckleBeam.displayValue = _displayValueExtractor.GetDisplayValue(target);
diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ColumnConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ColumnConversionToSpeckle.cs
index dc12c29082..afcf6f27eb 100644
--- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ColumnConversionToSpeckle.cs
+++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ColumnConversionToSpeckle.cs
@@ -42,22 +42,52 @@ public SOBR.RevitColumn Convert(IRevitFamilyInstance target)
SOBR.RevitColumn speckleColumn =
new() { family = symbol.FamilyName, type = target.Document.GetElement(target.GetTypeId()).NotNull().Name };
- var level = _parameterValueExtractor.GetValueAsRevitLevel(target, RevitBuiltInParameter.FAMILY_BASE_LEVEL_PARAM);
- speckleColumn.level = _levelConverter.Convert(level.NotNull());
-
- var topLevel = _parameterValueExtractor.GetValueAsRevitLevel(target, RevitBuiltInParameter.FAMILY_TOP_LEVEL_PARAM);
-
- speckleColumn.topLevel = _levelConverter.Convert(topLevel.NotNull());
- speckleColumn.baseOffset = _parameterValueExtractor.GetValueAsDouble(
- target,
- RevitBuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM
- );
+ //should these all be try?
+ if (
+ _parameterValueExtractor.TryGetValueAsRevitLevel(
+ target,
+ RevitBuiltInParameter.FAMILY_BASE_LEVEL_PARAM,
+ out var level
+ )
+ )
+ {
+ speckleColumn.level = _levelConverter.Convert(level);
+ }
+ //should these all be try?
+ if (
+ _parameterValueExtractor.TryGetValueAsRevitLevel(
+ target,
+ RevitBuiltInParameter.FAMILY_TOP_LEVEL_PARAM,
+ out var topLevel
+ )
+ )
+ {
+ speckleColumn.topLevel = _levelConverter.Convert(topLevel);
+ }
- speckleColumn.topOffset = _parameterValueExtractor.GetValueAsDouble(
- target,
- RevitBuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM
- );
+ //should these all be try?
+ if (
+ _parameterValueExtractor.TryGetValueAsDouble(
+ target,
+ RevitBuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM,
+ out var baseOffset
+ )
+ )
+ {
+ speckleColumn.baseOffset = baseOffset.Value;
+ }
+ //should these all be try?
+ if (
+ _parameterValueExtractor.TryGetValueAsDouble(
+ target,
+ RevitBuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM,
+ out var topOffset
+ )
+ )
+ {
+ speckleColumn.topOffset = topOffset.Value;
+ }
speckleColumn.facingFlipped = target.FacingFlipped;
speckleColumn.handFlipped = target.HandFlipped;
speckleColumn.isSlanted = target.IsSlantedColumn;
@@ -69,7 +99,7 @@ public SOBR.RevitColumn Convert(IRevitFamilyInstance target)
}
speckleColumn.baseLine =
- GetBaseCurve(target, speckleColumn.topLevel.elevation, speckleColumn.topOffset)
+ GetBaseCurve(target, speckleColumn.topLevel?.elevation, speckleColumn.topOffset)
?? throw new SpeckleConversionException("Unable to find a valid baseCurve for column");
speckleColumn.displayValue = _displayValueExtractor.GetDisplayValue(target);
@@ -79,7 +109,7 @@ public SOBR.RevitColumn Convert(IRevitFamilyInstance target)
return speckleColumn;
}
- private ICurve? GetBaseCurve(IRevitFamilyInstance target, double topLevelElevation, double topLevelOffset)
+ private ICurve? GetBaseCurve(IRevitFamilyInstance target, double? topLevelElevation, double topLevelOffset)
{
Base baseGeometry = _locationConverter.Convert(target.Location);
ICurve? baseCurve = baseGeometry as ICurve;
@@ -102,7 +132,12 @@ public SOBR.RevitColumn Convert(IRevitFamilyInstance target)
return new SOG.Line(
basePoint,
- new SOG.Point(basePoint.x, basePoint.y, topLevelElevation + topLevelOffset, _contextStack.Current.SpeckleUnits),
+ new SOG.Point(
+ basePoint.x,
+ basePoint.y,
+ topLevelElevation ?? 0 + topLevelOffset,
+ _contextStack.Current.SpeckleUnits
+ ),
_contextStack.Current.SpeckleUnits
);
}
diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/PointCloudToSpeckleConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/PointCloudToSpeckleConverter.cs
index ee5b81e95d..c552e7dbdf 100644
--- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/PointCloudToSpeckleConverter.cs
+++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/PointCloudToSpeckleConverter.cs
@@ -37,7 +37,7 @@ public SOG.Pointcloud Convert(IRevitPointCloudInstance target)
{
var minPlane = _revitPlaneUtils.CreateByNormalAndOrigin(
_revitxyzUtils.BasisZ,
- transform.OfPoint(boundingBox.Min)
+ transform.OfPoint(boundingBox.NotNull().Min)
);
var filter = _revitFilterFactory.CreateMultiPlaneFilter(minPlane);
var points = target.GetPoints(filter, 0.0001, 999999); // max limit is 1 mil but 1000000 throws error
diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/RevitRootElementProvider.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/RevitRootElementProvider.cs
new file mode 100644
index 0000000000..65aeca21da
--- /dev/null
+++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/RevitRootElementProvider.cs
@@ -0,0 +1,11 @@
+using Speckle.Converters.Common;
+using Speckle.Revit.Interfaces;
+
+namespace Speckle.Converters.RevitShared;
+
+public class RevitRootElementProvider : IRootElementProvider
+{
+ private static readonly Type s_wrappedElementType = typeof(IRevitElement);
+
+ public Type GetRootType() => s_wrappedElementType;
+}
diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/CeilingTopLevelConverterToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/CeilingTopLevelConverterToSpeckle.cs
index b757b03215..3dd7ed8cb6 100644
--- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/CeilingTopLevelConverterToSpeckle.cs
+++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/CeilingTopLevelConverterToSpeckle.cs
@@ -1,4 +1,4 @@
-using Objects;
+using Objects;
using Objects.BuiltElements.Revit;
using Objects.Geometry;
using Speckle.Converters.Common;
@@ -60,7 +60,7 @@ public override RevitCeiling Convert(IRevitCeiling target)
// but it is never being set. We should be setting it
var level = _parameterValueExtractor.GetValueAsRevitLevel(target, RevitBuiltInParameter.LEVEL_PARAM);
- speckleCeiling.level = _levelConverter.Convert(level.NotNull());
+ speckleCeiling.level = _levelConverter.Convert(level);
_parameterObjectAssigner.AssignParametersToBase(target, speckleCeiling);
speckleCeiling.displayValue = _displayValueExtractor.GetDisplayValue(target);
diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/ExtrusionRoofToSpeckleTopLevelConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/ExtrusionRoofToSpeckleTopLevelConverter.cs
index b02390e933..8dfeb7907a 100644
--- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/ExtrusionRoofToSpeckleTopLevelConverter.cs
+++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/ExtrusionRoofToSpeckleTopLevelConverter.cs
@@ -1,4 +1,4 @@
-using Objects.BuiltElements.Revit.RevitRoof;
+using Objects.BuiltElements.Revit.RevitRoof;
using Speckle.Converters.Common;
using Speckle.Converters.Common.Objects;
using Speckle.Converters.RevitShared.Extensions;
@@ -57,7 +57,7 @@ public override RevitExtrusionRoof Convert(IRevitExtrusionRoof target)
target,
RevitBuiltInParameter.ROOF_CONSTRAINT_LEVEL_PARAM
);
- speckleExtrusionRoof.level = _levelConverter.Convert(level.NotNull());
+ speckleExtrusionRoof.level = _levelConverter.Convert(level);
speckleExtrusionRoof.outline = _modelCurveArrayConverter.Convert(target.GetProfile());
var elementType = target.Document.GetElement(target.GetTypeId()).NotNull().ToType().NotNull();
diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/FloorTopLevelConverterToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/FloorTopLevelConverterToSpeckle.cs
index b6c8ade775..eb292cae5b 100644
--- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/FloorTopLevelConverterToSpeckle.cs
+++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/FloorTopLevelConverterToSpeckle.cs
@@ -1,4 +1,4 @@
-using Objects;
+using Objects;
using Speckle.Converters.Common;
using Speckle.Converters.Common.Objects;
using Speckle.Converters.RevitShared.Helpers;
diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/FootPrintRoofToSpeckleTopLevelConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/FootPrintRoofToSpeckleTopLevelConverter.cs
index 5a51d40f28..78600db3ff 100644
--- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/FootPrintRoofToSpeckleTopLevelConverter.cs
+++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/FootPrintRoofToSpeckleTopLevelConverter.cs
@@ -44,7 +44,8 @@ public override RevitFootprintRoof Convert(IRevitFootPrintRoof target)
var baseLevel = _parameterValueExtractor.GetValueAsRevitLevel(target, RevitBuiltInParameter.ROOF_BASE_LEVEL_PARAM);
// We don't currently validate the success of this TryGet, it is assumed some Roofs don't have a top-level.
- var topLevel = _parameterValueExtractor.GetValueAsRevitLevel(target, RevitBuiltInParameter.ROOF_UPTO_LEVEL_PARAM);
+ IRevitLevel? topLevel;
+ _parameterValueExtractor.TryGetValueAsRevitLevel(target, RevitBuiltInParameter.ROOF_UPTO_LEVEL_PARAM, out topLevel);
//POC: CNX-9403 can be null if the sides have different slopes.
//We currently don't validate the success or failure of this TryGet as it's not necessary, but will be once we start the above ticket.
@@ -53,7 +54,7 @@ public override RevitFootprintRoof Convert(IRevitFootPrintRoof target)
RevitFootprintRoof speckleFootprintRoof =
new()
{
- level = _levelConverter.Convert(baseLevel.NotNull()),
+ level = _levelConverter.Convert(baseLevel),
cutOffLevel = topLevel is not null ? _levelConverter.Convert(topLevel) : null,
slope = slope
};
diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/WallTopLevelConverterToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/WallTopLevelConverterToSpeckle.cs
index 3d48ca2ede..e9a0dbafc1 100644
--- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/WallTopLevelConverterToSpeckle.cs
+++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/WallTopLevelConverterToSpeckle.cs
@@ -1,4 +1,4 @@
-using Speckle.Converters.Common.Objects;
+using Speckle.Converters.Common.Objects;
using Speckle.Converters.Common;
using Objects;
using Speckle.Converters.RevitShared.Helpers;
@@ -74,10 +74,10 @@ private void AssignSpecificParameters(IRevitWall target, RevitWall speckleWall)
speckleWall.baseLine = _curveConverter.Convert(locationCurve.Curve);
var level = _parameterValueExtractor.GetValueAsRevitLevel(target, RevitBuiltInParameter.WALL_BASE_CONSTRAINT);
- speckleWall.level = _levelConverter.Convert(level.NotNull());
+ speckleWall.level = _levelConverter.Convert(level);
var topLevel = _parameterValueExtractor.GetValueAsRevitLevel(target, RevitBuiltInParameter.WALL_BASE_CONSTRAINT);
- speckleWall.topLevel = _levelConverter.Convert(topLevel.NotNull());
+ speckleWall.topLevel = _levelConverter.Convert(topLevel);
// POC : what to do if these parameters are unset (instead of assigning default)
_ = _parameterValueExtractor.TryGetValueAsDouble(
diff --git a/DUI3-DX/Converters/Rhino/Speckle.Converters.Rhino7.DependencyInjection/RhinoConverterModule.cs b/DUI3-DX/Converters/Rhino/Speckle.Converters.Rhino7.DependencyInjection/RhinoConverterModule.cs
index 9117848c90..088b93cc10 100644
--- a/DUI3-DX/Converters/Rhino/Speckle.Converters.Rhino7.DependencyInjection/RhinoConverterModule.cs
+++ b/DUI3-DX/Converters/Rhino/Speckle.Converters.Rhino7.DependencyInjection/RhinoConverterModule.cs
@@ -9,7 +9,7 @@ public class RhinoConverterModule : ISpeckleModule
{
public void Load(SpeckleContainerBuilder builder)
{
- builder.AddConverterCommon();
+ builder.AddConverterCommon();
// single stack per conversion
builder.AddScoped, RhinoConversionContextStack>();
}
diff --git a/DUI3-DX/DUI3/Speckle.Connectors.DUI/Bindings/AccountBinding.cs b/DUI3-DX/DUI3/Speckle.Connectors.DUI/Bindings/AccountBinding.cs
index ffd61239c1..6357195a43 100644
--- a/DUI3-DX/DUI3/Speckle.Connectors.DUI/Bindings/AccountBinding.cs
+++ b/DUI3-DX/DUI3/Speckle.Connectors.DUI/Bindings/AccountBinding.cs
@@ -5,8 +5,8 @@ namespace Speckle.Connectors.DUI.Bindings;
public class AccountBinding : IBinding
{
- public string Name { get; set; } = "accountsBinding";
- public IBridge Parent { get; private set; }
+ public string Name => "accountsBinding";
+ public IBridge Parent { get; }
public AccountBinding(IBridge bridge)
{
diff --git a/DUI3-DX/DUI3/Speckle.Connectors.DUI/Bindings/TestBinding.cs b/DUI3-DX/DUI3/Speckle.Connectors.DUI/Bindings/TestBinding.cs
index e4676053e0..f0523db541 100644
--- a/DUI3-DX/DUI3/Speckle.Connectors.DUI/Bindings/TestBinding.cs
+++ b/DUI3-DX/DUI3/Speckle.Connectors.DUI/Bindings/TestBinding.cs
@@ -9,8 +9,8 @@ namespace Speckle.Connectors.DUI.Bindings;
///
public class TestBinding : IBinding
{
- public string Name { get; set; } = "testBinding";
- public IBridge Parent { get; private set; }
+ public string Name => "testBinding";
+ public IBridge Parent { get; }
public TestBinding(IBridge bridge)
{
diff --git a/DUI3-DX/Sdk/Speckle.Connectors.Utils/NotNullExtensions.cs b/DUI3-DX/Sdk/Speckle.Connectors.Utils/NotNullExtensions.cs
index a34d6dd671..59d9f2b3c0 100644
--- a/DUI3-DX/Sdk/Speckle.Connectors.Utils/NotNullExtensions.cs
+++ b/DUI3-DX/Sdk/Speckle.Connectors.Utils/NotNullExtensions.cs
@@ -5,6 +5,7 @@ namespace Speckle.Connectors.Utils;
public static class NotNullExtensions
{
+ ///
public static async Task NotNull(
this Task task,
[CallerArgumentExpression(nameof(task))] string? message = null
@@ -19,6 +20,7 @@ public static async Task NotNull(
return x;
}
+ ///
public static async Task NotNull(
this Task task,
[CallerArgumentExpression(nameof(task))] string? message = null
@@ -33,6 +35,11 @@ public static async Task NotNull(
return x.Value;
}
+ /// the object to check for null
+ /// see
+ /// type
+ /// A non null value
+ /// was null
public static T NotNull([NotNull] this T? obj, [CallerArgumentExpression(nameof(obj))] string? paramName = null)
where T : class
{
@@ -43,6 +50,7 @@ public static T NotNull([NotNull] this T? obj, [CallerArgumentExpression(name
return obj;
}
+ ///
public static T NotNull([NotNull] this T? obj, [CallerArgumentExpression(nameof(obj))] string? paramName = null)
where T : struct
{
diff --git a/DUI3-DX/Sdk/Speckle.Converters.Common.DependencyInjection/ToHost/ConverterWithFallback.cs b/DUI3-DX/Sdk/Speckle.Converters.Common.DependencyInjection/ToHost/ConverterWithFallback.cs
index 9d972cdd99..1d143ef8f9 100644
--- a/DUI3-DX/Sdk/Speckle.Converters.Common.DependencyInjection/ToHost/ConverterWithFallback.cs
+++ b/DUI3-DX/Sdk/Speckle.Converters.Common.DependencyInjection/ToHost/ConverterWithFallback.cs
@@ -1,4 +1,5 @@
-using Speckle.Converters.Common.Objects;
+using System.Collections;
+using Speckle.Converters.Common.Objects;
using Speckle.Core.Models;
using Speckle.Core.Models.Extensions;
@@ -49,6 +50,10 @@ public object Convert(Base target)
var displayValue = target.TryGetDisplayValue();
if (displayValue != null)
{
+ if (displayValue is IList && !displayValue.Any())
+ {
+ throw new NotSupportedException($"No display value found for {type}");
+ }
return FallbackToDisplayValue(displayValue);
}
diff --git a/DUI3-DX/Sdk/Speckle.Converters.Common.Tests/FakeType.cs b/DUI3-DX/Sdk/Speckle.Converters.Common.Tests/FakeType.cs
new file mode 100644
index 0000000000..517313bd4b
--- /dev/null
+++ b/DUI3-DX/Sdk/Speckle.Converters.Common.Tests/FakeType.cs
@@ -0,0 +1,109 @@
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Reflection;
+
+namespace Speckle.Converters.Common.Tests;
+
+public class FakeType : Type
+{
+ public FakeType(string name)
+ {
+ Name = name;
+ }
+
+ public override object[] GetCustomAttributes(bool inherit) => throw new NotImplementedException();
+
+ public override bool IsDefined(Type attributeType, bool inherit) => throw new NotImplementedException();
+
+ public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) => throw new NotImplementedException();
+
+ public override Type GetInterface(string name, bool ignoreCase) => throw new NotImplementedException();
+
+ public override Type[] GetInterfaces() => throw new NotImplementedException();
+
+ public override EventInfo GetEvent(string name, BindingFlags bindingAttr) => throw new NotImplementedException();
+
+ public override EventInfo[] GetEvents(BindingFlags bindingAttr) => throw new NotImplementedException();
+
+ public override Type[] GetNestedTypes(BindingFlags bindingAttr) => throw new NotImplementedException();
+
+ public override Type GetNestedType(string name, BindingFlags bindingAttr) => throw new NotImplementedException();
+
+ public override Type GetElementType() => throw new NotImplementedException();
+
+ protected override bool HasElementTypeImpl() => throw new NotImplementedException();
+
+ protected override PropertyInfo GetPropertyImpl(
+ string name,
+ BindingFlags bindingAttr,
+ Binder binder,
+ Type returnType,
+ Type[] types,
+ ParameterModifier[] modifiers
+ ) => throw new NotImplementedException();
+
+ public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) => throw new NotImplementedException();
+
+ protected override MethodInfo GetMethodImpl(
+ string name,
+ BindingFlags bindingAttr,
+ Binder binder,
+ CallingConventions callConvention,
+ Type[] types,
+ ParameterModifier[] modifiers
+ ) => throw new NotImplementedException();
+
+ public override MethodInfo[] GetMethods(BindingFlags bindingAttr) => throw new NotImplementedException();
+
+ public override FieldInfo GetField(string name, BindingFlags bindingAttr) => throw new NotImplementedException();
+
+ public override FieldInfo[] GetFields(BindingFlags bindingAttr) => throw new NotImplementedException();
+
+ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) => throw new NotImplementedException();
+
+ protected override TypeAttributes GetAttributeFlagsImpl() => throw new NotImplementedException();
+
+ protected override bool IsArrayImpl() => throw new NotImplementedException();
+
+ protected override bool IsByRefImpl() => throw new NotImplementedException();
+
+ protected override bool IsPointerImpl() => throw new NotImplementedException();
+
+ protected override bool IsPrimitiveImpl() => throw new NotImplementedException();
+
+ protected override bool IsCOMObjectImpl() => throw new NotImplementedException();
+
+ public override object InvokeMember(
+ string name,
+ BindingFlags invokeAttr,
+ Binder binder,
+ object target,
+ object[] args,
+ ParameterModifier[] modifiers,
+ CultureInfo culture,
+ string[] namedParameters
+ ) => throw new NotImplementedException();
+
+ public override Type UnderlyingSystemType { get; }
+
+ protected override ConstructorInfo GetConstructorImpl(
+ BindingFlags bindingAttr,
+ Binder binder,
+ CallingConventions callConvention,
+ Type[] types,
+ ParameterModifier[] modifiers
+ ) => throw new NotImplementedException();
+
+ public override string Name { get; }
+
+ [SuppressMessage("Naming", "CA1720:Identifier contains type name")]
+ public override Guid GUID { get; } = Guid.Empty;
+ public override Module Module { get; }
+ public override Assembly Assembly { get; }
+ public override string FullName { get; }
+ public override string Namespace { get; }
+ public override string AssemblyQualifiedName { get; }
+ public override Type BaseType { get; }
+
+ public override object[] GetCustomAttributes(Type attributeType, bool inherit) => throw new NotImplementedException();
+}
diff --git a/DUI3-DX/Sdk/Speckle.Converters.Common.Tests/RootToSpeckleConverterTests.cs b/DUI3-DX/Sdk/Speckle.Converters.Common.Tests/RootToSpeckleConverterTests.cs
new file mode 100644
index 0000000000..a94bf874e4
--- /dev/null
+++ b/DUI3-DX/Sdk/Speckle.Converters.Common.Tests/RootToSpeckleConverterTests.cs
@@ -0,0 +1,67 @@
+using FluentAssertions;
+using Moq;
+using NUnit.Framework;
+using Speckle.Core.Models;
+using Speckle.Revit.Interfaces;
+
+namespace Speckle.Converters.Common.Tests;
+
+public class RootToSpeckleConverterTests
+{
+ private readonly MockRepository _repository = new(MockBehavior.Strict);
+
+ private readonly Mock _rootConvertManager;
+ private readonly Mock _proxyMapper;
+ private readonly Mock _rootElementProvider;
+
+ public RootToSpeckleConverterTests()
+ {
+ _rootConvertManager = _repository.Create();
+ _proxyMapper = _repository.Create();
+ _rootElementProvider = _repository.Create();
+ }
+
+ [TearDown]
+ public void Verify() => _repository.VerifyAll();
+
+ [Test]
+ public void Convert_BaseType()
+ {
+ try
+ {
+ Type baseType = new FakeType("baseType");
+ Type hostType = new FakeType("hostType");
+
+ object target = new();
+ Type targetType = new FakeType("targetType");
+
+ object wrappedTarget = new();
+ Base converted = new();
+
+ _rootConvertManager.Setup(x => x.GetTargetType(target)).Returns(targetType);
+ _rootElementProvider.Setup(x => x.GetRootType()).Returns(baseType);
+ _proxyMapper.Setup(x => x.GetHostTypeFromMappedType(baseType)).Returns(hostType);
+
+ _proxyMapper.Setup(x => x.GetMappedTypeFromHostType(targetType)).Returns((Type?)null);
+ _proxyMapper.Setup(x => x.GetMappedTypeFromProxyType(targetType)).Returns((Type?)null);
+
+ _rootConvertManager.Setup(x => x.IsSubClass(baseType, targetType)).Returns(true);
+ _proxyMapper.Setup(x => x.CreateProxy(baseType, target)).Returns(wrappedTarget);
+ _rootConvertManager.Setup(x => x.Convert(baseType, wrappedTarget)).Returns(converted);
+
+ var rootToSpeckleConverter = new RootToSpeckleConverter(
+ _proxyMapper.Object,
+ _rootConvertManager.Object,
+ _rootElementProvider.Object
+ );
+ var testConverted = rootToSpeckleConverter.Convert(target);
+
+ testConverted.Should().BeSameAs(converted);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ throw;
+ }
+ }
+}
diff --git a/DUI3-DX/Sdk/Speckle.Converters.Common.Tests/Speckle.Converters.Common.Tests.csproj b/DUI3-DX/Sdk/Speckle.Converters.Common.Tests/Speckle.Converters.Common.Tests.csproj
new file mode 100644
index 0000000000..e687d74095
--- /dev/null
+++ b/DUI3-DX/Sdk/Speckle.Converters.Common.Tests/Speckle.Converters.Common.Tests.csproj
@@ -0,0 +1,25 @@
+
+
+
+ net48
+ x64
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DUI3-DX/Sdk/Speckle.Converters.Common.Tests/packages.lock.json b/DUI3-DX/Sdk/Speckle.Converters.Common.Tests/packages.lock.json
new file mode 100644
index 0000000000..745cd3ba1e
--- /dev/null
+++ b/DUI3-DX/Sdk/Speckle.Converters.Common.Tests/packages.lock.json
@@ -0,0 +1,458 @@
+{
+ "version": 1,
+ "dependencies": {
+ ".NETFramework,Version=v4.8": {
+ "coverlet.collector": {
+ "type": "Direct",
+ "requested": "[6.0.2, )",
+ "resolved": "6.0.2",
+ "contentHash": "bJShQ6uWRTQ100ZeyiMqcFlhP7WJ+bCuabUs885dJiBEzMsJMSFr7BOyeCw4rgvQokteGi5rKQTlkhfQPUXg2A=="
+ },
+ "FluentAssertions": {
+ "type": "Direct",
+ "requested": "[6.12.0, )",
+ "resolved": "6.12.0",
+ "contentHash": "ZXhHT2YwP9lajrwSKbLlFqsmCCvFJMoRSK9t7sImfnCyd0OB3MhgxdoMcVqxbq1iyxD6mD2fiackWmBb7ayiXQ==",
+ "dependencies": {
+ "System.Threading.Tasks.Extensions": "4.5.0"
+ }
+ },
+ "Microsoft.NET.Test.Sdk": {
+ "type": "Direct",
+ "requested": "[17.10.0, )",
+ "resolved": "17.10.0",
+ "contentHash": "0/2HeACkaHEYU3wc83YlcD2Fi4LMtECJjqrtvw0lPi9DCEa35zSPt1j4fuvM8NagjDqJuh1Ja35WcRtn1Um6/A==",
+ "dependencies": {
+ "Microsoft.CodeCoverage": "17.10.0"
+ }
+ },
+ "Moq": {
+ "type": "Direct",
+ "requested": "[4.20.70, )",
+ "resolved": "4.20.70",
+ "contentHash": "4rNnAwdpXJBuxqrOCzCyICXHSImOTRktCgCWXWykuF1qwoIsVvEnR7PjbMk/eLOxWvhmj5Kwt+kDV3RGUYcNwg==",
+ "dependencies": {
+ "Castle.Core": "5.1.1",
+ "System.Threading.Tasks.Extensions": "4.5.4"
+ }
+ },
+ "NUnit": {
+ "type": "Direct",
+ "requested": "[4.1.0, )",
+ "resolved": "4.1.0",
+ "contentHash": "MT/DpAhjtiytzhTgTqIhBuWx4y26PKfDepYUHUM+5uv4TsryHC2jwFo5e6NhWkApCm/G6kZ80dRjdJFuAxq3rg==",
+ "dependencies": {
+ "System.Threading.Tasks.Extensions": "4.5.4"
+ }
+ },
+ "NUnit.Analyzers": {
+ "type": "Direct",
+ "requested": "[4.2.0, )",
+ "resolved": "4.2.0",
+ "contentHash": "4fJojPkzdoa4nB2+p6U+fITvPnVvwWSnsmiJ/Dl30xqiL3oxNbYvfeSLVd91hOmEjoUqSwN3Z7j1aFedjqWbUA=="
+ },
+ "PolySharp": {
+ "type": "Direct",
+ "requested": "[1.14.1, )",
+ "resolved": "1.14.1",
+ "contentHash": "mOOmFYwad3MIOL14VCjj02LljyF1GNw1wP0YVlxtcPvqdxjGGMNdNJJxHptlry3MOd8b40Flm8RPOM8JOlN2sQ=="
+ },
+ "Speckle.InterfaceGenerator": {
+ "type": "Direct",
+ "requested": "[0.9.5, )",
+ "resolved": "0.9.5",
+ "contentHash": "oU/L7pN1R7q8KkbrpQ3WJnHirPHqn+9DEA7asOcUiggV5dzVg1A/VYs7GOSusD24njxXh03tE3a2oTLOjt3cVg=="
+ },
+ "Speckle.Revit2023.Interfaces": {
+ "type": "Direct",
+ "requested": "[0.1.1-preview.0.24, )",
+ "resolved": "0.1.1-preview.0.24",
+ "contentHash": "BSVpOUJc9g6ISrw8GxvtkglTlITpHEDYNOhxv1ZPbckBsI0yO36JiphhQV4q57ERqD9PpCozUJkVhlCaxWeS6A=="
+ },
+ "Castle.Core": {
+ "type": "Transitive",
+ "resolved": "5.1.1",
+ "contentHash": "rpYtIczkzGpf+EkZgDr9CClTdemhsrwA/W5hMoPjLkRFnXzH44zDLoovXeKtmxb1ykXK9aJVODSpiJml8CTw2g=="
+ },
+ "GraphQL.Client": {
+ "type": "Transitive",
+ "resolved": "6.0.0",
+ "contentHash": "8yPNBbuVBpTptivyAlak4GZvbwbUcjeQTL4vN1HKHRuOykZ4r7l5fcLS6vpyPyLn0x8FsL31xbOIKyxbmR9rbA==",
+ "dependencies": {
+ "GraphQL.Client.Abstractions": "6.0.0",
+ "GraphQL.Client.Abstractions.Websocket": "6.0.0",
+ "System.Net.WebSockets.Client.Managed": "1.0.22",
+ "System.Reactive": "5.0.0"
+ }
+ },
+ "GraphQL.Client.Abstractions": {
+ "type": "Transitive",
+ "resolved": "6.0.0",
+ "contentHash": "h7uzWFORHZ+CCjwr/ThAyXMr0DPpzEANDa4Uo54wqCQ+j7qUKwqYTgOrb1W40sqbvNaZm9v/X7It31SUw0maHA==",
+ "dependencies": {
+ "GraphQL.Primitives": "6.0.0"
+ }
+ },
+ "GraphQL.Client.Abstractions.Websocket": {
+ "type": "Transitive",
+ "resolved": "6.0.0",
+ "contentHash": "Nr9bPf8gIOvLuXpqEpqr9z9jslYFJOvd0feHth3/kPqeR3uMbjF5pjiwh4jxyMcxHdr8Pb6QiXkV3hsSyt0v7A==",
+ "dependencies": {
+ "GraphQL.Client.Abstractions": "6.0.0"
+ }
+ },
+ "GraphQL.Primitives": {
+ "type": "Transitive",
+ "resolved": "6.0.0",
+ "contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
+ },
+ "Microsoft.Bcl.AsyncInterfaces": {
+ "type": "Transitive",
+ "resolved": "5.0.0",
+ "contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
+ "dependencies": {
+ "System.Threading.Tasks.Extensions": "4.5.4"
+ }
+ },
+ "Microsoft.CodeCoverage": {
+ "type": "Transitive",
+ "resolved": "17.10.0",
+ "contentHash": "yC7oSlnR54XO5kOuHlVOKtxomNNN1BWXX8lK1G2jaPXT9sUok7kCOoA4Pgs0qyFaCtMrNsprztYMeoEGqCm4uA=="
+ },
+ "Microsoft.CSharp": {
+ "type": "Transitive",
+ "resolved": "4.7.0",
+ "contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
+ },
+ "Microsoft.Data.Sqlite": {
+ "type": "Transitive",
+ "resolved": "7.0.5",
+ "contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
+ "dependencies": {
+ "Microsoft.Data.Sqlite.Core": "7.0.5",
+ "SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
+ }
+ },
+ "Microsoft.Data.Sqlite.Core": {
+ "type": "Transitive",
+ "resolved": "7.0.5",
+ "contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
+ "dependencies": {
+ "SQLitePCLRaw.core": "2.1.4"
+ }
+ },
+ "Microsoft.Extensions.Logging.Abstractions": {
+ "type": "Transitive",
+ "resolved": "7.0.0",
+ "contentHash": "kmn78+LPVMOWeITUjIlfxUPDsI0R6G0RkeAMBmQxAJ7vBJn4q2dTva7pWi65ceN5vPGjJ9q/Uae2WKgvfktJAw==",
+ "dependencies": {
+ "System.Buffers": "4.5.1",
+ "System.Memory": "4.5.5"
+ }
+ },
+ "Polly": {
+ "type": "Transitive",
+ "resolved": "7.2.3",
+ "contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
+ },
+ "Polly.Contrib.WaitAndRetry": {
+ "type": "Transitive",
+ "resolved": "1.1.1",
+ "contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
+ },
+ "Polly.Extensions.Http": {
+ "type": "Transitive",
+ "resolved": "3.0.0",
+ "contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
+ "dependencies": {
+ "Polly": "7.1.0"
+ }
+ },
+ "Sentry": {
+ "type": "Transitive",
+ "resolved": "3.33.0",
+ "contentHash": "8vbD2o6IR2wrRrkSiRbnodWGWUOqIlwYtzpjvPNOb5raJdOf+zxMwfS8f6nx9bmrTTfDj7KrCB8C/5OuicAc8A==",
+ "dependencies": {
+ "System.Reflection.Metadata": "5.0.0",
+ "System.Runtime.InteropServices.RuntimeInformation": "4.3.0",
+ "System.Text.Json": "5.0.2"
+ }
+ },
+ "Sentry.Serilog": {
+ "type": "Transitive",
+ "resolved": "3.33.0",
+ "contentHash": "V8BU7QGWg2qLYfNPqtuTBhC1opysny5l+Ifp6J6PhOeAxU0FssR7nYfbJVetrnLIoh2rd3DlJ6hHYYQosQYcUQ==",
+ "dependencies": {
+ "Sentry": "3.33.0",
+ "Serilog": "2.7.1"
+ }
+ },
+ "Serilog": {
+ "type": "Transitive",
+ "resolved": "2.12.0",
+ "contentHash": "xaiJLIdu6rYMKfQMYUZgTy8YK7SMZjB4Yk50C/u//Z4OsvxkUfSPJy4nknfvwAC34yr13q7kcyh4grbwhSxyZg=="
+ },
+ "Serilog.Enrichers.ClientInfo": {
+ "type": "Transitive",
+ "resolved": "1.3.0",
+ "contentHash": "mTc7PM+wC9Hr7LWSwqt5mmnlAr7RJs+eTb3PGPRhwdOackk95MkhUZognuxXEdlW19HAFNmEBTSBY5DfLwM8jQ==",
+ "dependencies": {
+ "Serilog": "2.4.0"
+ }
+ },
+ "Serilog.Enrichers.GlobalLogContext": {
+ "type": "Transitive",
+ "resolved": "3.0.0",
+ "contentHash": "IIZcj5mAUVhIl/NTA+YI2KC+sPDzcwvs0ZMHH42jsPfl1a4LVX7ohVpw5UK+e3GxuV3Nv239Il5oM2peUIl44g==",
+ "dependencies": {
+ "Serilog": "2.12.0"
+ }
+ },
+ "Serilog.Exceptions": {
+ "type": "Transitive",
+ "resolved": "8.4.0",
+ "contentHash": "nc/+hUw3lsdo0zCj0KMIybAu7perMx79vu72w0za9Nsi6mWyNkGXxYxakAjWB7nEmYL6zdmhEQRB4oJ2ALUeug==",
+ "dependencies": {
+ "Serilog": "2.8.0"
+ }
+ },
+ "Serilog.Formatting.Compact": {
+ "type": "Transitive",
+ "resolved": "1.1.0",
+ "contentHash": "pNroKVjo+rDqlxNG5PXkRLpfSCuDOBY0ri6jp9PLe505ljqwhwZz8ospy2vWhQlFu5GkIesh3FcDs4n7sWZODA==",
+ "dependencies": {
+ "Serilog": "2.8.0"
+ }
+ },
+ "Serilog.Sinks.Console": {
+ "type": "Transitive",
+ "resolved": "4.1.0",
+ "contentHash": "K6N5q+5fetjnJPvCmkWOpJ/V8IEIoMIB1s86OzBrbxwTyHxdx3pmz4H+8+O/Dc/ftUX12DM1aynx/dDowkwzqg==",
+ "dependencies": {
+ "Serilog": "2.10.0"
+ }
+ },
+ "Serilog.Sinks.File": {
+ "type": "Transitive",
+ "resolved": "5.0.0",
+ "contentHash": "uwV5hdhWPwUH1szhO8PJpFiahqXmzPzJT/sOijH/kFgUx+cyoDTMM8MHD0adw9+Iem6itoibbUXHYslzXsLEAg==",
+ "dependencies": {
+ "Serilog": "2.10.0"
+ }
+ },
+ "Serilog.Sinks.PeriodicBatching": {
+ "type": "Transitive",
+ "resolved": "3.1.0",
+ "contentHash": "NDWR7m3PalVlGEq3rzoktrXikjFMLmpwF0HI4sowo8YDdU+gqPlTHlDQiOGxHfB0sTfjPA9JjA7ctKG9zqjGkw==",
+ "dependencies": {
+ "Serilog": "2.0.0"
+ }
+ },
+ "Serilog.Sinks.Seq": {
+ "type": "Transitive",
+ "resolved": "5.2.2",
+ "contentHash": "1Csmo5ua7NKUe0yXUx+zsRefjAniPWcXFhUXxXG8pwo0iMiw2gjn9SOkgYnnxbgWqmlGv236w0N/dHc2v5XwMg==",
+ "dependencies": {
+ "Serilog": "2.12.0",
+ "Serilog.Formatting.Compact": "1.1.0",
+ "Serilog.Sinks.File": "5.0.0",
+ "Serilog.Sinks.PeriodicBatching": "3.1.0"
+ }
+ },
+ "SerilogTimings": {
+ "type": "Transitive",
+ "resolved": "3.0.1",
+ "contentHash": "Zs28eTgszAMwpIrbBnWHBI50yuxL50p/dmAUWmy75+axdZYK/Sjm5/5m1N/CisR8acJUhTVcjPZrsB1P5iv0Uw==",
+ "dependencies": {
+ "Serilog": "2.10.0"
+ }
+ },
+ "Speckle.Newtonsoft.Json": {
+ "type": "Transitive",
+ "resolved": "13.0.2",
+ "contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
+ },
+ "SQLitePCLRaw.bundle_e_sqlite3": {
+ "type": "Transitive",
+ "resolved": "2.1.4",
+ "contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==",
+ "dependencies": {
+ "SQLitePCLRaw.lib.e_sqlite3": "2.1.4",
+ "SQLitePCLRaw.provider.dynamic_cdecl": "2.1.4"
+ }
+ },
+ "SQLitePCLRaw.core": {
+ "type": "Transitive",
+ "resolved": "2.1.4",
+ "contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==",
+ "dependencies": {
+ "System.Memory": "4.5.3"
+ }
+ },
+ "SQLitePCLRaw.lib.e_sqlite3": {
+ "type": "Transitive",
+ "resolved": "2.1.4",
+ "contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
+ },
+ "SQLitePCLRaw.provider.dynamic_cdecl": {
+ "type": "Transitive",
+ "resolved": "2.1.4",
+ "contentHash": "ZsaKKhgYF9B1fvcnOGKl3EycNAwd9CRWX7v0rEfuPWhQQ5Jjpvf2VEHahiLIGHio3hxi3EIKFJw9KvyowWOUAw==",
+ "dependencies": {
+ "SQLitePCLRaw.core": "2.1.4"
+ }
+ },
+ "System.Buffers": {
+ "type": "Transitive",
+ "resolved": "4.5.1",
+ "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg=="
+ },
+ "System.Collections.Immutable": {
+ "type": "Transitive",
+ "resolved": "5.0.0",
+ "contentHash": "FXkLXiK0sVVewcso0imKQoOxjoPAj42R8HtjjbSjVPAzwDfzoyoznWxgA3c38LDbN9SJux1xXoXYAhz98j7r2g==",
+ "dependencies": {
+ "System.Memory": "4.5.4"
+ }
+ },
+ "System.DoubleNumerics": {
+ "type": "Transitive",
+ "resolved": "3.1.3",
+ "contentHash": "KRKEM/L3KBodjA9VOg3EifFVWUY6EOqaMB05UvPEDm7Zeby/kZW+4kdWUEPzW6xtkwf46p661L9NrbeeQhtLzw==",
+ "dependencies": {
+ "NETStandard.Library": "1.6.1"
+ }
+ },
+ "System.Memory": {
+ "type": "Transitive",
+ "resolved": "4.5.5",
+ "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
+ "dependencies": {
+ "System.Buffers": "4.5.1",
+ "System.Numerics.Vectors": "4.5.0",
+ "System.Runtime.CompilerServices.Unsafe": "4.5.3"
+ }
+ },
+ "System.Net.WebSockets.Client.Managed": {
+ "type": "Transitive",
+ "resolved": "1.0.22",
+ "contentHash": "WqEOxPlXjuZrIjUtXNE9NxEfU/n5E35iV2PtoZdJSUC4tlrqwHnTee+wvMIM4OUaJWmwrymeqcgYrE0IkGAgLA==",
+ "dependencies": {
+ "System.Buffers": "4.4.0",
+ "System.Numerics.Vectors": "4.4.0"
+ }
+ },
+ "System.Numerics.Vectors": {
+ "type": "Transitive",
+ "resolved": "4.5.0",
+ "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ=="
+ },
+ "System.Reactive": {
+ "type": "Transitive",
+ "resolved": "5.0.0",
+ "contentHash": "erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==",
+ "dependencies": {
+ "System.Threading.Tasks.Extensions": "4.5.4"
+ }
+ },
+ "System.Reflection.Metadata": {
+ "type": "Transitive",
+ "resolved": "5.0.0",
+ "contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ==",
+ "dependencies": {
+ "System.Collections.Immutable": "5.0.0"
+ }
+ },
+ "System.Runtime.CompilerServices.Unsafe": {
+ "type": "Transitive",
+ "resolved": "5.0.0",
+ "contentHash": "ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA=="
+ },
+ "System.Runtime.InteropServices.RuntimeInformation": {
+ "type": "Transitive",
+ "resolved": "4.3.0",
+ "contentHash": "cbz4YJMqRDR7oLeMRbdYv7mYzc++17lNhScCX0goO2XpGWdvAt60CGN+FHdePUEHCe/Jy9jUlvNAiNdM+7jsOw=="
+ },
+ "System.Text.Encodings.Web": {
+ "type": "Transitive",
+ "resolved": "5.0.1",
+ "contentHash": "KmJ+CJXizDofbq6mpqDoRRLcxgOd2z9X3XoFNULSbvbqVRZkFX3istvr+MUjL6Zw1RT+RNdoI4GYidIINtgvqQ==",
+ "dependencies": {
+ "System.Buffers": "4.5.1",
+ "System.Memory": "4.5.4"
+ }
+ },
+ "System.Text.Json": {
+ "type": "Transitive",
+ "resolved": "5.0.2",
+ "contentHash": "I47dVIGiV6SfAyppphxqupertT/5oZkYLDCX6vC3HpOI4ZLjyoKAreUoem2ie6G0RbRuFrlqz/PcTQjfb2DOfQ==",
+ "dependencies": {
+ "Microsoft.Bcl.AsyncInterfaces": "5.0.0",
+ "System.Buffers": "4.5.1",
+ "System.Memory": "4.5.4",
+ "System.Numerics.Vectors": "4.5.0",
+ "System.Runtime.CompilerServices.Unsafe": "5.0.0",
+ "System.Text.Encodings.Web": "5.0.1",
+ "System.Threading.Tasks.Extensions": "4.5.4",
+ "System.ValueTuple": "4.5.0"
+ }
+ },
+ "System.Threading.Tasks.Extensions": {
+ "type": "Transitive",
+ "resolved": "4.5.4",
+ "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
+ "dependencies": {
+ "System.Runtime.CompilerServices.Unsafe": "4.5.3"
+ }
+ },
+ "System.ValueTuple": {
+ "type": "Transitive",
+ "resolved": "4.5.0",
+ "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ=="
+ },
+ "speckle.autofac": {
+ "type": "Project",
+ "dependencies": {
+ "Microsoft.Extensions.Logging.Abstractions": "[7.0.0, )",
+ "Speckle.Core": "[2.0.999-local, )"
+ }
+ },
+ "speckle.converters.common": {
+ "type": "Project",
+ "dependencies": {
+ "Speckle.Autofac": "[2.0.999-local, )",
+ "Speckle.Objects": "[2.0.999-local, )",
+ "Speckle.Revit2023.Interfaces": "[0.1.1-preview.0.24, )"
+ }
+ },
+ "Speckle.Core": {
+ "type": "Project",
+ "dependencies": {
+ "GraphQL.Client": "[6.0.0, )",
+ "Microsoft.CSharp": "[4.7.0, )",
+ "Microsoft.Data.Sqlite": "[7.0.5, )",
+ "Polly": "[7.2.3, )",
+ "Polly.Contrib.WaitAndRetry": "[1.1.1, )",
+ "Polly.Extensions.Http": "[3.0.0, )",
+ "Sentry": "[3.33.0, )",
+ "Sentry.Serilog": "[3.33.0, )",
+ "Serilog": "[2.12.0, )",
+ "Serilog.Enrichers.ClientInfo": "[1.3.0, )",
+ "Serilog.Enrichers.GlobalLogContext": "[3.0.0, )",
+ "Serilog.Exceptions": "[8.4.0, )",
+ "Serilog.Sinks.Console": "[4.1.0, )",
+ "Serilog.Sinks.Seq": "[5.2.2, )",
+ "SerilogTimings": "[3.0.1, )",
+ "Speckle.Newtonsoft.Json": "[13.0.2, )",
+ "System.DoubleNumerics": "[3.1.3, )"
+ }
+ },
+ "Speckle.Objects": {
+ "type": "Project",
+ "dependencies": {
+ "Speckle.Core": "[2.0.999-local, )"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DUI3-DX/Sdk/Speckle.Converters.Common/IRootElementProvider.cs b/DUI3-DX/Sdk/Speckle.Converters.Common/IRootElementProvider.cs
new file mode 100644
index 0000000000..e183c154af
--- /dev/null
+++ b/DUI3-DX/Sdk/Speckle.Converters.Common/IRootElementProvider.cs
@@ -0,0 +1,6 @@
+namespace Speckle.Converters.Common;
+
+public interface IRootElementProvider
+{
+ Type GetRootType();
+}
diff --git a/DUI3-DX/Sdk/Speckle.Converters.Common/LegacyRootToSpeckleConverter.cs b/DUI3-DX/Sdk/Speckle.Converters.Common/LegacyRootToSpeckleConverter.cs
new file mode 100644
index 0000000000..34cd5576a2
--- /dev/null
+++ b/DUI3-DX/Sdk/Speckle.Converters.Common/LegacyRootToSpeckleConverter.cs
@@ -0,0 +1,37 @@
+using Speckle.Autofac.DependencyInjection;
+using Speckle.Converters.Common.Objects;
+using Speckle.Core.Models;
+
+namespace Speckle.Converters.Common;
+
+public class LegacyRootToSpeckleConverter : IRootToSpeckleConverter
+{
+ private readonly IFactory _toSpeckle;
+
+ public LegacyRootToSpeckleConverter(IFactory toSpeckle)
+ {
+ _toSpeckle = toSpeckle;
+ }
+
+ public Base Convert(object target)
+ {
+ Type type = target.GetType();
+ try
+ {
+ var objectConverter = _toSpeckle.ResolveInstance(type.Name); //poc: would be nice to have supertypes resolve
+
+ if (objectConverter == null)
+ {
+ throw new NotSupportedException($"No conversion found for {type.Name}");
+ }
+ var convertedObject = objectConverter.Convert(target);
+
+ return convertedObject;
+ }
+ catch (SpeckleConversionException e)
+ {
+ Console.WriteLine(e);
+ throw; // Just rethrowing for now, Logs may be needed here.
+ }
+ }
+}
diff --git a/DUI3-DX/Sdk/Speckle.Converters.Common/RootConvertManager.cs b/DUI3-DX/Sdk/Speckle.Converters.Common/RootConvertManager.cs
new file mode 100644
index 0000000000..4ae930fa1c
--- /dev/null
+++ b/DUI3-DX/Sdk/Speckle.Converters.Common/RootConvertManager.cs
@@ -0,0 +1,42 @@
+using Speckle.Autofac.DependencyInjection;
+using Speckle.Converters.Common.Objects;
+using Speckle.Core.Models;
+using Speckle.InterfaceGenerator;
+
+namespace Speckle.Converters.Common;
+
+[GenerateAutoInterface]
+public class RootConvertManager : IRootConvertManager
+{
+ private readonly IFactory _toSpeckle;
+
+ public RootConvertManager(IFactory toSpeckle)
+ {
+ _toSpeckle = toSpeckle;
+ }
+
+ public Type GetTargetType(object target) => target.GetType();
+
+ public bool IsSubClass(Type baseType, Type childType) => baseType.IsAssignableFrom(childType);
+
+ public Base Convert(Type type, object obj)
+ {
+ try
+ {
+ var objectConverter = _toSpeckle.ResolveInstance(type.Name); //poc: would be nice to have supertypes resolve
+
+ if (objectConverter == null)
+ {
+ throw new NotSupportedException($"No conversion found for {type.Name}");
+ }
+ var convertedObject = objectConverter.Convert(obj);
+
+ return convertedObject;
+ }
+ catch (SpeckleConversionException e)
+ {
+ Console.WriteLine(e);
+ throw; // Just rethrowing for now, Logs may be needed here.
+ }
+ }
+}
diff --git a/DUI3-DX/Sdk/Speckle.Converters.Common/RootToSpeckleConverter.cs b/DUI3-DX/Sdk/Speckle.Converters.Common/RootToSpeckleConverter.cs
index 04d87e8349..fac0af321d 100644
--- a/DUI3-DX/Sdk/Speckle.Converters.Common/RootToSpeckleConverter.cs
+++ b/DUI3-DX/Sdk/Speckle.Converters.Common/RootToSpeckleConverter.cs
@@ -1,5 +1,3 @@
-using Speckle.Autofac.DependencyInjection;
-using Speckle.Converters.Common.Objects;
using Speckle.Core.Models;
using Speckle.InterfaceGenerator;
using Speckle.Revit.Interfaces;
@@ -9,40 +7,41 @@ namespace Speckle.Converters.Common;
[GenerateAutoInterface]
public class RootToSpeckleConverter : IRootToSpeckleConverter
{
- private readonly IFactory _toSpeckle;
+ private readonly IRootConvertManager _rootConvertManager;
private readonly IProxyMapper _proxyMapper;
+ private readonly IRootElementProvider _rootElementProvider;
- public RootToSpeckleConverter(IFactory toSpeckle, IProxyMapper proxyMapper)
+ private readonly Type _revitElementType;
+
+ public RootToSpeckleConverter(
+ IProxyMapper proxyMapper,
+ IRootConvertManager rootConvertManager,
+ IRootElementProvider rootElementProvider
+ )
{
- _toSpeckle = toSpeckle;
_proxyMapper = proxyMapper;
+ _rootConvertManager = rootConvertManager;
+ _rootElementProvider = rootElementProvider;
+ _revitElementType = _proxyMapper.GetHostTypeFromMappedType(_rootElementProvider.GetRootType()).NotNull();
}
public Base Convert(object target)
{
- Type revitType = target.GetType();
+ Type revitType = _rootConvertManager.GetTargetType(target);
var wrapper = _proxyMapper.WrapIfExists(revitType, target);
if (wrapper == null)
{
- throw new NotSupportedException($"No wrapper found for Revit type: {revitType.Name}");
- }
- var (wrappedType, wrappedObject) = wrapper.Value;
- try
- {
- var objectConverter = _toSpeckle.ResolveInstance(wrappedType.Name); //poc: would be nice to have supertypes resolve
-
- if (objectConverter == null)
+ //try to fallback to element type
+ if (_rootConvertManager.IsSubClass(_revitElementType, revitType))
{
- throw new NotSupportedException($"No conversion found for {wrappedType.Name}");
+ return _rootConvertManager.Convert(
+ _rootElementProvider.GetRootType(),
+ _proxyMapper.CreateProxy(_rootElementProvider.GetRootType(), target)
+ );
}
- var convertedObject = objectConverter.Convert(wrappedObject);
-
- return convertedObject;
- }
- catch (SpeckleConversionException e)
- {
- Console.WriteLine(e);
- throw; // Just rethrowing for now, Logs may be needed here.
+ throw new NotSupportedException($"No wrapper found for Revit type: {revitType.Name}");
}
+ var (wrappedType, wrappedObject) = wrapper;
+ return _rootConvertManager.Convert(wrappedType, wrappedObject);
}
}
diff --git a/DUI3-DX/Sdk/Speckle.Converters.Common/Speckle.Converters.Common.csproj b/DUI3-DX/Sdk/Speckle.Converters.Common/Speckle.Converters.Common.csproj
index 761f021575..07793ee159 100644
--- a/DUI3-DX/Sdk/Speckle.Converters.Common/Speckle.Converters.Common.csproj
+++ b/DUI3-DX/Sdk/Speckle.Converters.Common/Speckle.Converters.Common.csproj
@@ -3,12 +3,13 @@
netstandard2.0
-
-
-
+
+
+
+