diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.Revit2023/Speckle.Connectors.Revit2023.csproj b/DUI3-DX/Connectors/Revit/Speckle.Connectors.Revit2023/Speckle.Connectors.Revit2023.csproj index 1ce038c81e..3cf6edeb8c 100644 --- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.Revit2023/Speckle.Connectors.Revit2023.csproj +++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.Revit2023/Speckle.Connectors.Revit2023.csproj @@ -30,7 +30,7 @@ - + diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitReceiveBinding.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitReceiveBinding.cs new file mode 100644 index 0000000000..77119f01a0 --- /dev/null +++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitReceiveBinding.cs @@ -0,0 +1,82 @@ +using Speckle.Connectors.DUI.Bindings; +using Speckle.Connectors.DUI.Bridge; +using Speckle.Connectors.DUI.Models.Card; +using Speckle.Connectors.DUI.Models; +using Speckle.Connectors.Utils.Builders; +using Speckle.Connectors.Utils.Cancellation; +using Speckle.Connectors.Utils.Operations; +using Speckle.Autofac.DependencyInjection; +using Speckle.Connectors.Utils; + +namespace Speckle.Connectors.Revit.Bindings; + +internal class RevitReceiveBinding : IReceiveBinding +{ + public string Name => "receiveBinding"; + public IBridge Parent { get; } + + private readonly CancellationManager _cancellationManager; + private readonly DocumentModelStore _store; + private readonly IUnitOfWorkFactory _unitOfWorkFactory; + public ReceiveBindingUICommands Commands { get; } + + public RevitReceiveBinding( + DocumentModelStore store, + CancellationManager cancellationManager, + IBridge parent, + IUnitOfWorkFactory unitOfWorkFactory + ) + { + Parent = parent; + _store = store; + _unitOfWorkFactory = unitOfWorkFactory; + _cancellationManager = cancellationManager; + Commands = new ReceiveBindingUICommands(parent); + } + + public void CancelReceive(string modelCardId) => _cancellationManager.CancelOperation(modelCardId); + + public async Task Receive(string modelCardId) + { + using var unitOfWork = _unitOfWorkFactory.Resolve(); + try + { + // Get receiver card + if (_store.GetModelById(modelCardId) is not ReceiverModelCard modelCard) + { + // Handle as GLOBAL ERROR at BrowserBridge + throw new InvalidOperationException("No download model card was found."); + } + + // Init cancellation token source -> Manager also cancel it if exist before + CancellationTokenSource cts = _cancellationManager.InitCancellationTokenSource(modelCardId); + + // Receive host objects + HostObjectBuilderResult conversionResults = await unitOfWork.Service + .Execute( + modelCard.AccountId.NotNull(), // POC: I hear -you are saying why we're passing them separately. Not sure pass the DUI3-> Connectors.DUI project dependency to the SDK-> Connector.Utils + modelCard.ProjectId.NotNull(), + modelCard.ProjectName.NotNull(), + modelCard.ModelName.NotNull(), + modelCard.SelectedVersionId.NotNull(), + cts.Token, + (status, progress) => + Commands.SetModelProgress(modelCardId, new ModelCardProgress(modelCardId, status, progress), cts) + ) + .ConfigureAwait(false); + + modelCard.BakedObjectIds = conversionResults.BakedObjectIds.ToList(); + Commands.SetModelReceiveResult( + modelCardId, + conversionResults.BakedObjectIds, + conversionResults.ConversionResults + ); + } + // Catch here specific exceptions if they related to model card. + catch (OperationCanceledException) + { + // SWALLOW -> UI handles it immediately, so we do not need to handle anything + return; + } + } +} diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/DependencyInjection/RevitConnectorModule.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/DependencyInjection/RevitConnectorModule.cs index ec1bcb5566..7ec943cde0 100644 --- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/DependencyInjection/RevitConnectorModule.cs +++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/DependencyInjection/RevitConnectorModule.cs @@ -4,16 +4,17 @@ using Speckle.Autofac.DependencyInjection; using Speckle.Connectors.DUI; using Speckle.Connectors.DUI.Bindings; -using Speckle.Connectors.DUI.Bridge; using Speckle.Connectors.DUI.Models; using Speckle.Connectors.Revit.Bindings; using Speckle.Connectors.Revit.HostApp; +using Speckle.Connectors.Revit.Operations.Receive; using Speckle.Connectors.Revit.Operations.Send; using Speckle.Connectors.Revit.Plugin; using Speckle.Connectors.Utils; using Speckle.Connectors.Utils.Builders; using Speckle.Connectors.Utils.Caching; using Speckle.Connectors.Utils.Operations; +using Speckle.Core.Models.GraphTraversal; namespace Speckle.Connectors.Revit.DependencyInjection; @@ -27,7 +28,7 @@ public void Load(SpeckleContainerBuilder builder) builder.AddDUI(); //builder.AddDUIView(); - builder.AddSingletonInstance(); + builder.AddSingletonInstance(); // POC: different versons for different versions of CEF builder.AddSingleton(BindingOptions.DefaultBinder); @@ -49,20 +50,23 @@ public void Load(SpeckleContainerBuilder builder) // and where the UoW should be // register UI bindings builder.AddSingleton(); - builder.AddSingleton("connectorName", "ArcGIS"); // POC: Easier like this for now, should be cleaned up later + builder.AddSingleton("connectorName", "Revit"); // POC: Easier like this for now, should be cleaned up later builder.AddSingleton(); builder.AddSingleton(); builder.AddSingleton(); builder.AddSingleton(); builder.AddSingleton(); - //no receive? + builder.AddSingleton(); builder.AddSingleton(); // send operation and dependencies builder.AddScoped>(); builder.AddScoped, RevitRootObjectBuilder>(); - - // register send conversion cache builder.AddSingleton(); + + // receive operation and dependencies + builder.AddScoped(); + builder.AddScoped(); + builder.AddSingleton(DefaultTraversal.CreateTraversalFunc()); } } diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Receive/ITransactionManager.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Receive/ITransactionManager.cs new file mode 100644 index 0000000000..d698dfac0f --- /dev/null +++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Receive/ITransactionManager.cs @@ -0,0 +1,13 @@ +using Autodesk.Revit.DB; + +namespace Speckle.Connectors.Revit.Operations.Receive; + +public interface ITransactionManager : IDisposable +{ + TransactionStatus CommitSubtransaction(); + TransactionStatus CommitTransaction(); + void RollbackSubTransaction(); + void RollbackTransaction(); + void StartSubtransaction(); + void StartTransaction(); +} diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Receive/RevitContextAccessor.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Receive/RevitContextAccessor.cs new file mode 100644 index 0000000000..d90ce9076b --- /dev/null +++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Receive/RevitContextAccessor.cs @@ -0,0 +1,9 @@ +using Revit.Async; +using Speckle.Connectors.Utils.Operations; + +namespace Speckle.Connectors.Revit.Operations.Receive; + +internal class RevitContextAccessor : ISyncToThread +{ + public Task RunOnThread(Func func) => RevitTask.RunAsync(func); +} diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Receive/RevitHostObjectBuilder.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Receive/RevitHostObjectBuilder.cs new file mode 100644 index 0000000000..245284543d --- /dev/null +++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Receive/RevitHostObjectBuilder.cs @@ -0,0 +1,85 @@ +using Speckle.Connectors.Utils.Builders; +using Speckle.Connectors.Utils.Conversion; +using Speckle.Converters.Common; +using Speckle.Core.Logging; +using Speckle.Core.Models.GraphTraversal; +using Speckle.Core.Models; +using Speckle.Converters.RevitShared.Helpers; +using Autodesk.Revit.DB; + +namespace Speckle.Connectors.Revit.Operations.Receive; + +/// +/// Potentially consolidate all application specific IHostObjectBuilders +/// https://spockle.atlassian.net/browse/DUI3-465 +/// +internal class RevitHostObjectBuilder : IHostObjectBuilder, IDisposable +{ + private readonly IRootToHostConverter _converter; + private readonly IRevitConversionContextStack _contextStack; + private readonly GraphTraversal _traverseFunction; + private readonly ITransactionManager _transactionManager; + + public RevitHostObjectBuilder( + IRootToHostConverter converter, + IRevitConversionContextStack contextStack, + GraphTraversal traverseFunction, + ITransactionManager transactionManager + ) + { + _converter = converter; + _contextStack = contextStack; + _traverseFunction = traverseFunction; + _transactionManager = transactionManager; + } + + public HostObjectBuilderResult Build( + Base rootObject, + string projectName, + string modelName, + Action? onOperationProgressed, + CancellationToken cancellationToken + ) + { + var objectsToConvert = _traverseFunction + .TraverseWithProgress(rootObject, onOperationProgressed, cancellationToken) + .Where(obj => obj.Current is not Collection); + + using TransactionGroup transactionGroup = new(_contextStack.Current.Document, $"Received data from {projectName}"); + transactionGroup.Start(); + _transactionManager.StartTransaction(); + + var conversionResults = BakeObjects(objectsToConvert); + + _transactionManager.CommitTransaction(); + transactionGroup.Assimilate(); + + return conversionResults; + } + + // POC: Potentially refactor out into an IObjectBaker. + private HostObjectBuilderResult BakeObjects(IEnumerable objectsGraph) + { + var conversionResults = new List(); + var bakedObjectIds = new List(); + + foreach (TraversalContext tc in objectsGraph) + { + try + { + var result = _converter.Convert(tc.Current); + } + catch (Exception ex) when (!ex.IsFatal()) + { + conversionResults.Add(new(Status.ERROR, tc.Current, null, null, ex)); + } + } + + return new(bakedObjectIds, conversionResults); + } + + public void Dispose() + { + _transactionManager?.Dispose(); + } +} diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Receive/TransactionManager.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Receive/TransactionManager.cs new file mode 100644 index 0000000000..aa2ec3153a --- /dev/null +++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Receive/TransactionManager.cs @@ -0,0 +1,124 @@ +using Autodesk.Revit.DB; +using Speckle.Converters.RevitShared.Helpers; + +namespace Speckle.Connectors.Revit.Operations.Receive; + +/// +/// Is responsible for all functionality regarding subtransactions, transactions, and transaction groups. +/// This includes starting, pausing, committing, and rolling back transactions +/// +public sealed class TransactionManager : ITransactionManager +{ + private readonly IRevitConversionContextStack _contextStack; + private Document Document => _contextStack.Current.Document; + + public TransactionManager(IRevitConversionContextStack contextStack) + { + _contextStack = contextStack; + } + + // poc : these are being disposed. I'm not sure why I need to supress this warning +#pragma warning disable CA2213 // Disposable fields should be disposed + private Transaction? _transaction; + private SubTransaction? _subTransaction; +#pragma warning restore CA2213 // Disposable fields should be disposed + + public void StartTransaction() + { + if (_transaction == null || !_transaction.IsValidObject || _transaction.GetStatus() != TransactionStatus.Started) + { + _transaction = new Transaction(Document, "Speckle Transaction"); + var failOpts = _transaction.GetFailureHandlingOptions(); + // POC: make sure to implement and add the failure preprocessor + // https://spockle.atlassian.net/browse/DUI3-461 + //failOpts.SetFailuresPreprocessor(_errorPreprocessingService); + failOpts.SetClearAfterRollback(true); + _transaction.SetFailureHandlingOptions(failOpts); + _transaction.Start(); + } + } + + public TransactionStatus CommitTransaction() + { + if ( + _subTransaction != null + && _subTransaction.IsValidObject + && _subTransaction.GetStatus() == TransactionStatus.Started + ) + { + var status = _subTransaction.Commit(); + if (status != TransactionStatus.Committed) + { + // POC: handle failed commit + //HandleFailedCommit(status); + } + } + if (_transaction != null && _transaction.IsValidObject && _transaction.GetStatus() == TransactionStatus.Started) + { + var status = _transaction.Commit(); + if (status != TransactionStatus.Committed) + { + // POC: handle failed commit + //HandleFailedCommit(status); + } + return status; + } + return TransactionStatus.Uninitialized; + } + + public void RollbackTransaction() + { + RollbackSubTransaction(); + if (_transaction != null && _transaction.IsValidObject && _transaction.GetStatus() == TransactionStatus.Started) + { + _transaction.RollBack(); + } + } + + public void StartSubtransaction() + { + StartTransaction(); + if ( + _subTransaction == null + || !_subTransaction.IsValidObject + || _subTransaction.GetStatus() != TransactionStatus.Started + ) + { + _subTransaction = new SubTransaction(Document); + _subTransaction.Start(); + } + } + + public TransactionStatus CommitSubtransaction() + { + if (_subTransaction != null && _subTransaction.IsValidObject) + { + var status = _subTransaction.Commit(); + if (status != TransactionStatus.Committed) + { + // POC: handle failed commit + //HandleFailedCommit(status); + } + return status; + } + return TransactionStatus.Uninitialized; + } + + public void RollbackSubTransaction() + { + if ( + _subTransaction != null + && _subTransaction.IsValidObject + && _subTransaction.GetStatus() == TransactionStatus.Started + ) + { + _subTransaction.RollBack(); + } + } + + public void Dispose() + { + _subTransaction?.Dispose(); + _transaction?.Dispose(); + } +} diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Speckle.Connectors.RevitShared.projitems b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Speckle.Connectors.RevitShared.projitems index 8a671aefc9..1abd960016 100644 --- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Speckle.Connectors.RevitShared.projitems +++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Speckle.Connectors.RevitShared.projitems @@ -1,4 +1,4 @@ - + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) @@ -19,6 +19,7 @@ + @@ -27,6 +28,10 @@ + + + + CefSharpPanel.xaml 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 60c5050217..f5211019ae 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.DependencyInjection/RevitConverterModule.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.DependencyInjection/RevitConverterModule.cs @@ -12,11 +12,12 @@ public class RevitConverterModule : ISpeckleModule { public void Load(SpeckleContainerBuilder builder) { - builder.AddConverterCommon(); + builder.AddConverterCommon(); builder.AddSingleton(new RevitContext()); // POC: do we need ToSpeckleScalingService as is, do we need to interface it out? builder.AddScoped(); + builder.AddScoped(); // POC: the concrete type can come out if we remove all the reference to it builder.AddScoped(); diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/IReferencePointConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/IReferencePointConverter.cs index f526412336..601ab31128 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/IReferencePointConverter.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/IReferencePointConverter.cs @@ -1,6 +1,8 @@ -namespace Speckle.Converters.RevitShared; +namespace Speckle.Converters.RevitShared; public interface IReferencePointConverter { - DB.XYZ ConvertToExternalCoordindates(DB.XYZ inbound, bool isPoint); + DB.XYZ ConvertToExternalCoordindates(DB.XYZ p, bool isPoint); + + DB.XYZ ToInternalCoordinates(DB.XYZ p, bool isPoint); } diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ReferencePointConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ReferencePointConverter.cs index 4704184be6..1cf1394bb0 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ReferencePointConverter.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ReferencePointConverter.cs @@ -1,4 +1,5 @@ using System.Diagnostics.CodeAnalysis; +using Autodesk.Revit.DB; using Speckle.Converters.RevitShared.Helpers; namespace Speckle.Converters.RevitShared; @@ -28,10 +29,21 @@ public ReferencePointConverter(IRevitConversionContextStack contextStack, RevitC // POC: the original allowed for the document to be passed in // if required, we would probably need to push the stack with a new document if the // doc can change during the lifeycycle of the conversions. This may need some looking into - public DB.XYZ ConvertToExternalCoordindates(DB.XYZ inbound, bool isPoint) + public DB.XYZ ConvertToExternalCoordindates(DB.XYZ p, bool isPoint) { var rpt = GetDocReferencePointTransform(_contextStack.Current.Document); - return isPoint ? rpt.OfPoint(inbound) : rpt.OfVector(inbound); + return (isPoint) ? rpt.Inverse.OfPoint(p) : rpt.Inverse.OfVector(p); + } + + /// + /// For importing in Revit, moves and rotates a point according to this document BasePoint + /// + /// + /// + public XYZ ToInternalCoordinates(XYZ p, bool isPoint) + { + var rpt = GetDocReferencePointTransform(_contextStack.Current.Document); + return (isPoint) ? rpt.OfPoint(p) : rpt.OfVector(p); } // POC: this might be better in some RevitDocumentService diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/RevitRootToHostConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/RevitRootToSpeckleConverter.cs similarity index 93% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/RevitRootToHostConverter.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/RevitRootToSpeckleConverter.cs index 78790ee19e..28336c4eb3 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/RevitRootToHostConverter.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/RevitRootToSpeckleConverter.cs @@ -6,12 +6,12 @@ namespace Speckle.Converters.RevitShared; // POC: maybe possible to restrict the access so this cannot be created directly? -public class RevitRootToHostConverter : IRootToSpeckleConverter +public class RevitRootToSpeckleConverter : IRootToSpeckleConverter { private readonly IConverterResolver _toSpeckle; private readonly ParameterValueExtractor _parameterValueExtractor; - public RevitRootToHostConverter( + public RevitRootToSpeckleConverter( IConverterResolver toSpeckle, ParameterValueExtractor parameterValueExtractor ) diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Services/ScalingServiceToHost.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Services/ScalingServiceToHost.cs new file mode 100644 index 0000000000..bf6e956279 --- /dev/null +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Services/ScalingServiceToHost.cs @@ -0,0 +1,32 @@ +using Autodesk.Revit.DB; +using Speckle.Converters.Common; + +namespace Speckle.Converters.RevitShared.Services; + +public sealed class ScalingServiceToHost +{ + public double ScaleToNative(double value, string units) + { + if (string.IsNullOrEmpty(units)) + { + return value; + } + + return UnitUtils.ConvertToInternalUnits(value, UnitsToNative(units)); + } + + public ForgeTypeId UnitsToNative(string units) + { + var u = Core.Kits.Units.GetUnitsFromString(units); + + return u switch + { + Core.Kits.Units.Millimeters => UnitTypeId.Millimeters, + Core.Kits.Units.Centimeters => UnitTypeId.Centimeters, + Core.Kits.Units.Meters => UnitTypeId.Meters, + Core.Kits.Units.Inches => UnitTypeId.Inches, + Core.Kits.Units.Feet => UnitTypeId.Feet, + _ => throw new SpeckleConversionException($"The Unit System \"{units}\" is unsupported."), + }; + } +} diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Speckle.Converters.RevitShared.projitems b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Speckle.Converters.RevitShared.projitems index 5e5d29480e..dce4c4898e 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Speckle.Converters.RevitShared.projitems +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Speckle.Converters.RevitShared.projitems @@ -21,47 +21,64 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -69,12 +86,8 @@ - - - - - + \ No newline at end of file diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/ArcConverterToHost.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/ArcConverterToHost.cs new file mode 100644 index 0000000000..6e9167c7eb --- /dev/null +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/ArcConverterToHost.cs @@ -0,0 +1,59 @@ +using Speckle.Converters.Common.Objects; +using Speckle.Converters.RevitShared.Services; +using Speckle.Core.Common; + +namespace Speckle.Converters.RevitShared.ToHost.Raw.Geometry; + +public class ArcConverterToHost : ITypedConverter +{ + private readonly ScalingServiceToHost _scalingService; + private readonly ITypedConverter _pointToXyzConverter; + private readonly ITypedConverter _planeConverter; + + public ArcConverterToHost( + ITypedConverter pointToXyzConverter, + ScalingServiceToHost scalingService, + ITypedConverter planeConverter + ) + { + _pointToXyzConverter = pointToXyzConverter; + _scalingService = scalingService; + _planeConverter = planeConverter; + } + + public DB.Arc Convert(SOG.Arc target) + { + double startAngle; + double endAngle; + + if (target.startAngle > target.endAngle) + { + startAngle = (double)target.endAngle; + endAngle = (double)target.startAngle; + } + else + { + startAngle = (double)target.startAngle.NotNull(); + endAngle = (double)target.endAngle.NotNull(); + } + + var plane = _planeConverter.Convert(target.plane); + + if (SOG.Point.Distance(target.startPoint, target.endPoint) < 1E-6) + { + // Endpoints coincide, it's a circle. + return DB.Arc.Create( + plane, + _scalingService.ScaleToNative(target.radius ?? 0, target.units), + startAngle, + endAngle + ); + } + + return DB.Arc.Create( + _pointToXyzConverter.Convert(target.startPoint), + _pointToXyzConverter.Convert(target.endPoint), + _pointToXyzConverter.Convert(target.midPoint) + ); + } +} diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/CircleConverterToHost.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/CircleConverterToHost.cs new file mode 100644 index 0000000000..55ba5f1974 --- /dev/null +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/CircleConverterToHost.cs @@ -0,0 +1,28 @@ +using Speckle.Converters.Common.Objects; +using Speckle.Converters.RevitShared.Services; +using Speckle.Core.Common; + +namespace Speckle.Converters.RevitShared.ToHost.Raw.Geometry; + +public class CircleConverterToHost : ITypedConverter +{ + private readonly ScalingServiceToHost _scalingService; + private readonly ITypedConverter _planeConverter; + + public CircleConverterToHost(ScalingServiceToHost scalingService, ITypedConverter planeConverter) + { + _scalingService = scalingService; + _planeConverter = planeConverter; + } + + public DB.Arc Convert(SOG.Circle target) + { + var plane = _planeConverter.Convert(target.plane); + return DB.Arc.Create( + plane, + _scalingService.ScaleToNative((double)target.radius.NotNull(), target.units), + 0, + 2 * Math.PI + ); + } +} diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/CurveConverterToHost.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/CurveConverterToHost.cs new file mode 100644 index 0000000000..5f1f40f603 --- /dev/null +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/CurveConverterToHost.cs @@ -0,0 +1,47 @@ +using Speckle.Converters.Common; +using Speckle.Converters.Common.Objects; + +namespace Speckle.Converters.RevitShared.ToSpeckle; + +public class CurveConverterToHost : ITypedConverter +{ + private readonly ITypedConverter _pointConverter; + + public CurveConverterToHost(ITypedConverter pointConverter) + { + _pointConverter = pointConverter; + } + + public DB.Curve Convert(SOG.Curve target) + { + var pts = new List(); + for (int i = 0; i < target.points.Count; i += 3) + { + //use PointToNative for conversion as that takes into account the Project Base Point + var point = new SOG.Point(target.points[i], target.points[i + 1], target.points[i + 2], target.units); + pts.Add(_pointConverter.Convert(point)); + } + + if (target.knots != null && target.weights != null && target.knots.Count > 0 && target.weights.Count > 0) + { + var weights = target.weights.GetRange(0, pts.Count); + var speckleKnots = new List(target.knots); + if (speckleKnots.Count != pts.Count + target.degree + 1) + { + // Curve has rhino knots, repeat first and last. + speckleKnots.Insert(0, speckleKnots[0]); + speckleKnots.Add(speckleKnots[^1]); + } + + //var knots = speckleKnots.GetRange(0, pts.Count + speckleCurve.degree + 1); + var curve = DB.NurbSpline.CreateCurve(target.degree, speckleKnots, pts, weights); + return curve; + } + else + { + var weights = target.weights.NotNull().GetRange(0, pts.Count); + var curve = DB.NurbSpline.CreateCurve(pts, weights); + return curve; + } + } +} diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/EllipseConverterToHost.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/EllipseConverterToHost.cs new file mode 100644 index 0000000000..f2c86ef7c8 --- /dev/null +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/EllipseConverterToHost.cs @@ -0,0 +1,40 @@ +using Speckle.Converters.Common.Objects; +using Speckle.Converters.RevitShared.Services; +using Speckle.Core.Common; + +namespace Speckle.Converters.RevitShared.ToHost.Raw.Geometry; + +public class EllipseConverterToHost : ITypedConverter +{ + private readonly ScalingServiceToHost _scalingService; + private readonly ITypedConverter _pointToXyzConverter; + private readonly ITypedConverter _planeConverter; + + public EllipseConverterToHost( + ITypedConverter pointToXyzConverter, + ScalingServiceToHost scalingService, + ITypedConverter planeConverter + ) + { + _pointToXyzConverter = pointToXyzConverter; + _scalingService = scalingService; + _planeConverter = planeConverter; + } + + public DB.Curve Convert(SOG.Ellipse target) + { + using DB.Plane basePlane = _planeConverter.Convert(target.plane); + + var e = DB.Ellipse.CreateCurve( + _pointToXyzConverter.Convert(target.plane.origin), + _scalingService.ScaleToNative((double)target.firstRadius.NotNull(), target.units), + _scalingService.ScaleToNative((double)target.secondRadius.NotNull(), target.units), + basePlane.XVec.Normalize(), + basePlane.YVec.Normalize(), + 0, + 2 * Math.PI + ); + e.MakeBound(target.trimDomain?.start ?? 0, target.trimDomain?.end ?? 2 * Math.PI); + return e; + } +} diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/ICurveConverterToHost.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/ICurveConverterToHost.cs new file mode 100644 index 0000000000..2b3eedcb15 --- /dev/null +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/ICurveConverterToHost.cs @@ -0,0 +1,129 @@ +using Objects; +using Speckle.Converters.Common; +using Speckle.Converters.Common.Objects; + +namespace Speckle.Converters.RevitShared.ToSpeckle; + +public class ICurveConverterToHost : ITypedConverter +{ + private readonly ITypedConverter _pointConverter; + private readonly ITypedConverter _vectorConverter; + private readonly ITypedConverter _arcConverter; + private readonly ITypedConverter _lineConverter; + private readonly ITypedConverter _circleConverter; + private readonly ITypedConverter _ellipseConverter; + private readonly ITypedConverter _polylineConverter; + private readonly ITypedConverter _curveConverter; + + public ICurveConverterToHost( + ITypedConverter pointConverter, + ITypedConverter vectorConverter, + ITypedConverter arcConverter, + ITypedConverter lineConverter, + ITypedConverter circleConverter, + ITypedConverter ellipseConverter, + ITypedConverter polylineConverter, + ITypedConverter curveConverter + ) + { + _pointConverter = pointConverter; + _vectorConverter = vectorConverter; + _arcConverter = arcConverter; + _lineConverter = lineConverter; + _circleConverter = circleConverter; + _ellipseConverter = ellipseConverter; + _polylineConverter = polylineConverter; + _curveConverter = curveConverter; + } + + public DB.CurveArray Convert(ICurve target) + { + DB.CurveArray curveArray = new(); + switch (target) + { + case SOG.Line line: + curveArray.Append(_lineConverter.Convert(line)); + return curveArray; + + case SOG.Arc arc: + curveArray.Append(_arcConverter.Convert(arc)); + return curveArray; + + case SOG.Circle circle: + curveArray.Append(_circleConverter.Convert(circle)); + return curveArray; + + case SOG.Ellipse ellipse: + curveArray.Append(_ellipseConverter.Convert(ellipse)); + return curveArray; + + case SOG.Spiral spiral: + return _polylineConverter.Convert(spiral.displayValue); + + case SOG.Curve nurbs: + var n = _curveConverter.Convert(nurbs); + + // poc : in original converter, we were passing a bool into this method 'splitIfClosed'. + // https://spockle.atlassian.net/browse/DUI3-462 + // I'm not entirely sure why we need to split curves, but there are several occurances + // of the method being called and overriding the bool to be true. + + //if (IsCurveClosed(n) && splitIfClosed) + //{ + // var split = SplitCurveInTwoHalves(n); + // curveArray.Append(split.Item1); + // curveArray.Append(split.Item2); + //} + //else + //{ + // curveArray.Append(n); + //} + curveArray.Append(n); + return curveArray; + + case SOG.Polyline poly: + return _polylineConverter.Convert(poly); + + case SOG.Polycurve plc: + foreach (var seg in plc.segments) + { + // Enumerate all curves in the array to ensure polylines get fully converted. + using var subCurves = Convert(seg); + var crvEnumerator = subCurves.GetEnumerator(); + while (crvEnumerator.MoveNext() && crvEnumerator.Current != null) + { + curveArray.Append(crvEnumerator.Current as DB.Curve); + } + } + return curveArray; + default: + throw new SpeckleConversionException($"The provided geometry of type {target.GetType()} is not a supported"); + } + } + + public bool IsCurveClosed(DB.Curve nativeCurve, double tol = 1E-6) + { + var endPoint = nativeCurve.GetEndPoint(0); + var source = nativeCurve.GetEndPoint(1); + var distanceTo = endPoint.DistanceTo(source); + return distanceTo < tol; + } + + public (DB.Curve, DB.Curve) SplitCurveInTwoHalves(DB.Curve nativeCurve) + { + using var curveArray = new DB.CurveArray(); + // Revit does not like single curve loop edges, so we split them in two. + var start = nativeCurve.GetEndParameter(0); + var end = nativeCurve.GetEndParameter(1); + var mid = start + ((end - start) / 2); + + var a = nativeCurve.Clone(); + a.MakeBound(start, mid); + curveArray.Append(a); + var b = nativeCurve.Clone(); + b.MakeBound(mid, end); + curveArray.Append(b); + + return (a, b); + } +} diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/LineConverterToHost.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/LineConverterToHost.cs new file mode 100644 index 0000000000..de8237e3ce --- /dev/null +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/LineConverterToHost.cs @@ -0,0 +1,16 @@ +using Speckle.Converters.Common.Objects; + +namespace Speckle.Converters.RevitShared.ToSpeckle; + +public class LineConverterToHost : ITypedConverter +{ + private readonly ITypedConverter _pointToXyzConverter; + + public LineConverterToHost(ITypedConverter pointToXyzConverter) + { + _pointToXyzConverter = pointToXyzConverter; + } + + public DB.Line Convert(SOG.Line target) => + DB.Line.CreateBound(_pointToXyzConverter.Convert(target.start), _pointToXyzConverter.Convert(target.end)); +} diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/PlaneConverterToHost.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/PlaneConverterToHost.cs new file mode 100644 index 0000000000..c789aba066 --- /dev/null +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/PlaneConverterToHost.cs @@ -0,0 +1,27 @@ +using Autodesk.Revit.DB; +using Objects.Geometry; +using Speckle.Converters.Common.Objects; + +namespace Speckle.Converters.RevitShared.ToSpeckle; + +public class PlaneConverterToHost : ITypedConverter +{ + private readonly ITypedConverter _pointConverter; + private readonly ITypedConverter _vectorConverter; + + public PlaneConverterToHost( + ITypedConverter pointConverter, + ITypedConverter vectorConverter + ) + { + _pointConverter = pointConverter; + _vectorConverter = vectorConverter; + } + + public DB.Plane Convert(SOG.Plane target) => + DB.Plane.CreateByOriginAndBasis( + _pointConverter.Convert(target.origin), + _vectorConverter.Convert(target.xdir).Normalize(), + _vectorConverter.Convert(target.ydir).Normalize() + ); +} diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/PointConverterToHost.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/PointConverterToHost.cs new file mode 100644 index 0000000000..66b8b5488b --- /dev/null +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/PointConverterToHost.cs @@ -0,0 +1,27 @@ +using Autodesk.Revit.DB; +using Speckle.Converters.Common.Objects; +using Speckle.Converters.RevitShared.Services; + +namespace Speckle.Converters.RevitShared.ToSpeckle; + +public class PointConverterToHost : ITypedConverter +{ + private readonly ScalingServiceToHost _scalingService; + private readonly IReferencePointConverter _referencePointConverter; + + public PointConverterToHost(ScalingServiceToHost scalingService, IReferencePointConverter referencePointConverter) + { + _scalingService = scalingService; + _referencePointConverter = referencePointConverter; + } + + public XYZ Convert(SOG.Point target) + { + var revitPoint = new XYZ( + _scalingService.ScaleToNative(target.x, target.units), + _scalingService.ScaleToNative(target.y, target.units), + _scalingService.ScaleToNative(target.z, target.units) + ); + return _referencePointConverter.ToInternalCoordinates(revitPoint, true); + } +} diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/PolylineConverterToHost.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/PolylineConverterToHost.cs new file mode 100644 index 0000000000..544df8254f --- /dev/null +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/PolylineConverterToHost.cs @@ -0,0 +1,88 @@ +using Autodesk.Revit.DB; +using Objects.Geometry; +using Speckle.Converters.Common.Objects; +using Speckle.Converters.RevitShared.Helpers; +using Speckle.Converters.RevitShared.Services; + +namespace Speckle.Converters.RevitShared.ToSpeckle; + +public class PolylineConverterToHost : ITypedConverter +{ + private readonly ITypedConverter _lineConverter; + private readonly ScalingServiceToHost _scalingService; + private readonly IRevitConversionContextStack _contextStack; + + public PolylineConverterToHost( + ITypedConverter lineConverter, + ScalingServiceToHost scalingService, + IRevitConversionContextStack contextStack + ) + { + _lineConverter = lineConverter; + _scalingService = scalingService; + _contextStack = contextStack; + } + + public CurveArray Convert(Polyline target) + { + var curveArray = new CurveArray(); + if (target.value.Count == 6) + { + // 6 coordinate values (two sets of 3), so polyline is actually a single line + curveArray.Append(_lineConverter.Convert(new SOG.Line(target.value, target.units))); + } + else + { + var pts = target.GetPoints(); + var lastPt = pts[0]; + for (var i = 1; i < pts.Count; i++) + { + var success = TryAppendLineSafely(curveArray, new SOG.Line(lastPt, pts[i], target.units)); + if (success) + { + lastPt = pts[i]; + } + } + + if (target.closed) + { + TryAppendLineSafely(curveArray, new SOG.Line(pts[^1], pts[0], target.units)); + } + } + return curveArray; + } + + /// + /// Checks if a Speckle is too sort to be created in Revit. + /// + /// + /// The length of the line will be computed on the spot to ensure it is accurate. + /// + /// The to be tested. + /// true if the line is too short, false otherwise. + public bool IsLineTooShort(SOG.Line line) + { + var scaleToNative = _scalingService.ScaleToNative(SOG.Point.Distance(line.start, line.end), line.units); + return scaleToNative < _contextStack.Current.Document.Application.ShortCurveTolerance; + } + + /// + /// Attempts to append a Speckle onto a Revit . + /// This method ensures the line is long enough to be supported. + /// It will also convert the line to Revit before appending it to the . + /// + /// The revit to add the line to. + /// The to be added. + /// True if the line was added, false otherwise. + public bool TryAppendLineSafely(CurveArray curveArray, SOG.Line line) + { + if (IsLineTooShort(line)) + { + // poc : logging "Some lines in the CurveArray where ignored due to being smaller than the allowed curve length." + return false; + } + + curveArray.Append(_lineConverter.Convert(line)); + return true; + } +} diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/VectorConverterToHost.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/VectorConverterToHost.cs new file mode 100644 index 0000000000..04f589d2cf --- /dev/null +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/Raw/Geometry/VectorConverterToHost.cs @@ -0,0 +1,28 @@ +using Autodesk.Revit.DB; +using Objects.Geometry; +using Speckle.Converters.Common.Objects; +using Speckle.Converters.RevitShared.Services; + +namespace Speckle.Converters.RevitShared.ToSpeckle; + +public class VectorConverterToHost : ITypedConverter +{ + private readonly ScalingServiceToHost _scalingService; + private readonly IReferencePointConverter _referencePointConverter; + + public VectorConverterToHost(ScalingServiceToHost scalingService, IReferencePointConverter referencePointConverter) + { + _scalingService = scalingService; + _referencePointConverter = referencePointConverter; + } + + public XYZ Convert(Vector target) + { + var revitVector = new XYZ( + _scalingService.ScaleToNative(target.x, target.units), + _scalingService.ScaleToNative(target.y, target.units), + _scalingService.ScaleToNative(target.z, target.units) + ); + return _referencePointConverter.ToInternalCoordinates(revitVector, false); + } +} diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/TopLevel/BaseTopLevelConverterToHost.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/TopLevel/BaseTopLevelConverterToHost.cs new file mode 100644 index 0000000000..4ea35a7980 --- /dev/null +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/TopLevel/BaseTopLevelConverterToHost.cs @@ -0,0 +1,17 @@ +using Speckle.Converters.Common.Objects; +using Speckle.Core.Models; + +namespace Speckle.Converters.RevitShared.ToSpeckle; + +public abstract class BaseTopLevelConverterToHost : IToHostTopLevelConverter + where TSpeckle : Base + where THost : notnull +{ + public abstract THost Convert(TSpeckle target); + + public object Convert(Base target) + { + var result = Convert((TSpeckle)target); + return result; + } +} diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/TopLevel/ModelCurveToSpeckleTopLevelConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/TopLevel/ModelCurveToSpeckleTopLevelConverter.cs new file mode 100644 index 0000000000..e037bafd9e --- /dev/null +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToHost/TopLevel/ModelCurveToSpeckleTopLevelConverter.cs @@ -0,0 +1,107 @@ +using Objects; +using Speckle.Converters.Common; +using Speckle.Converters.Common.Objects; +using Speckle.Converters.RevitShared.Helpers; +using System.Collections; + +namespace Speckle.Converters.RevitShared.ToSpeckle; + +[NameAndRankValue(nameof(SOBR.Curve.ModelCurve), 0)] +public class ModelCurveToHostTopLevelConverter : BaseTopLevelConverterToHost +{ + private readonly ITypedConverter _curveConverter; + private readonly IRevitConversionContextStack _contextStack; + + public ModelCurveToHostTopLevelConverter( + ITypedConverter curveConverter, + IRevitConversionContextStack conversionContext + ) + { + _curveConverter = curveConverter; + _contextStack = conversionContext; + } + + public override DB.ModelCurve[] Convert(SOBR.Curve.ModelCurve target) => + ModelCurvesFromEnumerator(_curveConverter.Convert(target.baseCurve).GetEnumerator(), target.baseCurve).ToArray(); + + private IEnumerable ModelCurvesFromEnumerator(IEnumerator curveEnum, ICurve speckleLine) + { + while (curveEnum.MoveNext() && curveEnum.Current != null) + { + var curve = (DB.Curve)curveEnum.Current; + // Curves must be bound in order to be valid model curves + if (!curve.IsBound) + { + curve.MakeBound(speckleLine.domain.start ?? 0, speckleLine.domain.end ?? Math.PI * 2); + } + + if (_contextStack.Current.Document.IsFamilyDocument) + { + yield return _contextStack.Current.Document.FamilyCreate.NewModelCurve( + curve, + NewSketchPlaneFromCurve(curve, _contextStack.Current.Document) + ); + } + else + { + yield return _contextStack.Current.Document.Create.NewModelCurve( + curve, + NewSketchPlaneFromCurve(curve, _contextStack.Current.Document) + ); + } + } + } + + /// + /// Credits: Grevit + /// Creates a new Sketch Plane from a Curve + /// https://github.com/grevit-dev/Grevit/blob/3c7a5cc198e00dfa4cc1e892edba7c7afd1a3f84/Grevit.Revit/Utilities.cs#L402 + /// + /// Curve to get plane from + /// Plane of the curve + private DB.SketchPlane NewSketchPlaneFromCurve(DB.Curve curve, DB.Document doc) + { + DB.XYZ startPoint = curve.GetEndPoint(0); + DB.XYZ endPoint = curve.GetEndPoint(1); + + // If Start end Endpoint are the same check further points. + int i = 2; + while (startPoint == endPoint && endPoint != null) + { + endPoint = curve.GetEndPoint(i); + i++; + } + + // Plane to return + DB.Plane plane; + + // If Z Values are equal the Plane is XY + if (startPoint.Z == endPoint.NotNull().Z) + { + plane = DB.Plane.CreateByNormalAndOrigin(DB.XYZ.BasisZ, startPoint); + } + // If X Values are equal the Plane is YZ + else if (startPoint.X == endPoint.X) + { + plane = DB.Plane.CreateByNormalAndOrigin(DB.XYZ.BasisX, startPoint); + } + // If Y Values are equal the Plane is XZ + else if (startPoint.Y == endPoint.Y) + { + plane = DB.Plane.CreateByNormalAndOrigin(DB.XYZ.BasisY, startPoint); + } + // Otherwise the Planes Normal Vector is not X,Y or Z. + // We draw lines from the Origin to each Point and use the Plane this one spans up. + else + { + using DB.CurveArray curves = new(); + curves.Append(curve); + curves.Append(DB.Line.CreateBound(new DB.XYZ(0, 0, 0), startPoint)); + curves.Append(DB.Line.CreateBound(endPoint, new DB.XYZ(0, 0, 0))); + + plane = DB.Plane.CreateByThreePoints(startPoint, new DB.XYZ(0, 0, 0), endPoint); + } + + return DB.SketchPlane.Create(doc, plane); + } +} diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/BeamConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/BeamConversionToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/BeamConversionToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/BeamConversionToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/BoundarySegmentConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/BoundarySegmentConversionToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/BoundarySegmentConversionToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/BoundarySegmentConversionToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/BraceToSpeckleConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/BraceToSpeckleConverter.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/BraceToSpeckleConverter.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/BraceToSpeckleConverter.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ColumnConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/ColumnConversionToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ColumnConversionToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/ColumnConversionToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/ArcToSpeckleConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/ArcToSpeckleConverter.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/ArcToSpeckleConverter.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/ArcToSpeckleConverter.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/BoundingBoxXYZToSpeckleConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/BoundingBoxXYZToSpeckleConverter.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/BoundingBoxXYZToSpeckleConverter.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/BoundingBoxXYZToSpeckleConverter.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/CircleToSpeckleConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/CircleToSpeckleConverter.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/CircleToSpeckleConverter.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/CircleToSpeckleConverter.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/CurveArrArrayToSpecklePolycurveConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/CurveArrArrayToSpecklePolycurveConverter.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/CurveArrArrayToSpecklePolycurveConverter.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/CurveArrArrayToSpecklePolycurveConverter.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/CurveArrayConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/CurveArrayConversionToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/CurveArrayConversionToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/CurveArrayConversionToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/CurveConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/CurveConversionToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/CurveConversionToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/CurveConversionToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/EllipseToSpeckleConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/EllipseToSpeckleConverter.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/EllipseToSpeckleConverter.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/EllipseToSpeckleConverter.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/HermiteSplineToSpeckleConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/HermiteSplineToSpeckleConverter.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/HermiteSplineToSpeckleConverter.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/HermiteSplineToSpeckleConverter.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/LineConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/LineConversionToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/LineConversionToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/LineConversionToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/MeshByMaterialDictionaryToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/MeshByMaterialDictionaryToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/MeshByMaterialDictionaryToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/MeshByMaterialDictionaryToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/MeshConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/MeshConversionToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/MeshConversionToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/MeshConversionToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/NurbsSplineToSpeckleConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/NurbsSplineToSpeckleConverter.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/NurbsSplineToSpeckleConverter.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/NurbsSplineToSpeckleConverter.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/PlaneToSpeckleConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/PlaneToSpeckleConverter.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/PlaneToSpeckleConverter.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/PlaneToSpeckleConverter.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/PointCloudToSpeckleConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/PointCloudToSpeckleConverter.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/PointCloudToSpeckleConverter.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/PointCloudToSpeckleConverter.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/PointConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/PointConversionToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/PointConversionToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/PointConversionToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/PolylineToSpeckleConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/PolylineToSpeckleConverter.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/PolylineToSpeckleConverter.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/PolylineToSpeckleConverter.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/SolidConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/SolidConversionToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/SolidConversionToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/SolidConversionToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/VectorToSpeckleConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/VectorToSpeckleConverter.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/VectorToSpeckleConverter.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/VectorToSpeckleConverter.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/XyzConversionToPoint.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/XyzConversionToPoint.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/XyzConversionToPoint.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/Geometry/XyzConversionToPoint.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/LevelConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/LevelConversionToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/LevelConversionToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/LevelConversionToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/LocationConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/LocationConversionToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/LocationConversionToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/LocationConversionToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/MaterialConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/MaterialConversionToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/MaterialConversionToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/MaterialConversionToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ModelCurveArrArrayToSpeckleConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/ModelCurveArrArrayToSpeckleConverter.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ModelCurveArrArrayToSpeckleConverter.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/ModelCurveArrArrayToSpeckleConverter.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ModelCurveArrayToSpeckleConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/ModelCurveArrayToSpeckleConverter.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ModelCurveArrayToSpeckleConverter.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/ModelCurveArrayToSpeckleConverter.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ParameterConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/ParameterConversionToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ParameterConversionToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/Raw/ParameterConversionToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/BaseTopLevelConverterToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/BaseTopLevelConverterToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/BaseTopLevelConverterToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/BaseTopLevelConverterToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/CeilingTopLevelConverterToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/CeilingTopLevelConverterToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/CeilingTopLevelConverterToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/CeilingTopLevelConverterToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/DirectShapeTopLevelConverterToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/DirectShapeTopLevelConverterToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/DirectShapeTopLevelConverterToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/DirectShapeTopLevelConverterToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/ElementTopLevelConverterToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/ElementTopLevelConverterToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/ElementTopLevelConverterToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/ElementTopLevelConverterToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/ExtrusionRoofToSpeckleTopLevelConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/ExtrusionRoofToSpeckleTopLevelConverter.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/ExtrusionRoofToSpeckleTopLevelConverter.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/ExtrusionRoofToSpeckleTopLevelConverter.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/FamilyInstanceTopLevelConverterToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/FamilyInstanceTopLevelConverterToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/FamilyInstanceTopLevelConverterToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/FamilyInstanceTopLevelConverterToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/FloorTopLevelConverterToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/FloorTopLevelConverterToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/FloorTopLevelConverterToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/FloorTopLevelConverterToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/FootPrintRoofToSpeckleTopLevelConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/FootPrintRoofToSpeckleTopLevelConverter.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/FootPrintRoofToSpeckleTopLevelConverter.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/FootPrintRoofToSpeckleTopLevelConverter.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/HostedElementConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/HostedElementConversionToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/HostedElementConversionToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/HostedElementConversionToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/ModelCurveToSpeckleTopLevelConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/ModelCurveToSpeckleTopLevelConverter.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/ModelCurveToSpeckleTopLevelConverter.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/ModelCurveToSpeckleTopLevelConverter.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/RoofBaseToSpeckleTopLevelTopLevelConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/RoofBaseToSpeckleTopLevelTopLevelConverter.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/RoofBaseToSpeckleTopLevelTopLevelConverter.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/RoofBaseToSpeckleTopLevelTopLevelConverter.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/RoomTopLevelConverterToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/RoomTopLevelConverterToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/RoomTopLevelConverterToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/RoomTopLevelConverterToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopographyTopLevelConverterToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/TopographyTopLevelConverterToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopographyTopLevelConverterToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/TopographyTopLevelConverterToSpeckle.cs diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/WallTopLevelConverterToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/WallTopLevelConverterToSpeckle.cs similarity index 100% rename from DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/WallTopLevelConverterToSpeckle.cs rename to DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/TopLevel/WallTopLevelConverterToSpeckle.cs