From d73834e27d8f7701918e21b540ff4c5307be9ce1 Mon Sep 17 00:00:00 2001 From: Claire Kuang Date: Wed, 30 Oct 2024 16:55:46 +0000 Subject: [PATCH 1/6] adds component unpacker to tekla connector --- .../GlobalUsing.cs | 2 + .../HostApp/ComponentUnpacker.cs | 62 +++++++++++++++++++ .../Operations/Send/TeklaRootObjectBuilder.cs | 12 +++- .../ServiceRegistration.cs | 2 + .../SpeckleApplicationIdExtensions.cs | 7 +++ .../TeklaRootToSpeckleConverter.cs | 3 +- .../Helpers/DisplayValueExtractor.cs | 13 ++-- 7 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 Connectors/Tekla/Speckle.Connector.Tekla2024/GlobalUsing.cs create mode 100644 Connectors/Tekla/Speckle.Connector.Tekla2024/HostApp/ComponentUnpacker.cs create mode 100644 Converters/Tekla/Speckle.Converter.Tekla2024/Extensions/SpeckleApplicationIdExtensions.cs diff --git a/Connectors/Tekla/Speckle.Connector.Tekla2024/GlobalUsing.cs b/Connectors/Tekla/Speckle.Connector.Tekla2024/GlobalUsing.cs new file mode 100644 index 00000000..1881675f --- /dev/null +++ b/Connectors/Tekla/Speckle.Connector.Tekla2024/GlobalUsing.cs @@ -0,0 +1,2 @@ +global using TG = Tekla.Structures.Geometry3d; +global using TSM = Tekla.Structures.Model; diff --git a/Connectors/Tekla/Speckle.Connector.Tekla2024/HostApp/ComponentUnpacker.cs b/Connectors/Tekla/Speckle.Connector.Tekla2024/HostApp/ComponentUnpacker.cs new file mode 100644 index 00000000..c313616d --- /dev/null +++ b/Connectors/Tekla/Speckle.Connector.Tekla2024/HostApp/ComponentUnpacker.cs @@ -0,0 +1,62 @@ +using Speckle.Converter.Tekla2024.Extensions; +using Speckle.Converters.Common.Objects; +using Speckle.Sdk.Models; +using Speckle.Sdk.Models.Proxies; + +namespace Speckle.Connector.Tekla2024.HostApp; + +public class ComponentUnpacker +{ + // POC: should add ILogger here in the case that component unpacker fails to unpack a component + + /// + /// Stores processed Base Components as group proxies. These include Components and Connections. + /// Expects to be scoped per send operation. Should be added to the root collection. + /// + public Dictionary ComponentProxiesCache { get; } + + private readonly ITypedConverter _modelObjectConverter; + + public ComponentUnpacker(ITypedConverter modelObjectConverter) + { + _modelObjectConverter = modelObjectConverter; + } + + public IEnumerable UnpackComponents(IReadOnlyList modelObjects) + { + foreach (TSM.ModelObject modelObject in modelObjects) + { + if (modelObject is TSM.BaseComponent component) + { + // create a group proxy for this component + string appId = component.GetSpeckleApplicationId(); + List childIds = new(); + + foreach (TSM.ModelObject child in component.GetChildren()) + { + childIds.Add(child.GetSpeckleApplicationId()); + yield return child; + } + + GroupProxy componentProxy = + new() + { + name = component.Name, + objects = childIds, + applicationId = appId + }; + + componentProxy["number"] = component.Number; + + if (!ComponentProxiesCache.ContainsKey(appId)) + { + ComponentProxiesCache.Add(appId, componentProxy); + } + } + else + { + yield return modelObject; + } + } + } +} diff --git a/Connectors/Tekla/Speckle.Connector.Tekla2024/Operations/Send/TeklaRootObjectBuilder.cs b/Connectors/Tekla/Speckle.Connector.Tekla2024/Operations/Send/TeklaRootObjectBuilder.cs index 40e7b247..f07d1421 100644 --- a/Connectors/Tekla/Speckle.Connector.Tekla2024/Operations/Send/TeklaRootObjectBuilder.cs +++ b/Connectors/Tekla/Speckle.Connector.Tekla2024/Operations/Send/TeklaRootObjectBuilder.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.Logging; +using Speckle.Connector.Tekla2024.HostApp; using Speckle.Connectors.Common.Builders; using Speckle.Connectors.Common.Caching; using Speckle.Connectors.Common.Conversion; @@ -21,13 +22,15 @@ public class TeklaRootObjectBuilder : IRootObjectBuilder private readonly IConverterSettingsStore _converterSettings; private readonly ILogger _logger; private readonly ISdkActivityFactory _activityFactory; + private readonly ComponentUnpacker _componentUnpacker; public TeklaRootObjectBuilder( IRootToSpeckleConverter rootToSpeckleConverter, ISendConversionCache sendConversionCache, IConverterSettingsStore converterSettings, ILogger logger, - ISdkActivityFactory activityFactory + ISdkActivityFactory activityFactory, + ComponentUnpacker componentUnpacker ) { _sendConversionCache = sendConversionCache; @@ -35,6 +38,7 @@ ISdkActivityFactory activityFactory _rootToSpeckleConverter = rootToSpeckleConverter; _logger = logger; _activityFactory = activityFactory; + _componentUnpacker = componentUnpacker; } public async Task Build( @@ -52,12 +56,16 @@ public async Task Build( Collection rootObjectCollection = new() { name = modelName }; rootObjectCollection["units"] = _converterSettings.Current.SpeckleUnits; + // Step 0: unpack all component model objects + List unpackedTeklaObjects = _componentUnpacker.UnpackComponents(teklaObjects).ToList(); + rootObjectCollection["componentProxies"] = _componentUnpacker.ComponentProxiesCache.Values; + List results = new(teklaObjects.Count); int count = 0; using (var _ = _activityFactory.Start("Convert all")) { - foreach (ModelObject teklaObject in teklaObjects) + foreach (ModelObject teklaObject in unpackedTeklaObjects) { using var _2 = _activityFactory.Start("Convert"); cancellationToken.ThrowIfCancellationRequested(); diff --git a/Connectors/Tekla/Speckle.Connector.Tekla2024/ServiceRegistration.cs b/Connectors/Tekla/Speckle.Connector.Tekla2024/ServiceRegistration.cs index 78653cef..6f861956 100644 --- a/Connectors/Tekla/Speckle.Connector.Tekla2024/ServiceRegistration.cs +++ b/Connectors/Tekla/Speckle.Connector.Tekla2024/ServiceRegistration.cs @@ -15,6 +15,7 @@ using Speckle.Connectors.DUI.Models.Card.SendFilter; using Speckle.Connectors.DUI.WebView; using Speckle.Converter.Tekla2024; +using Speckle.Converter.Tekla2024.Helpers; using Speckle.Converters.Common; using Speckle.Sdk; using Speckle.Sdk.Models.GraphTraversal; @@ -66,6 +67,7 @@ public static IServiceCollection AddTekla(this IServiceCollection services) IConverterSettingsStore, ConverterSettingsStore >(); + services.AddScoped(); services.AddMatchingInterfacesAsTransient(converterAssembly); diff --git a/Converters/Tekla/Speckle.Converter.Tekla2024/Extensions/SpeckleApplicationIdExtensions.cs b/Converters/Tekla/Speckle.Converter.Tekla2024/Extensions/SpeckleApplicationIdExtensions.cs new file mode 100644 index 00000000..58a8b91a --- /dev/null +++ b/Converters/Tekla/Speckle.Converter.Tekla2024/Extensions/SpeckleApplicationIdExtensions.cs @@ -0,0 +1,7 @@ +namespace Speckle.Converter.Tekla2024.Extensions; + +public static class SpeckleApplicationIdExtensions +{ + public static string GetSpeckleApplicationId(this TSM.ModelObject modelObject) => + modelObject.Identifier.GUID.ToString(); +} diff --git a/Converters/Tekla/Speckle.Converter.Tekla2024/TeklaRootToSpeckleConverter.cs b/Converters/Tekla/Speckle.Converter.Tekla2024/TeklaRootToSpeckleConverter.cs index fabb8adc..134b36b2 100644 --- a/Converters/Tekla/Speckle.Converter.Tekla2024/TeklaRootToSpeckleConverter.cs +++ b/Converters/Tekla/Speckle.Converter.Tekla2024/TeklaRootToSpeckleConverter.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.Logging; +using Speckle.Converter.Tekla2024.Extensions; using Speckle.Converters.Common; using Speckle.Converters.Common.Objects; using Speckle.Converters.Common.Registration; @@ -38,7 +39,7 @@ public Base Convert(object target) Base result = objectConverter.Convert(target); // add tekla specific identifiers - result.applicationId = modelObject.Identifier.GUID.ToString(); + result.applicationId = modelObject.GetSpeckleApplicationId(); //TODO: attach properties return result; diff --git a/Converters/Tekla/Speckle.Converter.Tekla2024/ToSpeckle/Helpers/DisplayValueExtractor.cs b/Converters/Tekla/Speckle.Converter.Tekla2024/ToSpeckle/Helpers/DisplayValueExtractor.cs index bf67d8a9..3e4ae8b2 100644 --- a/Converters/Tekla/Speckle.Converter.Tekla2024/ToSpeckle/Helpers/DisplayValueExtractor.cs +++ b/Converters/Tekla/Speckle.Converter.Tekla2024/ToSpeckle/Helpers/DisplayValueExtractor.cs @@ -26,11 +26,16 @@ public IEnumerable GetDisplayValue(TSM.ModelObject modelObject) // both beam and contour plate are child classes of part // its simpler to use part for common methods case TSM.Part part: - var solid = part.GetSolid(); - if (solid != null) + if (part.GetSolid() is TSM.Solid partSolid) { - var mesh = _meshConverter.Convert(solid); - yield return mesh; + yield return _meshConverter.Convert(partSolid); + } + break; + + case TSM.BoltGroup boltGroup: + if (boltGroup.GetSolid() is TSM.Solid boltSolid) + { + yield return _meshConverter.Convert(boltSolid); } break; From c7cec3090c8d70b53b5cfd0e216ef3bd47d9d97b Mon Sep 17 00:00:00 2001 From: Claire Kuang Date: Wed, 30 Oct 2024 17:08:56 +0000 Subject: [PATCH 2/6] removes model object converter --- .../HostApp/ComponentUnpacker.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Connectors/Tekla/Speckle.Connector.Tekla2024/HostApp/ComponentUnpacker.cs b/Connectors/Tekla/Speckle.Connector.Tekla2024/HostApp/ComponentUnpacker.cs index c313616d..3933568e 100644 --- a/Connectors/Tekla/Speckle.Connector.Tekla2024/HostApp/ComponentUnpacker.cs +++ b/Connectors/Tekla/Speckle.Connector.Tekla2024/HostApp/ComponentUnpacker.cs @@ -15,12 +15,7 @@ public class ComponentUnpacker /// public Dictionary ComponentProxiesCache { get; } - private readonly ITypedConverter _modelObjectConverter; - - public ComponentUnpacker(ITypedConverter modelObjectConverter) - { - _modelObjectConverter = modelObjectConverter; - } + public ComponentUnpacker() { } public IEnumerable UnpackComponents(IReadOnlyList modelObjects) { From 1b1ddb004aec8dfa12dbadddcb706c9a335a827d Mon Sep 17 00:00:00 2001 From: Claire Kuang Date: Wed, 30 Oct 2024 17:09:12 +0000 Subject: [PATCH 3/6] Update ComponentUnpacker.cs --- .../Speckle.Connector.Tekla2024/HostApp/ComponentUnpacker.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Connectors/Tekla/Speckle.Connector.Tekla2024/HostApp/ComponentUnpacker.cs b/Connectors/Tekla/Speckle.Connector.Tekla2024/HostApp/ComponentUnpacker.cs index 3933568e..6b21b261 100644 --- a/Connectors/Tekla/Speckle.Connector.Tekla2024/HostApp/ComponentUnpacker.cs +++ b/Connectors/Tekla/Speckle.Connector.Tekla2024/HostApp/ComponentUnpacker.cs @@ -1,6 +1,4 @@ using Speckle.Converter.Tekla2024.Extensions; -using Speckle.Converters.Common.Objects; -using Speckle.Sdk.Models; using Speckle.Sdk.Models.Proxies; namespace Speckle.Connector.Tekla2024.HostApp; From daec65d01dca8bc9fb0f908c0847fd3b0a4bff35 Mon Sep 17 00:00:00 2001 From: Claire Kuang Date: Wed, 30 Oct 2024 17:12:36 +0000 Subject: [PATCH 4/6] Update ComponentUnpacker.cs --- .../Speckle.Connector.Tekla2024/HostApp/ComponentUnpacker.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Connectors/Tekla/Speckle.Connector.Tekla2024/HostApp/ComponentUnpacker.cs b/Connectors/Tekla/Speckle.Connector.Tekla2024/HostApp/ComponentUnpacker.cs index 6b21b261..e7803c30 100644 --- a/Connectors/Tekla/Speckle.Connector.Tekla2024/HostApp/ComponentUnpacker.cs +++ b/Connectors/Tekla/Speckle.Connector.Tekla2024/HostApp/ComponentUnpacker.cs @@ -11,7 +11,7 @@ public class ComponentUnpacker /// Stores processed Base Components as group proxies. These include Components and Connections. /// Expects to be scoped per send operation. Should be added to the root collection. /// - public Dictionary ComponentProxiesCache { get; } + public Dictionary ComponentProxiesCache { get; } = new(); public ComponentUnpacker() { } From 4f1c1b5ece64de792fca318d950fd2f9639e6383 Mon Sep 17 00:00:00 2001 From: Claire Kuang Date: Wed, 30 Oct 2024 17:35:04 +0000 Subject: [PATCH 5/6] Update ServiceRegistration.cs --- .../Tekla/Speckle.Connector.Tekla2024/ServiceRegistration.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Connectors/Tekla/Speckle.Connector.Tekla2024/ServiceRegistration.cs b/Connectors/Tekla/Speckle.Connector.Tekla2024/ServiceRegistration.cs index 6f861956..5cac45ec 100644 --- a/Connectors/Tekla/Speckle.Connector.Tekla2024/ServiceRegistration.cs +++ b/Connectors/Tekla/Speckle.Connector.Tekla2024/ServiceRegistration.cs @@ -15,7 +15,6 @@ using Speckle.Connectors.DUI.Models.Card.SendFilter; using Speckle.Connectors.DUI.WebView; using Speckle.Converter.Tekla2024; -using Speckle.Converter.Tekla2024.Helpers; using Speckle.Converters.Common; using Speckle.Sdk; using Speckle.Sdk.Models.GraphTraversal; From 7c6af2105fd1c1dd2e38d6111de18fccb5dc2116 Mon Sep 17 00:00:00 2001 From: Claire Kuang Date: Wed, 30 Oct 2024 17:43:39 +0000 Subject: [PATCH 6/6] Update GlobalUsing.cs --- Connectors/Tekla/Speckle.Connector.Tekla2024/GlobalUsing.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Connectors/Tekla/Speckle.Connector.Tekla2024/GlobalUsing.cs b/Connectors/Tekla/Speckle.Connector.Tekla2024/GlobalUsing.cs index 1881675f..9cd59254 100644 --- a/Connectors/Tekla/Speckle.Connector.Tekla2024/GlobalUsing.cs +++ b/Connectors/Tekla/Speckle.Connector.Tekla2024/GlobalUsing.cs @@ -1,2 +1 @@ -global using TG = Tekla.Structures.Geometry3d; global using TSM = Tekla.Structures.Model;