diff --git a/Connectors/Tekla/Speckle.Connector.Tekla2024/Bindings/TeklaSendBinding.cs b/Connectors/Tekla/Speckle.Connector.Tekla2024/Bindings/TeklaSendBinding.cs index 25404b3e7..49bff38d5 100644 --- a/Connectors/Tekla/Speckle.Connector.Tekla2024/Bindings/TeklaSendBinding.cs +++ b/Connectors/Tekla/Speckle.Connector.Tekla2024/Bindings/TeklaSendBinding.cs @@ -1,6 +1,7 @@ using System.Collections.Concurrent; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Speckle.Connector.Tekla2024.Operations.Send.Settings; using Speckle.Connectors.Common.Caching; using Speckle.Connectors.Common.Cancellation; using Speckle.Connectors.Common.Operations; @@ -42,6 +43,7 @@ public sealed class TeklaSendBinding : ISendBinding, IDisposable private readonly ISdkActivityFactory _activityFactory; private readonly Model _model; private readonly Events _events; + private readonly ToSpeckleSettingsManager _toSpeckleSettingsManager; private ConcurrentDictionary ChangedObjectIds { get; set; } = new(); @@ -57,7 +59,8 @@ public TeklaSendBinding( ILogger logger, ITeklaConversionSettingsFactory teklaConversionSettingsFactory, ISpeckleApplication speckleApplication, - ISdkActivityFactory activityFactory + ISdkActivityFactory activityFactory, + ToSpeckleSettingsManager toSpeckleSettingsManager ) { _store = store; @@ -73,6 +76,7 @@ ISdkActivityFactory activityFactory Parent = parent; Commands = new SendBindingUICommands(parent); _activityFactory = activityFactory; + _toSpeckleSettingsManager = toSpeckleSettingsManager; _model = new Model(); _events = new Events(); @@ -103,15 +107,11 @@ private void ModelHandler_OnChange(List changes) public List GetSendFilters() => _sendFilters; - public List GetSendSettings() => []; + public List GetSendSettings() => [new SendRebarsAsSolidSetting(false)]; public async Task Send(string modelCardId) { using var activity = _activityFactory.Start(); - using var scope = _serviceProvider.CreateScope(); - scope - .ServiceProvider.GetRequiredService>() - .Initialize(_teklaConversionSettingsFactory.Create(_model)); try { @@ -119,6 +119,12 @@ public async Task Send(string modelCardId) { throw new InvalidOperationException("No publish model card was found."); } + using var scope = _serviceProvider.CreateScope(); + scope + .ServiceProvider.GetRequiredService>() + .Initialize( + _teklaConversionSettingsFactory.Create(_model, _toSpeckleSettingsManager.GetSendRebarsAsSolid(modelCard)) + ); CancellationToken cancellationToken = _cancellationManager.InitCancellationTokenSource(modelCardId); diff --git a/Connectors/Tekla/Speckle.Connector.Tekla2024/Operations/Send/Settings/SendRebarsAsSolidSetting.cs b/Connectors/Tekla/Speckle.Connector.Tekla2024/Operations/Send/Settings/SendRebarsAsSolidSetting.cs new file mode 100644 index 000000000..0d1f8f31e --- /dev/null +++ b/Connectors/Tekla/Speckle.Connector.Tekla2024/Operations/Send/Settings/SendRebarsAsSolidSetting.cs @@ -0,0 +1,12 @@ +using Speckle.Connectors.DUI.Settings; + +namespace Speckle.Connector.Tekla2024.Operations.Send.Settings; + +public class SendRebarsAsSolidSetting(bool value) : ICardSetting +{ + public string? Id { get; set; } = "sendRebarsAsSolid"; + public string? Title { get; set; } = "Send Rebars As Solid"; + public string? Type { get; set; } = "boolean"; + public object? Value { get; set; } = value; + public List? Enum { get; set; } +} diff --git a/Connectors/Tekla/Speckle.Connector.Tekla2024/Operations/Send/Settings/ToSpeckleSettingsManager.cs b/Connectors/Tekla/Speckle.Connector.Tekla2024/Operations/Send/Settings/ToSpeckleSettingsManager.cs new file mode 100644 index 000000000..84203757a --- /dev/null +++ b/Connectors/Tekla/Speckle.Connector.Tekla2024/Operations/Send/Settings/ToSpeckleSettingsManager.cs @@ -0,0 +1,39 @@ +using Speckle.Connectors.Common.Caching; +using Speckle.Connectors.DUI.Models.Card; +using Speckle.InterfaceGenerator; +using Speckle.Sdk.Common; + +namespace Speckle.Connector.Tekla2024.Operations.Send.Settings; + +[GenerateAutoInterface] +public class ToSpeckleSettingsManager : IToSpeckleSettingsManager +{ + private readonly ISendConversionCache _sendConversionCache; + private readonly Dictionary _sendRebarsAsSolidCache = new(); + + public ToSpeckleSettingsManager(ISendConversionCache sendConversionCache) + { + _sendConversionCache = sendConversionCache; + } + + public bool GetSendRebarsAsSolid(SenderModelCard modelCard) + { + var value = modelCard.Settings?.First(s => s.Id == "sendRebarsAsSolid").Value as bool?; + var returnValue = value != null && value.NotNull(); + if (_sendRebarsAsSolidCache.TryGetValue(modelCard.ModelCardId.NotNull(), out bool? previousValue)) + { + if (previousValue != returnValue) + { + EvictCacheForModelCard(modelCard); + } + } + _sendRebarsAsSolidCache[modelCard.ModelCardId] = returnValue; + return returnValue; + } + + private void EvictCacheForModelCard(SenderModelCard modelCard) + { + var objectIds = modelCard.SendFilter != null ? modelCard.SendFilter.NotNull().GetObjectIds() : []; + _sendConversionCache.EvictObjects(objectIds); + } +} diff --git a/Connectors/Tekla/Speckle.Connector.Tekla2024/ServiceRegistration.cs b/Connectors/Tekla/Speckle.Connector.Tekla2024/ServiceRegistration.cs index 5e02984c3..9c3621c7e 100644 --- a/Connectors/Tekla/Speckle.Connector.Tekla2024/ServiceRegistration.cs +++ b/Connectors/Tekla/Speckle.Connector.Tekla2024/ServiceRegistration.cs @@ -3,6 +3,7 @@ using Speckle.Connector.Tekla2024.Filters; using Speckle.Connector.Tekla2024.HostApp; using Speckle.Connector.Tekla2024.Operations.Send; +using Speckle.Connector.Tekla2024.Operations.Send.Settings; using Speckle.Connectors.Common; using Speckle.Connectors.Common.Builders; using Speckle.Connectors.Common.Caching; @@ -58,6 +59,8 @@ public static IServiceCollection AddTekla(this IServiceCollection services) services.AddScoped, TeklaRootObjectBuilder>(); services.AddScoped>(); + services.AddSingleton(); + services.AddTransient(); services.AddSingleton(); diff --git a/Converters/Tekla/Speckle.Converter.Tekla2024/TeklaConversionSettings.cs b/Converters/Tekla/Speckle.Converter.Tekla2024/TeklaConversionSettings.cs index c2e45b95f..7bd6f4930 100644 --- a/Converters/Tekla/Speckle.Converter.Tekla2024/TeklaConversionSettings.cs +++ b/Converters/Tekla/Speckle.Converter.Tekla2024/TeklaConversionSettings.cs @@ -2,4 +2,4 @@ namespace Speckle.Converter.Tekla2024; -public record TeklaConversionSettings(Model Document, string SpeckleUnits); +public record TeklaConversionSettings(Model Document, bool SendRebarsAsSolid, string SpeckleUnits); diff --git a/Converters/Tekla/Speckle.Converter.Tekla2024/TeklaConversionSettingsFactory.cs b/Converters/Tekla/Speckle.Converter.Tekla2024/TeklaConversionSettingsFactory.cs index fcf071622..f2c9fae60 100644 --- a/Converters/Tekla/Speckle.Converter.Tekla2024/TeklaConversionSettingsFactory.cs +++ b/Converters/Tekla/Speckle.Converter.Tekla2024/TeklaConversionSettingsFactory.cs @@ -14,6 +14,6 @@ IConverterSettingsStore settingsStore public TeklaConversionSettings Current => settingsStore.Current; // only handles automatic rn - public TeklaConversionSettings Create(Model document) => - new(document, unitsConverter.ConvertOrThrow(TSD.Units.Automatic)); + public TeklaConversionSettings Create(Model document, bool sendRebarsAsSolid) => + new(document, sendRebarsAsSolid, unitsConverter.ConvertOrThrow(TSD.Units.Automatic)); } diff --git a/Converters/Tekla/Speckle.Converter.Tekla2024/ToSpeckle/Helpers/DisplayValueExtractor.cs b/Converters/Tekla/Speckle.Converter.Tekla2024/ToSpeckle/Helpers/DisplayValueExtractor.cs index ad66e8d6a..c6be8659a 100644 --- a/Converters/Tekla/Speckle.Converter.Tekla2024/ToSpeckle/Helpers/DisplayValueExtractor.cs +++ b/Converters/Tekla/Speckle.Converter.Tekla2024/ToSpeckle/Helpers/DisplayValueExtractor.cs @@ -1,5 +1,6 @@ using Speckle.Converters.Common; using Speckle.Converters.Common.Objects; +using Speckle.Sdk.Common.Exceptions; using Speckle.Sdk.Models; namespace Speckle.Converter.Tekla2024.ToSpeckle.Helpers; @@ -49,29 +50,43 @@ public IEnumerable GetDisplayValue(TSM.ModelObject modelObject) } break; - // this section visualizes the rebars as lines case TSM.Reinforcement reinforcement: - var rebarGeometries = reinforcement.GetRebarComplexGeometries( - withHooks: true, - withoutClashes: true, - lengthAdjustments: true, - TSM.Reinforcement.RebarGeometrySimplificationTypeEnum.RATIONALIZED - ); - - foreach (TSM.RebarComplexGeometry barGeometry in rebarGeometries) + if (_settingsStore.Current.SendRebarsAsSolid) { - foreach (var leg in barGeometry.Legs) + if (reinforcement.GetSolid() is TSM.Solid reinforcementSolid) { - if (leg.Curve is TG.LineSegment legLine) - { - yield return _lineConverter.Convert(legLine); - } - else if (leg.Curve is TG.Arc legArc) + yield return _meshConverter.Convert(reinforcementSolid); + } + else + { + throw new ConversionException("The type has no solid."); + } + } + else + { + var rebarGeometries = reinforcement.GetRebarComplexGeometries( + withHooks: true, + withoutClashes: true, + lengthAdjustments: true, + TSM.Reinforcement.RebarGeometrySimplificationTypeEnum.RATIONALIZED + ); + + foreach (TSM.RebarComplexGeometry barGeometry in rebarGeometries) + { + foreach (var leg in barGeometry.Legs) { - yield return _arcConverter.Convert(legArc); + if (leg.Curve is TG.LineSegment legLine) + { + yield return _lineConverter.Convert(legLine); + } + else if (leg.Curve is TG.Arc legArc) + { + yield return _arcConverter.Convert(legArc); + } } } } + break; case TSM.Grid grid: @@ -82,15 +97,6 @@ public IEnumerable GetDisplayValue(TSM.ModelObject modelObject) break; - // use this section to visualize rebars as solid - // case TSM.Reinforcement reinforcement: - // if (reinforcement.GetSolid() is TSM.Solid reinforcementSolid) - // { - // yield return _meshConverter.Convert(reinforcementSolid); - // } - // break; - - default: yield break; }