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