diff --git a/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/ArcGISSendBinding.cs b/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/ArcGISSendBinding.cs index 79d393375a..b8abea01bd 100644 --- a/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/ArcGISSendBinding.cs +++ b/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/ArcGISSendBinding.cs @@ -2,7 +2,6 @@ using Speckle.Autofac.DependencyInjection; using Speckle.Connectors.DUI.Bindings; using Speckle.Connectors.DUI.Bridge; -using Speckle.Connectors.DUI.Utils; using Speckle.Connectors.ArcGis.Operations.Send; using Speckle.Connectors.Utils.Cancellation; using Speckle.Core.Logging; @@ -10,6 +9,7 @@ using Speckle.Connectors.ArcGIS.Utils; using Speckle.Connectors.DUI.Models.Card; using Speckle.Connectors.DUI.Models.Card.SendFilter; +using Speckle.Connectors.DUI.Settings; namespace Speckle.Connectors.ArcGIS.Bindings; diff --git a/DUI3-DX/Connectors/Autocad/Speckle.Connectors.AutocadShared/Bindings/AutocadSendBinding.cs b/DUI3-DX/Connectors/Autocad/Speckle.Connectors.AutocadShared/Bindings/AutocadSendBinding.cs index dab413d79f..05ca5806bd 100644 --- a/DUI3-DX/Connectors/Autocad/Speckle.Connectors.AutocadShared/Bindings/AutocadSendBinding.cs +++ b/DUI3-DX/Connectors/Autocad/Speckle.Connectors.AutocadShared/Bindings/AutocadSendBinding.cs @@ -138,15 +138,14 @@ private async Task SendInternal(string modelCardId) throw new InvalidOperationException("No objects were found. Please update your send filter!"); } - var sendInfo = new SendInfo() - { - AccountId = modelCard.AccountId, - ProjectId = modelCard.ProjectId, - ModelId = modelCard.ModelId, - ConvertedObjects = _convertedObjectReferences, - ChangedObjectIds = modelCard.ChangedObjectIds, - SourceApplication = _autocadSettings.HostAppInfo.Name - }; + var sendInfo = new SendInfo( + modelCard.AccountId, + modelCard.ProjectId, + modelCard.ModelId, + _autocadSettings.HostAppInfo.Name, + _convertedObjectReferences, + modelCard.ChangedObjectIds + ); var sendResult = await uow.Service .Execute( diff --git a/DUI3-DX/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/AutocadCommand.cs b/DUI3-DX/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/AutocadCommand.cs index 3619459acb..996dcaa90b 100644 --- a/DUI3-DX/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/AutocadCommand.cs +++ b/DUI3-DX/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/AutocadCommand.cs @@ -21,7 +21,7 @@ public class AutocadCommand public AutofacContainer? Container { get; private set; } - [CommandMethod("SpeckleDUI3DX")] + [CommandMethod("SpeckleNewUI")] public void Command() { if (PaletteSet != null) 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 542497b9f7..4ce71db171 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 @@ -39,11 +39,11 @@ - + - + diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Assets/logo16.png b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Assets/logo16.png new file mode 100644 index 0000000000..61872f0d0c Binary files /dev/null and b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Assets/logo16.png differ diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Assets/logo32.png b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Assets/logo32.png new file mode 100644 index 0000000000..2ad0c346ea Binary files /dev/null and b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Assets/logo32.png differ diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/BasicConnectorBindingRevit.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/BasicConnectorBindingRevit.cs index 0452730b05..4eb94b969b 100644 --- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/BasicConnectorBindingRevit.cs +++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/BasicConnectorBindingRevit.cs @@ -72,7 +72,6 @@ public DocumentInfo GetDocumentInfo() } // POC: Notify user here if document is null. - return new DocumentInfo { Name = doc.Title, diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/ReceiveBinding.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/ReceiveBinding.cs deleted file mode 100644 index 43d32511a5..0000000000 --- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/ReceiveBinding.cs +++ /dev/null @@ -1,144 +0,0 @@ -using System; -using Speckle.Connectors.DUI.Bridge; -using Speckle.Connectors.DUI.Models; -using Speckle.Connectors.Utils.Cancellation; -using Speckle.Converters.RevitShared.Helpers; -using Speckle.Core.Logging; - -namespace Speckle.Connectors.Revit.Bindings; - -internal class ReceiveBinding : RevitBaseBinding, ICancelable -{ - public CancellationManager CancellationManager { get; } = new(); - - public ReceiveBinding(RevitContext revitContext, DocumentModelStore store, IBridge bridge) - : base("receiveBinding", store, bridge, revitContext) { } - - public void CancelReceive(string modelCardId) => CancellationManager.CancelOperation(modelCardId); - - public async void Receive(string modelCardId, string versionId) - { - try - { - //// 0 - Init cancellation token source -> Manager also cancel it if exist before - //CancellationTokenSource cts = CancellationManager.InitCancellationTokenSource(modelCardId); - - //// 1 - Get receiver card - //ReceiverModelCard model = _store.GetModelById(modelCardId) as ReceiverModelCard; - - //// 2 - Get commit object from server - //Base commitObject = await Operations.GetCommitBase(Parent, model, versionId, cts.Token).ConfigureAwait(true); - - //if (cts.IsCancellationRequested) - //{ - // return; - //} - - //// 3 - Get converter - //ISpeckleConverter converter = Converters.GetConverter(Doc, RevitAppProvider.Version()); - - //// 4 - Traverse commit object - //List objectsToConvert = Traversal.GetObjectsToConvert(commitObject, converter); - - //// 5 - Bake objects - //BakeObjects(objectsToConvert, converter, modelCardId, cts); - } - catch (Exception e) when (!e.IsFatal()) - { - //if (e is OperationCanceledException) - //{ - // Progress.CancelReceive(Parent, modelCardId); - // return; - //} - //throw; - } - } - - //private async void BakeObjects( - // List objectsToConvert, - // ISpeckleConverter converter, - // string modelCardId, - // CancellationTokenSource cts - //) - //{ - // (bool success, Exception exception) = await RevitTask - // .RunAsync(app => - // { - // string transactionName = $"Baking model from {modelCardId}"; - // using TransactionGroup g = new(Doc, transactionName); - // using Transaction t = new(Doc, transactionName); - // g.Start(); - // t.Start(); - - // try - // { - // converter.SetContextDocument(t); - // List errors = new(); - // int count = 0; - // foreach (Base objToConvert in objectsToConvert) - // { - // count++; - // if (cts.IsCancellationRequested) - // { - // Progress.CancelReceive(Parent, modelCardId, (double)count / objectsToConvert.Count); - // break; - // } - // try - // { - // double progress = (double)count / objectsToConvert.Count; - // Progress.ReceiverProgressToBrowser(Parent, modelCardId, progress); - // object convertedObject = converter.ConvertToNative(objToConvert); - // RefreshView(); - // } - // catch (SpeckleException e) - // { - // errors.Add($"Object couldn't converted with id: {objToConvert.id}, type: {objToConvert.speckle_type}\n"); - // Console.WriteLine(e); - // } - // } - // Notification.ReportReceive(Parent, errors, modelCardId, objectsToConvert.Count); - - // t.Commit(); - - // if (t.GetStatus() == TransactionStatus.RolledBack) - // { - // int numberOfErrors = 0; // Previously get from errorEater - // return ( - // false, - // new SpeckleException( - // $"The Revit API could not resolve {numberOfErrors} unique errors and {numberOfErrors} total errors when trying to commit the Speckle model. The whole transaction is being rolled back." - // ) - // ); - // } - - // g.Assimilate(); - // return (true, null); - // } - // catch (SpeckleException ex) - // { - // t.RollBack(); - // g.RollBack(); - // return (false, ex); //We can't throw exceptions in from RevitTask, but we can return it along with a success status - // } - // }) - // .ConfigureAwait(false); - //} - - //private void RefreshView() - //{ - // // regenerate the document and then implement a hack to "refresh" the view - // UiDoc.Document.Regenerate(); - - // // get the active ui view - // View view = UiDoc.ActiveGraphicalView ?? UiDoc.ActiveView; - // if (view is TableView) - // { - // return; - // } - - // UIView uiView = UiDoc.GetOpenUIViews().FirstOrDefault(uv => uv.ViewId.Equals(view.Id)); - - // // "refresh" the active view - // uiView?.Zoom(1); - //} -} diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitBaseBinding.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitBaseBinding.cs index 6822f0650e..1a18f5ac53 100644 --- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitBaseBinding.cs +++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/RevitBaseBinding.cs @@ -11,14 +11,14 @@ internal abstract class RevitBaseBinding : IBinding public string Name { get; protected set; } public IBridge Parent { get; protected set; } - protected readonly DocumentModelStore _store; - protected readonly RevitContext _revitContext; + protected readonly DocumentModelStore Store; + protected readonly RevitContext RevitContext; public RevitBaseBinding(string name, DocumentModelStore store, IBridge bridge, RevitContext revitContext) { Name = name; Parent = bridge; - _store = store; - _revitContext = revitContext; + Store = store; + RevitContext = revitContext; } } diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/SelectionBinding.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/SelectionBinding.cs index 3c339526d7..ee69c66e52 100644 --- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/SelectionBinding.cs +++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/SelectionBinding.cs @@ -24,12 +24,7 @@ IBridge bridge // POC: we can inject the solution here // TODO: Need to figure it out equivalent of SelectionChanged for Revit2020 - _revitContext.UIApplication.SelectionChanged += (_, _) => _revitIdleManager.SubscribeToIdle(OnSelectionChanged); - - _revitContext.UIApplication.ViewActivated += (_, _) => - { - Parent.Send(SelectionBindingEvents.SET_SELECTION, new SelectionInfo()); - }; + RevitContext.UIApplication.SelectionChanged += (_, _) => _revitIdleManager.SubscribeToIdle(OnSelectionChanged); } private void OnSelectionChanged() @@ -42,7 +37,7 @@ public SelectionInfo GetSelection() // POC: this was also being called on shutdown // probably the bridge needs to be able to know if the plugin has been terminated // also on termination the OnSelectionChanged event needs unwinding - var selectionIds = _revitContext.UIApplication.ActiveUIDocument.Selection + var selectionIds = RevitContext.UIApplication.ActiveUIDocument.Selection .GetElementIds() .Select(id => id.ToString()) .ToList(); diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/SendBinding.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/SendBinding.cs index 72f91ef72c..67fa8c8b21 100644 --- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/SendBinding.cs +++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/SendBinding.cs @@ -11,11 +11,12 @@ using System.Threading.Tasks; using System.Threading; using Speckle.Converters.RevitShared.Helpers; -using Speckle.Connectors.Revit.Operations.Send; using Speckle.Connectors.DUI.Models.Card; using Speckle.Connectors.DUI.Bindings; using Speckle.Autofac.DependencyInjection; using Speckle.Connectors.DUI.Models; +using Speckle.Connectors.Utils.Operations; +using Speckle.Core.Models; namespace Speckle.Connectors.Revit.Bindings; @@ -27,6 +28,12 @@ internal class SendBinding : RevitBaseBinding, ICancelable, ISendBinding // POC: does it need injecting? private HashSet ChangedObjectIds { get; set; } = new(); + /// + /// Keeps track of previously converted objects as a dictionary of (applicationId, object reference). + /// + private readonly Dictionary _convertedObjectReferences = new(); + + private readonly RevitSettings _revitSettings; private readonly IRevitIdleManager _idleManager; private readonly IUnitOfWorkFactory _unitOfWorkFactory; @@ -35,12 +42,14 @@ public SendBinding( RevitContext revitContext, DocumentModelStore store, IBridge bridge, - IUnitOfWorkFactory unitOfWorkFactory + IUnitOfWorkFactory unitOfWorkFactory, + RevitSettings revitSettings ) : base("sendBinding", store, bridge, revitContext) { _idleManager = idleManager; _unitOfWorkFactory = unitOfWorkFactory; + _revitSettings = revitSettings; Commands = new SendBindingUICommands(bridge); // TODO expiry events @@ -78,25 +87,45 @@ private async Task HandleSend(string modelCardId) // bubbling up to the bridge. try { - if (_store.GetModelById(modelCardId) is not SenderModelCard modelCard) + if (Store.GetModelById(modelCardId) is not SenderModelCard modelCard) { throw new InvalidOperationException("No publish model card was found."); } - using IUnitOfWork sendOperation = _unitOfWorkFactory.Resolve(); + using IUnitOfWork> sendOperation = _unitOfWorkFactory.Resolve< + SendOperation + >(); + + List revitObjects = modelCard.SendFilter.GetObjectIds().Select(id => ElementId.Parse(id)).ToList(); + + var sendInfo = new SendInfo( + modelCard.AccountId, + modelCard.ProjectId, + modelCard.ModelId, + _revitSettings.HostSlug, + _convertedObjectReferences, + modelCard.ChangedObjectIds + ); - string versionId = await sendOperation.Service + var sendResult = await sendOperation.Service .Execute( - modelCard.SendFilter, - modelCard.AccountId, - modelCard.ProjectId, - modelCard.ModelId, + revitObjects, + sendInfo, (status, progress) => OnSendOperationProgress(modelCardId, status, progress), cts.Token ) .ConfigureAwait(false); - Commands.SetModelCreatedVersionId(modelCardId, versionId); + // Store the converted references in memory for future send operations, overwriting the existing values for the given application id. + foreach (var kvp in sendResult.convertedReferences) + { + _convertedObjectReferences[kvp.Key + modelCard.ProjectId] = kvp.Value; + } + + // It's important to reset the model card's list of changed obj ids so as to ensure we accurately keep track of changes between send operations. + modelCard.ChangedObjectIds = new(); + + Commands.SetModelCreatedVersionId(modelCardId, sendResult.rootObjId); } catch (OperationCanceledException) { @@ -166,15 +195,18 @@ private void DocChangeHandler(Autodesk.Revit.DB.Events.DocumentChangedEventArgs private void RunExpirationChecks() { - List senders = _store.GetSenders(); + List senders = Store.GetSenders(); + string[] objectIdsList = ChangedObjectIds.ToArray(); List expiredSenderIds = new(); - foreach (var sender in senders) + foreach (SenderModelCard modelCard in senders) { - bool isExpired = sender.SendFilter.CheckExpiry(ChangedObjectIds.ToArray()); + var intersection = modelCard.SendFilter.GetObjectIds().Intersect(objectIdsList).ToList(); + bool isExpired = modelCard.SendFilter.CheckExpiry(ChangedObjectIds.ToArray()); if (isExpired) { - expiredSenderIds.Add(sender.ModelCardId); + expiredSenderIds.Add(modelCard.ModelCardId); + modelCard.ChangedObjectIds.UnionWith(intersection); } } diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/DependencyInjection/AutofacUIModule.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/DependencyInjection/AutofacUIModule.cs index 5fed7ce26c..d3e86d8ac3 100644 --- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/DependencyInjection/AutofacUIModule.cs +++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/DependencyInjection/AutofacUIModule.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using Autodesk.Revit.DB; using Autofac; using CefSharp; using Microsoft.Extensions.Logging; @@ -14,13 +15,12 @@ using Speckle.Connectors.Revit.HostApp; using Speckle.Connectors.Revit.Operations.Send; using Speckle.Connectors.Revit.Plugin; +using Speckle.Connectors.Utils.Builders; using Speckle.Connectors.Utils.Operations; using Speckle.Converters.RevitShared.Helpers; using Speckle.Core.Transports; using Speckle.Newtonsoft.Json; using Speckle.Newtonsoft.Json.Serialization; -using IRootObjectSender = Speckle.Connectors.Revit.Operations.Send.IRootObjectSender; -using RootObjectSender = Speckle.Connectors.Revit.Operations.Send.RootObjectSender; namespace Speckle.Connectors.Revit.DependencyInjection; @@ -75,16 +75,14 @@ protected override void Load(ContainerBuilder builder) builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); - // POC: Hide Load button as Revit connector is publish only for the open alpha. - //builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); // send operation and dependencies builder.RegisterType().As().SingleInstance().AutoActivate(); - builder.RegisterType().AsSelf().InstancePerLifetimeScope(); + builder.RegisterType>().AsSelf().InstancePerLifetimeScope(); builder.RegisterType().AsSelf().InstancePerLifetimeScope(); builder.RegisterType().AsSelf().InstancePerLifetimeScope(); - builder.RegisterType().AsSelf().InstancePerLifetimeScope(); + builder.RegisterType().As>().InstancePerLifetimeScope(); builder.RegisterType().As().InstancePerDependency(); builder.RegisterType().As().SingleInstance(); diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/HostApp/RevitDocumentStore.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/HostApp/RevitDocumentStore.cs index 43141730e3..b3e4c339a4 100644 --- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/HostApp/RevitDocumentStore.cs +++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/HostApp/RevitDocumentStore.cs @@ -57,17 +57,17 @@ private void OnViewActivated(object sender, ViewActivatedEventArgs e) return; } - if (e.PreviousActiveView?.Document != null) - { - WriteToFileWithDoc(e.PreviousActiveView.Document); - } - // Return only if we are switching views that belongs to same document if (e.PreviousActiveView?.Document != null && e.PreviousActiveView.Document.Equals(e.CurrentActiveView.Document)) { return; } + if (e.PreviousActiveView?.Document != null) + { + WriteToFileWithDoc(e.PreviousActiveView.Document); + } + IsDocumentInit = true; ReadFromFile(); OnDocumentChanged(); diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Send/IRootObjectSender.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Send/IRootObjectSender.cs deleted file mode 100644 index 28611e51b7..0000000000 --- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Send/IRootObjectSender.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using Speckle.Core.Models; -using System.Threading.Tasks; -using System.Threading; - -namespace Speckle.Connectors.Revit.Operations.Send; - -/// -/// Contract for the send operation that handles an assembled object. -/// In production, this will send to a server. -/// In testing, this could send to a sqlite db or just save to a dictionary. -/// -public interface IRootObjectSender -{ - public Task Send( - Base commitObject, - string accountId, - string projectId, - string modelId, - Action? onOperationProgressed = null, - CancellationToken ct = default - ); -} diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Send/RootObjectBuilder.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Send/RootObjectBuilder.cs index ae7a094bc8..ea69596b5d 100644 --- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Send/RootObjectBuilder.cs +++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Send/RootObjectBuilder.cs @@ -6,23 +6,25 @@ using Autodesk.Revit.DB; using Speckle.Converters.RevitShared.Helpers; using System.Linq; +using Speckle.Connectors.Utils.Builders; +using Speckle.Connectors.Utils.Operations; using Speckle.Core.Logging; namespace Speckle.Connectors.Revit.Operations.Send; -public class RootObjectBuilder +public class RootObjectBuilder : IRootObjectBuilder { // POC: SendSelection and RevitConversionContextStack should be interfaces, former needs interfaces private readonly ISpeckleConverterToSpeckle _converter; private readonly ToSpeckleConvertedObjectsCache _convertedObjectsCache; - private readonly RevitConversionContextStack _contextStack; + private readonly IRevitConversionContextStack _contextStack; private readonly Dictionary _collectionCache; private readonly Collection _rootObject; public RootObjectBuilder( ISpeckleConverterToSpeckle converter, ToSpeckleConvertedObjectsCache convertedObjectsCache, - RevitConversionContextStack contextStack + IRevitConversionContextStack contextStack ) { _converter = converter; @@ -34,42 +36,43 @@ RevitConversionContextStack contextStack _collectionCache = new Dictionary(); _rootObject = new Collection() { - name = _contextStack.Current.Document.Document.PathName.Split('\\').Last().Split('.').First() + name = _contextStack.Current.Document.PathName.Split('\\').Last().Split('.').First() }; } public Base Build( - SendSelection sendSelection, + IReadOnlyList objects, + SendInfo sendInfo, Action? onOperationProgressed = null, CancellationToken ct = default ) { - var doc = _contextStack.Current.Document.Document; // POC: Document.Document is funny + var doc = _contextStack.Current.Document; if (doc.IsFamilyDocument) { throw new SpeckleException("Family Environment documents are not supported."); } - var objects = new List(); // = _contextStack.Current.Document.Document.GetElements(sendSelection.SelectedItems).ToList(); + var revitElements = new List(); // = _contextStack.Current.Document.GetElements(sendSelection.SelectedItems).ToList(); - foreach (var id in sendSelection.SelectedItems) + foreach (var id in objects) { - var el = _contextStack.Current.Document.Document.GetElement(ElementId.Parse(id)); + var el = _contextStack.Current.Document.GetElement(id); if (el != null) { - objects.Add(el); + revitElements.Add(el); } } - if (objects.Count == 0) + if (revitElements.Count == 0) { throw new InvalidOperationException("No objects were found. Please update your send filter!"); } var countProgress = 0; // because for(int i = 0; ...) loops are so last year - foreach (Element revitElement in objects) + foreach (Element revitElement in revitElements) { ct.ThrowIfCancellationRequested(); @@ -77,24 +80,32 @@ public Base Build( var path = new[] { doc.GetElement(revitElement.LevelId) is not Level level ? "No level" : level.Name, cat }; var collection = GetAndCreateObjectHostCollection(path); - if (_convertedObjectsCache.ContainsBaseConvertedFromId(revitElement.UniqueId)) - { - continue; - } - + var applicationId = revitElement.Id.ToString(); try { - var convertedElement = _converter.Convert(revitElement); - convertedElement.applicationId = revitElement.Id.ToString(); - collection.elements.Add(convertedElement); + Base converted; + if ( + !sendInfo.ChangedObjectIds.Contains(applicationId) + && sendInfo.ConvertedObjects.TryGetValue(applicationId + sendInfo.ProjectId, out ObjectReference value) + ) + { + converted = value; + } + else + { + converted = _converter.Convert(revitElement); + converted.applicationId = applicationId; + } + + collection.elements.Add(converted); } - catch (SpeckleConversionException ex) + catch (SpeckleConversionException) { // POC: logging } countProgress++; - onOperationProgressed?.Invoke("Converting", (double)countProgress / objects.Count); + onOperationProgressed?.Invoke("Converting", (double)countProgress / revitElements.Count); } return _rootObject; diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Send/RootObjectSender.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Send/RootObjectSender.cs deleted file mode 100644 index 40889e5d55..0000000000 --- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Send/RootObjectSender.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; -using Speckle.Connectors.Utils.Operations; -using Speckle.Core.Api; -using System.Threading.Tasks; -using System.Threading; -using Speckle.Connectors.Revit.Plugin; -using Speckle.Core.Credentials; -using Speckle.Core.Models; -using Speckle.Core.Transports; - -namespace Speckle.Connectors.Revit.Operations.Send; - -/// -/// Default implementation of the which takes a and sends -/// it to a server described by the parameters in the method -/// -internal sealed class RootObjectSender : IRootObjectSender -{ - // POC: unsure about this factory pattern - a little weakly typed (being a Func) - private readonly ServerTransport.Factory _transportFactory; - private readonly RevitSettings _revitSettings; - - public RootObjectSender(ServerTransport.Factory transportFactory, RevitSettings revitSettings) - { - _transportFactory = transportFactory; - _revitSettings = revitSettings; - } - - public async Task Send( - Base commitObject, - string accountId, - string projectId, - string modelId, - Action? onOperationProgressed = null, - CancellationToken ct = default - ) - { - ct.ThrowIfCancellationRequested(); - - onOperationProgressed?.Invoke("Uploading...", null); - - Account account = AccountManager.GetAccount(accountId); - - ITransport transport = _transportFactory(account, projectId, 60, null); - var sendResult = await SendHelper.Send(commitObject, transport, true, null, ct).ConfigureAwait(false); - - ct.ThrowIfCancellationRequested(); - - onOperationProgressed?.Invoke("Linking version to model...", null); - - using var apiClient = new Client(account); - string versionId = await apiClient - .CommitCreate( - new CommitCreateInput - { - streamId = projectId, - branchName = modelId, - sourceApplication = _revitSettings.HostSlug, // POC: These naming is a bit? - objectId = sendResult.rootObjId - }, - ct - ) - .ConfigureAwait(true); - - return versionId; - } -} diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Send/SendOperation.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Send/SendOperation.cs deleted file mode 100644 index 7db122223f..0000000000 --- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Send/SendOperation.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using Speckle.Core.Models; -using System.Threading.Tasks; -using System.Threading; -using Speckle.Connectors.DUI.Models.Card.SendFilter; -using Speckle.Converters.RevitShared.Helpers; - -namespace Speckle.Connectors.Revit.Operations.Send; - -public sealed class SendOperation -{ - private readonly RootObjectBuilder _rootObjectBuilder; - private readonly IRootObjectSender _rootObjectSender; - - public SendOperation(RootObjectBuilder rootObjectBuilder, IRootObjectSender rootObjectSender) - { - _rootObjectBuilder = rootObjectBuilder; - _rootObjectSender = rootObjectSender; - } - - /// - /// Executes a send operation given information about the host objects and the destination account. - /// - /// - /// - /// - /// - /// - /// - /// - public async Task Execute( - ISendFilter sendFilter, - string accountId, - string projectId, - string modelId, - Action? onOperationProgressed = null, - CancellationToken ct = default - ) - { - // POC: have changed this as I don't understand the injecting of the ISendFilter when we can just use it here - // it begs the question whether ISendFilter should just be injected into the roo object builder and whether this function needs it at all? - // this class is now so thing I wonder if it should exist at all? - Base commitObject = _rootObjectBuilder.Build( - new SendSelection(sendFilter.GetObjectIds()), - onOperationProgressed, - ct - ); - - return await _rootObjectSender - .Send(commitObject, accountId, projectId, modelId, onOperationProgressed, ct) - .ConfigureAwait(true); - } -} diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Plugin/RevitExternalApplication.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Plugin/RevitExternalApplication.cs index d47d66a7dd..c73cfc59e2 100644 --- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Plugin/RevitExternalApplication.cs +++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Plugin/RevitExternalApplication.cs @@ -32,11 +32,11 @@ public RevitExternalApplication() // POC: load from JSON file? _revitSettings = new RevitSettings { - RevitPanelName = "Speckle DUI3 (DI)", + RevitPanelName = "Speckle New UI", RevitTabName = "Speckle", - RevitTabTitle = "Speckle DUI3 (DI)", + RevitTabTitle = "Speckle New UI", RevitVersionName = "2023", - RevitButtonName = "Speckle DUI3 (DI)", + RevitButtonName = "Speckle New UI", RevitButtonText = "Revit Connector", ModuleFolders = new string[] { Path.GetDirectoryName(typeof(RevitExternalApplication).Assembly.Location) }, HostSlug = "Revit" @@ -50,7 +50,7 @@ public Result OnStartup(UIControlledApplication application) // POC: not sure what this is doing... could be messing up our Aliasing???? AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve; _container = new AutofacContainer(new StorageInfo()); - _container.PreBuildEvent += _container_PreBuildEvent; + _container.PreBuildEvent += ContainerPreBuildEvent; // init DI _container @@ -72,7 +72,7 @@ public Result OnStartup(UIControlledApplication application) return Result.Succeeded; } - private void _container_PreBuildEvent(object sender, ContainerBuilder containerBuilder) + private void ContainerPreBuildEvent(object sender, ContainerBuilder containerBuilder) { // POC: need to settle on the mechanism and location as to where we should register these services containerBuilder.RegisterRawConversions(); diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Plugin/RevitIdleManager.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Plugin/RevitIdleManager.cs index d4877b6828..76b723ff9c 100644 --- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Plugin/RevitIdleManager.cs +++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Plugin/RevitIdleManager.cs @@ -16,7 +16,7 @@ internal class RevitIdleManager : IRevitIdleManager private readonly ConcurrentDictionary _calls = new(); // POC: still not thread safe - private volatile bool _hasSubscribed = false; + private volatile bool _hasSubscribed; public RevitIdleManager(RevitContext revitContext) { diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Plugin/RevitPlugin.cs b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Plugin/RevitPlugin.cs index 19a9e72b38..9e0a2041d4 100644 --- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Plugin/RevitPlugin.cs +++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Plugin/RevitPlugin.cs @@ -9,6 +9,11 @@ using Speckle.Connectors.DUI.Bindings; using System.Diagnostics; using Speckle.Converters.RevitShared.Helpers; +using Speckle.Core.Logging; +using System.Reflection; +using System.Windows.Media.Imaging; +using System.Windows.Media; +using System.IO; namespace Speckle.Connectors.Revit.Plugin; @@ -18,7 +23,6 @@ internal class RevitPlugin : IRevitPlugin private readonly RevitSettings _revitSettings; private readonly IEnumerable> _bindings; // should be lazy to ensure the bindings are not created too early private readonly BindingOptions _bindingOptions; - private readonly CefSharpPanel _panel; private readonly RevitContext _revitContext; private readonly CefSharpPanel _cefSharpPanel; @@ -62,11 +66,12 @@ private void CreateTabAndRibbonPanel(UIControlledApplication application) } catch (ArgumentException) { - throw; + // exception occurs when the speckle tab has already been created. + // this happens when both the dui2 and the dui3 connectors are installed. Can be safely ignored. } RibbonPanel specklePanel = application.CreateRibbonPanel(_revitSettings.RevitTabName, _revitSettings.RevitTabTitle); - PushButton _ = + PushButton dui3Button = specklePanel.AddItem( new PushButtonData( _revitSettings.RevitButtonName, @@ -75,6 +80,23 @@ private void CreateTabAndRibbonPanel(UIControlledApplication application) typeof(SpeckleRevitCommand).FullName ) ) as PushButton; + + string path = typeof(RevitPlugin).Assembly.Location; + dui3Button.Image = LoadPngImgSource( + $"Speckle.Connectors.Revit{_revitSettings.RevitVersionName}.Assets.logo16.png", + path + ); + dui3Button.LargeImage = LoadPngImgSource( + $"Speckle.Connectors.Revit{_revitSettings.RevitVersionName}.Assets.logo32.png", + path + ); + dui3Button.ToolTipImage = LoadPngImgSource( + $"Speckle.Connectors.Revit{_revitSettings.RevitVersionName}.Assets.logo32.png", + path + ); + dui3Button.ToolTip = "Speckle Connector for Revit New UI"; + //dui3Button.AvailabilityClassName = typeof(CmdAvailabilityViews).FullName; + dui3Button.SetContextualHelp(new ContextualHelp(ContextualHelpType.Url, "https://speckle.systems")); } private void OnApplicationInitialized(object sender, Autodesk.Revit.DB.Events.ApplicationInitializedEventArgs e) @@ -147,4 +169,22 @@ private void RegisterPanelAndInitializePlugin() #endif }; } + + private ImageSource? LoadPngImgSource(string sourceName, string path) + { + try + { + var assembly = Assembly.LoadFrom(Path.Combine(path)); + var icon = assembly.GetManifestResourceStream(sourceName); + PngBitmapDecoder decoder = new(icon, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); + ImageSource source = decoder.Frames[0]; + return source; + } + catch (Exception ex) when (!ex.IsFatal()) + { + // POC: logging + } + + return null; + } } diff --git a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Plugin/Speckle.Connectors.Revit2023.addin b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Plugin/Speckle.Connectors.Revit2023.addin index 17a6874f65..5e07999bbd 100644 --- a/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Plugin/Speckle.Connectors.Revit2023.addin +++ b/DUI3-DX/Connectors/Revit/Speckle.Connectors.RevitShared/Plugin/Speckle.Connectors.Revit2023.addin @@ -1,8 +1,8 @@  - Speckle Revit Connector | DUI3 + Kits + DI - Speckle Revit Connector | DUI3 + Kits + DI + Speckle Revit Connector New UI + Speckle Revit Connector New UI Speckle.Connectors.Revit2023\Speckle.Connectors.Revit2023.dll Speckle.Connectors.Revit.Plugin.RevitExternalApplication 27ccff2c-011c-4374-bb79-b93990d0c86a 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 25aa1128b9..6543a56b68 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 @@ -9,6 +9,8 @@ Speckle.Connectors.Revit + + Always @@ -16,7 +18,6 @@ - @@ -26,10 +27,7 @@ - - - CefSharpPanel.xaml diff --git a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoSelectionBinding.cs b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoSelectionBinding.cs index 395055fc69..5a00123167 100644 --- a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoSelectionBinding.cs +++ b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoSelectionBinding.cs @@ -31,12 +31,6 @@ public RhinoSelectionBinding(RhinoIdleManager idleManager, IBridge parent) { idleManager.SubscribeToIdle(OnSelectionChanged); }; - - RhinoDoc.EndOpenDocumentInitialViewUpdate += (_, _) => - { - // Resets selection doc change - Parent?.Send(SELECTION_EVENT, new SelectionInfo()); - }; } private void OnSelectionChanged() diff --git a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoSendBinding.cs b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoSendBinding.cs index 7295f999d8..33adb7f6b0 100644 --- a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoSendBinding.cs +++ b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Bindings/RhinoSendBinding.cs @@ -8,7 +8,6 @@ using Speckle.Connectors.DUI.Bridge; using Speckle.Connectors.DUI.Models; using Speckle.Connectors.DUI.Models.Card; -using Speckle.Connectors.DUI.Utils; using Speckle.Connectors.Rhino7.HostApp; using Speckle.Connectors.Utils.Cancellation; using Speckle.Core.Logging; @@ -19,6 +18,7 @@ using Speckle.Connectors.DUI.Models.Card.SendFilter; using Speckle.Connectors.Utils.Operations; using Speckle.Core.Models; +using Speckle.Connectors.DUI.Settings; namespace Speckle.Connectors.Rhino7.Bindings; @@ -156,15 +156,14 @@ public async Task Send(string modelCardId) .Where(obj => obj != null) .ToList(); - var sendInfo = new SendInfo() - { - AccountId = modelCard.AccountId, - ProjectId = modelCard.ProjectId, - ModelId = modelCard.ModelId, - ConvertedObjects = _convertedObjectReferences, - ChangedObjectIds = modelCard.ChangedObjectIds, - SourceApplication = _rhinoSettings.HostAppInfo.Name - }; + var sendInfo = new SendInfo( + modelCard.AccountId, + modelCard.ProjectId, + modelCard.ModelId, + _rhinoSettings.HostAppInfo.Name, + _convertedObjectReferences, + modelCard.ChangedObjectIds + ); var sendResult = await unitOfWork.Service .Execute( diff --git a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Operations/Receive/RhinoHostObjectBuilder.cs b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Operations/Receive/RhinoHostObjectBuilder.cs index 61c75aa048..3e0e0d1d23 100644 --- a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Operations/Receive/RhinoHostObjectBuilder.cs +++ b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Operations/Receive/RhinoHostObjectBuilder.cs @@ -127,7 +127,7 @@ CancellationToken cancellationToken if (conversionExceptions.Count != 0) { - throw new AggregateException("Some conversions failed. Please check inner exceptions.", conversionExceptions); + throw new AggregateException("Conversion failed for some objects.", conversionExceptions); } return newObjectIds; diff --git a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Plugin/Speckle.Connectors.Rhino7Command.cs b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Plugin/Speckle.Connectors.Rhino7Command.cs index 6bfe6166a9..751213cb0e 100644 --- a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Plugin/Speckle.Connectors.Rhino7Command.cs +++ b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Plugin/Speckle.Connectors.Rhino7Command.cs @@ -1,9 +1,10 @@ -using System; +using System; using Rhino; using Rhino.Commands; using Rhino.Input.Custom; using Rhino.UI; using Speckle.Connectors.Rhino7.HostApp; +using Speckle.Connectors.Rhino7.Properties; namespace Speckle.Connectors.Rhino7.Plugin; @@ -17,8 +18,8 @@ public SpeckleConnectorsRhino7Command() Panels.RegisterPanel( SpeckleConnectorsRhino7Plugin.Instance, typeof(SpeckleRhinoPanelHost), - "SpeckleRhino7DUI3", - System.Drawing.SystemIcons.Information, + "Speckle (New UI)", + Resources.speckle32, PanelType.System ); } diff --git a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Plugin/Speckle.Connectors.Rhino7Plugin.cs b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Plugin/Speckle.Connectors.Rhino7Plugin.cs index 0fcc3e9121..a4abed8dc4 100644 --- a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Plugin/Speckle.Connectors.Rhino7Plugin.cs +++ b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Plugin/Speckle.Connectors.Rhino7Plugin.cs @@ -25,6 +25,7 @@ public class SpeckleConnectorsRhino7Plugin : PlugIn { private IRhinoPlugin? _rhinoPlugin; + protected override string LocalPlugInName => "Speckle (New UI)"; public AutofacContainer? Container { get; private set; } public SpeckleConnectorsRhino7Plugin() diff --git a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Properties/AssemblyInfo.cs b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Properties/AssemblyInfo.cs index 88eada7ed2..abbb317629 100644 --- a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Properties/AssemblyInfo.cs +++ b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Properties/AssemblyInfo.cs @@ -1,20 +1,23 @@ -using System.Runtime.InteropServices; +using System.Resources; +using System.Runtime.InteropServices; using Rhino.PlugIns; // Plug-in Description Attributes - all of these are optional. // These will show in Rhino's option dialog, in the tab Plug-ins. [assembly: PlugInDescription(DescriptionType.Address, "")] [assembly: PlugInDescription(DescriptionType.Country, "")] -[assembly: PlugInDescription(DescriptionType.Email, "")] +[assembly: PlugInDescription(DescriptionType.Email, "hello@speckle.systems")] [assembly: PlugInDescription(DescriptionType.Phone, "")] [assembly: PlugInDescription(DescriptionType.Fax, "")] -[assembly: PlugInDescription(DescriptionType.Organization, "")] +[assembly: PlugInDescription(DescriptionType.Organization, "Speckle Systems Ltd.")] [assembly: PlugInDescription(DescriptionType.UpdateUrl, "")] -[assembly: PlugInDescription(DescriptionType.WebSite, "")] +[assembly: PlugInDescription(DescriptionType.WebSite, "https://speckle.systems")] // Icons should be Windows .ico files and contain 32-bit images in the following sizes: 16, 24, 32, 48, and 256. -[assembly: PlugInDescription(DescriptionType.Icon, "Speckle.Connectors.Rhino7.EmbeddedResources.plugin-utility.ico")] +[assembly: PlugInDescription(DescriptionType.Icon, "Speckle.Connectors.Rhino7.Resources.speckle32.ico")] // The following GUID is for the ID of the typelib if this project is exposed to COM // This will also be the Guid of the Rhino plug-in [assembly: Guid("2153799A-0CEC-40DE-BC3A-01E5055222FF")] + +[assembly: NeutralResourcesLanguage("en")] diff --git a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Properties/Resources.Designer.cs b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Properties/Resources.Designer.cs new file mode 100644 index 0000000000..ec3cee7dbb --- /dev/null +++ b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Properties/Resources.Designer.cs @@ -0,0 +1,83 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Speckle.Connectors.Rhino7.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Speckle.Connectors.Rhino7.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap logo32 { + get { + object obj = ResourceManager.GetObject("logo32", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + internal static System.Drawing.Icon speckle32 { + get { + object obj = ResourceManager.GetObject("speckle32", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + } +} diff --git a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Properties/Resources.resx b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Properties/Resources.resx new file mode 100644 index 0000000000..61bb1d8964 --- /dev/null +++ b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Properties/Resources.resx @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\logo32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\speckle32.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Resources/logo32.png b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Resources/logo32.png new file mode 100644 index 0000000000..39074dca39 Binary files /dev/null and b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Resources/logo32.png differ diff --git a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Resources/speckle32.ico b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Resources/speckle32.ico new file mode 100644 index 0000000000..87c4f42107 Binary files /dev/null and b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Resources/speckle32.ico differ diff --git a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Speckle.Connectors.Rhino7.csproj b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Speckle.Connectors.Rhino7.csproj index de5305a768..05d6c4f816 100644 --- a/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Speckle.Connectors.Rhino7.csproj +++ b/DUI3-DX/Connectors/Rhino/Speckle.Connectors.Rhino7/Speckle.Connectors.Rhino7.csproj @@ -13,22 +13,38 @@ - + + - - - - + + + + - - - - - + + + + + + + + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + diff --git a/DUI3-DX/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Geometry/PolycurveToHostConverter.cs b/DUI3-DX/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Geometry/PolycurveToHostConverter.cs index 73e87bbd76..6a10f2bbc5 100644 --- a/DUI3-DX/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Geometry/PolycurveToHostConverter.cs +++ b/DUI3-DX/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Geometry/PolycurveToHostConverter.cs @@ -8,7 +8,7 @@ namespace Speckle.Converters.AutocadShared.ToHost.Geometry; /// /// A polycurve has segments as list and it can contain different kind of ICurve objects like Arc, Line, Polyline, Curve etc.. -/// If polycurve segments is consist of only with Arcs and Lines, it can be represented as Polyline in Autucad. +/// If polycurve segments are planar and only of type and , it can be represented as Polyline in Autocad. /// Otherwise we convert it as spline (list of ADB.Entity) that switch cases according to each segment type. /// [NameAndRankValue(nameof(SOG.Polycurve), NameAndRankValueAttribute.SPECKLE_DEFAULT_RANK)] @@ -45,13 +45,12 @@ public object Convert(Base target) private bool IsPolycurvePlanar(SOG.Polycurve polycurve) { double? z = null; - foreach (var segment in polycurve.segments) + foreach (Objects.ICurve segment in polycurve.segments) { switch (segment) { case SOG.Line o: z ??= o.start.z; - if (o.start.z != z || o.end.z != z) { return false; @@ -60,7 +59,6 @@ private bool IsPolycurvePlanar(SOG.Polycurve polycurve) break; case SOG.Arc o: z ??= o.startPoint.z; - if (o.startPoint.z != z || o.midPoint.z != z || o.endPoint.z != z) { return false; @@ -69,7 +67,6 @@ private bool IsPolycurvePlanar(SOG.Polycurve polycurve) break; case SOG.Curve o: z ??= o.points[2]; - for (int i = 2; i < o.points.Count; i += 3) { if (o.points[i] != z) @@ -81,7 +78,6 @@ private bool IsPolycurvePlanar(SOG.Polycurve polycurve) break; case SOG.Spiral o: z ??= o.startPoint.z; - if (o.startPoint.z != z || o.endPoint.z != z) { return false; diff --git a/DUI3-DX/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Raw/PolycurveToHostPolylineRawConverter.cs b/DUI3-DX/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Raw/PolycurveToHostPolylineRawConverter.cs index 1bbe733549..874feb8908 100644 --- a/DUI3-DX/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Raw/PolycurveToHostPolylineRawConverter.cs +++ b/DUI3-DX/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Raw/PolycurveToHostPolylineRawConverter.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using Speckle.Converters.Common; using Speckle.Converters.Common.Objects; @@ -25,13 +26,14 @@ public PolycurveToHostPolylineRawConverter( public ADB.Polyline RawConvert(SOG.Polycurve target) { ADB.Polyline polyline = new() { Closed = target.closed }; - var plane = new AG.Plane( - AG.Point3d.Origin, - AG.Vector3d.ZAxis.TransformBy(_contextStack.Current.Document.Editor.CurrentUserCoordinateSystem) - ); + AG.Plane plane = + new( + AG.Point3d.Origin, + AG.Vector3d.ZAxis.TransformBy(_contextStack.Current.Document.Editor.CurrentUserCoordinateSystem) + ); int count = 0; - foreach (var segment in target.segments) + foreach (Objects.ICurve segment in target.segments) { switch (segment) { @@ -46,12 +48,13 @@ public ADB.Polyline RawConvert(SOG.Polycurve target) break; case SOG.Arc arc: // POC: possibly endAngle and startAngle null? - var angle = arc.endAngle - arc.startAngle; + double? angle = arc.endAngle - arc.startAngle; angle = angle < 0 ? angle + 2 * Math.PI : angle; if (angle is null) { throw new ArgumentNullException(nameof(arc), "Cannot convert arc without angle value."); } + var bulge = Math.Tan((double)angle / 4) * BulgeDirection(arc.startPoint, arc.midPoint, arc.endPoint); polyline.AddVertexAt(count, _pointConverter.RawConvert(arc.startPoint).Convert2d(plane), bulge, 0, 0); if (!target.closed && count == target.segments.Count - 1) @@ -62,12 +65,13 @@ public ADB.Polyline RawConvert(SOG.Polycurve target) count++; break; case SOG.Spiral o: - var vertices = o.displayValue.GetPoints().Select(_pointConverter.RawConvert).ToList(); - foreach (var vertex in vertices) + List vertices = o.displayValue.GetPoints().Select(_pointConverter.RawConvert).ToList(); + foreach (AG.Point3d vertex in vertices) { polyline.AddVertexAt(count, vertex.Convert2d(plane), 0, 0, 0); count++; } + break; default: break; @@ -87,13 +91,6 @@ private int BulgeDirection(SOG.Point start, SOG.Point mid, SOG.Point end) // calculate cross product z direction double z = v1[0] * v2[1] - v2[0] * v1[1]; - if (z > 0) - { - return -1; - } - else - { - return 1; - } + return z > 0 ? -1 : 1; } } diff --git a/DUI3-DX/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/Polyline2dToSpeckleConverter.cs b/DUI3-DX/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/Polyline2dToSpeckleConverter.cs index 9902877848..9091a7b06d 100644 --- a/DUI3-DX/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/Polyline2dToSpeckleConverter.cs +++ b/DUI3-DX/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/Polyline2dToSpeckleConverter.cs @@ -156,7 +156,7 @@ public SOG.Autocad.AutocadPolycurve RawConvert(ADB.Polyline2d target) } } - // for splines, convert the spline curve and display value and add to the segments list and + // for splines, convert the spline curve and display value and add to the segments list if (isSpline) { SOG.Curve spline = _splineConverter.RawConvert(target.Spline); diff --git a/DUI3-DX/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/Polyline3dToSpeckleConverter.cs b/DUI3-DX/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/Polyline3dToSpeckleConverter.cs index 346a6f2729..fff827612e 100644 --- a/DUI3-DX/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/Polyline3dToSpeckleConverter.cs +++ b/DUI3-DX/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/Polyline3dToSpeckleConverter.cs @@ -4,7 +4,6 @@ using Speckle.Core.Models; using Speckle.Converters.Autocad.Extensions; using System.Linq; -using Autodesk.AutoCAD.Geometry; namespace Speckle.Converters.Autocad.Geometry; @@ -12,7 +11,7 @@ namespace Speckle.Converters.Autocad.Geometry; /// The class converter. Converts to . /// /// -/// of type will have only s in . +/// of type will have only one in . /// of type and will have only one in . /// The IHostObjectToSpeckleConversion inheritance should only expect database-resident Polyline2d objects. IRawConversion inheritance can expect non database-resident objects, when generated from other converters. /// @@ -65,53 +64,54 @@ public SOG.Autocad.AutocadPolycurve RawConvert(ADB.Polyline3d target) ) .Where(e => e.VertexType != ADB.Vertex3dType.FitVertex) // Do not collect fit vertex points, they are not used for creation .ToList(); - - List segments = new(); for (int i = 0; i < vertices.Count; i++) { - Point3d vertex = vertices[i].Position; + // vertex value is in the Global Coordinate System (GCS). + value.AddRange(vertices[i].Position.ToArray()); + } - // get vertex value in the Global Coordinate System (GCS). - value.AddRange(vertex.ToArray()); + List segments = new(); + // for spline polyline3ds, get the spline curve segment + // and explode the curve to get the spline displayvalue + if (target.PolyType is not ADB.Poly3dType.SimplePoly) + { + // get the spline segment + SOG.Curve spline = _splineConverter.RawConvert(target.Spline); - // construct the segment lines if this is a simple poly - if (i < vertices.Count - 1) + // get the spline displayvalue by exploding the polyline + List segmentValues = new(); + ADB.DBObjectCollection exploded = new(); + target.Explode(exploded); + for (int i = 0; i < exploded.Count; i++) { - if (polyType is SOG.Autocad.AutocadPolyType.Simple3d) + if (exploded[i] is ADB.Curve segment) { - var nextVertex = vertices[i + 1].Position; - SOG.Point start = _pointConverter.RawConvert(vertex); - SOG.Point end = _pointConverter.RawConvert(nextVertex); - - SOG.Line segment = new(start, end, _contextStack.Current.SpeckleUnits); - segments.Add(segment); + segmentValues.AddRange(segment.StartPoint.ToArray()); + if (i == exploded.Count - 1) + { + segmentValues.AddRange(segment.EndPoint.ToArray()); + } } } - } - // get the spline curve segment if this is a spline polyline3d - if (polyType is not SOG.Autocad.AutocadPolyType.Simple3d) - { - // add first 3 coordinate to last for display value polyline for spline - if (target.Closed) + SOG.Polyline displayValue = segmentValues.ConvertToSpecklePolyline(_contextStack.Current.SpeckleUnits); + if (displayValue != null) { - var firstPoint = value.Take(3).ToList(); - value.AddRange(firstPoint); + spline.displayValue = displayValue; } - SOG.Curve spline = _splineConverter.RawConvert(target.Spline); - spline.displayValue = value.ConvertToSpecklePolyline(_contextStack.Current.SpeckleUnits); - segments.Add(spline); } + // for simple polyline3ds just get the polyline segment from the value else { + SOG.Polyline polyline = value.ConvertToSpecklePolyline(_contextStack.Current.SpeckleUnits); if (target.Closed) { - SOG.Point start = _pointConverter.RawConvert(vertices.First().Position); - SOG.Point end = _pointConverter.RawConvert(vertices.Last().Position); - segments.Add(new SOG.Line(start, end, _contextStack.Current.SpeckleUnits)); + polyline.closed = true; } + + segments.Add(polyline); } SOG.Box bbox = _boxConverter.RawConvert(target.GeometricExtents); diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.DependencyInjection/AutofacRevitConverterModule.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.DependencyInjection/AutofacRevitConverterModule.cs index 93e4001ae2..f8399dc827 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.DependencyInjection/AutofacRevitConverterModule.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.Revit2023.DependencyInjection/AutofacRevitConverterModule.cs @@ -33,11 +33,7 @@ protected override void Load(ContainerBuilder builder) builder.RegisterType().AsSelf().InstancePerLifetimeScope(); // POC: the concrete type can come out if we remove all the reference to it - builder - .RegisterType() - .As() - .AsSelf() - .InstancePerLifetimeScope(); + builder.RegisterType().As().InstancePerLifetimeScope(); builder .RegisterType() diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/GlobalUsings.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/GlobalUsings.cs index 4839a81393..5a7a8f20bd 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/GlobalUsings.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/GlobalUsings.cs @@ -1,6 +1,5 @@ global using DB = Autodesk.Revit.DB; global using DBA = Autodesk.Revit.DB.Architecture; -global using UI = Autodesk.Revit.UI; global using SOG = Objects.Geometry; global using SOBR = Objects.BuiltElements.Revit; global using SOBE = Objects.BuiltElements; diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/IRevitConversionContextStack.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/IRevitConversionContextStack.cs index af3e959715..1cf5d4b80c 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/IRevitConversionContextStack.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/IRevitConversionContextStack.cs @@ -10,4 +10,4 @@ namespace Speckle.Converters.RevitShared.Helpers; )] // POC: so this should *probably* be Document and NOT UI.UIDocument, the former is Conversion centric // and the latter is more for connector -public interface IRevitConversionContextStack : IConversionContextStack { } +public interface IRevitConversionContextStack : IConversionContextStack { } diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/RevitConversionContextStack.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/RevitConversionContextStack.cs index 9b20274ae0..ce43a88901 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/RevitConversionContextStack.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/RevitConversionContextStack.cs @@ -10,9 +10,7 @@ namespace Speckle.Converters.RevitShared.Helpers; )] // POC: so this should *probably* be Document and NOT UI.UIDocument, the former is Conversion centric // and the latter is more for connector -public class RevitConversionContextStack - : ConversionContextStack, - IRevitConversionContextStack +public class RevitConversionContextStack : ConversionContextStack, IRevitConversionContextStack { public const double TOLERANCE = 0.0164042; // 5mm in ft @@ -22,7 +20,7 @@ public RevitConversionContextStack(RevitContext context, IHostToSpeckleUnitConve // so should this perpetuate or do we assume this is valid? // relting on the context.UIApplication?.ActiveUIDocument is not right // this should be some IActiveDocument I suspect? - context.UIApplication?.ActiveUIDocument + context.UIApplication?.ActiveUIDocument?.Document ?? throw new SpeckleConversionException("Active UI document could not be determined"), context.UIApplication.ActiveUIDocument.Document.GetUnits().GetFormatOptions(SpecTypeId.Length).GetUnitTypeId(), unitConverter diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/ToSpeckleConvertedObjectsCache.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/ToSpeckleConvertedObjectsCache.cs index bf8a54a384..c4c91d9fb8 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/ToSpeckleConvertedObjectsCache.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Helpers/ToSpeckleConvertedObjectsCache.cs @@ -17,4 +17,9 @@ public bool ContainsBaseConvertedFromId(string revitUniqueId) { return _uniqueIdToConvertedBaseDict.ContainsKey(revitUniqueId); } + + public bool TryGetConvertedBase(string revitUniqueId, out Base? value) + { + return _uniqueIdToConvertedBaseDict.TryGetValue(revitUniqueId, out value); + } } diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ColumnConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ColumnConversionToSpeckle.cs index f9daa14b1e..f50bea3ec5 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ColumnConversionToSpeckle.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ColumnConversionToSpeckle.cs @@ -16,7 +16,7 @@ public class ColumnConversionToSpeckle : IRawConversion _levelConverter; private readonly ParameterValueExtractor _parameterValueExtractor; private readonly DisplayValueExtractor _displayValueExtractor; - private readonly RevitConversionContextStack _contextStack; + private readonly IRevitConversionContextStack _contextStack; private readonly ParameterObjectAssigner _parameterObjectAssigner; public ColumnConversionToSpeckle( @@ -24,7 +24,7 @@ public ColumnConversionToSpeckle( IRawConversion levelConverter, ParameterValueExtractor parameterValueExtractor, DisplayValueExtractor displayValueExtractor, - RevitConversionContextStack contextStack, + IRevitConversionContextStack contextStack, ParameterObjectAssigner parameterObjectAssigner ) { diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/CurveArrayConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/CurveArrayConversionToSpeckle.cs index a4d5f4fc67..327be89dbf 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/CurveArrayConversionToSpeckle.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/CurveArrayConversionToSpeckle.cs @@ -9,12 +9,12 @@ namespace Speckle.Converters.RevitShared.ToSpeckle; public sealed class CurveArrayConversionToSpeckle : IRawConversion { - private readonly RevitConversionContextStack _contextStack; + private readonly IRevitConversionContextStack _contextStack; private readonly ScalingServiceToSpeckle _scalingService; private readonly IRawConversion _curveConverter; public CurveArrayConversionToSpeckle( - RevitConversionContextStack contextStack, + IRevitConversionContextStack contextStack, ScalingServiceToSpeckle scalingService, IRawConversion curveConverter ) diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/LineConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/LineConversionToSpeckle.cs index 847be282a5..fd00f57360 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/LineConversionToSpeckle.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/LineConversionToSpeckle.cs @@ -7,12 +7,12 @@ namespace Speckle.Converters.RevitShared.ToSpeckle; public class LineConversionToSpeckle : IRawConversion { - private readonly RevitConversionContextStack _contextStack; + private readonly IRevitConversionContextStack _contextStack; private readonly IRawConversion _xyzToPointConverter; private readonly ScalingServiceToSpeckle _scalingService; public LineConversionToSpeckle( - RevitConversionContextStack contextStack, + IRevitConversionContextStack contextStack, IRawConversion xyzToPointConverter, ScalingServiceToSpeckle scalingService ) diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/MeshByMaterialDictionaryToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/MeshByMaterialDictionaryToSpeckle.cs index 2a1e71adf8..f9d7d760df 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/MeshByMaterialDictionaryToSpeckle.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/MeshByMaterialDictionaryToSpeckle.cs @@ -6,13 +6,13 @@ namespace Speckle.Converters.RevitShared.ToSpeckle; public class MeshByMaterialDictionaryToSpeckle : IRawConversion>, List> { - private readonly RevitConversionContextStack _contextStack; + private readonly IRevitConversionContextStack _contextStack; private readonly IRawConversion _xyzToPointConverter; private readonly IRawConversion _materialConverter; public MeshByMaterialDictionaryToSpeckle( IRawConversion materialConverter, - RevitConversionContextStack contextStack, + IRevitConversionContextStack contextStack, IRawConversion xyzToPointConverter ) { @@ -53,7 +53,7 @@ public MeshByMaterialDictionaryToSpeckle( units: _contextStack.Current.SpeckleUnits ); - var doc = _contextStack.Current.Document.Document; + var doc = _contextStack.Current.Document; if (doc.GetElement(materialId) is DB.Material material) { speckleMesh["renderMaterial"] = _materialConverter.RawConvert(material); diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/MeshConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/MeshConversionToSpeckle.cs index 55ef357c86..635537ea78 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/MeshConversionToSpeckle.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/MeshConversionToSpeckle.cs @@ -8,10 +8,10 @@ public class MeshConversionToSpeckle : IRawConversion { private readonly IRawConversion _xyzToPointConverter; private readonly IRawConversion _materialConverter; - private readonly RevitConversionContextStack _contextStack; + private readonly IRevitConversionContextStack _contextStack; public MeshConversionToSpeckle( - RevitConversionContextStack contextStack, + IRevitConversionContextStack contextStack, IRawConversion xyzToPointConverter, IRawConversion materialConverter ) @@ -23,7 +23,7 @@ public MeshConversionToSpeckle( public SOG.Mesh RawConvert(DB.Mesh target) { - var doc = _contextStack.Current.Document.Document; + var doc = _contextStack.Current.Document; List vertices = GetSpeckleMeshVertexData(target); List faces = GetSpeckleMeshFaceData(target); diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/XyzConversionToPoint.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/XyzConversionToPoint.cs index c4e0268611..4322f45094 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/XyzConversionToPoint.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/Geometry/XyzConversionToPoint.cs @@ -7,9 +7,12 @@ namespace Speckle.Converters.RevitShared.ToSpeckle; public class XyzConversionToPoint : IRawConversion { private readonly ScalingServiceToSpeckle _toSpeckleScalingService; - private readonly RevitConversionContextStack _contextStack; + private readonly IRevitConversionContextStack _contextStack; - public XyzConversionToPoint(ScalingServiceToSpeckle toSpeckleScalingService, RevitConversionContextStack contextStack) + public XyzConversionToPoint( + ScalingServiceToSpeckle toSpeckleScalingService, + IRevitConversionContextStack contextStack + ) { _toSpeckleScalingService = toSpeckleScalingService; _contextStack = contextStack; diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ModelCurveArrayToSpeckleConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ModelCurveArrayToSpeckleConverter.cs index b6131fd7b6..c91e343f68 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ModelCurveArrayToSpeckleConverter.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Raw/ModelCurveArrayToSpeckleConverter.cs @@ -8,12 +8,12 @@ namespace Speckle.Converters.RevitShared.Raw; internal class ModelCurveArrayToSpeckleConverter : IRawConversion { - private readonly RevitConversionContextStack _contextStack; + private readonly IRevitConversionContextStack _contextStack; private readonly ScalingServiceToSpeckle _scalingService; private readonly IRawConversion _curveConverter; public ModelCurveArrayToSpeckleConverter( - RevitConversionContextStack contextStack, + IRevitConversionContextStack contextStack, ScalingServiceToSpeckle scalingService, IRawConversion curveConverter ) diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ReferencePointConverter.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ReferencePointConverter.cs index 89e4e35b80..89d68bb58f 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ReferencePointConverter.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ReferencePointConverter.cs @@ -29,7 +29,7 @@ public ReferencePointConverter(IRevitConversionContextStack contextStack, RevitC // doc can change during the lifeycycle of the conversions. This may need some looking into public DB.XYZ ConvertToExternalCoordindates(DB.XYZ inbound, bool isPoint) { - var rpt = GetDocReferencePointTransform(_contextStack.Current.Document.Document); + var rpt = GetDocReferencePointTransform(_contextStack.Current.Document); return isPoint ? rpt.OfPoint(inbound) : rpt.OfVector(inbound); } @@ -60,7 +60,7 @@ public DB.Transform GetReferencePointTransform(string referencePointSetting) // POC: bogus disposal below #pragma warning disable CA2000 - var points = new DB.FilteredElementCollector(_contextStack.Current.Document.Document) + var points = new DB.FilteredElementCollector(_contextStack.Current.Document) .OfClass(typeof(DB.BasePoint)) .Cast() .ToList(); diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/RevitConverterToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/RevitConverterToSpeckle.cs index 0a07f8dfba..540cd4ccad 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/RevitConverterToSpeckle.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/RevitConverterToSpeckle.cs @@ -45,17 +45,6 @@ public Base Convert(object target) // POC: is this the right place? result.applicationId = element.UniqueId; - try - { - _convertedObjectsCache.AddConvertedBase(element.UniqueId, result); - } - catch (ArgumentException) - { - // POC: object converted multiple times - // we are doing this all the time in our current converter, and the serializer is fixing it for us. - // so for now, I am just silencing this exception - // https://spockle.atlassian.net/browse/CNX-9402 - } _parameterValueExtractor.RemoveUniqueId(element.UniqueId); } diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Services/ScalingServiceToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Services/ScalingServiceToSpeckle.cs index d036ff33c5..a0c2779048 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Services/ScalingServiceToSpeckle.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/Services/ScalingServiceToSpeckle.cs @@ -10,10 +10,10 @@ public sealed class ScalingServiceToSpeckle private readonly double _defaultLengthConversionFactor; // POC: this seems like the reverse relationship - public ScalingServiceToSpeckle(RevitConversionContextStack contextStack) + public ScalingServiceToSpeckle(IRevitConversionContextStack contextStack) { // POC: this is accurate for the current context stack - Units documentUnits = contextStack.Current.Document.Document.GetUnits(); + Units documentUnits = contextStack.Current.Document.GetUnits(); FormatOptions formatOptions = documentUnits.GetFormatOptions(SpecTypeId.Length); var lengthUnitsTypeId = formatOptions.GetUnitTypeId(); _defaultLengthConversionFactor = ScaleStatic(1, lengthUnitsTypeId); diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/DirectShapeConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/DirectShapeConversionToSpeckle.cs index 35bf7b2a94..2e6340e853 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/DirectShapeConversionToSpeckle.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/DirectShapeConversionToSpeckle.cs @@ -9,13 +9,13 @@ namespace Speckle.Converters.Revit2023.ToSpeckle; [NameAndRankValue(nameof(DB.DirectShape), NameAndRankValueAttribute.SPECKLE_DEFAULT_RANK)] public class DirectShapeConversionToSpeckle : BaseConversionToSpeckle { - private readonly RevitConversionContextStack _contextStack; + private readonly IRevitConversionContextStack _contextStack; private readonly ParameterObjectAssigner _parameterObjectAssigner; private readonly DisplayValueExtractor _displayValueExtractor; public DirectShapeConversionToSpeckle( ParameterObjectAssigner parameterObjectAssigner, - RevitConversionContextStack contextStack, + IRevitConversionContextStack contextStack, DisplayValueExtractor displayValueExtractor ) { diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/HostedElementConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/HostedElementConversionToSpeckle.cs index 45388c02ee..5709bba293 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/HostedElementConversionToSpeckle.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/HostedElementConversionToSpeckle.cs @@ -13,12 +13,12 @@ public class HostedElementConversionToSpeckle { private readonly ToSpeckleConvertedObjectsCache _convertedObjectsCache; private readonly ISpeckleConverterToSpeckle _converter; - private readonly RevitConversionContextStack _contextStack; + private readonly IRevitConversionContextStack _contextStack; public HostedElementConversionToSpeckle( ToSpeckleConvertedObjectsCache convertedObjectsCache, ISpeckleConverterToSpeckle converter, - RevitConversionContextStack contextStack + IRevitConversionContextStack contextStack ) { _convertedObjectsCache = convertedObjectsCache; @@ -30,11 +30,7 @@ public IEnumerable ConvertHostedElements(IEnumerable hostedElem { foreach (var elemId in hostedElementIds) { - Element element = _contextStack.Current.Document.Document.GetElement(elemId); - if (_convertedObjectsCache.ContainsBaseConvertedFromId(element.UniqueId)) - { - continue; - } + Element element = _contextStack.Current.Document.GetElement(elemId); Base @base; try diff --git a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/WallConversionToSpeckle.cs b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/WallConversionToSpeckle.cs index 9ea1acb847..f69d6a14b5 100644 --- a/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/WallConversionToSpeckle.cs +++ b/DUI3-DX/Converters/Revit/Speckle.Converters.RevitShared/ToSpeckle/WallConversionToSpeckle.cs @@ -18,7 +18,7 @@ public class WallConversionToSpeckle : BaseConversionToSpeckle _levelConverter; private readonly IRawConversion> _curveArrArrayConverter; private readonly ParameterValueExtractor _parameterValueExtractor; - private readonly RevitConversionContextStack _contextStack; + private readonly IRevitConversionContextStack _contextStack; private readonly DisplayValueExtractor _displayValueExtractor; private readonly ParameterObjectAssigner _parameterObjectAssigner; private readonly ISpeckleConverterToSpeckle _converter; @@ -27,7 +27,7 @@ public WallConversionToSpeckle( IRawConversion curveConverter, IRawConversion levelConverter, IRawConversion> curveArrArrayConverter, - RevitConversionContextStack contextStack, + IRevitConversionContextStack contextStack, ParameterValueExtractor parameterValueExtractor, DisplayValueExtractor displayValueExtractor, ParameterObjectAssigner parameterObjectAssigner, @@ -124,7 +124,7 @@ private IEnumerable ConvertElements(IEnumerable elementIds) { foreach (DB.ElementId elementId in elementIds) { - yield return _converter.Convert(_contextStack.Current.Document.Document.GetElement(elementId)); + yield return _converter.Convert(_contextStack.Current.Document.GetElement(elementId)); } } diff --git a/DUI3-DX/DUI3/Speckle.Connectors.DUI/Bindings/IBinding.cs b/DUI3-DX/DUI3/Speckle.Connectors.DUI/Bindings/IBinding.cs index 88382706cb..bfaacb7c7c 100644 --- a/DUI3-DX/DUI3/Speckle.Connectors.DUI/Bindings/IBinding.cs +++ b/DUI3-DX/DUI3/Speckle.Connectors.DUI/Bindings/IBinding.cs @@ -16,7 +16,7 @@ public interface IBinding /// /// Bindings will be wrapped by a browser specific bridge, and they will need - /// to use that bridge to send events to the Frontend, via SendToBrowser(IHostAppEvent) or SendToBrowser(string). + /// to use that bridge to send events to the Frontend, via SendToBrowser(IHostAppEvent). /// TODO: we'll probably need a factory class of sorts to handle the proper wrapping. Currently, on bridge instantiation the parent is set in the bindings class that has been wrapped around. Not vvv elegant. /// public IBridge Parent { get; } diff --git a/DUI3-DX/DUI3/Speckle.Connectors.DUI/Bridge/BrowserBridge.cs b/DUI3-DX/DUI3/Speckle.Connectors.DUI/Bridge/BrowserBridge.cs index 276556a18e..c5cfb065cc 100644 --- a/DUI3-DX/DUI3/Speckle.Connectors.DUI/Bridge/BrowserBridge.cs +++ b/DUI3-DX/DUI3/Speckle.Connectors.DUI/Bridge/BrowserBridge.cs @@ -71,9 +71,10 @@ private struct RunMethodArgs } /// - /// Creates a new bridge. + /// Initializes a new instance of the class. /// - /// The actual binding class. + /// The settings to use for JSON serialization and deserialization. + /// The factory to create a logger for . public BrowserBridge(JsonSerializerSettings jsonSerializerSettings, ILoggerFactory loggerFactory) { _serializerOptions = jsonSerializerSettings; @@ -119,7 +120,6 @@ Action showDevToolsAction } ); - // _logger.LogInformation("Bridge bound to front end name {FrontEndName}", binding.Name); } @@ -212,13 +212,10 @@ private void ExecuteMethod(string methodName, string requestId, string args) var resultTyped = method.Invoke(Binding, typedArgs); - // Was it an async method (in bridgeClass?) - var resultTypedTask = resultTyped as Task; - string resultJson; // Was the method called async? - if (resultTypedTask == null) + if (resultTyped is not Task resultTypedTask) { // Regular method: no need to await things resultJson = JsonConvert.SerializeObject(resultTyped, _serializerOptions); diff --git a/DUI3-DX/DUI3/Speckle.Connectors.DUI/Models/Card/ModelCard.cs b/DUI3-DX/DUI3/Speckle.Connectors.DUI/Models/Card/ModelCard.cs index 29be3e792e..e883ff8d22 100644 --- a/DUI3-DX/DUI3/Speckle.Connectors.DUI/Models/Card/ModelCard.cs +++ b/DUI3-DX/DUI3/Speckle.Connectors.DUI/Models/Card/ModelCard.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using Speckle.Connectors.DUI.Settings; using Speckle.Connectors.DUI.Utils; namespace Speckle.Connectors.DUI.Models.Card; diff --git a/DUI3-DX/DUI3/Speckle.Connectors.DUI/Settings/CardSetting.cs b/DUI3-DX/DUI3/Speckle.Connectors.DUI/Settings/CardSetting.cs index 5ce5fd83fb..b7cc2bf382 100644 --- a/DUI3-DX/DUI3/Speckle.Connectors.DUI/Settings/CardSetting.cs +++ b/DUI3-DX/DUI3/Speckle.Connectors.DUI/Settings/CardSetting.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; +using Speckle.Connectors.DUI.Utils; -namespace Speckle.Connectors.DUI.Utils; +namespace Speckle.Connectors.DUI.Settings; public class CardSetting : DiscriminatedObject { diff --git a/DUI3-DX/DUI3/Speckle.Connectors.DUI/Utils/DiscriminatedObject.cs b/DUI3-DX/DUI3/Speckle.Connectors.DUI/Utils/DiscriminatedObject.cs index b7385bbff6..e0d341c6b6 100644 --- a/DUI3-DX/DUI3/Speckle.Connectors.DUI/Utils/DiscriminatedObject.cs +++ b/DUI3-DX/DUI3/Speckle.Connectors.DUI/Utils/DiscriminatedObject.cs @@ -2,7 +2,7 @@ namespace Speckle.Connectors.DUI.Utils; /// /// Any polymorphic type base should inherit from this class in order for it to be properly deserialized. -/// - Class inheritance scenario For example, if you have a base class BaseSettings, and from it you create RhinoBaseSettings & AutocadBaseSettings, the BaseSetting class should inherit from this class. +/// - Class inheritance scenario For example, if you have a base class BaseSettings, and from it you create RhinoBaseSettings and AutocadBaseSettings, the BaseSetting class should inherit from this class. /// - Interface scenario: you have an ISenderCard interface, which you implement as ReceiverCard and SenderCard. Both ReceiverCard and SenderCard should inherit from this class. /// /// POC: should probaby be changed to attribute instead of inheritence? TBC diff --git a/DUI3-DX/DUI3/Speckle.Connectors.DUI/Utils/DiscriminatedObjectConverter.cs b/DUI3-DX/DUI3/Speckle.Connectors.DUI/Utils/DiscriminatedObjectConverter.cs index faca3fe869..42d6bd145b 100644 --- a/DUI3-DX/DUI3/Speckle.Connectors.DUI/Utils/DiscriminatedObjectConverter.cs +++ b/DUI3-DX/DUI3/Speckle.Connectors.DUI/Utils/DiscriminatedObjectConverter.cs @@ -11,8 +11,7 @@ namespace Speckle.Connectors.DUI.Utils; /// -/// This converter ensures we can do polymorphic deserialization to concrete types. It is automatically added to all -/// serialization settings from . This converter is intended +/// This converter ensures we can do polymorphic deserialization to concrete types. This converter is intended /// for use only with UI bound types, not Speckle Bases. /// // POC: automatic registration of compatible objects @@ -85,8 +84,6 @@ JsonSerializer serializer // then we can cache everything on startup foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies().Reverse()) { - List? types; - try { // POC: contains is weak diff --git a/DUI3-DX/Sdk/Speckle.Connectors.Utils/Operations/SendInfo.cs b/DUI3-DX/Sdk/Speckle.Connectors.Utils/Operations/SendInfo.cs index 82b80722b9..be5f595a83 100644 --- a/DUI3-DX/Sdk/Speckle.Connectors.Utils/Operations/SendInfo.cs +++ b/DUI3-DX/Sdk/Speckle.Connectors.Utils/Operations/SendInfo.cs @@ -3,12 +3,30 @@ namespace Speckle.Connectors.Utils.Operations; -public struct SendInfo +public readonly struct SendInfo { - public string AccountId { get; set; } - public string ProjectId { get; set; } - public string ModelId { get; set; } - public string SourceApplication { get; set; } - public Dictionary ConvertedObjects { get; set; } - public HashSet ChangedObjectIds { get; set; } + public SendInfo( + string accountId, + string projectId, + string modelId, + string sourceApplication, + IReadOnlyDictionary convertedObjects, + ISet changedObjectIds + ) + { + AccountId = accountId; + ProjectId = projectId; + ModelId = modelId; + SourceApplication = sourceApplication; + ConvertedObjects = convertedObjects; + ChangedObjectIds = changedObjectIds; + } + + public string AccountId { get; } + public string ProjectId { get; } + public string ModelId { get; } + public string SourceApplication { get; } + public IReadOnlyDictionary ConvertedObjects { get; } + + public ISet ChangedObjectIds { get; } } diff --git a/DUI3-DX/Sdk/Speckle.Connectors.Utils/Operations/SendOperation.cs b/DUI3-DX/Sdk/Speckle.Connectors.Utils/Operations/SendOperation.cs index 6fa7c7b881..b29e9c9fc0 100644 --- a/DUI3-DX/Sdk/Speckle.Connectors.Utils/Operations/SendOperation.cs +++ b/DUI3-DX/Sdk/Speckle.Connectors.Utils/Operations/SendOperation.cs @@ -31,7 +31,9 @@ ISyncToMainThread syncToMainThread CancellationToken ct = default ) { - Base commitObject = _rootObjectBuilder.Build(objects, sendInfo, onOperationProgressed, ct); + Base commitObject = await _syncToMainThread + .RunOnThread(() => _rootObjectBuilder.Build(objects, sendInfo, onOperationProgressed, ct)) + .ConfigureAwait(false); // base object handler is separated so we can do some testing on non-production databases // exact interface may want to be tweaked when we implement this diff --git a/Directory.Build.props b/Directory.Build.props index 1633475efe..6d817ccfc9 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -38,7 +38,7 @@ CA1303;CA1304;CA1305;CA1307;CA1308;CA1309;CA1310;CA1311;CA2101; NU1701; - CA1815;CA1054;CA1852;CA1812;CA1003;CA2109;$(NoWarn) + CA1815;CA1054;CA1852;CA1812;CA1003;CA2109;CA1848;$(NoWarn)