Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 055cdb67a7 | |||
| bc57632f3d | |||
| d443d2149b | |||
| b8edac1072 | |||
| 155d53c740 | |||
| 90c9308b8b |
+26
-29
@@ -4,36 +4,33 @@
|
||||
|
||||
# * @specklesystems/connectors
|
||||
|
||||
# Core
|
||||
# Not needed, falls back on team approval
|
||||
|
||||
# Objects
|
||||
# Converters require product owner approval, anything else falls back to team approval
|
||||
|
||||
Objects/ConverterAutocadCivil/* @clairekuang @connorivy
|
||||
Objects/ConverterCSI/* @connorivy
|
||||
Objects/ConverterDynamo/* @teocomi @alanrynne
|
||||
Objects/ConverterMicrostation/* @connorivy
|
||||
Objects/ConverterRevit/* @connorivy @teocomi
|
||||
Objects/ConverterRhinoGh/* @alanrynne @clairekuang
|
||||
Objects/ConverterTeklaStructures/* @connorivy
|
||||
Objects/StructuralUtilities/PolygonMesher/* @connorivy
|
||||
|
||||
# Connectors
|
||||
|
||||
/Connectors/ArcGIS/* @KatKatKateryna
|
||||
/Connectors/Autocad/* @clairekuang @oguzhankoral @didimitrie
|
||||
/Connectors/Civil3d/* @clairekuang @oguzhankoral @didimitrie
|
||||
/Connectors/CSi/* @bjoernsteinhagen @dogukankaratas
|
||||
/Connectors/Navisworks/* @jsdbroughton
|
||||
/Connectors/Revit/* @clairekuang @oguzhankoral @didimitrie
|
||||
/Connectors/Rhino/* @clairekuang @oguzhankoral @didimitrie
|
||||
/Connectors/Tekla/* @bjoernsteinhagen @dogukankaratas
|
||||
ConnectorAutocadCivil/* @clairekuang
|
||||
ConnectorArchicad/* @jozseflkiss
|
||||
ConnectorCSI/* @connorivy
|
||||
ConnectorDynamo/* @teocomi @alanrynne
|
||||
ConnectorGrasshopper/* @alanrynne @clairekuang
|
||||
ConnectorMicrostation/* @clairekuang
|
||||
ConnectorRevit/* @teocomi @connorivy
|
||||
ConnectorRhino/* @clairekuang @alanrynne
|
||||
ConnectorTeklaStructures/* @connorivy
|
||||
|
||||
# Converters
|
||||
/Convertors/ArcGIS/* @KatKatKateryna
|
||||
/Convertors/Autocad/* @clairekuang @oguzhankoral @didimitrie
|
||||
/Convertors/Civil3d/* @clairekuang @oguzhankoral @didimitrie
|
||||
/Convertors/CSi/* @bjoernsteinhagen @dogukankaratas
|
||||
/Convertors/Navisworks/* @jsdbroughton
|
||||
/Convertors/Revit/* @clairekuang @oguzhankoral @didimitrie
|
||||
/Convertors/Rhino/* @clairekuang @oguzhankoral @didimitrie
|
||||
/Convertors/Tekla/* @bjoernsteinhagen @dogukankaratas
|
||||
# DesktopUI
|
||||
|
||||
# DUI
|
||||
|
||||
/DUI3/* @clairekuang @oguzhankoral @didimitrie
|
||||
|
||||
# Importers
|
||||
/Importers/* @JR-Morgan @didimitrie @oguzhankoral @adamhathcock
|
||||
|
||||
# SDK
|
||||
/SDK/* @JR-Morgan @clairekuang @didimitrie @oguzhankoral @adamhathcock
|
||||
|
||||
# Build
|
||||
/Build/* @JR-Morgan @oguzhankoral @adamhathcock
|
||||
DesktopUI2/* @teocomi @clairekuang
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ public static class Consts
|
||||
]
|
||||
),
|
||||
new(
|
||||
"teklastructures",
|
||||
"tekla-structures",
|
||||
[
|
||||
new("Connectors/Tekla/Speckle.Connector.Tekla2023", "net48"),
|
||||
new("Connectors/Tekla/Speckle.Connector.Tekla2024", "net48")
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using ArcGIS.Core.Data;
|
||||
using ArcGIS.Desktop.Core;
|
||||
using ArcGIS.Desktop.Editing.Events;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using ArcGIS.Desktop.Mapping.Events;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -16,6 +15,7 @@ using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Exceptions;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
@@ -46,7 +46,6 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IArcGISConversionSettingsFactory _arcGISConversionSettingsFactory;
|
||||
private readonly IThreadContext _threadContext;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to aggregate the changed objects' id. Note we're using a concurrent dictionary here as the expiry check method is not thread safe, and this was causing problems. See:
|
||||
@@ -72,7 +71,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
IArcGISConversionSettingsFactory arcGisConversionSettingsFactory,
|
||||
MapMembersUtils mapMemberUtils,
|
||||
IThreadContext threadContext,
|
||||
ISpeckleApplication speckleApplication,
|
||||
IEventAggregator eventAggregator,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
)
|
||||
{
|
||||
@@ -87,15 +86,11 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
_arcGISConversionSettingsFactory = arcGisConversionSettingsFactory;
|
||||
_mapMemberUtils = mapMemberUtils;
|
||||
_threadContext = threadContext;
|
||||
_speckleApplication = speckleApplication;
|
||||
|
||||
Parent = parent;
|
||||
Commands = new SendBindingUICommands(parent);
|
||||
SubscribeToArcGISEvents();
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
{
|
||||
_sendConversionCache.ClearCache();
|
||||
};
|
||||
eventAggregator.GetEvent<DocumentStoreChangedEvent>().Subscribe(OnDocumentStoreChangedEvent);
|
||||
}
|
||||
|
||||
private void OnDocumentStoreChangedEvent(object _) => _sendConversionCache.ClearCache();
|
||||
@@ -105,7 +100,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
LayersRemovedEvent.Subscribe(
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await QueuedTask.Run(async () => await GetIdsForLayersRemovedEvent(a))
|
||||
async () => await _threadContext.RunOnWorkerAsync(async () => await GetIdsForLayersRemovedEvent(a))
|
||||
),
|
||||
true
|
||||
);
|
||||
@@ -113,7 +108,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
StandaloneTablesRemovedEvent.Subscribe(
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await QueuedTask.Run(async () => await GetIdsForStandaloneTablesRemovedEvent(a))
|
||||
async () => await _threadContext.RunOnWorkerAsync(async () => await GetIdsForStandaloneTablesRemovedEvent(a))
|
||||
),
|
||||
true
|
||||
);
|
||||
@@ -121,7 +116,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
MapPropertyChangedEvent.Subscribe(
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await QueuedTask.Run(async () => await GetIdsForMapPropertyChangedEvent(a))
|
||||
async () => await _threadContext.RunOnWorkerAsync(async () => await GetIdsForMapPropertyChangedEvent(a))
|
||||
),
|
||||
true
|
||||
); // Map units, CRS etc.
|
||||
@@ -129,7 +124,8 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
MapMemberPropertiesChangedEvent.Subscribe(
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await QueuedTask.Run(async () => await GetIdsForMapMemberPropertiesChangedEvent(a))
|
||||
async () =>
|
||||
await _threadContext.RunOnWorkerAsync(async () => await GetIdsForMapMemberPropertiesChangedEvent(a))
|
||||
),
|
||||
true
|
||||
); // e.g. Layer name
|
||||
@@ -138,7 +134,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
_ =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await QueuedTask.Run(SubscribeToMapMembersDataSourceChange);
|
||||
await _threadContext.RunOnWorker(SubscribeToMapMembersDataSourceChange);
|
||||
}),
|
||||
true
|
||||
);
|
||||
@@ -379,25 +375,21 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
|
||||
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
List<MapMember> mapMembers = await QueuedTask.Run(() =>
|
||||
{
|
||||
scope
|
||||
.ServiceProvider.GetRequiredService<IConverterSettingsStore<ArcGISConversionSettings>>()
|
||||
.Initialize(
|
||||
_arcGISConversionSettingsFactory.Create(
|
||||
Project.Current,
|
||||
MapView.Active.Map,
|
||||
new CRSoffsetRotation(MapView.Active.Map)
|
||||
)
|
||||
);
|
||||
|
||||
return modelCard
|
||||
.SendFilter.NotNull()
|
||||
.RefreshObjectIds()
|
||||
.Select(id => (MapMember)MapView.Active.Map.FindLayer(id) ?? MapView.Active.Map.FindStandaloneTable(id))
|
||||
.Where(obj => obj != null)
|
||||
.ToList();
|
||||
});
|
||||
scope
|
||||
.ServiceProvider.GetRequiredService<IConverterSettingsStore<ArcGISConversionSettings>>()
|
||||
.Initialize(
|
||||
_arcGISConversionSettingsFactory.Create(
|
||||
Project.Current,
|
||||
MapView.Active.Map,
|
||||
new CRSoffsetRotation(MapView.Active.Map)
|
||||
)
|
||||
);
|
||||
List<MapMember> mapMembers = modelCard
|
||||
.SendFilter.NotNull()
|
||||
.RefreshObjectIds()
|
||||
.Select(id => (MapMember)MapView.Active.Map.FindLayer(id) ?? MapView.Active.Map.FindStandaloneTable(id))
|
||||
.Where(obj => obj != null)
|
||||
.ToList();
|
||||
|
||||
if (mapMembers.Count == 0)
|
||||
{
|
||||
@@ -405,27 +397,24 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
|
||||
}
|
||||
|
||||
await QueuedTask.Run(() =>
|
||||
// subscribe to the selected layer events
|
||||
foreach (MapMember mapMember in mapMembers)
|
||||
{
|
||||
// subscribe to the selected layer events
|
||||
foreach (MapMember mapMember in mapMembers)
|
||||
if (mapMember is FeatureLayer featureLayer)
|
||||
{
|
||||
if (mapMember is FeatureLayer featureLayer)
|
||||
{
|
||||
SubscribeToFeatureLayerDataSourceChange(featureLayer);
|
||||
}
|
||||
else if (mapMember is StandaloneTable table)
|
||||
{
|
||||
SubscribeToTableDataSourceChange(table);
|
||||
}
|
||||
SubscribeToFeatureLayerDataSourceChange(featureLayer);
|
||||
}
|
||||
});
|
||||
else if (mapMember is StandaloneTable table)
|
||||
{
|
||||
SubscribeToTableDataSourceChange(table);
|
||||
}
|
||||
}
|
||||
|
||||
var sendResult = await scope
|
||||
.ServiceProvider.GetRequiredService<SendOperation<MapMember>>()
|
||||
.Execute(
|
||||
mapMembers,
|
||||
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
|
||||
modelCard.GetSendInfo("ArcGIS"), // POC: get host app name from settings? same for GetReceiveInfo
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
|
||||
cancellationItem.Token
|
||||
);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using ArcGIS.Core.Data;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using Speckle.Connectors.ArcGIS.Utils;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Sdk;
|
||||
@@ -21,28 +21,24 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
public BasicConnectorBindingCommands Commands { get; }
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
|
||||
public BasicConnectorBinding(
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
ISpeckleApplication speckleApplication,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
_speckleApplication = speckleApplication;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
Parent = parent;
|
||||
Commands = new BasicConnectorBindingCommands(parent);
|
||||
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await Commands.NotifyDocumentChanged();
|
||||
});
|
||||
eventAggregator.GetEvent<DocumentStoreChangedEvent>().Subscribe(OnDocumentStoreChangedEvent);
|
||||
}
|
||||
|
||||
private async Task OnDocumentStoreChangedEvent(object _) => await Commands.NotifyDocumentChanged();
|
||||
|
||||
public string GetSourceApplicationName() => _speckleApplication.Slug;
|
||||
|
||||
public string GetSourceApplicationVersion() => _speckleApplication.HostApplicationVersion;
|
||||
@@ -67,18 +63,19 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
|
||||
|
||||
public async Task HighlightObjects(IReadOnlyList<string> objectIds)
|
||||
public Task HighlightObjects(IReadOnlyList<string> objectIds)
|
||||
{
|
||||
await HighlightObjectsOnView(objectIds.Select(x => new ObjectID(x)).ToList());
|
||||
HighlightObjectsOnView(objectIds.Select(x => new ObjectID(x)).ToList());
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task HighlightModel(string modelCardId)
|
||||
public Task HighlightModel(string modelCardId)
|
||||
{
|
||||
var model = _store.GetModelById(modelCardId);
|
||||
|
||||
if (model is null)
|
||||
{
|
||||
return;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
var objectIds = new List<ObjectID>();
|
||||
@@ -95,24 +92,22 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
if (objectIds is null)
|
||||
{
|
||||
return;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
await HighlightObjectsOnView(objectIds);
|
||||
HighlightObjectsOnView(objectIds);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task HighlightObjectsOnView(IReadOnlyList<ObjectID> objectIds)
|
||||
private void HighlightObjectsOnView(IReadOnlyList<ObjectID> objectIds)
|
||||
{
|
||||
await QueuedTask.Run(() =>
|
||||
{
|
||||
MapView mapView = MapView.Active;
|
||||
MapView mapView = MapView.Active;
|
||||
|
||||
List<MapMemberFeature> mapMembersFeatures = GetMapMembers(objectIds, mapView);
|
||||
ClearSelectionInTOC();
|
||||
ClearSelection();
|
||||
SelectMapMembersInTOC(mapMembersFeatures);
|
||||
SelectMapMembersAndFeatures(mapMembersFeatures);
|
||||
mapView.ZoomToSelected();
|
||||
});
|
||||
List<MapMemberFeature> mapMembersFeatures = GetMapMembers(objectIds, mapView);
|
||||
ClearSelectionInTOC();
|
||||
ClearSelection();
|
||||
SelectMapMembersInTOC(mapMembersFeatures);
|
||||
SelectMapMembersAndFeatures(mapMembersFeatures);
|
||||
mapView.ZoomToSelected();
|
||||
}
|
||||
|
||||
private List<MapMemberFeature> GetMapMembers(IReadOnlyList<ObjectID> objectIds, MapView mapView)
|
||||
|
||||
+1
-2
@@ -10,7 +10,6 @@ using Speckle.Connectors.Common;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
@@ -28,7 +27,7 @@ public static class ArcGISConnectorModule
|
||||
public static void AddArcGIS(this IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddConnectorUtils();
|
||||
serviceCollection.AddDUI<DefaultThreadContext, ArcGISDocumentStore>();
|
||||
serviceCollection.AddDUI<ArcGISThreadContext, ArcGISDocumentStore>();
|
||||
serviceCollection.AddDUIView();
|
||||
|
||||
// Register bindings
|
||||
|
||||
+1
-15
@@ -1,7 +1,6 @@
|
||||
using System.Diagnostics.Contracts;
|
||||
using ArcGIS.Core.CIM;
|
||||
using ArcGIS.Core.Geometry;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using Speckle.Connectors.ArcGIS.HostApp;
|
||||
using Speckle.Connectors.ArcGIS.Utils;
|
||||
@@ -61,19 +60,6 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
return QueuedTask.Run(
|
||||
() => BuildInternal(rootObject, projectName, modelName, onOperationProgressed, cancellationToken)
|
||||
);
|
||||
}
|
||||
|
||||
private HostObjectBuilderResult BuildInternal(
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
// TODO get spatialRef and offsets & rotation from ProjectInfo in CommitObject
|
||||
// ATM, GIS commit CRS is stored per layer (in FeatureClass converter), but should be moved to the Root level too
|
||||
@@ -240,7 +226,7 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
bakedObjectIds.AddRange(createdLayerGroups.Values.Select(x => x.URI));
|
||||
|
||||
// TODO: validated a correct set regarding bakedobject ids
|
||||
return new HostObjectBuilderResult(bakedObjectIds, results);
|
||||
return Task.FromResult(new HostObjectBuilderResult(bakedObjectIds, results));
|
||||
}
|
||||
|
||||
private IReadOnlyCollection<LocalToGlobalMap> GetObjectsToConvert(Base rootObject)
|
||||
|
||||
+10
-107
@@ -1,6 +1,5 @@
|
||||
using ArcGIS.Core.Data.Raster;
|
||||
using ArcGIS.Core.Geometry;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.ArcGIS.HostApp;
|
||||
using Speckle.Connectors.ArcGIS.HostApp.Extensions;
|
||||
@@ -50,14 +49,7 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
_mapMemberUtils = mapMemberUtils;
|
||||
}
|
||||
|
||||
public Task<RootObjectBuilderResult> Build(
|
||||
IReadOnlyList<ADM.MapMember> layers,
|
||||
SendInfo __,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
) => QueuedTask.Run(() => BuildInternal(layers, __, onOperationProgressed, cancellationToken));
|
||||
|
||||
private async Task<RootObjectBuilderResult> BuildInternal(
|
||||
public async Task<RootObjectBuilderResult> Build(
|
||||
IReadOnlyList<ADM.MapMember> layers,
|
||||
SendInfo __,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
@@ -102,26 +94,19 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
// We need to unpack the selected mapmembers into all leaf-level mapmembers (containing just objects) and build the root collection structure during unpacking.
|
||||
// Mapmember dynamically attached properties are also added at this step.
|
||||
List<ADM.MapMember> unpackedLayers;
|
||||
Dictionary<ADM.MapMember, long> layersWithFeatureCount;
|
||||
long allFeaturesCount;
|
||||
ADM.Map map = ADM.MapView.Active.Map;
|
||||
IEnumerable<ADM.MapMember> layersOrdered = _mapMemberUtils.GetMapMembersInOrder(map, layers);
|
||||
using (var _ = _activityFactory.Start("Unpacking selection"))
|
||||
{
|
||||
unpackedLayers = _layerUnpacker.UnpackSelection(layersOrdered, rootCollection);
|
||||
|
||||
// count number of features to convert. Raster layers are counter as 1 feature for now (not ideal)
|
||||
layersWithFeatureCount = CountAllFeaturesInLayers(unpackedLayers);
|
||||
allFeaturesCount = layersWithFeatureCount.Values.Sum();
|
||||
}
|
||||
|
||||
List<SendConversionResult> results = new(unpackedLayers.Count);
|
||||
onOperationProgressed.Report(new("Converting", null));
|
||||
using (var convertingActivity = _activityFactory.Start("Converting objects"))
|
||||
{
|
||||
long count = 0;
|
||||
|
||||
foreach (var (layer, layerFeatureCount) in layersWithFeatureCount)
|
||||
int count = 0;
|
||||
foreach (ADM.MapMember layer in unpackedLayers)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
string layerApplicationId = layer.GetSpeckleApplicationId();
|
||||
@@ -149,33 +134,15 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
switch (layer)
|
||||
{
|
||||
case ADM.FeatureLayer featureLayer:
|
||||
List<Base> convertedFeatureLayerObjects = ConvertFeatureLayerObjects(
|
||||
featureLayer,
|
||||
count,
|
||||
allFeaturesCount,
|
||||
onOperationProgressed,
|
||||
cancellationToken
|
||||
);
|
||||
List<Base> convertedFeatureLayerObjects = ConvertFeatureLayerObjects(featureLayer);
|
||||
layerCollection.elements.AddRange(convertedFeatureLayerObjects);
|
||||
break;
|
||||
case ADM.RasterLayer rasterLayer:
|
||||
List<Base> convertedRasterLayerObjects = ConvertRasterLayerObjects(
|
||||
rasterLayer,
|
||||
count,
|
||||
allFeaturesCount,
|
||||
onOperationProgressed,
|
||||
cancellationToken
|
||||
);
|
||||
List<Base> convertedRasterLayerObjects = ConvertRasterLayerObjects(rasterLayer);
|
||||
layerCollection.elements.AddRange(convertedRasterLayerObjects);
|
||||
break;
|
||||
case ADM.LasDatasetLayer lasDatasetLayer:
|
||||
List<Base> convertedLasDatasetObjects = ConvertLasDatasetLayerObjects(
|
||||
lasDatasetLayer,
|
||||
count,
|
||||
allFeaturesCount,
|
||||
onOperationProgressed,
|
||||
cancellationToken
|
||||
);
|
||||
List<Base> convertedLasDatasetObjects = ConvertLasDatasetLayerObjects(lasDatasetLayer);
|
||||
layerCollection.elements.AddRange(convertedLasDatasetObjects);
|
||||
break;
|
||||
default:
|
||||
@@ -183,8 +150,6 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
sdkStatus = SdkActivityStatusCode.Error;
|
||||
break;
|
||||
}
|
||||
|
||||
count += layerFeatureCount;
|
||||
results.Add(new(status, layerApplicationId, layer.GetType().Name, layerCollection));
|
||||
convertingActivity?.SetStatus(sdkStatus);
|
||||
}
|
||||
@@ -201,6 +166,7 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
convertingActivity?.RecordException(ex);
|
||||
}
|
||||
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / layers.Count));
|
||||
await Task.Yield();
|
||||
}
|
||||
}
|
||||
@@ -216,41 +182,7 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
return new RootObjectBuilderResult(rootCollection, results);
|
||||
}
|
||||
|
||||
private Dictionary<ADM.MapMember, long> CountAllFeaturesInLayers(List<ADM.MapMember> unpackedLayers)
|
||||
{
|
||||
Dictionary<ADM.MapMember, long> layersFeatureCount = new();
|
||||
|
||||
foreach (ADM.MapMember layer in unpackedLayers)
|
||||
{
|
||||
switch (layer)
|
||||
{
|
||||
case ADM.FeatureLayer featureLayer:
|
||||
layersFeatureCount.Add(featureLayer, featureLayer.GetFeatureClass().GetCount());
|
||||
break;
|
||||
case ADM.RasterLayer rasterLayer:
|
||||
// count Raster layer as 1 feature: not optimal but this is the approach for now
|
||||
layersFeatureCount.Add(rasterLayer, 1);
|
||||
break;
|
||||
case ADM.LasDatasetLayer lasDatasetLayer:
|
||||
var dataset = lasDatasetLayer.GetLasDataset();
|
||||
// simple dataset.GetPointCount() keeps returning null, so switched to EstimatePointCount
|
||||
layersFeatureCount.Add(
|
||||
lasDatasetLayer,
|
||||
(long)dataset.EstimatePointCount(dataset.GetDefinition().GetExtent())
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return layersFeatureCount;
|
||||
}
|
||||
|
||||
private List<Base> ConvertFeatureLayerObjects(
|
||||
ADM.FeatureLayer featureLayer,
|
||||
long count,
|
||||
long allFeaturesCount,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
private List<Base> ConvertFeatureLayerObjects(ADM.FeatureLayer featureLayer)
|
||||
{
|
||||
string layerApplicationId = featureLayer.GetSpeckleApplicationId();
|
||||
List<Base> convertedObjects = new();
|
||||
@@ -264,9 +196,6 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
{
|
||||
while (rowCursor.MoveNext())
|
||||
{
|
||||
// allow cancellation before every feature
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// Same IDisposable issue appears to happen on Row class too. Docs say it should always be disposed of manually by the caller.
|
||||
using (ACD.Row row = rowCursor.Current)
|
||||
{
|
||||
@@ -280,8 +209,6 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
// process the object color
|
||||
_colorUnpacker.ProcessFeatureLayerColor(row, applicationId);
|
||||
}
|
||||
// update report
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / allFeaturesCount));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,38 +216,19 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
}
|
||||
|
||||
// POC: raster colors are stored as mesh vertex colors in RasterToSpeckleConverter. Should probably move to color unpacker.
|
||||
private List<Base> ConvertRasterLayerObjects(
|
||||
ADM.RasterLayer rasterLayer,
|
||||
long count,
|
||||
long allFeaturesCount,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
private List<Base> ConvertRasterLayerObjects(ADM.RasterLayer rasterLayer)
|
||||
{
|
||||
string layerApplicationId = rasterLayer.GetSpeckleApplicationId();
|
||||
List<Base> convertedObjects = new();
|
||||
Raster raster = rasterLayer.GetRaster();
|
||||
|
||||
// check cancellation token before conversion
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
Base converted = _rootToSpeckleConverter.Convert(raster);
|
||||
string applicationId = raster.GetSpeckleApplicationId(layerApplicationId);
|
||||
converted.applicationId = applicationId;
|
||||
convertedObjects.Add(converted);
|
||||
|
||||
// update report
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / allFeaturesCount));
|
||||
|
||||
return convertedObjects;
|
||||
}
|
||||
|
||||
private List<Base> ConvertLasDatasetLayerObjects(
|
||||
ADM.LasDatasetLayer lasDatasetLayer,
|
||||
long count,
|
||||
long allFeaturesCount,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
private List<Base> ConvertLasDatasetLayerObjects(ADM.LasDatasetLayer lasDatasetLayer)
|
||||
{
|
||||
string layerApplicationId = lasDatasetLayer.GetSpeckleApplicationId();
|
||||
List<Base> convertedObjects = new();
|
||||
@@ -334,9 +242,6 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
{
|
||||
while (ptCursor.MoveNext())
|
||||
{
|
||||
// allow cancellation before every point
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
using (ACD.Analyst3D.LasPoint pt = ptCursor.Current)
|
||||
{
|
||||
Base converted = _rootToSpeckleConverter.Convert(pt);
|
||||
@@ -347,8 +252,6 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
// process the object color
|
||||
_colorUnpacker.ProcessLasLayerColor(pt, applicationId);
|
||||
}
|
||||
// update report
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / allFeaturesCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.Utils;
|
||||
|
||||
//don't check for GUI as it's the same check we do in ThreadContext
|
||||
public class ArcGISThreadContext : ThreadContext
|
||||
{
|
||||
protected override Task<T> MainToWorkerAsync<T>(Func<Task<T>> action)
|
||||
{
|
||||
if (QueuedTask.OnWorker)
|
||||
{
|
||||
return action();
|
||||
}
|
||||
else
|
||||
{
|
||||
return QueuedTask.Run(async () => await action());
|
||||
}
|
||||
}
|
||||
|
||||
protected override Task<T> WorkerToMainAsync<T>(Func<Task<T>> action) => QueuedTask.Run(async () => await action());
|
||||
|
||||
protected override Task<T> MainToWorker<T>(Func<T> action)
|
||||
{
|
||||
if (QueuedTask.OnWorker)
|
||||
{
|
||||
return Task.FromResult(action());
|
||||
}
|
||||
else
|
||||
{
|
||||
return QueuedTask.Run(action);
|
||||
}
|
||||
}
|
||||
|
||||
protected override Task<T> WorkerToMain<T>(Func<T> action) => QueuedTask.Run(action);
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
using System.Xml.Linq;
|
||||
using ArcGIS.Desktop.Core.Events;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using ArcGIS.Desktop.Mapping.Events;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
|
||||
@@ -13,15 +13,18 @@ namespace Speckle.Connectors.ArcGIS.Utils;
|
||||
public class ArcGISDocumentStore : DocumentModelStore
|
||||
{
|
||||
private readonly IThreadContext _threadContext;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
|
||||
public ArcGISDocumentStore(
|
||||
IJsonSerializer jsonSerializer,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IThreadContext threadContext
|
||||
IThreadContext threadContext,
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
: base(jsonSerializer)
|
||||
{
|
||||
_threadContext = threadContext;
|
||||
_eventAggregator = eventAggregator;
|
||||
ActiveMapViewChangedEvent.Subscribe(a => topLevelExceptionHandler.CatchUnhandled(() => OnMapViewChanged(a)), true);
|
||||
ProjectSavingEvent.Subscribe(
|
||||
_ =>
|
||||
@@ -39,13 +42,16 @@ public class ArcGISDocumentStore : DocumentModelStore
|
||||
},
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
public override async Task OnDocumentStoreInitialized()
|
||||
{
|
||||
// in case plugin was loaded into already opened Map, read metadata from the current Map
|
||||
if (!IsDocumentInit && MapView.Active != null)
|
||||
{
|
||||
IsDocumentInit = true;
|
||||
LoadState();
|
||||
OnDocumentChanged();
|
||||
await _eventAggregator.GetEvent<DocumentStoreChangedEvent>().PublishAsync(new object());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +76,7 @@ public class ArcGISDocumentStore : DocumentModelStore
|
||||
/// <summary>
|
||||
/// On map view switch, this event trigger twice, first for outgoing view, second for incoming view.
|
||||
/// </summary>
|
||||
private void OnMapViewChanged(ActiveMapViewChangedEventArgs args)
|
||||
private async void OnMapViewChanged(ActiveMapViewChangedEventArgs args)
|
||||
{
|
||||
if (args.IncomingView is null)
|
||||
{
|
||||
@@ -79,12 +85,12 @@ public class ArcGISDocumentStore : DocumentModelStore
|
||||
|
||||
IsDocumentInit = true;
|
||||
LoadState();
|
||||
OnDocumentChanged();
|
||||
await _eventAggregator.GetEvent<DocumentStoreChangedEvent>().PublishAsync(new object());
|
||||
}
|
||||
|
||||
protected override void HostAppSaveState(string modelCardState) =>
|
||||
QueuedTask
|
||||
.Run(() =>
|
||||
_threadContext
|
||||
.RunOnWorker(() =>
|
||||
{
|
||||
Map map = MapView.Active.Map;
|
||||
// Read existing metadata - To prevent messing existing metadata. 🤞 Hope other add-in developers will do same :D
|
||||
@@ -113,8 +119,8 @@ public class ArcGISDocumentStore : DocumentModelStore
|
||||
.FireAndForget();
|
||||
|
||||
protected override void LoadState() =>
|
||||
QueuedTask
|
||||
.Run(() =>
|
||||
_threadContext
|
||||
.RunOnWorker(() =>
|
||||
{
|
||||
Map map = MapView.Active.Map;
|
||||
var metadata = map.GetMetadata();
|
||||
|
||||
@@ -226,9 +226,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -236,8 +236,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -261,7 +261,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -294,40 +294,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
},
|
||||
"net6.0-windows7.0/win-x64": {
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,8 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -294,7 +294,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -333,40 +333,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,8 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -294,7 +294,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -333,40 +333,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,8 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -295,7 +295,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -334,40 +334,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,9 +215,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -225,8 +225,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -251,7 +251,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -290,39 +290,39 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
|
||||
+6
-9
@@ -4,6 +4,7 @@ using Speckle.Connectors.Autocad.HostApp.Extensions;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Sdk;
|
||||
@@ -21,7 +22,6 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly IThreadContext _threadContext;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly ILogger<AutocadBasicConnectorBinding> _logger;
|
||||
|
||||
public BasicConnectorBindingCommands Commands { get; }
|
||||
@@ -32,8 +32,8 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
|
||||
IAccountManager accountManager,
|
||||
ISpeckleApplication speckleApplication,
|
||||
ILogger<AutocadBasicConnectorBinding> logger,
|
||||
IThreadContext threadContext,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
IEventAggregator eventAggregator,
|
||||
IThreadContext threadContext
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
@@ -41,16 +41,13 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
|
||||
_accountManager = accountManager;
|
||||
_speckleApplication = speckleApplication;
|
||||
Commands = new BasicConnectorBindingCommands(parent);
|
||||
eventAggregator.GetEvent<DocumentStoreChangedEvent>().Subscribe(OnDocumentStoreChangedEvent);
|
||||
_logger = logger;
|
||||
_threadContext = threadContext;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await Commands.NotifyDocumentChanged();
|
||||
});
|
||||
}
|
||||
|
||||
private async Task OnDocumentStoreChangedEvent(object _) => await Commands.NotifyDocumentChanged();
|
||||
|
||||
public string GetConnectorVersion() => _speckleApplication.SpeckleVersion;
|
||||
|
||||
public string GetSourceApplicationName() => _speckleApplication.Slug;
|
||||
|
||||
+2
-9
@@ -2,7 +2,6 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
@@ -26,7 +25,6 @@ public sealed class AutocadReceiveBinding : IReceiveBinding
|
||||
private readonly ILogger<AutocadReceiveBinding> _logger;
|
||||
private readonly IAutocadConversionSettingsFactory _autocadConversionSettingsFactory;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly IThreadContext _threadContext;
|
||||
|
||||
private ReceiveBindingUICommands Commands { get; }
|
||||
|
||||
@@ -38,8 +36,7 @@ public sealed class AutocadReceiveBinding : IReceiveBinding
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<AutocadReceiveBinding> logger,
|
||||
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
|
||||
ISpeckleApplication speckleApplication,
|
||||
IThreadContext threadContext
|
||||
ISpeckleApplication speckleApplication
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
@@ -49,17 +46,13 @@ public sealed class AutocadReceiveBinding : IReceiveBinding
|
||||
_logger = logger;
|
||||
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
|
||||
_speckleApplication = speckleApplication;
|
||||
_threadContext = threadContext;
|
||||
Parent = parent;
|
||||
Commands = new ReceiveBindingUICommands(parent);
|
||||
}
|
||||
|
||||
public void CancelReceive(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
|
||||
|
||||
public async Task Receive(string modelCardId) =>
|
||||
await _threadContext.RunOnMainAsync(async () => await ReceiveInternal(modelCardId));
|
||||
|
||||
public async Task ReceiveInternal(string modelCardId)
|
||||
public async Task Receive(string modelCardId)
|
||||
{
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
scope
|
||||
|
||||
+28
-19
@@ -1,42 +1,48 @@
|
||||
using Autodesk.AutoCAD.ApplicationServices;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Autodesk.AutoCAD.EditorInput;
|
||||
using Speckle.Connectors.Autocad.HostApp.Extensions;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.Autocad.Plugin;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Bindings;
|
||||
|
||||
public class AutocadSelectionBinding : ISelectionBinding
|
||||
{
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IThreadContext _threadContext;
|
||||
private const string SELECTION_EVENT = "setSelection";
|
||||
private readonly HashSet<Document> _visitedDocuments = new();
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly HashSet<string> _visitedDocuments = new();
|
||||
|
||||
public string Name => "selectionBinding";
|
||||
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
public AutocadSelectionBinding(
|
||||
IBrowserBridge parent,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IThreadContext threadContext
|
||||
)
|
||||
public AutocadSelectionBinding(IBrowserBridge parent, IEventAggregator eventAggregator)
|
||||
{
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
_threadContext = threadContext;
|
||||
_eventAggregator = eventAggregator;
|
||||
Parent = parent;
|
||||
|
||||
// POC: Use here Context for doc. In converters it's OK but we are still lacking to use context into bindings.
|
||||
// It is with the case of if binding created with already a document
|
||||
// This is valid when user opens acad file directly double clicking
|
||||
TryRegisterDocumentForSelection(Application.DocumentManager.MdiActiveDocument);
|
||||
Application.DocumentManager.DocumentActivated += (_, e) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => OnDocumentChanged(e.Document));
|
||||
eventAggregator.GetEvent<DocumentActivatedEvent>().Subscribe(OnDocumentChanged);
|
||||
eventAggregator.GetEvent<ImpliedSelectionChangedEvent>().Subscribe(OnSelectionChanged);
|
||||
eventAggregator.GetEvent<DocumentToBeDestroyedEvent>().Subscribe(OnDocumentDestroyed);
|
||||
}
|
||||
|
||||
private void OnDocumentChanged(Document? document) => TryRegisterDocumentForSelection(document);
|
||||
private void OnDocumentDestroyed(DocumentCollectionEventArgs e)
|
||||
{
|
||||
if (!_visitedDocuments.Contains(e.Document.Name))
|
||||
{
|
||||
e.Document.ImpliedSelectionChanged -= DocumentOnImpliedSelectionChanged;
|
||||
_visitedDocuments.Remove(e.Document.Name);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDocumentChanged(DocumentCollectionEventArgs e) => TryRegisterDocumentForSelection(e.Document);
|
||||
|
||||
private void TryRegisterDocumentForSelection(Document? document)
|
||||
{
|
||||
@@ -45,21 +51,24 @@ public class AutocadSelectionBinding : ISelectionBinding
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_visitedDocuments.Contains(document))
|
||||
if (!_visitedDocuments.Contains(document.Name))
|
||||
{
|
||||
document.ImpliedSelectionChanged += (_, _) =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () => await _threadContext.RunOnMainAsync(OnSelectionChanged));
|
||||
document.ImpliedSelectionChanged += DocumentOnImpliedSelectionChanged;
|
||||
|
||||
_visitedDocuments.Add(document);
|
||||
_visitedDocuments.Add(document.Name);
|
||||
}
|
||||
}
|
||||
|
||||
// ReSharper disable once AsyncVoidMethod
|
||||
private async void DocumentOnImpliedSelectionChanged(object? sender, EventArgs e) =>
|
||||
await _eventAggregator.GetEvent<ImpliedSelectionChangedEvent>().PublishAsync(e);
|
||||
|
||||
// NOTE: Autocad 2022 caused problems, so we need to refactor things a bit in here to always store
|
||||
// selection info locally (and get it updated by the event, which we can control to run on the main thread).
|
||||
// Ui requests to GetSelection() should just return this local copy that is kept up to date by the event handler.
|
||||
private SelectionInfo _selectionInfo;
|
||||
|
||||
private async Task OnSelectionChanged()
|
||||
private async Task OnSelectionChanged(EventArgs _)
|
||||
{
|
||||
_selectionInfo = GetSelectionInternal();
|
||||
await Parent.Send(SELECTION_EVENT, _selectionInfo);
|
||||
|
||||
+54
-24
@@ -1,16 +1,19 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Autodesk.AutoCAD.ApplicationServices;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp.Extensions;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Autocad.Plugin;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Exceptions;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
@@ -39,8 +42,7 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
private readonly ILogger<AutocadSendBinding> _logger;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly IThreadContext _threadContext;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IAppIdleManager _idleManager;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to aggregate the changed objects' id. Note we're using a concurrent dictionary here as the expiry check method is not thread safe, and this was causing problems. See:
|
||||
@@ -61,8 +63,7 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
ILogger<AutocadSendBinding> logger,
|
||||
ISpeckleApplication speckleApplication,
|
||||
IThreadContext threadContext,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IAppIdleManager idleManager
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
@@ -74,29 +75,46 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
_logger = logger;
|
||||
_speckleApplication = speckleApplication;
|
||||
_threadContext = threadContext;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
_idleManager = idleManager;
|
||||
_eventAggregator = eventAggregator;
|
||||
Parent = parent;
|
||||
Commands = new SendBindingUICommands(parent);
|
||||
|
||||
Application.DocumentManager.DocumentActivated += (_, args) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => SubscribeToObjectChanges(args.Document));
|
||||
|
||||
if (Application.DocumentManager.CurrentDocument != null)
|
||||
{
|
||||
// catches the case when autocad just opens up with a blank new doc
|
||||
SubscribeToObjectChanges(Application.DocumentManager.CurrentDocument);
|
||||
TryRegisterSubscribeToObjectChanges(Application.DocumentManager.CurrentDocument);
|
||||
}
|
||||
// Since ids of the objects generates from same seed, we should clear the cache always whenever doc swapped.
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
{
|
||||
_sendConversionCache.ClearCache();
|
||||
};
|
||||
|
||||
eventAggregator.GetEvent<DocumentActivatedEvent>().Subscribe(SubscribeToObjectChanges);
|
||||
eventAggregator.GetEvent<DocumentStoreChangedEvent>().Subscribe(OnDocumentStoreChangedEvent);
|
||||
eventAggregator.GetEvent<DocumentToBeDestroyedEvent>().Subscribe(OnDocumentDestroyed);
|
||||
eventAggregator.GetEvent<ObjectAppendedEvent>().Subscribe(OnObjectAppended);
|
||||
eventAggregator.GetEvent<ObjectErasedEvent>().Subscribe(ObjectErased);
|
||||
eventAggregator.GetEvent<ObjectModifiedEvent>().Subscribe(ObjectModified);
|
||||
}
|
||||
|
||||
private void OnDocumentDestroyed(DocumentCollectionEventArgs args)
|
||||
{
|
||||
Document doc = args.Document;
|
||||
if (!_docSubsTracker.Contains(doc.Name))
|
||||
{
|
||||
doc.Database.ObjectAppended -= DatabaseOnObjectAppended;
|
||||
doc.Database.ObjectErased -= DatabaseOnObjectErased;
|
||||
doc.Database.ObjectModified -= DatabaseObjectModified;
|
||||
|
||||
_docSubsTracker.Remove(doc.Name);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDocumentStoreChangedEvent(object _) => _sendConversionCache.ClearCache();
|
||||
|
||||
private readonly List<string> _docSubsTracker = new();
|
||||
|
||||
private void SubscribeToObjectChanges(Document doc)
|
||||
private void SubscribeToObjectChanges(DocumentCollectionEventArgs e) =>
|
||||
TryRegisterSubscribeToObjectChanges(e.Document);
|
||||
|
||||
private void TryRegisterSubscribeToObjectChanges(Document? doc)
|
||||
{
|
||||
if (doc == null || doc.Database == null || _docSubsTracker.Contains(doc.Name))
|
||||
{
|
||||
@@ -104,21 +122,33 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
}
|
||||
|
||||
_docSubsTracker.Add(doc.Name);
|
||||
doc.Database.ObjectAppended += (_, e) => OnObjectChanged(e.DBObject);
|
||||
doc.Database.ObjectErased += (_, e) => OnObjectChanged(e.DBObject);
|
||||
doc.Database.ObjectModified += (_, e) => OnObjectChanged(e.DBObject);
|
||||
doc.Database.ObjectAppended += DatabaseOnObjectAppended;
|
||||
doc.Database.ObjectErased += DatabaseOnObjectErased;
|
||||
doc.Database.ObjectModified += DatabaseObjectModified;
|
||||
}
|
||||
|
||||
private void OnObjectChanged(DBObject dbObject) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => OnChangeChangedObjectIds(dbObject));
|
||||
private async void DatabaseOnObjectAppended(object sender, ObjectEventArgs e) =>
|
||||
await _eventAggregator.GetEvent<ObjectAppendedEvent>().PublishAsync(e);
|
||||
|
||||
private async void DatabaseOnObjectErased(object sender, ObjectErasedEventArgs e) =>
|
||||
await _eventAggregator.GetEvent<ObjectErasedEvent>().PublishAsync(e);
|
||||
|
||||
private async void DatabaseObjectModified(object sender, ObjectEventArgs e) =>
|
||||
await _eventAggregator.GetEvent<ObjectModifiedEvent>().PublishAsync(e);
|
||||
|
||||
private void OnObjectAppended(ObjectEventArgs e) => OnChangeChangedObjectIds(e.DBObject);
|
||||
|
||||
private void ObjectErased(ObjectErasedEventArgs e) => OnChangeChangedObjectIds(e.DBObject);
|
||||
|
||||
private void ObjectModified(ObjectEventArgs e) => OnChangeChangedObjectIds(e.DBObject);
|
||||
|
||||
private void OnChangeChangedObjectIds(DBObject dBObject)
|
||||
{
|
||||
ChangedObjectIds[dBObject.GetSpeckleApplicationId()] = 1;
|
||||
_idleManager.SubscribeToIdle(nameof(AutocadSendBinding), async () => await RunExpirationChecks());
|
||||
_eventAggregator.GetEvent<IdleEvent>().OneTimeSubscribe(nameof(AutocadSendBinding), RunExpirationChecks);
|
||||
}
|
||||
|
||||
private async Task RunExpirationChecks()
|
||||
private async Task RunExpirationChecks(object _)
|
||||
{
|
||||
var senders = _store.GetSenders();
|
||||
string[] objectIdsList = ChangedObjectIds.Keys.ToArray();
|
||||
@@ -145,7 +175,7 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
public List<ICardSetting> GetSendSettings() => [];
|
||||
|
||||
public async Task Send(string modelCardId) =>
|
||||
await _threadContext.RunOnMainAsync(async () => await SendInternal(modelCardId));
|
||||
await _threadContext.RunOnWorkerAsync(async () => await SendInternal(modelCardId));
|
||||
|
||||
protected abstract void InitializeSettings(IServiceProvider serviceProvider);
|
||||
|
||||
@@ -184,7 +214,7 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
.ServiceProvider.GetRequiredService<SendOperation<AutocadRootObject>>()
|
||||
.Execute(
|
||||
autocadObjects,
|
||||
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
|
||||
cancellationItem.Token
|
||||
);
|
||||
|
||||
@@ -5,6 +5,7 @@ using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Converters.Autocad;
|
||||
@@ -29,8 +30,7 @@ public sealed class AutocadSendBinding : AutocadSendBaseBinding
|
||||
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
|
||||
ISpeckleApplication speckleApplication,
|
||||
IThreadContext threadContext,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IAppIdleManager appIdleManager
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
: base(
|
||||
store,
|
||||
@@ -43,8 +43,7 @@ public sealed class AutocadSendBinding : AutocadSendBaseBinding
|
||||
logger,
|
||||
speckleApplication,
|
||||
threadContext,
|
||||
topLevelExceptionHandler,
|
||||
appIdleManager
|
||||
eventAggregator
|
||||
)
|
||||
{
|
||||
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
|
||||
|
||||
-3
@@ -13,7 +13,6 @@ using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Connectors.DUI.WebView;
|
||||
using Speckle.Sdk.Models.GraphTraversal;
|
||||
@@ -49,8 +48,6 @@ public static class SharedRegistration
|
||||
serviceCollection.AddScoped<AutocadMaterialUnpacker>();
|
||||
serviceCollection.AddScoped<IAutocadMaterialBaker, AutocadMaterialBaker>();
|
||||
|
||||
serviceCollection.AddSingleton<IAppIdleManager, AutocadIdleManager>();
|
||||
|
||||
// operation progress manager
|
||||
serviceCollection.AddSingleton<IOperationProgressManager, OperationProgressManager>();
|
||||
|
||||
|
||||
+20
-14
@@ -1,4 +1,6 @@
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Autodesk.AutoCAD.ApplicationServices;
|
||||
using Speckle.Connectors.Autocad.Plugin;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
|
||||
@@ -9,19 +11,28 @@ public class AutocadDocumentStore : DocumentModelStore
|
||||
private const string NULL_DOCUMENT_NAME = "Null Doc";
|
||||
private string _previousDocName;
|
||||
private readonly AutocadDocumentManager _autocadDocumentManager;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
|
||||
public AutocadDocumentStore(
|
||||
IJsonSerializer jsonSerializer,
|
||||
AutocadDocumentManager autocadDocumentManager,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
: base(jsonSerializer)
|
||||
{
|
||||
_autocadDocumentManager = autocadDocumentManager;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
_eventAggregator = eventAggregator;
|
||||
_previousDocName = NULL_DOCUMENT_NAME;
|
||||
|
||||
eventAggregator.GetEvent<DocumentActivatedEvent>().Subscribe(DocChanged);
|
||||
|
||||
// since below event triggered as secondary, it breaks the logic in OnDocChangeInternal function, leaving it here for now.
|
||||
// Autodesk.AutoCAD.ApplicationServices.Application.DocumentWindowCollection.DocumentWindowActivated += (_, args) =>
|
||||
// OnDocChangeInternal((Document)args.DocumentWindow.Document);
|
||||
}
|
||||
|
||||
public override async Task OnDocumentStoreInitialized()
|
||||
{
|
||||
// POC: Will be addressed to move it into AutocadContext!
|
||||
if (Application.DocumentManager.MdiActiveDocument != null)
|
||||
{
|
||||
@@ -29,18 +40,13 @@ public class AutocadDocumentStore : DocumentModelStore
|
||||
// POC: this logic might go when we have document management in context
|
||||
// It is with the case of if binding created with already a document
|
||||
// This is valid when user opens acad file directly double clicking
|
||||
OnDocChangeInternal(Application.DocumentManager.MdiActiveDocument);
|
||||
await TryDocChanged(Application.DocumentManager.MdiActiveDocument);
|
||||
}
|
||||
|
||||
Application.DocumentManager.DocumentActivated += (_, e) =>
|
||||
topLevelExceptionHandler.CatchUnhandled(() => OnDocChangeInternal(e.Document));
|
||||
|
||||
// since below event triggered as secondary, it breaks the logic in OnDocChangeInternal function, leaving it here for now.
|
||||
// Autodesk.AutoCAD.ApplicationServices.Application.DocumentWindowCollection.DocumentWindowActivated += (_, args) =>
|
||||
// OnDocChangeInternal((Document)args.DocumentWindow.Document);
|
||||
}
|
||||
|
||||
private void OnDocChangeInternal(Document? doc)
|
||||
private async Task DocChanged(DocumentCollectionEventArgs e) => await TryDocChanged(e.Document);
|
||||
|
||||
private async Task TryDocChanged(Document? doc)
|
||||
{
|
||||
var currentDocName = doc != null ? doc.Name : NULL_DOCUMENT_NAME;
|
||||
if (_previousDocName == currentDocName)
|
||||
@@ -50,7 +56,7 @@ public class AutocadDocumentStore : DocumentModelStore
|
||||
|
||||
_previousDocName = currentDocName;
|
||||
LoadState();
|
||||
OnDocumentChanged();
|
||||
await _eventAggregator.GetEvent<DocumentStoreChangedEvent>().PublishAsync(new object());
|
||||
}
|
||||
|
||||
protected override void LoadState()
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.InterfaceGenerator;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.HostApp;
|
||||
|
||||
public partial interface IAutocadIdleManager : IAppIdleManager;
|
||||
|
||||
[GenerateAutoInterface]
|
||||
public sealed class AutocadIdleManager(IIdleCallManager idleCallManager)
|
||||
: AppIdleManager(idleCallManager),
|
||||
IAutocadIdleManager
|
||||
{
|
||||
private readonly IIdleCallManager _idleCallManager = idleCallManager;
|
||||
|
||||
protected override void AddEvent() => Application.Idle += AutocadAppOnIdle;
|
||||
|
||||
private void AutocadAppOnIdle(object? sender, EventArgs e) =>
|
||||
_idleCallManager.AppOnIdle(() => Application.Idle -= AutocadAppOnIdle);
|
||||
}
|
||||
+8
-19
@@ -160,21 +160,15 @@ public class AutocadHostObjectBuilder(
|
||||
var converted = converter.Convert(obj);
|
||||
|
||||
// 2: handle result
|
||||
switch (converted)
|
||||
if (converted is Entity entity)
|
||||
{
|
||||
case Entity entity:
|
||||
var bakedEntity = BakeObject(entity, obj, layerName);
|
||||
convertedEntities.Add(bakedEntity);
|
||||
break;
|
||||
|
||||
case List<(Entity, Base)> listConversionResult: // this is from fallback conversion for brep/brepx/subdx/extrusionx/polycurve
|
||||
var bakedFallbackEntities = BakeObjectsAsGroup(listConversionResult, obj, layerName, baseLayerNamePrefix);
|
||||
convertedEntities.UnionWith(bakedFallbackEntities);
|
||||
break;
|
||||
|
||||
default:
|
||||
// TODO: capture defualt case with report object here? Same as in Rhino
|
||||
break;
|
||||
var bakedEntity = BakeObject(entity, obj, layerName);
|
||||
convertedEntities.Add(bakedEntity);
|
||||
}
|
||||
else if (converted is List<(Entity, Base)> fallbackConversionResult)
|
||||
{
|
||||
var bakedFallbackEntities = BakeObjectsAsGroup(fallbackConversionResult, obj, layerName, baseLayerNamePrefix);
|
||||
convertedEntities.UnionWith(bakedFallbackEntities);
|
||||
}
|
||||
|
||||
tr.Commit();
|
||||
@@ -214,11 +208,6 @@ public class AutocadHostObjectBuilder(
|
||||
entities.Add(conversionResult);
|
||||
}
|
||||
|
||||
if (entities.Count <= 1) // return if empty list or only one, because we don't want to create empty or single item groups.
|
||||
{
|
||||
return entities;
|
||||
}
|
||||
|
||||
var tr = Application.DocumentManager.CurrentDocument.Database.TransactionManager.TopTransaction;
|
||||
var groupDictionary = (DBDictionary)
|
||||
tr.GetObject(Application.DocumentManager.CurrentDocument.Database.GroupDictionaryId, OpenMode.ForWrite);
|
||||
|
||||
@@ -4,6 +4,7 @@ using Autodesk.AutoCAD.Windows;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.Common;
|
||||
using Speckle.Connectors.DUI;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.WebView;
|
||||
#if AUTOCAD
|
||||
using Speckle.Connectors.Autocad.DependencyInjection;
|
||||
@@ -48,6 +49,7 @@ public class AutocadCommand
|
||||
services.AddCivil3dConverters();
|
||||
#endif
|
||||
Container = services.BuildServiceProvider();
|
||||
AutocadEvents.Register(Container.GetRequiredService<IEventAggregator>());
|
||||
Container.UseDUI();
|
||||
|
||||
var panelWebView = Container.GetRequiredService<DUI3ControlWebView>();
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
using Autodesk.AutoCAD.ApplicationServices;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Plugin;
|
||||
|
||||
public class DocumentActivatedEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: ThreadedEvent<DocumentCollectionEventArgs>(threadContext, exceptionHandler);
|
||||
|
||||
public class DocumentToBeDestroyedEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: ThreadedEvent<DocumentCollectionEventArgs>(threadContext, exceptionHandler);
|
||||
|
||||
public class ImpliedSelectionChangedEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: ThreadedEvent<EventArgs>(threadContext, exceptionHandler);
|
||||
|
||||
public class ObjectAppendedEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: ThreadedEvent<ObjectEventArgs>(threadContext, exceptionHandler);
|
||||
|
||||
public class ObjectErasedEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: ThreadedEvent<ObjectErasedEventArgs>(threadContext, exceptionHandler);
|
||||
|
||||
public class ObjectModifiedEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: ThreadedEvent<ObjectEventArgs>(threadContext, exceptionHandler);
|
||||
|
||||
public static class AutocadEvents
|
||||
{
|
||||
public static void Register(IEventAggregator eventAggregator)
|
||||
{
|
||||
Application.Idle += async (_, e) => await eventAggregator.GetEvent<IdleEvent>().PublishAsync(e);
|
||||
|
||||
Application.DocumentManager.DocumentActivated += async (_, e) =>
|
||||
await eventAggregator.GetEvent<DocumentActivatedEvent>().PublishAsync(e);
|
||||
Application.DocumentManager.DocumentToBeDestroyed += async (_, e) =>
|
||||
await eventAggregator.GetEvent<DocumentToBeDestroyedEvent>().PublishAsync(e);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -21,7 +21,6 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadColorUnpacker.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadGroupBaker.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadGroupUnpacker.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadIdleManager.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadInstanceBaker.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadInstanceUnpacker.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadLayerBaker.cs" />
|
||||
@@ -41,6 +40,7 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\AutocadRootObject.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\AutocadRootObjectBaseBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\AutocadRootObjectBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\AutocadEvents.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\AutocadRibbon.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\AutocadExtensionApplication.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\AutocadCommand.cs" />
|
||||
|
||||
@@ -268,9 +268,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -278,8 +278,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -304,7 +304,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -343,40 +343,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,9 +268,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -278,8 +278,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -304,7 +304,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -343,40 +343,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,9 +268,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -278,8 +278,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -304,7 +304,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -343,40 +343,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,9 +224,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -234,8 +234,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -261,7 +261,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -300,39 +300,39 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
|
||||
@@ -6,6 +6,7 @@ using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Converters.Autocad;
|
||||
@@ -33,8 +34,7 @@ public sealed class Civil3dSendBinding : AutocadSendBaseBinding
|
||||
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
|
||||
ISpeckleApplication speckleApplication,
|
||||
IThreadContext threadContext,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IAppIdleManager appIdleManager
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
: base(
|
||||
store,
|
||||
@@ -47,8 +47,7 @@ public sealed class Civil3dSendBinding : AutocadSendBaseBinding
|
||||
logger,
|
||||
speckleApplication,
|
||||
threadContext,
|
||||
topLevelExceptionHandler,
|
||||
appIdleManager
|
||||
eventAggregator
|
||||
)
|
||||
{
|
||||
_civil3dConversionSettingsFactory = civil3dConversionSettingsFactory;
|
||||
|
||||
+3
@@ -6,6 +6,7 @@ using Speckle.Connectors.Civil3dShared.Bindings;
|
||||
using Speckle.Connectors.Civil3dShared.Operations.Send;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Converters.Civil3dShared.Helpers;
|
||||
using Speckle.Converters.Civil3dShared.ToSpeckle;
|
||||
using Speckle.Sdk;
|
||||
|
||||
@@ -27,5 +28,7 @@ public static class Civil3dConnectorModule
|
||||
|
||||
// additional classes
|
||||
serviceCollection.AddScoped<PropertySetDefinitionHandler>();
|
||||
serviceCollection.AddScoped<CatchmentGroupHandler>();
|
||||
serviceCollection.AddScoped<PipeNetworkHandler>();
|
||||
}
|
||||
}
|
||||
|
||||
+9
@@ -4,6 +4,7 @@ using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Converters.Civil3dShared.Helpers;
|
||||
using Speckle.Converters.Civil3dShared.ToSpeckle;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk.Logging;
|
||||
@@ -15,10 +16,14 @@ public sealed class Civil3dRootObjectBuilder : AutocadRootObjectBaseBuilder
|
||||
{
|
||||
private readonly AutocadLayerUnpacker _layerUnpacker;
|
||||
private readonly PropertySetDefinitionHandler _propertySetDefinitionHandler;
|
||||
private readonly CatchmentGroupHandler _catchmentGroupHandler;
|
||||
private readonly PipeNetworkHandler _pipeNetworkHandler;
|
||||
|
||||
public Civil3dRootObjectBuilder(
|
||||
AutocadLayerUnpacker layerUnpacker,
|
||||
PropertySetDefinitionHandler propertySetDefinitionHandler,
|
||||
CatchmentGroupHandler catchmentGroupHandler,
|
||||
PipeNetworkHandler pipeNetworkHandler,
|
||||
IRootToSpeckleConverter converter,
|
||||
ISendConversionCache sendConversionCache,
|
||||
AutocadInstanceUnpacker instanceObjectManager,
|
||||
@@ -41,6 +46,8 @@ public sealed class Civil3dRootObjectBuilder : AutocadRootObjectBaseBuilder
|
||||
{
|
||||
_layerUnpacker = layerUnpacker;
|
||||
_propertySetDefinitionHandler = propertySetDefinitionHandler;
|
||||
_catchmentGroupHandler = catchmentGroupHandler;
|
||||
_pipeNetworkHandler = pipeNetworkHandler;
|
||||
}
|
||||
|
||||
public override (Collection, LayerTableRecord?) CreateObjectCollection(Entity entity, Transaction tr)
|
||||
@@ -54,5 +61,7 @@ public sealed class Civil3dRootObjectBuilder : AutocadRootObjectBaseBuilder
|
||||
public override void AddAdditionalProxiesToRoot(Collection rootObject)
|
||||
{
|
||||
rootObject[ProxyKeys.PROPERTYSET_DEFINITIONS] = _propertySetDefinitionHandler.Definitions;
|
||||
rootObject["catchmentGroupProxies"] = _catchmentGroupHandler.CatchmentGroupProxiesCache.Values.ToList();
|
||||
rootObject["pipeNetworkProxies"] = _pipeNetworkHandler.PipeNetworkProxiesCache.Values.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
+11
-26
@@ -1,6 +1,6 @@
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Sdk;
|
||||
@@ -11,8 +11,7 @@ public class CsiSharedBasicConnectorBinding : IBasicConnectorBinding
|
||||
{
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IThreadContext _threadContext;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
public string Name => "baseBinding";
|
||||
public IBrowserBridge Parent { get; }
|
||||
public BasicConnectorBindingCommands Commands { get; }
|
||||
@@ -21,28 +20,20 @@ public class CsiSharedBasicConnectorBinding : IBasicConnectorBinding
|
||||
IBrowserBridge parent,
|
||||
ISpeckleApplication speckleApplication,
|
||||
DocumentModelStore store,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IThreadContext threadContext
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
{
|
||||
_threadContext = threadContext;
|
||||
Parent = parent;
|
||||
_speckleApplication = speckleApplication;
|
||||
_store = store;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
Commands = new BasicConnectorBindingCommands(Parent);
|
||||
_eventAggregator = eventAggregator;
|
||||
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
// enforce main thread
|
||||
await _threadContext.RunOnMainAsync(async () =>
|
||||
{
|
||||
await Commands.NotifyDocumentChanged();
|
||||
});
|
||||
});
|
||||
_eventAggregator.GetEvent<DocumentStoreChangedEvent>().Subscribe(OnDocumentStoreChangedEvent);
|
||||
}
|
||||
|
||||
private async Task OnDocumentStoreChangedEvent(object _) => await Commands.NotifyDocumentChanged();
|
||||
|
||||
public string GetConnectorVersion() => _speckleApplication.SpeckleVersion;
|
||||
|
||||
public string GetSourceApplicationName() => _speckleApplication.Slug;
|
||||
@@ -53,17 +44,11 @@ public class CsiSharedBasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
public DocumentModelStore GetDocumentState() => _store;
|
||||
|
||||
/// <remarks>Operations must run on the main thread for ETABS and SAP 2000</remarks>
|
||||
public void AddModel(ModelCard model) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnThread(() => _store.AddModel(model), true));
|
||||
public void AddModel(ModelCard model) => _store.AddModel(model);
|
||||
|
||||
/// <remarks>Operations must run on the main thread for ETABS and SAP 2000</remarks>
|
||||
public void UpdateModel(ModelCard model) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnThread(() => _store.UpdateModel(model), true));
|
||||
public void UpdateModel(ModelCard model) => _store.UpdateModel(model);
|
||||
|
||||
/// <remarks>Operations must run on the main thread for ETABS and SAP 2000</remarks>
|
||||
public void RemoveModel(ModelCard model) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnThread(() => _store.RemoveModel(model), true));
|
||||
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
|
||||
|
||||
public Task HighlightModel(string modelCardId) => Task.CompletedTask;
|
||||
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.CSiShared.Events;
|
||||
using Speckle.Connectors.CSiShared.HostApp;
|
||||
using Speckle.Connectors.CSiShared.Utils;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Converters.CSiShared.Utils;
|
||||
using Timer = System.Timers.Timer;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared.Bindings;
|
||||
|
||||
public class CsiSharedSelectionBinding : ISelectionBinding, IDisposable
|
||||
public sealed class CsiSharedSelectionBinding : ISelectionBinding
|
||||
{
|
||||
private bool _disposed;
|
||||
private readonly Timer _selectionTimer;
|
||||
private readonly ICsiApplicationService _csiApplicationService;
|
||||
private readonly IThreadContext _threadContext;
|
||||
private HashSet<string> _lastSelection = new();
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
|
||||
public IBrowserBridge Parent { get; }
|
||||
public string Name => "selectionBinding";
|
||||
@@ -23,58 +19,27 @@ public class CsiSharedSelectionBinding : ISelectionBinding, IDisposable
|
||||
public CsiSharedSelectionBinding(
|
||||
IBrowserBridge parent,
|
||||
ICsiApplicationService csiApplicationService,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IThreadContext threadContext
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
{
|
||||
_threadContext = threadContext;
|
||||
Parent = parent;
|
||||
_csiApplicationService = csiApplicationService;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
|
||||
_selectionTimer = new Timer(1000);
|
||||
_selectionTimer.Elapsed += (_, _) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnMain(CheckSelectionChanged));
|
||||
_selectionTimer.Start();
|
||||
eventAggregator.GetEvent<SelectionBindingEvent>().SubscribePeriodic(TimeSpan.FromSeconds(1), CheckSelectionChanged);
|
||||
}
|
||||
|
||||
private void CheckSelectionChanged()
|
||||
private void CheckSelectionChanged(object _)
|
||||
{
|
||||
// timer callbacks are on a background thread, but CSI API calls must be on main thread
|
||||
var currentSelection = GetSelection();
|
||||
var currentIds = new HashSet<string>(currentSelection.SelectedObjectIds);
|
||||
|
||||
if (!_lastSelection.SetEquals(currentIds))
|
||||
{
|
||||
_lastSelection = currentIds;
|
||||
// ensure UI updates also run on main thread
|
||||
_threadContext.RunOnMain(
|
||||
() =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(
|
||||
() => Parent.Send(SelectionBindingEvents.SET_SELECTION, currentSelection)
|
||||
)
|
||||
);
|
||||
Parent.Send(SelectionBindingEvents.SET_SELECTION, currentSelection);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_selectionTimer?.Dispose();
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the selection and creates an encoded ID (objectType and objectName).
|
||||
/// </summary>
|
||||
@@ -91,18 +56,22 @@ public class CsiSharedSelectionBinding : ISelectionBinding, IDisposable
|
||||
|
||||
var encodedIds = new List<string>(numberItems);
|
||||
var typeCounts = new Dictionary<string, int>();
|
||||
|
||||
for (int i = 0; i < numberItems; i++)
|
||||
{
|
||||
var typeKey = (ModelObjectType)objectType[i];
|
||||
var typeName = typeKey.ToString();
|
||||
|
||||
encodedIds.Add(ObjectIdentifier.Encode(objectType[i], objectName[i]));
|
||||
typeCounts[typeName] = (typeCounts.TryGetValue(typeName, out var count) ? count : 0) + 1; // NOTE: Cross-framework compatibility (net 48 and net8)
|
||||
}
|
||||
|
||||
var summary =
|
||||
encodedIds.Count == 0
|
||||
? "No objects selected."
|
||||
: $"{encodedIds.Count} objects ({string.Join(", ",
|
||||
typeCounts.Select(kv => $"{kv.Value} {kv.Key}"))})";
|
||||
|
||||
return new SelectionInfo(encodedIds, summary);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ public sealed class CsiSharedSendBinding : ISendBinding
|
||||
.ServiceProvider.GetRequiredService<SendOperation<ICsiWrapper>>()
|
||||
.Execute(
|
||||
wrappers,
|
||||
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
|
||||
cancellationItem.Token
|
||||
);
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared.Events;
|
||||
|
||||
public class ModelChangedEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: PeriodicThreadedEvent(threadContext, exceptionHandler);
|
||||
@@ -0,0 +1,8 @@
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared.Events;
|
||||
|
||||
public class SelectionBindingEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: PeriodicThreadedEvent(threadContext, exceptionHandler);
|
||||
@@ -1,26 +1,22 @@
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.CSiShared.Events;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Helpers;
|
||||
using Speckle.Sdk.Logging;
|
||||
using Timer = System.Timers.Timer;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared.HostApp;
|
||||
|
||||
public class CsiDocumentModelStore : DocumentModelStore, IDisposable
|
||||
public class CsiDocumentModelStore : DocumentModelStore
|
||||
{
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly ILogger<CsiDocumentModelStore> _logger;
|
||||
private readonly ICsiApplicationService _csiApplicationService;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IThreadContext _threadContext;
|
||||
private readonly Timer _modelCheckTimer;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private string _lastModelFilename = string.Empty;
|
||||
private bool _disposed;
|
||||
private string HostAppUserDataPath { get; set; }
|
||||
private string DocumentStateFile { get; set; }
|
||||
private string ModelPathHash { get; set; }
|
||||
@@ -30,27 +26,18 @@ public class CsiDocumentModelStore : DocumentModelStore, IDisposable
|
||||
ISpeckleApplication speckleApplication,
|
||||
ILogger<CsiDocumentModelStore> logger,
|
||||
ICsiApplicationService csiApplicationService,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IThreadContext threadContext
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
: base(jsonSerializer)
|
||||
{
|
||||
_threadContext = threadContext;
|
||||
_speckleApplication = speckleApplication;
|
||||
_logger = logger;
|
||||
_csiApplicationService = csiApplicationService;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
|
||||
// initialize timer to check for model changes
|
||||
_modelCheckTimer = new Timer(1000);
|
||||
|
||||
// timer runs on background thread but model checks must be on main thread
|
||||
_modelCheckTimer.Elapsed += (_, _) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnMain(CheckModelChanges));
|
||||
_modelCheckTimer.Start();
|
||||
_eventAggregator = eventAggregator;
|
||||
eventAggregator.GetEvent<ModelChangedEvent>().SubscribePeriodic(TimeSpan.FromSeconds(1), CheckModelChanges);
|
||||
}
|
||||
|
||||
private void CheckModelChanges()
|
||||
private async Task CheckModelChanges(object _)
|
||||
{
|
||||
string currentFilename = _csiApplicationService.SapModel.GetModelFilename();
|
||||
|
||||
@@ -62,7 +49,8 @@ public class CsiDocumentModelStore : DocumentModelStore, IDisposable
|
||||
_lastModelFilename = currentFilename;
|
||||
SetPaths();
|
||||
LoadState();
|
||||
OnDocumentChanged();
|
||||
|
||||
await _eventAggregator.GetEvent<DocumentStoreChangedEvent>().PublishAsync(new object());
|
||||
}
|
||||
|
||||
public override Task OnDocumentStoreInitialized()
|
||||
@@ -132,25 +120,4 @@ public class CsiDocumentModelStore : DocumentModelStore, IDisposable
|
||||
ClearAndSave();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
_modelCheckTimer.Dispose();
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\CsiSharedBasicConnectorBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\CsiSharedSelectionBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\CsiSharedSendBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Events\ModelChangedEvent.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Events\SelectionBindingEvent.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Filters\CsiSharedSelectionFilter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\MaterialUnpacker.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\CsiSendCollectionManager.cs" />
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,8 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -287,7 +287,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.etabs21": {
|
||||
@@ -332,40 +332,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,9 +215,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -225,8 +225,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -243,7 +243,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.etabs22": {
|
||||
@@ -288,39 +288,39 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,8 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -287,7 +287,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2020": {
|
||||
@@ -334,40 +334,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,8 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -287,7 +287,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2021": {
|
||||
@@ -334,40 +334,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,8 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -287,7 +287,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2022": {
|
||||
@@ -334,40 +334,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,8 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -287,7 +287,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2023": {
|
||||
@@ -334,40 +334,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,8 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -287,7 +287,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2024": {
|
||||
@@ -334,40 +334,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
@@ -265,9 +265,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -275,8 +275,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -293,7 +293,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2025": {
|
||||
@@ -334,40 +334,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
+9
-8
@@ -1,34 +1,35 @@
|
||||
using Speckle.Connector.Navisworks.Services;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
|
||||
namespace Speckle.Connector.Navisworks.Bindings;
|
||||
|
||||
public class NavisworksSelectionBinding : ISelectionBinding
|
||||
{
|
||||
private readonly IAppIdleManager _idleManager;
|
||||
private readonly IElementSelectionService _selectionService;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private const string SELECTION_EVENT = "setSelection";
|
||||
public string Name { get; } = "selectionBinding";
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
public NavisworksSelectionBinding(
|
||||
IAppIdleManager idleManager,
|
||||
IBrowserBridge parent,
|
||||
IElementSelectionService selectionService
|
||||
IElementSelectionService selectionService,
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
{
|
||||
_idleManager = idleManager;
|
||||
_selectionService = selectionService;
|
||||
_eventAggregator = eventAggregator;
|
||||
Parent = parent;
|
||||
|
||||
NavisworksApp.ActiveDocument.CurrentSelection.Changed += OnSelectionChange;
|
||||
eventAggregator.GetEvent<SelectionChangedEvent>().Subscribe(OnSelectionChange);
|
||||
}
|
||||
|
||||
private void OnSelectionChange(object? o, EventArgs eventArgs) =>
|
||||
_idleManager.SubscribeToIdle(nameof(NavisworksSelectionBinding), async () => await UpdateSelectionAsync());
|
||||
private void OnSelectionChange(object _) =>
|
||||
_eventAggregator.GetEvent<IdleEvent>().OneTimeSubscribe(nameof(NavisworksSelectionBinding), UpdateSelectionAsync);
|
||||
|
||||
private async Task UpdateSelectionAsync()
|
||||
private async Task UpdateSelectionAsync(object _)
|
||||
{
|
||||
var selInfo = GetSelection();
|
||||
await Parent.Send(SELECTION_EVENT, selInfo);
|
||||
|
||||
+14
-32
@@ -1,11 +1,9 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connector.Navisworks.Operations.Send.Filters;
|
||||
using Speckle.Connector.Navisworks.Operations.Send.Settings;
|
||||
using Speckle.Connector.Navisworks.Services;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Exceptions;
|
||||
@@ -31,6 +29,7 @@ public class NavisworksSendBinding : ISendBinding
|
||||
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly List<ISendFilter> _sendFilters;
|
||||
private readonly ICancellationManager _cancellationManager;
|
||||
private readonly IOperationProgressManager _operationProgressManager;
|
||||
private readonly ILogger<NavisworksSendBinding> _logger;
|
||||
@@ -39,11 +38,11 @@ public class NavisworksSendBinding : ISendBinding
|
||||
private readonly INavisworksConversionSettingsFactory _conversionSettingsFactory;
|
||||
private readonly ToSpeckleSettingsManagerNavisworks _toSpeckleSettingsManagerNavisworks;
|
||||
private readonly IElementSelectionService _selectionService;
|
||||
private readonly IThreadContext _threadContext;
|
||||
|
||||
public NavisworksSendBinding(
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
IEnumerable<ISendFilter> sendFilters,
|
||||
IServiceProvider serviceProvider,
|
||||
ICancellationManager cancellationManager,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
@@ -52,14 +51,14 @@ public class NavisworksSendBinding : ISendBinding
|
||||
ISdkActivityFactory activityFactory,
|
||||
INavisworksConversionSettingsFactory conversionSettingsFactory,
|
||||
ToSpeckleSettingsManagerNavisworks toSpeckleSettingsManagerNavisworks,
|
||||
IElementSelectionService selectionService,
|
||||
IThreadContext threadContext
|
||||
IElementSelectionService selectionService
|
||||
)
|
||||
{
|
||||
Parent = parent;
|
||||
Commands = new SendBindingUICommands(parent);
|
||||
_store = store;
|
||||
_serviceProvider = serviceProvider;
|
||||
_sendFilters = sendFilters.ToList();
|
||||
_cancellationManager = cancellationManager;
|
||||
_operationProgressManager = operationProgressManager;
|
||||
_logger = logger;
|
||||
@@ -68,18 +67,12 @@ public class NavisworksSendBinding : ISendBinding
|
||||
_conversionSettingsFactory = conversionSettingsFactory;
|
||||
_toSpeckleSettingsManagerNavisworks = toSpeckleSettingsManagerNavisworks;
|
||||
_selectionService = selectionService;
|
||||
_threadContext = threadContext;
|
||||
SubscribeToNavisworksEvents();
|
||||
}
|
||||
|
||||
private static void SubscribeToNavisworksEvents() { }
|
||||
|
||||
// Do not change the behavior/scope of this class on send binding unless make sure the behavior is same. Otherwise, we might not be able to update list of saved sets.
|
||||
public List<ISendFilter> GetSendFilters() =>
|
||||
[
|
||||
new NavisworksSelectionFilter() { IsDefault = true },
|
||||
new NavisworksSavedSetsFilter(new ElementSelectionService())
|
||||
];
|
||||
public List<ISendFilter> GetSendFilters() => _sendFilters;
|
||||
|
||||
public List<ICardSetting> GetSendSettings() =>
|
||||
[
|
||||
@@ -87,13 +80,9 @@ public class NavisworksSendBinding : ISendBinding
|
||||
new OriginModeSetting(OriginMode.ModelOrigin),
|
||||
new IncludeInternalPropertiesSetting(false),
|
||||
new ConvertHiddenElementsSetting(false),
|
||||
new PreserveModelHierarchySetting(false),
|
||||
];
|
||||
|
||||
public async Task Send(string modelCardId) =>
|
||||
await _threadContext.RunOnMainAsync(async () => await SendInternal(modelCardId));
|
||||
|
||||
private async Task SendInternal(string modelCardId)
|
||||
public async Task Send(string modelCardId)
|
||||
{
|
||||
using var activity = _activityFactory.Start();
|
||||
try
|
||||
@@ -138,8 +127,7 @@ public class NavisworksSendBinding : ISendBinding
|
||||
originMode: _toSpeckleSettingsManagerNavisworks.GetOriginMode(modelCard),
|
||||
visualRepresentationMode: _toSpeckleSettingsManagerNavisworks.GetVisualRepresentationMode(modelCard),
|
||||
convertHiddenElements: _toSpeckleSettingsManagerNavisworks.GetConvertHiddenElements(modelCard),
|
||||
includeInternalProperties: _toSpeckleSettingsManagerNavisworks.GetIncludeInternalProperties(modelCard),
|
||||
preserveModelHierarchy: _toSpeckleSettingsManagerNavisworks.GetPreserveModelHierarchy(modelCard)
|
||||
includeInternalProperties: _toSpeckleSettingsManagerNavisworks.GetIncludeInternalProperties(modelCard)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -151,23 +139,17 @@ public class NavisworksSendBinding : ISendBinding
|
||||
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
|
||||
}
|
||||
|
||||
var modelItems = selectedPaths
|
||||
var modelItems = modelCard
|
||||
.SendFilter.NotNull()
|
||||
.RefreshObjectIds()
|
||||
.Select(_selectionService.GetModelItemFromPath)
|
||||
.SelectMany(_selectionService.GetGeometryNodes)
|
||||
.Where(_selectionService.IsVisible)
|
||||
.ToList();
|
||||
|
||||
if (modelItems.Count != 0)
|
||||
{
|
||||
return modelItems;
|
||||
}
|
||||
|
||||
var convertHiddenElementsSetting =
|
||||
modelCard.Settings!.FirstOrDefault(s => s.Id == "convertHiddenElements")?.Value as bool? ?? false;
|
||||
var message = convertHiddenElementsSetting
|
||||
? "No visible objects were found to convert. Please update your publish filter!"
|
||||
: "No objects were found to convert. Please update your publish filter, or check items are visible!";
|
||||
throw new SpeckleSendFilterException(message);
|
||||
return modelItems.Count == 0
|
||||
? throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!")
|
||||
: modelItems;
|
||||
}
|
||||
|
||||
private async Task<SendOperationResult> ExecuteSendOperation(
|
||||
@@ -180,7 +162,7 @@ public class NavisworksSendBinding : ISendBinding
|
||||
.ServiceProvider.GetRequiredService<SendOperation<NAV.ModelItem>>()
|
||||
.Execute(
|
||||
navisworksModelItems,
|
||||
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCard.ModelCardId.NotNull(), token),
|
||||
token
|
||||
);
|
||||
|
||||
-4
@@ -11,7 +11,6 @@ using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Connectors.DUI.WebView;
|
||||
@@ -52,8 +51,6 @@ public static class NavisworksConnectorServiceRegistration
|
||||
serviceCollection.AddScoped<NavisworksMaterialUnpacker>();
|
||||
serviceCollection.AddScoped<NavisworksColorUnpacker>();
|
||||
|
||||
serviceCollection.AddSingleton<IAppIdleManager, NavisworksIdleManager>();
|
||||
|
||||
// Sending operations
|
||||
serviceCollection.AddScoped<IRootObjectBuilder<NAV.ModelItem>, NavisworksRootObjectBuilder>();
|
||||
serviceCollection.AddScoped<SendOperation<NAV.ModelItem>>();
|
||||
@@ -67,7 +64,6 @@ public static class NavisworksConnectorServiceRegistration
|
||||
|
||||
// register filters
|
||||
serviceCollection.AddScoped<ISendFilter, NavisworksSelectionFilter>();
|
||||
serviceCollection.AddScoped<ISendFilter, NavisworksSavedSetsFilter>();
|
||||
serviceCollection.AddScoped<IElementSelectionService, ElementSelectionService>();
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -43,13 +43,12 @@ public class NavisworksColorUnpacker(
|
||||
Dictionary<string, ColorProxy> colorProxies = [];
|
||||
Dictionary<string, string> mergedIds = [];
|
||||
|
||||
// Build mergedIds map once
|
||||
foreach (var group in groupedNodes)
|
||||
{
|
||||
string groupKey = group.Key;
|
||||
|
||||
foreach (var nodePath in group.Value.Select(selectionService.GetModelItemPath))
|
||||
foreach (var node in group.Value)
|
||||
{
|
||||
mergedIds[nodePath] = groupKey;
|
||||
mergedIds[selectionService.GetModelItemPath(node)] = group.Key;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,13 +56,13 @@ public class NavisworksColorUnpacker(
|
||||
{
|
||||
try
|
||||
{
|
||||
// Skip non-2D elements
|
||||
if (!Is2DElement(navisworksObject))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var navisworksObjectId = selectionService.GetModelItemPath(navisworksObject);
|
||||
|
||||
var finalId = mergedIds.TryGetValue(navisworksObjectId, out var mergedId) ? mergedId : navisworksObjectId;
|
||||
|
||||
var geometry = navisworksObject.Geometry;
|
||||
@@ -78,6 +77,7 @@ public class NavisworksColorUnpacker(
|
||||
geometry.OriginalColor,
|
||||
defaultColor
|
||||
);
|
||||
|
||||
var colorId = Select(
|
||||
mode,
|
||||
$"{geometry.ActiveColor.GetHashCode()}_{geometry.ActiveTransparency}".GetHashCode(),
|
||||
|
||||
+26
-23
@@ -1,7 +1,7 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connector.Navisworks.Bindings;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
|
||||
namespace Speckle.Connector.Navisworks.HostApp;
|
||||
|
||||
@@ -12,8 +12,7 @@ namespace Speckle.Connector.Navisworks.HostApp;
|
||||
public sealed class NavisworksDocumentEvents
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IAppIdleManager _idleManager;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly object _subscriptionLock = new();
|
||||
|
||||
private bool _isSubscribed;
|
||||
@@ -26,23 +25,22 @@ public sealed class NavisworksDocumentEvents
|
||||
/// Initializes a new instance of the <see cref="NavisworksDocumentEvents"/> class and subscribes to document events.
|
||||
/// </summary>
|
||||
/// <param name="serviceProvider">The service provider for dependency injection.</param>
|
||||
public NavisworksDocumentEvents(
|
||||
IServiceProvider serviceProvider,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IAppIdleManager idleManager
|
||||
)
|
||||
public NavisworksDocumentEvents(IServiceProvider serviceProvider, IEventAggregator eventAggregator)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
_idleManager = idleManager;
|
||||
_eventAggregator = eventAggregator;
|
||||
|
||||
SubscribeToDocumentModelEvents();
|
||||
_eventAggregator.GetEvent<ActiveDocumentChangingEvent>().Subscribe(UnsubscribeFromDocumentModelEvents);
|
||||
_eventAggregator.GetEvent<ActiveDocumentChangedEvent>().Subscribe(SubscribeToDocumentModelEvents);
|
||||
_eventAggregator.GetEvent<CollectionChangingEvent>().Subscribe(HandleDocumentModelCountChanging);
|
||||
_eventAggregator.GetEvent<CollectionChangedEvent>().Subscribe(HandleDocumentModelCountChanged);
|
||||
SubscribeToDocumentModelEvents(new object());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribes to document-level events to monitor model state changes.
|
||||
/// </summary>
|
||||
private void SubscribeToDocumentModelEvents()
|
||||
private void SubscribeToDocumentModelEvents(object _)
|
||||
{
|
||||
lock (_subscriptionLock)
|
||||
{
|
||||
@@ -54,34 +52,39 @@ public sealed class NavisworksDocumentEvents
|
||||
var activeDocument = NavisworksApp.ActiveDocument;
|
||||
if (activeDocument != null)
|
||||
{
|
||||
activeDocument.Models.CollectionChanged += HandleDocumentModelCountChanged;
|
||||
activeDocument.Models.CollectionChanging += HandleDocumentModelCountChanging;
|
||||
activeDocument.Models.CollectionChanged += OnCollectionChanged;
|
||||
activeDocument.Models.CollectionChanging += OnCollectionChanging;
|
||||
}
|
||||
|
||||
_isSubscribed = true;
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnCollectionChanged(object sender, EventArgs _) =>
|
||||
await _eventAggregator.GetEvent<CollectionChangedEvent>().PublishAsync(sender);
|
||||
|
||||
private async void OnCollectionChanging(object sender, EventArgs _) =>
|
||||
await _eventAggregator.GetEvent<CollectionChangingEvent>().PublishAsync(sender);
|
||||
|
||||
/// <summary>
|
||||
/// Tracks the current model count before changes occur.
|
||||
/// </summary>
|
||||
private void HandleDocumentModelCountChanging(object sender, EventArgs e) =>
|
||||
private void HandleDocumentModelCountChanging(object sender) =>
|
||||
_priorModelCount = ((NAV.Document)sender).Models.Count;
|
||||
|
||||
/// <summary>
|
||||
/// Schedules processing of model count changes during idle time.
|
||||
/// </summary>
|
||||
private void HandleDocumentModelCountChanged(object sender, EventArgs e)
|
||||
private void HandleDocumentModelCountChanged(object sender)
|
||||
{
|
||||
_finalModelCount = ((NAV.Document)sender).Models.Count;
|
||||
|
||||
_topLevelExceptionHandler.CatchUnhandled(
|
||||
() =>
|
||||
_idleManager.SubscribeToIdle(nameof(NavisworksDocumentEvents), async () => await ProcessModelStateChangeAsync())
|
||||
);
|
||||
_eventAggregator
|
||||
.GetEvent<IdleEvent>()
|
||||
.OneTimeSubscribe(nameof(NavisworksDocumentEvents), ProcessModelStateChangeAsync);
|
||||
}
|
||||
|
||||
private async Task ProcessModelStateChangeAsync()
|
||||
private async Task ProcessModelStateChangeAsync(object _)
|
||||
{
|
||||
if (_isProcessing)
|
||||
{
|
||||
@@ -130,8 +133,8 @@ public sealed class NavisworksDocumentEvents
|
||||
|
||||
private void UnsubscribeFromModelEvents(NAV.Document document)
|
||||
{
|
||||
document.Models.CollectionChanged -= HandleDocumentModelCountChanged;
|
||||
document.Models.CollectionChanging -= HandleDocumentModelCountChanging;
|
||||
document.Models.CollectionChanged -= OnCollectionChanged;
|
||||
document.Models.CollectionChanging -= OnCollectionChanging;
|
||||
|
||||
var sendBinding = _serviceProvider
|
||||
.GetRequiredService<IEnumerable<IBinding>>()
|
||||
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
|
||||
namespace Speckle.Connector.Navisworks.HostApp;
|
||||
|
||||
/// <summary>
|
||||
/// Manages the scheduling of deferred operations during Navisworks idle periods.
|
||||
/// Ensures UI updates and operations are batched efficiently to prevent UI freezing.
|
||||
/// </summary>
|
||||
public sealed class NavisworksIdleManager : AppIdleManager
|
||||
{
|
||||
private readonly IIdleCallManager _idleCallManager;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the NavisworksIdleManager.
|
||||
/// </summary>
|
||||
/// <param name="idleCallManager">The manager responsible for queuing and executing deferred operations.</param>
|
||||
public NavisworksIdleManager(IIdleCallManager idleCallManager)
|
||||
: base(idleCallManager)
|
||||
{
|
||||
_idleCallManager = idleCallManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribes to Navisworks idle events when operations are queued.
|
||||
/// </summary>
|
||||
protected override void AddEvent() => NavisworksApp.Idle += NavisworksAppOnIdle;
|
||||
|
||||
private void NavisworksAppOnIdle(object? sender, EventArgs e) =>
|
||||
_idleCallManager.AppOnIdle(() => NavisworksApp.Idle -= NavisworksAppOnIdle);
|
||||
}
|
||||
+6
-4
@@ -43,13 +43,12 @@ public class NavisworksMaterialUnpacker(
|
||||
Dictionary<string, RenderMaterialProxy> renderMaterialProxies = [];
|
||||
Dictionary<string, string> mergedIds = [];
|
||||
|
||||
// Build mergedIds map once
|
||||
foreach (var group in groupedNodes)
|
||||
{
|
||||
string groupKey = group.Key;
|
||||
|
||||
foreach (var nodePath in group.Value.Select(selectionService.GetModelItemPath))
|
||||
foreach (var node in group.Value)
|
||||
{
|
||||
mergedIds[nodePath] = groupKey;
|
||||
mergedIds[selectionService.GetModelItemPath(node)] = group.Key;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +63,7 @@ public class NavisworksMaterialUnpacker(
|
||||
|
||||
var navisworksObjectId = selectionService.GetModelItemPath(navisworksObject);
|
||||
var finalId = mergedIds.TryGetValue(navisworksObjectId, out var mergedId) ? mergedId : navisworksObjectId;
|
||||
|
||||
var geometry = navisworksObject.Geometry;
|
||||
var mode = converterSettings.Current.User.VisualRepresentationMode;
|
||||
|
||||
@@ -76,6 +76,7 @@ public class NavisworksMaterialUnpacker(
|
||||
geometry.OriginalColor,
|
||||
defaultColor
|
||||
);
|
||||
|
||||
var renderTransparency = Select(
|
||||
mode,
|
||||
geometry.ActiveTransparency,
|
||||
@@ -83,6 +84,7 @@ public class NavisworksMaterialUnpacker(
|
||||
geometry.OriginalTransparency,
|
||||
0.0
|
||||
);
|
||||
|
||||
var renderMaterialId = Select(
|
||||
mode,
|
||||
$"{geometry.ActiveColor.GetHashCode()}_{geometry.ActiveTransparency}".GetHashCode(),
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
|
||||
namespace Speckle.Connector.Navisworks;
|
||||
|
||||
public class SelectionChangedEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: ThreadedEvent<object>(threadContext, exceptionHandler);
|
||||
|
||||
public class ActiveDocumentChangingEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: ThreadedEvent<object>(threadContext, exceptionHandler);
|
||||
|
||||
public class ActiveDocumentChangedEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: ThreadedEvent<object>(threadContext, exceptionHandler);
|
||||
|
||||
public class CollectionChangingEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: ThreadedEvent<object>(threadContext, exceptionHandler);
|
||||
|
||||
public class CollectionChangedEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: ThreadedEvent<object>(threadContext, exceptionHandler);
|
||||
|
||||
public static class NavisworksEvents
|
||||
{
|
||||
public static void Register(IEventAggregator eventAggregator)
|
||||
{
|
||||
NavisworksApp.Idle += async (_, _) => await eventAggregator.GetEvent<IdleEvent>().PublishAsync(new object());
|
||||
NavisworksApp.ActiveDocument.CurrentSelection.Changed += async (_, _) =>
|
||||
await eventAggregator.GetEvent<SelectionChangedEvent>().PublishAsync(new object());
|
||||
NavisworksApp.ActiveDocumentChanging += async (_, _) =>
|
||||
await eventAggregator.GetEvent<ActiveDocumentChangingEvent>().PublishAsync(new object());
|
||||
NavisworksApp.ActiveDocumentChanged += async (_, _) =>
|
||||
await eventAggregator.GetEvent<ActiveDocumentChangedEvent>().PublishAsync(new object());
|
||||
}
|
||||
}
|
||||
-107
@@ -1,107 +0,0 @@
|
||||
using Speckle.Connector.Navisworks.Services;
|
||||
using Speckle.Connectors.DUI.Exceptions;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
|
||||
namespace Speckle.Connector.Navisworks.Operations.Send.Filters;
|
||||
|
||||
public class NavisworksSavedSetsFilter : DiscriminatedObject, ISendFilterSelect
|
||||
{
|
||||
private readonly IElementSelectionService _selectionService;
|
||||
|
||||
public NavisworksSavedSetsFilter(IElementSelectionService selectionService)
|
||||
{
|
||||
_selectionService = selectionService;
|
||||
|
||||
GetSavedSets();
|
||||
}
|
||||
|
||||
public string Id { get; set; } = "navisworksSavedSets";
|
||||
public string Name { get; set; } = "Saved Sets";
|
||||
public string? Summary { get; set; }
|
||||
public bool IsDefault { get; set; }
|
||||
public List<string> SelectedObjectIds { get; set; } = [];
|
||||
public Dictionary<string, string>? IdMap { get; set; }
|
||||
|
||||
public bool IsMultiSelectable { get; set; } = true;
|
||||
public List<SendFilterSelectItem> SelectedItems { get; set; }
|
||||
public List<SendFilterSelectItem> Items { get; set; }
|
||||
|
||||
public List<string> RefreshObjectIds()
|
||||
{
|
||||
List<string> objectIds = [];
|
||||
|
||||
if (SelectedItems.Count == 0)
|
||||
{
|
||||
return objectIds;
|
||||
}
|
||||
|
||||
NAV.SavedItemCollection? selectionSets = NavisworksApp.ActiveDocument.SelectionSets.RootItem.Children;
|
||||
|
||||
foreach (var selectedSetGuid in SelectedItems)
|
||||
{
|
||||
var guid = new Guid(selectedSetGuid.Id);
|
||||
var index = selectionSets.IndexOfGuid(guid);
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
throw new SpeckleSendFilterException($"Selection set with GUID {guid} not found.");
|
||||
}
|
||||
|
||||
var selectionSetItem = selectionSets[index];
|
||||
var selectionSet = (NAV.SelectionSet)selectionSetItem;
|
||||
|
||||
if (selectionSet.HasSearch)
|
||||
{
|
||||
objectIds.AddRange(ResolveSearchSet(selectionSet.Search));
|
||||
}
|
||||
|
||||
if (selectionSet.HasExplicitModelItems)
|
||||
{
|
||||
objectIds.AddRange(ResolveSelectionSet(selectionSet.ExplicitModelItems));
|
||||
}
|
||||
}
|
||||
|
||||
return objectIds;
|
||||
}
|
||||
|
||||
private IEnumerable<string> ResolveSelectionSet(NAV.ModelItemCollection selectionSetExplicitModelItems) =>
|
||||
selectionSetExplicitModelItems
|
||||
.Where(_selectionService.IsVisible) // Exclude hidden elements
|
||||
.Select(_selectionService.GetModelItemPath) // Resolve to index paths
|
||||
.ToList();
|
||||
|
||||
private IEnumerable<string> ResolveSearchSet(NAV.Search selectionSetSearch) =>
|
||||
selectionSetSearch
|
||||
.FindAll(NavisworksApp.ActiveDocument, false)
|
||||
.Where(_selectionService.IsVisible) // Exclude hidden elements
|
||||
.Select(_selectionService.GetModelItemPath) // Resolve to index paths
|
||||
.ToList();
|
||||
|
||||
/// <summary>
|
||||
/// Since it is called from constructor, it is re-called whenever UI calls SendBinding.GetSendFilters() on SendFilter dialog.
|
||||
/// Do not change the behavior/scope of this class on send binding unless make sure the behavior is same. Otherwise we might not be able to update list of saved sets.
|
||||
/// </summary>
|
||||
private void GetSavedSets()
|
||||
{
|
||||
List<NAV.SavedItem> savedSetRecords = NavisworksApp
|
||||
.ActiveDocument.SelectionSets.RootItem.Children.Where(set => !set.IsGroup)
|
||||
.ToList();
|
||||
|
||||
Items = savedSetRecords
|
||||
.Select(setRecord =>
|
||||
{
|
||||
NAV.SavedItem? record = setRecord.CreateCopy();
|
||||
string? name = record.DisplayName;
|
||||
|
||||
while (record.Parent != null)
|
||||
{
|
||||
name = record.Parent.DisplayName + "::" + name;
|
||||
record = record.Parent;
|
||||
}
|
||||
|
||||
return new SendFilterSelectItem(setRecord.Guid.ToString(), name);
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
+6
-149
@@ -1,5 +1,4 @@
|
||||
using Speckle.Connector.Navisworks.Services;
|
||||
using Speckle.Converter.Navisworks.Constants;
|
||||
|
||||
namespace Speckle.Connector.Navisworks.Operations.Send;
|
||||
|
||||
@@ -8,158 +7,16 @@ namespace Speckle.Connector.Navisworks.Operations.Send;
|
||||
/// </summary>
|
||||
public static class GeometryNodeMerger
|
||||
{
|
||||
/// <summary>
|
||||
/// Groups sibling geometry nodes based on material properties for merging.
|
||||
/// Only merges nodes that share the same parent and have identical material properties.
|
||||
/// </summary>
|
||||
/// <param name="nodes">The collection of ModelItems to process</param>
|
||||
/// <returns>Dictionary mapping parent paths (with material signature suffix) to their mergeable child nodes</returns>
|
||||
public static Dictionary<string, List<NAV.ModelItem>> GroupSiblingGeometryNodes(IReadOnlyList<NAV.ModelItem> nodes)
|
||||
{
|
||||
var selectionService = new ElementSelectionService();
|
||||
|
||||
// Group nameless geometry nodes by parent path and material signature
|
||||
var mergeableGroups = nodes
|
||||
public static Dictionary<string, List<NAV.ModelItem>> GroupSiblingGeometryNodes(IReadOnlyList<NAV.ModelItem> nodes) =>
|
||||
nodes
|
||||
.Where(node => node.HasGeometry && string.IsNullOrEmpty(node.DisplayName)) // Only anonymous geometry nodes
|
||||
.GroupBy(node =>
|
||||
{
|
||||
// Get parent path
|
||||
var path = selectionService.GetModelItemPath(node);
|
||||
var service = new ElementSelectionService();
|
||||
var path = service.GetModelItemPath(node);
|
||||
var lastSeparatorIndex = path.LastIndexOf(PathConstants.SEPARATOR);
|
||||
var parentPath = lastSeparatorIndex == -1 ? path : path[..lastSeparatorIndex];
|
||||
|
||||
// Generate material signature
|
||||
string signature = GenerateSignature(node);
|
||||
|
||||
// Combine parent path with signature
|
||||
return $"{parentPath}{PathConstants.MATERIAL_SEPARATOR}{signature}";
|
||||
return lastSeparatorIndex == -1 ? path : path[..lastSeparatorIndex];
|
||||
})
|
||||
.Where(group => group.Count() > 1) // Only include groups with multiple children
|
||||
.Where(group => group.Count() > 1) // Only group multiples
|
||||
.ToDictionary(group => group.Key, group => group.ToList());
|
||||
|
||||
return mergeableGroups;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a signature for a node based on material properties
|
||||
/// </summary>
|
||||
private static string GenerateSignature(NAV.ModelItem node)
|
||||
{
|
||||
var signatureProperties = new Dictionary<string, object>();
|
||||
|
||||
// We can as many signature defining methods as we want here
|
||||
AddMaterialProperties(node, signatureProperties);
|
||||
|
||||
// When we are done adding properties, we can generate the signature
|
||||
return GetSignature(signatureProperties);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds material-related properties to the properties dictionary
|
||||
/// </summary>
|
||||
private static void AddMaterialProperties(NAV.ModelItem node, Dictionary<string, object> properties)
|
||||
{
|
||||
if (!node.HasGeometry || node.Geometry == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var geometry = node.Geometry;
|
||||
if (geometry.ActiveColor != null)
|
||||
{
|
||||
properties["ActiveColor"] = (geometry.ActiveColor.R, geometry.ActiveColor.G, geometry.ActiveColor.B);
|
||||
properties["ActiveTransparency"] = geometry.ActiveTransparency;
|
||||
}
|
||||
|
||||
// Add material name if available
|
||||
var materialName = GetMaterialName(node);
|
||||
if (!string.IsNullOrEmpty(materialName))
|
||||
{
|
||||
properties["MaterialName"] = materialName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a hash-based signature from a dictionary of properties.
|
||||
/// </summary>
|
||||
/// <param name="properties">Dictionary containing property name/value pairs to include in the signature</param>
|
||||
/// <param name="hashLength">Length of the returned hash string (default: 8 characters)</param>
|
||||
/// <returns>A hash string representing the combined properties</returns>
|
||||
private static string GetSignature(Dictionary<string, object> properties, int hashLength = 8)
|
||||
{
|
||||
if (properties.Count == 0)
|
||||
{
|
||||
return "empty";
|
||||
}
|
||||
|
||||
// Build a consistent string representation of all properties
|
||||
var hashInput = new System.Text.StringBuilder();
|
||||
|
||||
// Sort keys to ensure consistent order
|
||||
var sortedKeys = properties.Keys.OrderBy(k => k).ToList();
|
||||
|
||||
foreach (var key in sortedKeys)
|
||||
{
|
||||
var value = properties[key];
|
||||
switch (value)
|
||||
{
|
||||
case null:
|
||||
continue;
|
||||
// Format numbers with fixed precision to avoid floating point inconsistencies
|
||||
case double doubleValue:
|
||||
hashInput.Append($"{key}:{Math.Round(doubleValue, 6)}_");
|
||||
break;
|
||||
case float floatValue:
|
||||
hashInput.Append($"{key}:{Math.Round(floatValue, 6)}_");
|
||||
break;
|
||||
default:
|
||||
hashInput.Append($"{key}:{value.GetHashCode()}_");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hashInput.Length == 0)
|
||||
{
|
||||
return "empty";
|
||||
}
|
||||
|
||||
// Use MD5 hash with warning suppression
|
||||
#pragma warning disable CA5351 // Do Not Use Broken Cryptographic Algorithms
|
||||
using var md5 = System.Security.Cryptography.MD5.Create();
|
||||
var inputBytes = System.Text.Encoding.UTF8.GetBytes(hashInput.ToString());
|
||||
var hashBytes = md5.ComputeHash(inputBytes);
|
||||
#pragma warning restore CA5351
|
||||
|
||||
var fullHashString = BitConverter.ToString(hashBytes).Replace("-", "");
|
||||
return fullHashString[..Math.Min(hashLength, fullHashString.Length)];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts material name from a node if available.
|
||||
/// </summary>
|
||||
private static string GetMaterialName(NAV.ModelItem node)
|
||||
{
|
||||
// Check Item category for material name
|
||||
var itemCategory = node.PropertyCategories.FindCategoryByDisplayName("Item");
|
||||
if (itemCategory != null)
|
||||
{
|
||||
var itemProperties = itemCategory.Properties;
|
||||
var itemMaterial = itemProperties.FindPropertyByDisplayName("Material");
|
||||
if (itemMaterial != null && !string.IsNullOrEmpty(itemMaterial.DisplayName))
|
||||
{
|
||||
return itemMaterial.Value.ToDisplayString();
|
||||
}
|
||||
}
|
||||
|
||||
// Check Material category for material name
|
||||
var materialPropertyCategory = node.PropertyCategories.FindCategoryByDisplayName("Material");
|
||||
if (materialPropertyCategory == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var material = materialPropertyCategory.Properties;
|
||||
var name = material.FindPropertyByDisplayName("Name");
|
||||
return name != null && !string.IsNullOrEmpty(name.DisplayName) ? name.Value.ToDisplayString() : string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
-146
@@ -1,146 +0,0 @@
|
||||
using Speckle.Connector.Navisworks.Services;
|
||||
using Speckle.Converter.Navisworks.Constants;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
|
||||
namespace Speckle.Connector.Navisworks.Operations.Send;
|
||||
|
||||
/// <summary>
|
||||
/// Rebuilds the Navisworks document hierarchy from converted geometry leaves while preserving
|
||||
/// the parent-child relationships between elements in the original model structure.
|
||||
/// </summary>
|
||||
public class NavisworksHierarchyBuilder
|
||||
{
|
||||
private readonly Dictionary<string, Base?> _geometryLeaves;
|
||||
private readonly IRootToSpeckleConverter _converter;
|
||||
private readonly IElementSelectionService _selectionService;
|
||||
private readonly Dictionary<string, Base> _allNodes;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the NavisworksHierarchyBuilder.
|
||||
/// </summary>
|
||||
/// <param name="geometryLeaves">Dictionary of path-indexed converted geometry elements</param>
|
||||
/// <param name="converter">Converter to transform Navisworks elements to Speckle objects</param>
|
||||
/// <param name="selectionService">Service for resolving Navisworks element paths</param>
|
||||
public NavisworksHierarchyBuilder(
|
||||
Dictionary<string, Base?> geometryLeaves,
|
||||
IRootToSpeckleConverter converter,
|
||||
IElementSelectionService selectionService
|
||||
)
|
||||
{
|
||||
_geometryLeaves = geometryLeaves;
|
||||
_converter = converter;
|
||||
_selectionService = selectionService;
|
||||
_allNodes = new Dictionary<string, Base>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a hierarchical tree of Speckle objects that mirrors the Navisworks document structure.
|
||||
/// </summary>
|
||||
/// <returns>List of root-level Speckle Base objects containing the full hierarchy</returns>
|
||||
public List<Base> BuildHierarchy()
|
||||
{
|
||||
foreach (var kvp in _geometryLeaves)
|
||||
{
|
||||
if (kvp.Value != null)
|
||||
{
|
||||
_allNodes[kvp.Key] = kvp.Value;
|
||||
}
|
||||
}
|
||||
|
||||
// For each leaf path, traverse up the document structure converting any missing ancestors
|
||||
foreach (var nodePath in _allNodes.ToList().Select(kvp => kvp.Key))
|
||||
{
|
||||
ClimbUpToRoot(nodePath);
|
||||
}
|
||||
|
||||
var allPaths = _allNodes.Keys.ToList();
|
||||
allPaths.Sort(
|
||||
(a, b) =>
|
||||
{
|
||||
var depthA = a.Count(c => c == PathConstants.SEPARATOR);
|
||||
var depthB = b.Count(c => c == PathConstants.SEPARATOR);
|
||||
return depthB.CompareTo(depthA); // <- Sort in ascending order of path length
|
||||
}
|
||||
);
|
||||
|
||||
// Link nodes to parents and identify root nodes that have no recognized parent
|
||||
var rootCandidates = new Dictionary<string, Base>(_allNodes);
|
||||
|
||||
foreach (var nodePath in allPaths)
|
||||
{
|
||||
if (nodePath == "0")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var nodeBase = _allNodes[nodePath];
|
||||
var parentPath = GetParentPath(nodePath);
|
||||
|
||||
if (string.IsNullOrEmpty(parentPath))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Navisworks API: Add child elements to parent collections
|
||||
if (!_allNodes.TryGetValue(parentPath, out var parentBase) || parentBase is not Collection parentCollection)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
parentCollection.elements.Add(nodeBase);
|
||||
rootCandidates.Remove(nodePath);
|
||||
}
|
||||
|
||||
var rootNodes = rootCandidates.Values.ToList();
|
||||
PruneEmptyCollections(rootNodes);
|
||||
|
||||
return rootNodes;
|
||||
}
|
||||
|
||||
private void ClimbUpToRoot(string currentPath)
|
||||
{
|
||||
while (!string.IsNullOrEmpty(currentPath) && currentPath != "0")
|
||||
{
|
||||
var parentPath = GetParentPath(currentPath);
|
||||
|
||||
if (string.IsNullOrEmpty(parentPath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_allNodes.ContainsKey(parentPath))
|
||||
{
|
||||
currentPath = parentPath;
|
||||
continue;
|
||||
}
|
||||
|
||||
var parentModelItem = _selectionService.GetModelItemFromPath(parentPath);
|
||||
var parentConverted = _converter.Convert(parentModelItem);
|
||||
_allNodes[parentPath] = parentConverted;
|
||||
|
||||
currentPath = parentPath;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetParentPath(string path)
|
||||
{
|
||||
var idx = path.LastIndexOf(PathConstants.SEPARATOR);
|
||||
return idx == -1 ? string.Empty : path[..idx];
|
||||
}
|
||||
|
||||
private static void PruneEmptyCollections(List<Base> nodes)
|
||||
{
|
||||
foreach (var node in nodes.ToList())
|
||||
{
|
||||
if (node is not Collection collection)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
PruneEmptyCollections(collection.elements);
|
||||
collection.elements.RemoveAll(child => child is Collection { elements.Count: 0 });
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-20
@@ -144,27 +144,12 @@ public class NavisworksRootObjectBuilder(
|
||||
Dictionary<string, List<NAV.ModelItem>> groupedNodes
|
||||
)
|
||||
{
|
||||
// First build the grouped nodes as before
|
||||
var finalElements = new List<Base>();
|
||||
var processedPaths = new HashSet<string>();
|
||||
|
||||
AddGroupedElements(finalElements, convertedBases, groupedNodes, processedPaths);
|
||||
|
||||
// If hierarchy mode is enabled, reorganize into proper nested structure
|
||||
if (converterSettings.Current.User.PreserveModelHierarchy)
|
||||
{
|
||||
var hierarchyBuilder = new NavisworksHierarchyBuilder(
|
||||
convertedBases,
|
||||
rootToSpeckleConverter,
|
||||
elementSelectionService
|
||||
);
|
||||
|
||||
var hierarchy = hierarchyBuilder.BuildHierarchy();
|
||||
|
||||
return hierarchy;
|
||||
}
|
||||
|
||||
// Otherwise continue with flat mode
|
||||
AddRemainingElements(finalElements, convertedBases, processedPaths);
|
||||
|
||||
return finalElements;
|
||||
}
|
||||
|
||||
@@ -236,8 +221,7 @@ public class NavisworksRootObjectBuilder(
|
||||
/// </remarks>
|
||||
private NavisworksObject CreateNavisworksObject(string groupKey, List<Base> siblingBases)
|
||||
{
|
||||
string cleanParentPath = ElementSelectionHelper.GetCleanPath(groupKey);
|
||||
(string name, string path) = GetContext(cleanParentPath);
|
||||
(string name, string path) = GetContext(groupKey);
|
||||
|
||||
return new NavisworksObject
|
||||
{
|
||||
@@ -245,7 +229,7 @@ public class NavisworksRootObjectBuilder(
|
||||
displayValue = siblingBases.SelectMany(b => b["displayValue"] as List<Base> ?? []).ToList(),
|
||||
properties = siblingBases.First()["properties"] as Dictionary<string, object?> ?? [],
|
||||
units = converterSettings.Current.Derived.SpeckleUnits,
|
||||
applicationId = groupKey, // Use the full composite key as applicationId to preserve uniqueness
|
||||
applicationId = groupKey,
|
||||
["path"] = path
|
||||
};
|
||||
}
|
||||
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
using Speckle.Connectors.DUI.Settings;
|
||||
|
||||
namespace Speckle.Connector.Navisworks.Operations.Send.Settings;
|
||||
|
||||
public class PreserveModelHierarchySetting(bool value) : ICardSetting
|
||||
{
|
||||
public string? Id { get; set; } = "preserveModelHierarchy";
|
||||
public string? Title { get; set; } = "Preserve Model Hierarchy";
|
||||
public string? Type { get; set; } = "boolean";
|
||||
public List<string>? Enum { get; set; }
|
||||
public object? Value { get; set; } = value;
|
||||
}
|
||||
-18
@@ -17,7 +17,6 @@ public class ToSpeckleSettingsManagerNavisworks : IToSpeckleSettingsManagerNavis
|
||||
private readonly Dictionary<string, OriginMode> _originModeCache = [];
|
||||
private readonly Dictionary<string, bool?> _convertHiddenElementsCache = [];
|
||||
private readonly Dictionary<string, bool?> _includeInternalPropertiesCache = [];
|
||||
private readonly Dictionary<string, bool?> _preserveModelHierarchyCache = [];
|
||||
|
||||
public ToSpeckleSettingsManagerNavisworks(ISendConversionCache sendConversionCache)
|
||||
{
|
||||
@@ -121,23 +120,6 @@ public class ToSpeckleSettingsManagerNavisworks : IToSpeckleSettingsManagerNavis
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
public bool GetPreserveModelHierarchy([NotNull] SenderModelCard modelCard)
|
||||
{
|
||||
var value = modelCard.Settings?.FirstOrDefault(s => s.Id == "preserveModelHierarchy")?.Value as bool?;
|
||||
|
||||
var returnValue = value != null && value.NotNull();
|
||||
if (_preserveModelHierarchyCache.TryGetValue(modelCard.ModelCardId.NotNull(), out var previousValue))
|
||||
{
|
||||
if (previousValue != returnValue)
|
||||
{
|
||||
EvictCacheForModelCard(modelCard);
|
||||
}
|
||||
}
|
||||
|
||||
_preserveModelHierarchyCache[modelCard.ModelCardId] = returnValue;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private void EvictCacheForModelCard(SenderModelCard modelCard)
|
||||
{
|
||||
var objectIds = modelCard.SendFilter != null ? modelCard.SendFilter.NotNull().SelectedObjectIds : [];
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Speckle.Connector.Navisworks;
|
||||
|
||||
public static class PathConstants
|
||||
{
|
||||
public const char SEPARATOR = '/';
|
||||
}
|
||||
+2
@@ -7,6 +7,7 @@ using Speckle.Connector.Navisworks.HostApp;
|
||||
using Speckle.Connector.Navisworks.Plugin.Tools;
|
||||
using Speckle.Connectors.Common;
|
||||
using Speckle.Connectors.DUI;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.WebView;
|
||||
using Speckle.Converter.Navisworks.DependencyInjection;
|
||||
using Speckle.Sdk.Host;
|
||||
@@ -45,6 +46,7 @@ internal sealed class Connector : NAV.Plugins.DockPanePlugin
|
||||
services.AddNavisworksConverter();
|
||||
|
||||
Container = services.BuildServiceProvider();
|
||||
NavisworksEvents.Register(Container.GetRequiredService<IEventAggregator>());
|
||||
Container.UseDUI();
|
||||
Container.GetRequiredService<NavisworksDocumentEvents>();
|
||||
|
||||
|
||||
+2
-4
@@ -18,19 +18,17 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\NavisworksColorUnpacker.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\NavisworksDocumentEvents.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\NavisworksDocumentModelStore.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\NavisworksIdleManager.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\NavisworksMaterialUnpacker.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)NavisworksEvents.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\GeometryNodeMerger.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\NavisworksHierarchyBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\NavisworksRootObjectBuilder.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\ConvertHiddenEleementsSetting.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\IncludeInternalPropertiesSetting.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\OriginModeSetting.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\PreserveModelHierarchySetting.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\ToSpeckleSettingsManagerNavisworks.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\VisualRepresentationSetting.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Filters\NavisworksSelectionFilter.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Filters\NavisworksSavedSetsFilter.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)PathConstants.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\BrowserPane.xaml.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\DockableConnectorPane.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\NavisworksRibbon.xaml.cs"/>
|
||||
|
||||
@@ -287,9 +287,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -297,8 +297,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
@@ -308,7 +308,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2022": {
|
||||
@@ -348,16 +348,16 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -368,26 +368,26 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,9 +287,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -297,8 +297,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
@@ -308,7 +308,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2023": {
|
||||
@@ -348,16 +348,16 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -368,26 +368,26 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,9 +287,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -297,8 +297,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
@@ -308,7 +308,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2024": {
|
||||
@@ -348,16 +348,16 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -368,26 +368,26 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,9 +237,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -247,8 +247,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
@@ -258,7 +258,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2025": {
|
||||
@@ -298,16 +298,16 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -318,25 +318,25 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
|
||||
+8
-16
@@ -1,6 +1,7 @@
|
||||
using Autodesk.Revit.DB;
|
||||
using Revit.Async;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Connectors.RevitShared;
|
||||
@@ -20,16 +21,15 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
public BasicConnectorBindingCommands Commands { get; }
|
||||
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly RevitContext _revitContext;
|
||||
private readonly IRevitContext _revitContext;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
|
||||
public BasicConnectorBindingRevit(
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
RevitContext revitContext,
|
||||
IRevitContext revitContext,
|
||||
ISpeckleApplication speckleApplication,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
{
|
||||
Name = "baseBinding";
|
||||
@@ -37,16 +37,13 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
_store = store;
|
||||
_revitContext = revitContext;
|
||||
_speckleApplication = speckleApplication;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
Commands = new BasicConnectorBindingCommands(parent);
|
||||
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await Commands.NotifyDocumentChanged();
|
||||
});
|
||||
eventAggregator.GetEvent<DocumentStoreChangedEvent>().Subscribe(OnDocumentStoreChangedEvent);
|
||||
}
|
||||
|
||||
private async Task OnDocumentStoreChangedEvent(object _) => await Commands.NotifyDocumentChanged();
|
||||
|
||||
public string GetConnectorVersion() => _speckleApplication.SpeckleVersion;
|
||||
|
||||
public string GetSourceApplicationName() => _speckleApplication.Slug;
|
||||
@@ -103,12 +100,7 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
var view = revitViewsFilter.GetView();
|
||||
if (view is not null)
|
||||
{
|
||||
await RevitTask
|
||||
.RunAsync(() =>
|
||||
{
|
||||
_revitContext.UIApplication.ActiveUIDocument.ActiveView = view;
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
_revitContext.UIApplication.ActiveUIDocument.ActiveView = view;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Connectors.Revit.Plugin;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.RevitShared.Settings;
|
||||
using Speckle.Sdk;
|
||||
@@ -99,10 +98,6 @@ internal sealed class RevitReceiveBinding : IReceiveBinding
|
||||
// Idea for later -> when cancel called, create promise from UI to solve it later with this catch block.
|
||||
// So have 3 state on UI -> Cancellation clicked -> Cancelling -> Cancelled
|
||||
}
|
||||
catch (SpeckleRevitTaskException ex)
|
||||
{
|
||||
await SpeckleRevitTaskException.ProcessException(modelCardId, ex, _logger, Commands);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
|
||||
{
|
||||
_logger.LogModelCardHandledError(ex);
|
||||
|
||||
@@ -8,6 +8,7 @@ using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Exceptions;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
@@ -28,8 +29,7 @@ namespace Speckle.Connectors.Revit.Bindings;
|
||||
|
||||
internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
{
|
||||
private readonly IAppIdleManager _idleManager;
|
||||
private readonly RevitContext _revitContext;
|
||||
private readonly IRevitContext _revitContext;
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly ICancellationManager _cancellationManager;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
@@ -40,7 +40,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
private readonly ElementUnpacker _elementUnpacker;
|
||||
private readonly IRevitConversionSettingsFactory _revitConversionSettingsFactory;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to aggregate the changed objects' id. Note we're using a concurrent dictionary here as the expiry check method is not thread safe, and this was causing problems. See:
|
||||
@@ -51,8 +51,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
private ConcurrentDictionary<ElementId, byte> ChangedObjectIds { get; set; } = new();
|
||||
|
||||
public RevitSendBinding(
|
||||
IAppIdleManager idleManager,
|
||||
RevitContext revitContext,
|
||||
IRevitContext revitContext,
|
||||
DocumentModelStore store,
|
||||
ICancellationManager cancellationManager,
|
||||
IBrowserBridge bridge,
|
||||
@@ -64,11 +63,10 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
ElementUnpacker elementUnpacker,
|
||||
IRevitConversionSettingsFactory revitConversionSettingsFactory,
|
||||
ISpeckleApplication speckleApplication,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
: base("sendBinding", bridge)
|
||||
{
|
||||
_idleManager = idleManager;
|
||||
_revitContext = revitContext;
|
||||
_store = store;
|
||||
_cancellationManager = cancellationManager;
|
||||
@@ -80,15 +78,14 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
_elementUnpacker = elementUnpacker;
|
||||
_revitConversionSettingsFactory = revitConversionSettingsFactory;
|
||||
_speckleApplication = speckleApplication;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
_eventAggregator = eventAggregator;
|
||||
|
||||
Commands = new SendBindingUICommands(bridge);
|
||||
// TODO expiry events
|
||||
// TODO filters need refresh events
|
||||
|
||||
revitContext.UIApplication.NotNull().Application.DocumentChanged += (_, e) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => DocChangeHandler(e));
|
||||
_store.DocumentChanged += (_, _) => topLevelExceptionHandler.FireAndForget(async () => await OnDocumentChanged());
|
||||
eventAggregator.GetEvent<DocumentChangedEvent>().Subscribe(DocChangeHandler);
|
||||
eventAggregator.GetEvent<DocumentStoreChangedEvent>().Subscribe(OnDocumentStoreChangedEvent);
|
||||
}
|
||||
|
||||
private async Task OnDocumentStoreChangedEvent(object _) => await Commands.NotifyDocumentChanged();
|
||||
@@ -148,7 +145,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
.ServiceProvider.GetRequiredService<SendOperation<ElementId>>()
|
||||
.Execute(
|
||||
elementIds,
|
||||
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
|
||||
cancellationItem.Token
|
||||
);
|
||||
@@ -161,10 +158,6 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
// Idea for later -> when cancel called, create promise from UI to solve it later with this catch block.
|
||||
// So have 3 state on UI -> Cancellation clicked -> Cancelling -> Cancelled
|
||||
}
|
||||
catch (SpeckleRevitTaskException ex)
|
||||
{
|
||||
await SpeckleRevitTaskException.ProcessException(modelCardId, ex, _logger, Commands);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
|
||||
{
|
||||
_logger.LogModelCardHandledError(ex);
|
||||
@@ -180,7 +173,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
private async Task<List<Element>> RefreshElementsOnSender(SenderModelCard modelCard)
|
||||
{
|
||||
var activeUIDoc =
|
||||
_revitContext.UIApplication.NotNull().ActiveUIDocument
|
||||
_revitContext.UIApplication.ActiveUIDocument
|
||||
?? throw new SpeckleException("Unable to retrieve active UI document");
|
||||
|
||||
if (modelCard.SendFilter is IRevitSendFilter viewFilter)
|
||||
@@ -256,7 +249,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
|
||||
if (addedElementIds.Count > 0)
|
||||
{
|
||||
_idleManager.SubscribeToIdle(nameof(PostSetObjectIds), PostSetObjectIds);
|
||||
_eventAggregator.GetEvent<IdleEvent>().OneTimeSubscribe(nameof(PostSetObjectIds), PostSetObjectIds);
|
||||
}
|
||||
|
||||
if (HaveUnitsChanged(e.GetDocument()))
|
||||
@@ -276,8 +269,8 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
_sendConversionCache.EvictObjects(unpackedObjectIds);
|
||||
}
|
||||
|
||||
_idleManager.SubscribeToIdle(nameof(CheckFilterExpiration), CheckFilterExpiration);
|
||||
_idleManager.SubscribeToIdle(nameof(RunExpirationChecks), RunExpirationChecks);
|
||||
_eventAggregator.GetEvent<IdleEvent>().OneTimeSubscribe(nameof(CheckFilterExpiration), CheckFilterExpiration);
|
||||
_eventAggregator.GetEvent<IdleEvent>().OneTimeSubscribe(nameof(RunExpirationChecks), RunExpirationChecks);
|
||||
}
|
||||
|
||||
// Keeps track of doc and current units
|
||||
@@ -314,7 +307,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
return false;
|
||||
}
|
||||
|
||||
private async Task PostSetObjectIds()
|
||||
private async Task PostSetObjectIds(object _)
|
||||
{
|
||||
foreach (var sender in _store.GetSenders().ToList())
|
||||
{
|
||||
@@ -325,7 +318,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
/// <summary>
|
||||
/// Notifies ui if any filters need refreshing. Currently, this only applies for view filters.
|
||||
/// </summary>
|
||||
private async Task CheckFilterExpiration()
|
||||
private async Task CheckFilterExpiration(object _)
|
||||
{
|
||||
// NOTE: below code seems like more make sense in terms of performance but it causes unmanaged exception on Revit
|
||||
// using var viewCollector = new FilteredElementCollector(RevitContext.UIApplication?.ActiveUIDocument.Document);
|
||||
@@ -336,21 +329,17 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
// await Commands.RefreshSendFilters();
|
||||
// }
|
||||
|
||||
if (
|
||||
ChangedObjectIds.Keys.Any(e =>
|
||||
_revitContext.UIApplication.NotNull().ActiveUIDocument.Document.GetElement(e) is View
|
||||
)
|
||||
)
|
||||
if (ChangedObjectIds.Keys.Any(e => _revitContext.UIApplication.ActiveUIDocument.Document.GetElement(e) is View))
|
||||
{
|
||||
await Commands.RefreshSendFilters();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RunExpirationChecks()
|
||||
private async Task RunExpirationChecks(object _)
|
||||
{
|
||||
var senders = _store.GetSenders().ToList();
|
||||
// string[] objectIdsList = ChangedObjectIds.Keys.ToArray();
|
||||
var doc = _revitContext.UIApplication.NotNull().ActiveUIDocument.Document;
|
||||
var doc = _revitContext.UIApplication.ActiveUIDocument.Document;
|
||||
|
||||
if (doc == null)
|
||||
{
|
||||
@@ -404,11 +393,6 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
viewFilter.SetContext(_revitContext);
|
||||
}
|
||||
|
||||
if (modelCard.SendFilter is null || modelCard.SendFilter.IdMap is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var selectedObjects = modelCard.SendFilter.NotNull().IdMap.NotNull().Values;
|
||||
var intersection = selectedObjects.Intersect(objUniqueIds).ToList();
|
||||
bool isExpired = intersection.Count != 0;
|
||||
|
||||
@@ -1,47 +1,27 @@
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.Revit.Plugin;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
using Speckle.Sdk.Common;
|
||||
|
||||
namespace Speckle.Connectors.Revit.Bindings;
|
||||
|
||||
// POC: we need a base a RevitBaseBinding
|
||||
internal sealed class SelectionBinding : RevitBaseBinding, ISelectionBinding, IDisposable
|
||||
internal sealed class SelectionBinding : RevitBaseBinding, ISelectionBinding
|
||||
{
|
||||
#if REVIT2022
|
||||
private readonly System.Timers.Timer _selectionTimer;
|
||||
#endif
|
||||
private readonly RevitContext _revitContext;
|
||||
private readonly IAppIdleManager _idleManager;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IRevitContext _revitContext;
|
||||
|
||||
public SelectionBinding(
|
||||
RevitContext revitContext,
|
||||
IBrowserBridge parent,
|
||||
IAppIdleManager idleManager,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
)
|
||||
public SelectionBinding(IRevitContext revitContext, IBrowserBridge parent, IEventAggregator eventAggregator)
|
||||
: base("selectionBinding", parent)
|
||||
{
|
||||
_revitContext = revitContext;
|
||||
_idleManager = idleManager;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
|
||||
#if REVIT2022
|
||||
// NOTE: getting the selection data should be a fast function all, even for '000s of elements - and having a timer hitting it every 1s is ok.
|
||||
_selectionTimer = new System.Timers.Timer(1000);
|
||||
_selectionTimer.Elapsed += (_, _) => _topLevelExceptionHandler.CatchUnhandled(OnSelectionChanged);
|
||||
_selectionTimer.Start();
|
||||
#else
|
||||
|
||||
_revitContext.UIApplication.NotNull().SelectionChanged += (_, _) =>
|
||||
_idleManager.SubscribeToIdle(nameof(SelectionBinding), OnSelectionChanged);
|
||||
#endif
|
||||
eventAggregator.GetEvent<SelectionChangedEvent>().Subscribe(OnSelectionChanged);
|
||||
}
|
||||
|
||||
private void OnSelectionChanged()
|
||||
private void OnSelectionChanged(object _)
|
||||
{
|
||||
if (_revitContext.UIApplication.NotNull().ActiveUIDocument == null)
|
||||
if (_revitContext.UIApplication.ActiveUIDocument == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -50,7 +30,7 @@ internal sealed class SelectionBinding : RevitBaseBinding, ISelectionBinding, ID
|
||||
|
||||
public SelectionInfo GetSelection()
|
||||
{
|
||||
if (_revitContext.UIApplication.NotNull().ActiveUIDocument == null)
|
||||
if (_revitContext.UIApplication.ActiveUIDocument == null)
|
||||
{
|
||||
return new SelectionInfo(Array.Empty<string>(), "No objects selected.");
|
||||
}
|
||||
@@ -66,11 +46,4 @@ internal sealed class SelectionBinding : RevitBaseBinding, ISelectionBinding, ID
|
||||
.ToList();
|
||||
return new SelectionInfo(selectionIds, $"{selectionIds.Count} objects selected.");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
#if REVIT2022
|
||||
_selectionTimer.Dispose();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -15,6 +15,7 @@ using Speckle.Connectors.Revit.Operations.Send;
|
||||
using Speckle.Connectors.Revit.Operations.Send.Settings;
|
||||
using Speckle.Connectors.Revit.Plugin;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
using Speckle.Sdk.Models.GraphTraversal;
|
||||
|
||||
namespace Speckle.Connectors.Revit.DependencyInjection;
|
||||
@@ -44,8 +45,7 @@ public static class ServiceRegistration
|
||||
|
||||
serviceCollection.AddSingleton<IBinding>(sp => sp.GetRequiredService<IBasicConnectorBinding>());
|
||||
serviceCollection.AddSingleton<IBasicConnectorBinding, BasicConnectorBindingRevit>();
|
||||
|
||||
serviceCollection.AddSingleton<IAppIdleManager, RevitIdleManager>();
|
||||
serviceCollection.AddSingleton<IRevitContext>(sp => sp.GetRequiredService<IRevitPlugin>());
|
||||
|
||||
// send operation and dependencies
|
||||
serviceCollection.AddScoped<SendOperation<ElementId>>();
|
||||
|
||||
@@ -9,9 +9,9 @@ namespace Speckle.Connectors.Revit.HostApp;
|
||||
/// </summary>
|
||||
public class ElementUnpacker
|
||||
{
|
||||
private readonly RevitContext _revitContext;
|
||||
private readonly IRevitContext _revitContext;
|
||||
|
||||
public ElementUnpacker(RevitContext revitContext)
|
||||
public ElementUnpacker(IRevitContext revitContext)
|
||||
{
|
||||
_revitContext = revitContext;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.DB.ExtensibleStorage;
|
||||
using Autodesk.Revit.UI;
|
||||
using Autodesk.Revit.UI.Events;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Revit.Async;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
using Speckle.Connectors.Revit.Plugin;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
using Speckle.Sdk.Common;
|
||||
|
||||
namespace Speckle.Connectors.Revit.HostApp;
|
||||
|
||||
@@ -17,51 +16,43 @@ internal sealed class RevitDocumentStore : DocumentModelStore
|
||||
// POC: move to somewhere central?
|
||||
private static readonly Guid s_revitDocumentStoreId = new("D35B3695-EDC9-4E15-B62A-D3FC2CB83FA3");
|
||||
|
||||
private readonly IAppIdleManager _idleManager;
|
||||
private readonly RevitContext _revitContext;
|
||||
private readonly IRevitContext _revitContext;
|
||||
private readonly DocumentModelStorageSchema _documentModelStorageSchema;
|
||||
private readonly IdStorageSchema _idStorageSchema;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IThreadContext _threadContext;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
|
||||
public RevitDocumentStore(
|
||||
IAppIdleManager idleManager,
|
||||
RevitContext revitContext,
|
||||
IRevitContext revitContext,
|
||||
IJsonSerializer jsonSerializer,
|
||||
DocumentModelStorageSchema documentModelStorageSchema,
|
||||
IdStorageSchema idStorageSchema,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IThreadContext threadContext
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
: base(jsonSerializer)
|
||||
{
|
||||
_idleManager = idleManager;
|
||||
_revitContext = revitContext;
|
||||
_documentModelStorageSchema = documentModelStorageSchema;
|
||||
_idStorageSchema = idStorageSchema;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
_threadContext = threadContext;
|
||||
_eventAggregator = eventAggregator;
|
||||
|
||||
UIApplication uiApplication = _revitContext.UIApplication.NotNull();
|
||||
|
||||
uiApplication.ViewActivated += (s, e) => _topLevelExceptionHandler.CatchUnhandled(() => OnViewActivated(s, e));
|
||||
|
||||
uiApplication.Application.DocumentOpening += (_, _) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => IsDocumentInit = false);
|
||||
|
||||
uiApplication.Application.DocumentOpened += (_, _) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => IsDocumentInit = false);
|
||||
eventAggregator.GetEvent<DocumentOpenedEvent>().Subscribe(OnDocumentOpen);
|
||||
eventAggregator.GetEvent<DocumentOpeningEvent>().Subscribe(OnDocumentOpen);
|
||||
eventAggregator.GetEvent<ViewActivatedEvent>().Subscribe(OnViewActivated);
|
||||
|
||||
// There is no event that we can hook here for double-click file open...
|
||||
// It is kind of harmless since we create this object as "SingleInstance".
|
||||
LoadState();
|
||||
OnDocumentChanged();
|
||||
}
|
||||
|
||||
private void OnDocumentOpen(object _) => IsDocumentInit = false;
|
||||
|
||||
public override Task OnDocumentStoreInitialized() =>
|
||||
_eventAggregator.GetEvent<DocumentStoreChangedEvent>().PublishAsync(new object());
|
||||
|
||||
/// <summary>
|
||||
/// This is the place where we track document switch for new document -> Responsible to Read from new doc
|
||||
/// </summary>
|
||||
private void OnViewActivated(object? _, ViewActivatedEventArgs e)
|
||||
private void OnViewActivated(ViewActivatedEventArgs e)
|
||||
{
|
||||
if (e.Document == null)
|
||||
{
|
||||
@@ -75,14 +66,13 @@ internal sealed class RevitDocumentStore : DocumentModelStore
|
||||
}
|
||||
|
||||
IsDocumentInit = true;
|
||||
_idleManager.SubscribeToIdle(
|
||||
nameof(RevitDocumentStore),
|
||||
() =>
|
||||
{
|
||||
LoadState();
|
||||
OnDocumentChanged();
|
||||
}
|
||||
);
|
||||
_eventAggregator.GetEvent<IdleEvent>().OneTimeSubscribe(nameof(RevitDocumentStore), OnIdleEvent);
|
||||
}
|
||||
|
||||
private async Task OnIdleEvent(object _)
|
||||
{
|
||||
LoadState();
|
||||
await _eventAggregator.GetEvent<DocumentStoreChangedEvent>().PublishAsync(new object());
|
||||
}
|
||||
|
||||
protected override void HostAppSaveState(string modelCardState)
|
||||
@@ -94,25 +84,23 @@ internal sealed class RevitDocumentStore : DocumentModelStore
|
||||
return;
|
||||
}
|
||||
|
||||
_threadContext
|
||||
.RunOnMain(() =>
|
||||
{
|
||||
using Transaction t = new(doc, "Speckle Write State");
|
||||
t.Start();
|
||||
using DataStorage ds = GetSettingsDataStorage(doc) ?? DataStorage.Create(doc);
|
||||
RevitTask.RunAsync(() =>
|
||||
{
|
||||
using Transaction t = new(doc, "Speckle Write State");
|
||||
t.Start();
|
||||
using DataStorage ds = GetSettingsDataStorage(doc) ?? DataStorage.Create(doc);
|
||||
|
||||
using Entity stateEntity = new(_documentModelStorageSchema.GetSchema());
|
||||
string serializedModels = Serialize();
|
||||
stateEntity.Set("contents", serializedModels);
|
||||
using Entity stateEntity = new(_documentModelStorageSchema.GetSchema());
|
||||
string serializedModels = Serialize();
|
||||
stateEntity.Set("contents", serializedModels);
|
||||
|
||||
using Entity idEntity = new(_idStorageSchema.GetSchema());
|
||||
idEntity.Set("Id", s_revitDocumentStoreId);
|
||||
using Entity idEntity = new(_idStorageSchema.GetSchema());
|
||||
idEntity.Set("Id", s_revitDocumentStoreId);
|
||||
|
||||
ds.SetEntity(idEntity);
|
||||
ds.SetEntity(stateEntity);
|
||||
t.Commit();
|
||||
})
|
||||
.FireAndForget();
|
||||
ds.SetEntity(idEntity);
|
||||
ds.SetEntity(stateEntity);
|
||||
t.Commit();
|
||||
});
|
||||
}
|
||||
|
||||
protected override void LoadState()
|
||||
|
||||
@@ -12,7 +12,6 @@ public class SendCollectionManager
|
||||
{
|
||||
private readonly IConverterSettingsStore<RevitConversionSettings> _converterSettings;
|
||||
private readonly Dictionary<string, Collection> _collectionCache = new();
|
||||
private readonly Dictionary<ElementId, (string name, Dictionary<string, object?> props)> _levelCache = new(); // stores level id and its properties
|
||||
|
||||
public SendCollectionManager(IConverterSettingsStore<RevitConversionSettings> converterSettings)
|
||||
{
|
||||
@@ -31,29 +30,9 @@ public class SendCollectionManager
|
||||
var doc = _converterSettings.Current.Document;
|
||||
var path = new List<string>();
|
||||
|
||||
// Step 0: get the level and its properties
|
||||
string levelName = "No Level";
|
||||
Dictionary<string, object?> levelProperties = new();
|
||||
if (element.LevelId != ElementId.InvalidElementId)
|
||||
{
|
||||
if (_levelCache.TryGetValue(element.LevelId, out var cachedLevel))
|
||||
{
|
||||
levelName = cachedLevel.name;
|
||||
levelProperties = cachedLevel.props;
|
||||
}
|
||||
else
|
||||
{
|
||||
var level = (Level)doc.GetElement(element.LevelId);
|
||||
levelName = level.Name;
|
||||
levelProperties.Add("elevation", level.Elevation);
|
||||
levelProperties.Add("units", _converterSettings.Current.SpeckleUnits);
|
||||
_levelCache.Add(element.LevelId, (levelName, levelProperties));
|
||||
}
|
||||
}
|
||||
|
||||
// Step 1: create path components. Currently, this is
|
||||
// level > category > type
|
||||
path.Add(levelName);
|
||||
path.Add(doc.GetElement(element.LevelId) is not Level level ? "No level" : level.Name);
|
||||
path.Add(element.Category?.Name ?? "No category");
|
||||
var typeId = element.GetTypeId();
|
||||
if (typeId != ElementId.InvalidElementId)
|
||||
@@ -78,9 +57,8 @@ public class SendCollectionManager
|
||||
string flatPathName = "";
|
||||
Collection previousCollection = rootObject;
|
||||
|
||||
for (int i = 0; i < path.Count; i++)
|
||||
foreach (var pathItem in path)
|
||||
{
|
||||
var pathItem = path[i];
|
||||
flatPathName += pathItem;
|
||||
Collection childCollection;
|
||||
if (_collectionCache.TryGetValue(flatPathName, out Collection? collection))
|
||||
@@ -90,13 +68,6 @@ public class SendCollectionManager
|
||||
else
|
||||
{
|
||||
childCollection = new Collection(pathItem);
|
||||
// add props if it's the 1st path item, representing level
|
||||
// if the structure ever changes from level > category > type, this needs to be changed
|
||||
if (i == 0 && levelProperties.Count > 0)
|
||||
{
|
||||
childCollection["properties"] = levelProperties;
|
||||
}
|
||||
|
||||
previousCollection.elements.Add(childCollection);
|
||||
_collectionCache[flatPathName] = childCollection;
|
||||
}
|
||||
|
||||
+12
-26
@@ -5,7 +5,7 @@ namespace Speckle.Connectors.Revit.HostApp;
|
||||
public static class SupportedCategoriesUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Filters out all categories besides Model categories, and Grids in Annotation. This utility should be used
|
||||
/// Filters out all categories besides Model categories. This utility should be used
|
||||
/// to clean any elements we might want to send pre-conversion as well as in what categories
|
||||
/// to display in our category filter.
|
||||
/// </summary>
|
||||
@@ -13,32 +13,18 @@ public static class SupportedCategoriesUtils
|
||||
/// <returns></returns>
|
||||
public static bool IsSupportedCategory(Category? category)
|
||||
{
|
||||
if (category is null || !category.IsVisibleInUI)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (category.CategoryType)
|
||||
{
|
||||
case CategoryType.Annotation:
|
||||
return
|
||||
#if REVIT2023_OR_GREATER
|
||||
category.BuiltInCategory == BuiltInCategory.OST_Grids;
|
||||
return category is not null
|
||||
&& (
|
||||
category.CategoryType == CategoryType.Model
|
||||
// || category.CategoryType == CategoryType.AnalyticalModel
|
||||
)
|
||||
#if REVIT_2023_OR_GREATER
|
||||
&& category.BuiltInCategory != BuiltInCategory.OST_AreaSchemes
|
||||
&& category.BuiltInCategory != BuiltInCategory.OST_AreaSchemeLines
|
||||
#else
|
||||
category.Name == "OST_Grids";
|
||||
&& category.Name != "OST_AreaSchemeLines"
|
||||
&& category.Name != "OST_AreaSchemes"
|
||||
#endif
|
||||
|
||||
case CategoryType.Model:
|
||||
return
|
||||
#if REVIT2023_OR_GREATER
|
||||
category.BuiltInCategory != BuiltInCategory.OST_AreaSchemes
|
||||
&& category.BuiltInCategory != BuiltInCategory.OST_AreaSchemeLines;
|
||||
#else
|
||||
category.Name != "OST_AreaSchemeLines" && category.Name != "OST_AreaSchemes";
|
||||
#endif
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
&& category.IsVisibleInUI;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -4,5 +4,5 @@ namespace Speckle.Connectors.RevitShared.Operations.Send.Filters;
|
||||
|
||||
public interface IRevitSendFilter
|
||||
{
|
||||
public void SetContext(RevitContext revitContext);
|
||||
public void SetContext(IRevitContext revitContext);
|
||||
}
|
||||
|
||||
+4
-5
@@ -4,7 +4,6 @@ using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
using Speckle.Connectors.Revit.HostApp;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
using Speckle.Sdk.Common;
|
||||
|
||||
namespace Speckle.Connectors.RevitShared.Operations.Send.Filters;
|
||||
|
||||
@@ -12,7 +11,7 @@ public record CategoryData(string Name, string Id);
|
||||
|
||||
public class RevitCategoriesFilter : DiscriminatedObject, ISendFilter, IRevitSendFilter
|
||||
{
|
||||
private RevitContext _revitContext;
|
||||
private IRevitContext _revitContext;
|
||||
private Document? _doc;
|
||||
public string Id { get; set; } = "revitCategories";
|
||||
public string Name { get; set; } = "Categories";
|
||||
@@ -25,10 +24,10 @@ public class RevitCategoriesFilter : DiscriminatedObject, ISendFilter, IRevitSen
|
||||
|
||||
public RevitCategoriesFilter() { }
|
||||
|
||||
public RevitCategoriesFilter(RevitContext revitContext)
|
||||
public RevitCategoriesFilter(IRevitContext revitContext)
|
||||
{
|
||||
_revitContext = revitContext;
|
||||
_doc = _revitContext.UIApplication.NotNull().ActiveUIDocument.Document;
|
||||
_doc = _revitContext.UIApplication.ActiveUIDocument.Document;
|
||||
|
||||
GetCategories();
|
||||
}
|
||||
@@ -84,7 +83,7 @@ public class RevitCategoriesFilter : DiscriminatedObject, ISendFilter, IRevitSen
|
||||
/// NOTE: this is needed since we need doc on `GetObjectIds()` function after it deserialized.
|
||||
/// DI doesn't help here to pass RevitContext from constructor.
|
||||
/// </summary>
|
||||
public void SetContext(RevitContext revitContext)
|
||||
public void SetContext(IRevitContext revitContext)
|
||||
{
|
||||
_revitContext = revitContext;
|
||||
_doc = _revitContext.UIApplication?.ActiveUIDocument.Document;
|
||||
|
||||
+3
-3
@@ -8,7 +8,7 @@ namespace Speckle.Connectors.RevitShared.Operations.Send.Filters;
|
||||
|
||||
public class RevitViewsFilter : DiscriminatedObject, ISendFilter, IRevitSendFilter
|
||||
{
|
||||
private RevitContext _revitContext;
|
||||
private IRevitContext _revitContext;
|
||||
private Document? _doc;
|
||||
public string Id { get; set; } = "revitViews";
|
||||
public string Name { get; set; } = "Views";
|
||||
@@ -21,7 +21,7 @@ public class RevitViewsFilter : DiscriminatedObject, ISendFilter, IRevitSendFilt
|
||||
|
||||
public RevitViewsFilter() { }
|
||||
|
||||
public RevitViewsFilter(RevitContext revitContext)
|
||||
public RevitViewsFilter(IRevitContext revitContext)
|
||||
{
|
||||
_revitContext = revitContext;
|
||||
_doc = _revitContext.UIApplication?.ActiveUIDocument.Document;
|
||||
@@ -109,7 +109,7 @@ public class RevitViewsFilter : DiscriminatedObject, ISendFilter, IRevitSendFilt
|
||||
/// NOTE: this is needed since we need doc on `GetObjectIds()` function after it deserialized.
|
||||
/// DI doesn't help here to pass RevitContext from constructor.
|
||||
/// </summary>
|
||||
public void SetContext(RevitContext revitContext)
|
||||
public void SetContext(IRevitContext revitContext)
|
||||
{
|
||||
_revitContext = revitContext;
|
||||
_doc = _revitContext.UIApplication?.ActiveUIDocument.Document;
|
||||
|
||||
+2
-3
@@ -85,7 +85,7 @@ public class RevitRootObjectBuilder(
|
||||
|
||||
var countProgress = 0;
|
||||
var cacheHitCount = 0;
|
||||
var skippedObjectCount = 0;
|
||||
|
||||
foreach (Element revitElement in atomicObjects)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
@@ -105,7 +105,6 @@ public class RevitRootObjectBuilder(
|
||||
new SpeckleException($"Category {cat} is not supported.")
|
||||
)
|
||||
);
|
||||
skippedObjectCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -135,7 +134,7 @@ public class RevitRootObjectBuilder(
|
||||
onOperationProgressed.Report(new("Converting", (double)++countProgress / atomicObjects.Count));
|
||||
}
|
||||
|
||||
if (results.All(x => x.Status == Status.ERROR) || skippedObjectCount == atomicObjects.Count)
|
||||
if (results.All(x => x.Status == Status.ERROR))
|
||||
{
|
||||
throw new SpeckleException("Failed to convert all objects.");
|
||||
}
|
||||
|
||||
+2
-2
@@ -13,7 +13,7 @@ namespace Speckle.Connectors.Revit.Operations.Send.Settings;
|
||||
[GenerateAutoInterface]
|
||||
public class ToSpeckleSettingsManager : IToSpeckleSettingsManager
|
||||
{
|
||||
private readonly RevitContext _revitContext;
|
||||
private readonly IRevitContext _revitContext;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly ElementUnpacker _elementUnpacker;
|
||||
|
||||
@@ -23,7 +23,7 @@ public class ToSpeckleSettingsManager : IToSpeckleSettingsManager
|
||||
private readonly Dictionary<string, bool?> _sendNullParamsCache = new();
|
||||
|
||||
public ToSpeckleSettingsManager(
|
||||
RevitContext revitContext,
|
||||
IRevitContext revitContext,
|
||||
ISendConversionCache sendConversionCache,
|
||||
ElementUnpacker elementUnpacker
|
||||
)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
|
||||
namespace Speckle.Connectors.Revit.Plugin;
|
||||
|
||||
internal interface IRevitPlugin
|
||||
internal interface IRevitPlugin : IRevitContext
|
||||
{
|
||||
void Initialise();
|
||||
void Shutdown();
|
||||
|
||||
@@ -3,15 +3,13 @@ using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using Autodesk.Revit.ApplicationServices;
|
||||
using Autodesk.Revit.UI;
|
||||
using CefSharp;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Revit.Async;
|
||||
using Speckle.Connectors.Common;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Revit.Plugin;
|
||||
@@ -21,7 +19,6 @@ internal sealed class RevitCefPlugin : IRevitPlugin
|
||||
private readonly UIControlledApplication _uIControlledApplication;
|
||||
private readonly IServiceProvider _serviceProvider; // should be lazy to ensure the bindings are not created too early
|
||||
private readonly BindingOptions _bindingOptions;
|
||||
private readonly RevitContext _revitContext;
|
||||
private readonly CefSharpPanel _cefSharpPanel;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
|
||||
@@ -29,17 +26,17 @@ internal sealed class RevitCefPlugin : IRevitPlugin
|
||||
UIControlledApplication uIControlledApplication,
|
||||
IServiceProvider serviceProvider,
|
||||
BindingOptions bindingOptions,
|
||||
RevitContext revitContext,
|
||||
CefSharpPanel cefSharpPanel,
|
||||
ISpeckleApplication speckleApplication
|
||||
ISpeckleApplication speckleApplication,
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
{
|
||||
_uIControlledApplication = uIControlledApplication;
|
||||
_serviceProvider = serviceProvider;
|
||||
_bindingOptions = bindingOptions;
|
||||
_revitContext = revitContext;
|
||||
_cefSharpPanel = cefSharpPanel;
|
||||
_speckleApplication = speckleApplication;
|
||||
eventAggregator.GetEvent<ApplicationInitializedEvent>().Subscribe(OnApplicationInitialized);
|
||||
}
|
||||
|
||||
public void Initialise()
|
||||
@@ -47,7 +44,6 @@ internal sealed class RevitCefPlugin : IRevitPlugin
|
||||
// Create and register panels before app initialized. this is needed for double-click file open
|
||||
CreateTabAndRibbonPanel(_uIControlledApplication);
|
||||
RegisterDockablePane();
|
||||
_uIControlledApplication.ControlledApplication.ApplicationInitialized += OnApplicationInitialized;
|
||||
}
|
||||
|
||||
public void Shutdown()
|
||||
@@ -94,27 +90,14 @@ internal sealed class RevitCefPlugin : IRevitPlugin
|
||||
$"Speckle.Connectors.Revit{_speckleApplication.HostApplicationVersion}.Assets.logo32.png",
|
||||
path
|
||||
);
|
||||
dui3Button.ToolTip = "Speckle (Beta) for Revit";
|
||||
//dui3Button.AvailabilityClassName = typeof(CmdAvailabilityViews).FullName;
|
||||
dui3Button.ToolTip = "Next Gen Speckle Connector (Beta) for Revit";
|
||||
dui3Button.SetContextualHelp(new ContextualHelp(ContextualHelpType.Url, "https://speckle.systems"));
|
||||
}
|
||||
|
||||
private void OnApplicationInitialized(object? sender, Autodesk.Revit.DB.Events.ApplicationInitializedEventArgs e)
|
||||
private void OnApplicationInitialized(UIApplication uiApplication)
|
||||
{
|
||||
var uiApplication = new UIApplication(sender as Application);
|
||||
_revitContext.UIApplication = uiApplication;
|
||||
UIApplication = uiApplication;
|
||||
|
||||
// POC: might be worth to interface this out, we shall see...
|
||||
RevitTask.Initialize(uiApplication);
|
||||
|
||||
PostApplicationInit(); // for double-click file open
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Actions to run after UiApplication initialized. This is needed for double-click file open issue.
|
||||
/// </summary>
|
||||
private void PostApplicationInit()
|
||||
{
|
||||
var bindings = _serviceProvider.GetRequiredService<IEnumerable<IBinding>>();
|
||||
// binding the bindings to each bridge
|
||||
foreach (IBinding binding in bindings)
|
||||
@@ -123,7 +106,7 @@ internal sealed class RevitCefPlugin : IRevitPlugin
|
||||
binding.Parent.AssociateWithBinding(binding);
|
||||
}
|
||||
|
||||
_cefSharpPanel.Browser.IsBrowserInitializedChanged += (sender, e) =>
|
||||
_cefSharpPanel.Browser.IsBrowserInitializedChanged += (_, e) =>
|
||||
{
|
||||
if (e.NewValue is false)
|
||||
{
|
||||
@@ -159,7 +142,7 @@ internal sealed class RevitCefPlugin : IRevitPlugin
|
||||
// Otherwise pane cannot be registered for double-click file open.
|
||||
_uIControlledApplication.RegisterDockablePane(
|
||||
RevitExternalApplication.DockablePanelId,
|
||||
"Speckle (Beta) for Revit",
|
||||
"Speckle (Beta)",
|
||||
_cefSharpPanel
|
||||
);
|
||||
}
|
||||
@@ -181,4 +164,6 @@ internal sealed class RevitCefPlugin : IRevitPlugin
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public UIApplication UIApplication { get; private set; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
using Autodesk.Revit.ApplicationServices;
|
||||
using Autodesk.Revit.UI;
|
||||
using Autodesk.Revit.UI.Events;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
|
||||
namespace Speckle.Connectors.Revit.Plugin;
|
||||
|
||||
public class ApplicationInitializedEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: ThreadedEvent<UIApplication>(threadContext, exceptionHandler);
|
||||
|
||||
public class ViewActivatedEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: ThreadedEvent<ViewActivatedEventArgs>(threadContext, exceptionHandler);
|
||||
|
||||
public class DocumentOpeningEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: ThreadedEvent<object>(threadContext, exceptionHandler);
|
||||
|
||||
public class DocumentOpenedEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: ThreadedEvent<object>(threadContext, exceptionHandler);
|
||||
|
||||
public class SelectionChangedEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: ThreadedEvent<object>(threadContext, exceptionHandler);
|
||||
|
||||
public class DocumentChangedEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: ThreadedEvent<Autodesk.Revit.DB.Events.DocumentChangedEventArgs>(threadContext, exceptionHandler);
|
||||
|
||||
#if REVIT2022
|
||||
public class PeriodicSelectionEvent(IThreadContext threadContext, ITopLevelExceptionHandler exceptionHandler)
|
||||
: PeriodicThreadedEvent(threadContext, exceptionHandler);
|
||||
#endif
|
||||
|
||||
public static class RevitEvents
|
||||
{
|
||||
private static IEventAggregator? s_eventAggregator;
|
||||
|
||||
public static void Register(IEventAggregator eventAggregator, UIControlledApplication application)
|
||||
{
|
||||
s_eventAggregator = eventAggregator;
|
||||
application.Idling += async (_, _) => await eventAggregator.GetEvent<IdleEvent>().PublishAsync(new object());
|
||||
application.ControlledApplication.ApplicationInitialized += async (sender, _) =>
|
||||
await eventAggregator
|
||||
.GetEvent<ApplicationInitializedEvent>()
|
||||
.PublishAsync(new UIApplication(sender as Application));
|
||||
application.ViewActivated += async (_, args) =>
|
||||
await eventAggregator.GetEvent<ViewActivatedEvent>().PublishAsync(args);
|
||||
application.ControlledApplication.DocumentOpened += async (_, _) =>
|
||||
await eventAggregator.GetEvent<DocumentOpenedEvent>().PublishAsync(new object());
|
||||
application.ControlledApplication.DocumentOpening += async (_, _) =>
|
||||
await eventAggregator.GetEvent<DocumentOpeningEvent>().PublishAsync(new object());
|
||||
application.ControlledApplication.DocumentChanged += async (_, args) =>
|
||||
await eventAggregator.GetEvent<DocumentChangedEvent>().PublishAsync(args);
|
||||
|
||||
#if REVIT2022
|
||||
// NOTE: getting the selection data should be a fast function all, even for '000s of elements - and having a timer hitting it every 1s is ok.
|
||||
eventAggregator.GetEvent<PeriodicSelectionEvent>().SubscribePeriodic(TimeSpan.FromSeconds(1), OnSelectionChanged);
|
||||
#else
|
||||
|
||||
application.SelectionChanged += (_, _) =>
|
||||
eventAggregator.GetEvent<IdleEvent>().OneTimeSubscribe("Selection", OnSelectionChanged);
|
||||
#endif
|
||||
}
|
||||
|
||||
private static async Task OnSelectionChanged(object _)
|
||||
{
|
||||
if (s_eventAggregator is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await s_eventAggregator.GetEvent<SelectionChangedEvent>().PublishAsync(new object());
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging;
|
||||
using Revit.Async;
|
||||
using Speckle.Connectors.Common;
|
||||
using Speckle.Connectors.DUI;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.Revit.DependencyInjection;
|
||||
using Speckle.Converters.RevitShared;
|
||||
using Speckle.Sdk;
|
||||
@@ -52,6 +53,7 @@ internal sealed class RevitExternalApplication : IExternalApplication
|
||||
_container.UseDUI();
|
||||
|
||||
RevitTask.Initialize(application);
|
||||
RevitEvents.Register(_container.GetRequiredService<IEventAggregator>(), application);
|
||||
// resolve root object
|
||||
_revitPlugin = _container.GetRequiredService<IRevitPlugin>();
|
||||
_revitPlugin.Initialise();
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Revit.Async;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Revit.Plugin;
|
||||
|
||||
@@ -8,82 +7,16 @@ public class RevitThreadContext : ThreadContext
|
||||
{
|
||||
protected override Task<T> MainToWorkerAsync<T>(Func<Task<T>> action) => action();
|
||||
|
||||
protected override Task<T> WorkerToMainAsync<T>(Func<Task<T>> action) => CatchExceptions(action);
|
||||
protected override Task<T> WorkerToMainAsync<T>(Func<Task<T>> action) =>
|
||||
RevitTask.RunAsync(async () => await action());
|
||||
|
||||
protected override Task<T> MainToWorker<T>(Func<T> action) => Task.FromResult(action());
|
||||
|
||||
protected override Task<T> WorkerToMain<T>(Func<T> action) => CatchExceptions(action);
|
||||
protected override Task<T> WorkerToMain<T>(Func<T> action) => RevitTask.RunAsync(action);
|
||||
|
||||
protected override Task RunMainAsync(Func<Task> action) => CatchExceptions(action);
|
||||
protected override Task RunMainAsync(Func<Task> action) => RevitTask.RunAsync(action);
|
||||
|
||||
protected override Task<T> RunMainAsync<T>(Func<T> action) => CatchExceptions(action);
|
||||
protected override Task<T> RunMainAsync<T>(Func<T> action) => RevitTask.RunAsync(action);
|
||||
|
||||
protected override Task<T> RunMainAsync<T>(Func<Task<T>> action) => CatchExceptions(action);
|
||||
|
||||
private static async Task<T> CatchExceptions<T>(Func<T> action)
|
||||
{
|
||||
Exception? ex = null;
|
||||
//force the usage of the application overload
|
||||
var ret = await RevitTask.RunAsync(_ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return action();
|
||||
}
|
||||
catch (Exception e) when (!e.IsFatal())
|
||||
{
|
||||
ex = e;
|
||||
return default;
|
||||
}
|
||||
});
|
||||
if (ex is not null)
|
||||
{
|
||||
throw new SpeckleRevitTaskException(ex);
|
||||
}
|
||||
return ret!;
|
||||
}
|
||||
|
||||
private static async Task<T> CatchExceptions<T>(Func<Task<T>> action)
|
||||
{
|
||||
Exception? ex = null;
|
||||
//force the usage of the application overload
|
||||
var ret = await RevitTask.RunAsync(async _ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return await action();
|
||||
}
|
||||
catch (Exception e) when (!e.IsFatal())
|
||||
{
|
||||
ex = e;
|
||||
return default;
|
||||
}
|
||||
});
|
||||
if (ex is not null)
|
||||
{
|
||||
throw new SpeckleRevitTaskException(ex);
|
||||
}
|
||||
return ret!;
|
||||
}
|
||||
|
||||
private static async Task CatchExceptions(Func<Task> action)
|
||||
{
|
||||
Exception? ex = null;
|
||||
//force the usage of the application overload
|
||||
await RevitTask.RunAsync(async _ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await action();
|
||||
}
|
||||
catch (Exception e) when (!e.IsFatal())
|
||||
{
|
||||
ex = e;
|
||||
}
|
||||
});
|
||||
if (ex is not null)
|
||||
{
|
||||
throw new SpeckleRevitTaskException(ex);
|
||||
}
|
||||
}
|
||||
protected override Task<T> RunMainAsync<T>(Func<Task<T>> action) => RevitTask.RunAsync(action);
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
|
||||
namespace Speckle.Connectors.Revit.Plugin;
|
||||
|
||||
#pragma warning disable CA1032
|
||||
public class SpeckleRevitTaskException(Exception exception) : SpeckleException("Revit operation failed", exception)
|
||||
#pragma warning restore CA1032
|
||||
{
|
||||
public static async Task ProcessException<T>(
|
||||
string modelCardId,
|
||||
SpeckleRevitTaskException ex,
|
||||
ILogger<T> logger,
|
||||
BasicConnectorBindingCommands commands
|
||||
)
|
||||
where T : IBinding
|
||||
{
|
||||
Exception e = ex.InnerException.NotNull();
|
||||
while (e is SpeckleRevitTaskException srte)
|
||||
{
|
||||
e = srte.InnerException.NotNull();
|
||||
}
|
||||
if (e is OperationCanceledException)
|
||||
{
|
||||
// SWALLOW -> UI handles it immediately, so we do not need to handle anything for now!
|
||||
// Idea for later -> when cancel called, create promise from UI to solve it later with this catch block.
|
||||
// So have 3 state on UI -> Cancellation clicked -> Cancelling -> Cancelled
|
||||
return;
|
||||
}
|
||||
//log everything though
|
||||
logger.LogModelCardHandledError(ex);
|
||||
//always process the inner exception
|
||||
await commands.SetModelError(modelCardId, e);
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -44,12 +44,11 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\ToSpeckleSettingsManager.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\ReferencePointSetting.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\DetailLevelSetting.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitEvents.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\IRevitPlugin.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitCommand.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitExternalApplication.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitIdleManager.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitThreadContext.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitCefPlugin.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\SpeckleRevitTaskException.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -268,9 +268,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -278,8 +278,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -296,7 +296,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.rhino7": {
|
||||
@@ -342,40 +342,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,9 +268,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -278,8 +278,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.270, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.270, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -296,7 +296,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.270, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.rhino8": {
|
||||
@@ -342,40 +342,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "9lCAC/Hsz2cbTVjwgHixLX2R7TNF8C90xd6rm0LsFPRgx926k15ep4k9q9wXHrblmP5Mc34qD1x9cwrSXzCiaA==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.270"
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "dzcd3A5jn4KpcgC8a1VuoLt1RwDvUfazmi5uKbiXuGFuxXMkGbZXr+xmXbyDL1C0HQqm+vZpOBcdSea/Q62/0g==",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.270"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.270, )",
|
||||
"resolved": "3.1.0-dev.270",
|
||||
"contentHash": "4nkNrmfNwnI+clIgZgBn+M42ISstQs1GrZH/6F97cmU0uczanVy0JTw011vKp5pPGmwZx8QFxVXbvwV5Ofx47A=="
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-11
@@ -4,6 +4,7 @@ using Rhino.Geometry;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Connectors.Rhino.Extensions;
|
||||
@@ -21,32 +22,29 @@ public sealed class RhinoBasicConnectorBinding : IBasicConnectorBinding
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
|
||||
public RhinoBasicConnectorBinding(
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
ISendConversionCache sendConversionCache,
|
||||
ISpeckleApplication speckleApplication,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
Parent = parent;
|
||||
_sendConversionCache = sendConversionCache;
|
||||
_speckleApplication = speckleApplication;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
Commands = new BasicConnectorBindingCommands(parent);
|
||||
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await Commands.NotifyDocumentChanged();
|
||||
// Note: this prevents scaling issues when copy-pasting from one rhino doc to another in the same session.
|
||||
_sendConversionCache.ClearCache();
|
||||
});
|
||||
eventAggregator.GetEvent<DocumentStoreChangedEvent>().Subscribe(OnDocumentStoreChangedEvent);
|
||||
}
|
||||
|
||||
// eventAggregator.GetEvent<DocumentStoreChangedEvent>().Subscribe(OnDocumentStoreChangedEvent);
|
||||
private async Task OnDocumentStoreChangedEvent(object _)
|
||||
{
|
||||
await Commands.NotifyDocumentChanged();
|
||||
// Note: this prevents scaling issues when copy-pasting from one rhino doc to another in the same session.
|
||||
_sendConversionCache.ClearCache();
|
||||
}
|
||||
|
||||
public string GetConnectorVersion() => _speckleApplication.SpeckleVersion;
|
||||
|
||||
@@ -2,31 +2,32 @@ using Rhino;
|
||||
using Rhino.DocObjects;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.RhinoShared;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.Bindings;
|
||||
|
||||
public class RhinoSelectionBinding : ISelectionBinding
|
||||
{
|
||||
private readonly IAppIdleManager _idleManager;
|
||||
private const string SELECTION_EVENT = "setSelection";
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
|
||||
public string Name => "selectionBinding";
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
public RhinoSelectionBinding(IAppIdleManager idleManager, IBrowserBridge parent)
|
||||
public RhinoSelectionBinding(IBrowserBridge parent, IEventAggregator eventAggregator)
|
||||
{
|
||||
_idleManager = idleManager;
|
||||
Parent = parent;
|
||||
|
||||
RhinoDoc.SelectObjects += OnSelectionChange;
|
||||
RhinoDoc.DeselectObjects += OnSelectionChange;
|
||||
RhinoDoc.DeselectAllObjects += OnSelectionChange;
|
||||
_eventAggregator = eventAggregator;
|
||||
eventAggregator.GetEvent<SelectObjects>().Subscribe(OnSelectionChange);
|
||||
eventAggregator.GetEvent<DeselectObjects>().Subscribe(OnSelectionChange);
|
||||
eventAggregator.GetEvent<DeselectAllObjects>().Subscribe(OnSelectionChange);
|
||||
}
|
||||
|
||||
private void OnSelectionChange(object? o, EventArgs eventArgs) =>
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSelectionBinding), UpdateSelection);
|
||||
private void OnSelectionChange(EventArgs eventArgs) =>
|
||||
_eventAggregator.GetEvent<IdleEvent>().OneTimeSubscribe(nameof(RhinoSelectionBinding), UpdateSelection);
|
||||
|
||||
private void UpdateSelection()
|
||||
private void UpdateSelection(object _)
|
||||
{
|
||||
SelectionInfo selInfo = GetSelection();
|
||||
Parent.Send(SELECTION_EVENT, selInfo);
|
||||
|
||||
@@ -10,12 +10,14 @@ using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Exceptions;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Connectors.DUI.Settings;
|
||||
using Speckle.Connectors.RhinoShared;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.Rhino;
|
||||
using Speckle.Sdk;
|
||||
@@ -40,8 +42,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
private readonly IRhinoConversionSettingsFactory _rhinoConversionSettingsFactory;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly ISdkActivityFactory _activityFactory;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IAppIdleManager _idleManager;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to aggregate the changed objects' id. Objects in this list will be reconverted.
|
||||
@@ -63,7 +64,6 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
|
||||
public RhinoSendBinding(
|
||||
DocumentModelStore store,
|
||||
IAppIdleManager idleManager,
|
||||
IBrowserBridge parent,
|
||||
IEnumerable<ISendFilter> sendFilters,
|
||||
IServiceProvider serviceProvider,
|
||||
@@ -74,11 +74,10 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
IRhinoConversionSettingsFactory rhinoConversionSettingsFactory,
|
||||
ISpeckleApplication speckleApplication,
|
||||
ISdkActivityFactory activityFactory,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
_idleManager = idleManager;
|
||||
_serviceProvider = serviceProvider;
|
||||
_sendFilters = sendFilters.ToList();
|
||||
_cancellationManager = cancellationManager;
|
||||
@@ -88,194 +87,203 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
_rhinoConversionSettingsFactory = rhinoConversionSettingsFactory;
|
||||
_speckleApplication = speckleApplication;
|
||||
Parent = parent;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
Commands = new SendBindingUICommands(parent); // POC: Commands are tightly coupled with their bindings, at least for now, saves us injecting a factory.
|
||||
_activityFactory = activityFactory;
|
||||
_eventAggregator = eventAggregator;
|
||||
PreviousUnitSystem = RhinoDoc.ActiveDoc.ModelUnitSystem;
|
||||
SubscribeToRhinoEvents();
|
||||
SubscribeToRhinoEvents(eventAggregator);
|
||||
}
|
||||
|
||||
#pragma warning disable CA1502
|
||||
private void SubscribeToRhinoEvents()
|
||||
#pragma warning restore CA1502
|
||||
private void SubscribeToRhinoEvents(IEventAggregator eventAggregator)
|
||||
{
|
||||
Command.BeginCommand += (_, e) =>
|
||||
{
|
||||
if (e.CommandEnglishName == "BlockEdit")
|
||||
{
|
||||
var selectedObject = RhinoDoc.ActiveDoc.Objects.GetSelectedObjects(false, false).First();
|
||||
ChangedObjectIds[selectedObject.Id.ToString()] = 1;
|
||||
}
|
||||
eventAggregator.GetEvent<BeginCommandEvent>().Subscribe(OnBeginCommandEvent);
|
||||
|
||||
if (e.CommandEnglishName == "Ungroup")
|
||||
{
|
||||
foreach (RhinoObject selectedObject in RhinoDoc.ActiveDoc.Objects.GetSelectedObjects(false, false))
|
||||
{
|
||||
ChangedObjectIdsInGroupsOrLayers[selectedObject.Id.ToString()] = 1;
|
||||
}
|
||||
_idleManager.SubscribeToIdle("a", RunExpirationChecks);
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
}
|
||||
};
|
||||
|
||||
RhinoDoc.ActiveDocumentChanged += (_, e) =>
|
||||
{
|
||||
PreviousUnitSystem = e.Document.ModelUnitSystem;
|
||||
};
|
||||
eventAggregator.GetEvent<ActiveDocumentChanged>().Subscribe(OnActiveDocumentChanged);
|
||||
|
||||
// NOTE: BE CAREFUL handling things in this event handler since it is triggered whenever we save something into file!
|
||||
RhinoDoc.DocumentPropertiesChanged += async (_, e) =>
|
||||
{
|
||||
var newUnit = e.Document.ModelUnitSystem;
|
||||
if (newUnit != PreviousUnitSystem)
|
||||
{
|
||||
PreviousUnitSystem = newUnit;
|
||||
eventAggregator.GetEvent<DocumentPropertiesChanged>().Subscribe(OnDocumentPropertiesChanged);
|
||||
|
||||
await InvalidateAllSender();
|
||||
}
|
||||
};
|
||||
eventAggregator.GetEvent<AddRhinoObject>().Subscribe(OnAddRhinoObject);
|
||||
|
||||
RhinoDoc.AddRhinoObject += (_, e) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() =>
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ChangedObjectIds[e.ObjectId.ToString()] = 1;
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
});
|
||||
|
||||
RhinoDoc.DeleteRhinoObject += (_, e) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() =>
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ChangedObjectIds[e.ObjectId.ToString()] = 1;
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
});
|
||||
eventAggregator.GetEvent<DeleteRhinoObject>().Subscribe(OnDeleteRhinoObject);
|
||||
|
||||
// NOTE: Catches an object's material change from one user defined doc material to another. Does not catch (as the top event is not triggered) swapping material sources for an object or moving to/from the default material (this is handled below)!
|
||||
RhinoDoc.RenderMaterialsTableEvent += (_, args) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() =>
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
eventAggregator.GetEvent<RenderMaterialsTableEvent>().Subscribe(OnRenderMaterialsTableEvent);
|
||||
|
||||
if (args is RhinoDoc.RenderMaterialAssignmentChangedEventArgs changedEventArgs)
|
||||
{
|
||||
ChangedObjectIds[changedEventArgs.ObjectId.ToString()] = 1;
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
}
|
||||
});
|
||||
eventAggregator.GetEvent<GroupTableEvent>().Subscribe(OnGroupTableEvent);
|
||||
|
||||
RhinoDoc.GroupTableEvent += (_, args) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() =>
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var obj in RhinoDoc.ActiveDoc.Groups.GroupMembers(args.GroupIndex))
|
||||
{
|
||||
ChangedObjectIdsInGroupsOrLayers[obj.Id.ToString()] = 1;
|
||||
}
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
});
|
||||
|
||||
RhinoDoc.LayerTableEvent += (_, args) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() =>
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
args.EventType == LayerTableEventType.Deleted
|
||||
|| args.EventType == LayerTableEventType.Current
|
||||
|| args.EventType == LayerTableEventType.Added
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var layer = RhinoDoc.ActiveDoc.Layers[args.LayerIndex];
|
||||
|
||||
var allLayers = args.Document.Layers.Where(l => /* NOTE: layer path may actually be null in some cases (rhino's fault, not ours) */
|
||||
l.FullPath != null && l.FullPath.Contains(layer.Name)
|
||||
); // not e imperfect, but layer.GetChildren(true) is valid only in v8 and above; this filter will include the original layer.
|
||||
foreach (var childLayer in allLayers)
|
||||
{
|
||||
var sublayerObjs = RhinoDoc.ActiveDoc.Objects.FindByLayer(childLayer) ?? [];
|
||||
foreach (var obj in sublayerObjs)
|
||||
{
|
||||
ChangedObjectIdsInGroupsOrLayers[obj.Id.ToString()] = 1;
|
||||
}
|
||||
}
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
});
|
||||
eventAggregator.GetEvent<LayerTableEvent>().Subscribe(OnLayerTableEvent);
|
||||
|
||||
// Catches and stores changed material ids. These are then used in the expiry checks to invalidate all objects that have assigned any of those material ids.
|
||||
RhinoDoc.MaterialTableEvent += (_, args) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() =>
|
||||
eventAggregator.GetEvent<MaterialTableEvent>().Subscribe(OnMaterialTableEvent);
|
||||
|
||||
eventAggregator.GetEvent<ModifyObjectAttributes>().Subscribe(OnModifyObjectAttributes);
|
||||
|
||||
eventAggregator.GetEvent<ReplaceRhinoObject>().Subscribe(OnReplaceRhinoObject);
|
||||
}
|
||||
|
||||
private void OnActiveDocumentChanged(DocumentEventArgs e) => PreviousUnitSystem = e.Document.ModelUnitSystem;
|
||||
|
||||
private async Task OnDocumentPropertiesChanged(DocumentEventArgs e)
|
||||
{
|
||||
var newUnit = e.Document.ModelUnitSystem;
|
||||
if (newUnit != PreviousUnitSystem)
|
||||
{
|
||||
PreviousUnitSystem = newUnit;
|
||||
|
||||
await InvalidateAllSender();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnBeginCommandEvent(CommandEventArgs e)
|
||||
{
|
||||
if (e.CommandEnglishName == "BlockEdit")
|
||||
{
|
||||
var selectedObject = RhinoDoc.ActiveDoc.Objects.GetSelectedObjects(false, false).First();
|
||||
ChangedObjectIds[selectedObject.Id.ToString()] = 1;
|
||||
}
|
||||
|
||||
if (e.CommandEnglishName == "Ungroup")
|
||||
{
|
||||
foreach (RhinoObject selectedObject in RhinoDoc.ActiveDoc.Objects.GetSelectedObjects(false, false))
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ChangedObjectIdsInGroupsOrLayers[selectedObject.Id.ToString()] = 1;
|
||||
}
|
||||
_eventAggregator.GetEvent<IdleEvent>().OneTimeSubscribe(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
}
|
||||
}
|
||||
|
||||
if (args.EventType == MaterialTableEventType.Modified)
|
||||
{
|
||||
ChangedMaterialIndexes[args.Index] = 1;
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
}
|
||||
});
|
||||
private void OnAddRhinoObject(RhinoObjectEventArgs e)
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RhinoDoc.ModifyObjectAttributes += (_, e) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() =>
|
||||
ChangedObjectIds[e.ObjectId.ToString()] = 1;
|
||||
_eventAggregator.GetEvent<IdleEvent>().OneTimeSubscribe(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
}
|
||||
|
||||
private void OnDeleteRhinoObject(RhinoObjectEventArgs e)
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ChangedObjectIds[e.ObjectId.ToString()] = 1;
|
||||
_eventAggregator.GetEvent<IdleEvent>().OneTimeSubscribe(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
}
|
||||
|
||||
private void OnRenderMaterialsTableEvent(RhinoDoc.RenderContentTableEventArgs e)
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (e is RhinoDoc.RenderMaterialAssignmentChangedEventArgs changedEventArgs)
|
||||
{
|
||||
ChangedObjectIds[changedEventArgs.ObjectId.ToString()] = 1;
|
||||
_eventAggregator.GetEvent<IdleEvent>().OneTimeSubscribe(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGroupTableEvent(GroupTableEventArgs args)
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var obj in RhinoDoc.ActiveDoc.Groups.GroupMembers(args.GroupIndex))
|
||||
{
|
||||
ChangedObjectIdsInGroupsOrLayers[obj.Id.ToString()] = 1;
|
||||
}
|
||||
_eventAggregator.GetEvent<IdleEvent>().OneTimeSubscribe(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
}
|
||||
|
||||
private void OnLayerTableEvent(LayerTableEventArgs args)
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
args.EventType == LayerTableEventType.Deleted
|
||||
|| args.EventType == LayerTableEventType.Current
|
||||
|| args.EventType == LayerTableEventType.Added
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var layer = RhinoDoc.ActiveDoc.Layers[args.LayerIndex];
|
||||
if (layer.Name is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// add all objects from the changed layers and sublayers to the non-destructively changed object list.
|
||||
var allLayers = args.Document.Layers.Where(l => /* NOTE: layer path may actually be null in some cases (rhino's fault, not ours) */
|
||||
l.FullPath != null && l.FullPath.Contains(layer.Name)
|
||||
); // not e imperfect, but layer.GetChildren(true) is valid only in v8 and above; this filter will include the original layer.
|
||||
foreach (var childLayer in allLayers)
|
||||
{
|
||||
var sublayerObjs = RhinoDoc.ActiveDoc.Objects.FindByLayer(childLayer) ?? [];
|
||||
foreach (var obj in sublayerObjs)
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ChangedObjectIdsInGroupsOrLayers[obj.Id.ToString()] = 1;
|
||||
}
|
||||
}
|
||||
_eventAggregator.GetEvent<IdleEvent>().OneTimeSubscribe(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
}
|
||||
|
||||
// NOTE: not sure yet we want to track every attribute changes yet. Explicitly tracking atts that change commit data. TBD
|
||||
if (
|
||||
e.OldAttributes.LayerIndex != e.NewAttributes.LayerIndex
|
||||
|| e.OldAttributes.MaterialSource != e.NewAttributes.MaterialSource
|
||||
|| e.OldAttributes.MaterialIndex != e.NewAttributes.MaterialIndex // NOTE: this does not work when swapping around from custom doc materials, it works when you swap TO/FROM default material
|
||||
|| e.OldAttributes.ColorSource != e.NewAttributes.ColorSource
|
||||
|| e.OldAttributes.ObjectColor != e.NewAttributes.ObjectColor
|
||||
|| e.OldAttributes.Name != e.NewAttributes.Name
|
||||
|| e.OldAttributes.UserStringCount != e.NewAttributes.UserStringCount
|
||||
|| e.OldAttributes.GetUserStrings() != e.NewAttributes.GetUserStrings()
|
||||
)
|
||||
{
|
||||
ChangedObjectIds[e.RhinoObject.Id.ToString()] = 1;
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
}
|
||||
});
|
||||
private void OnMaterialTableEvent(MaterialTableEventArgs args)
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RhinoDoc.ReplaceRhinoObject += (_, e) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() =>
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (args.EventType == MaterialTableEventType.Modified)
|
||||
{
|
||||
ChangedMaterialIndexes[args.Index] = 1;
|
||||
_eventAggregator.GetEvent<IdleEvent>().OneTimeSubscribe(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
}
|
||||
}
|
||||
|
||||
ChangedObjectIds[e.NewRhinoObject.Id.ToString()] = 1;
|
||||
ChangedObjectIds[e.OldRhinoObject.Id.ToString()] = 1;
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
});
|
||||
private void OnModifyObjectAttributes(RhinoModifyObjectAttributesEventArgs e)
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: not sure yet we want to track every attribute changes yet. TBD
|
||||
// NOTE: we might want to track here user strings too (once we send them out), and more!
|
||||
if (
|
||||
e.OldAttributes.LayerIndex != e.NewAttributes.LayerIndex
|
||||
|| e.OldAttributes.MaterialSource != e.NewAttributes.MaterialSource
|
||||
|| e.OldAttributes.MaterialIndex != e.NewAttributes.MaterialIndex // NOTE: this does not work when swapping around from custom doc materials, it works when you swap TO/FROM default material
|
||||
)
|
||||
{
|
||||
ChangedObjectIds[e.RhinoObject.Id.ToString()] = 1;
|
||||
_eventAggregator.GetEvent<IdleEvent>().OneTimeSubscribe(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnReplaceRhinoObject(RhinoReplaceObjectEventArgs e)
|
||||
{
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ChangedObjectIds[e.NewRhinoObject.Id.ToString()] = 1;
|
||||
ChangedObjectIds[e.OldRhinoObject.Id.ToString()] = 1;
|
||||
_eventAggregator.GetEvent<IdleEvent>().OneTimeSubscribe(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
}
|
||||
|
||||
public List<ISendFilter> GetSendFilters() => _sendFilters;
|
||||
@@ -316,7 +324,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
.ServiceProvider.GetRequiredService<SendOperation<RhinoObject>>()
|
||||
.Execute(
|
||||
rhinoObjects,
|
||||
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
|
||||
cancellationItem.Token
|
||||
);
|
||||
@@ -342,7 +350,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
/// <summary>
|
||||
/// Checks if any sender model cards contain any of the changed objects. If so, also updates the changed objects hashset for each model card - this last part is important for on send change detection.
|
||||
/// </summary>
|
||||
private async Task RunExpirationChecks()
|
||||
private async Task RunExpirationChecks(object _)
|
||||
{
|
||||
// Note: added here a guard against executing this if there's no active doc present.
|
||||
if (RhinoDoc.ActiveDoc == null)
|
||||
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
using Rhino;
|
||||
using Rhino.DocObjects;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.HostApp.Properties;
|
||||
|
||||
/// <summary>
|
||||
/// Extracts properties for rhino objects.
|
||||
/// </summary>
|
||||
public class PropertiesExtractor
|
||||
{
|
||||
public Dictionary<string, object?> GetProperties(RhinoObject rhObject)
|
||||
{
|
||||
Dictionary<string, object?> properties = new();
|
||||
var userStrings = rhObject.Attributes.GetUserStrings();
|
||||
foreach (var key in userStrings.AllKeys)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (userStrings[key].StartsWith("%<"))
|
||||
{
|
||||
var value = RhinoApp.ParseTextField(userStrings[key], rhObject, null);
|
||||
properties[key] = value;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
// Shh. We can fail silently here - it's not even worth logging. I expect users will complain properties are missing.
|
||||
}
|
||||
|
||||
properties[key] = userStrings[key];
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,37 @@
|
||||
using Rhino;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
using Speckle.Connectors.RhinoShared;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.HostApp;
|
||||
|
||||
public class RhinoDocumentStore : DocumentModelStore
|
||||
{
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private const string SPECKLE_KEY = "Speckle_DUI3";
|
||||
public override bool IsDocumentInit { get; set; } = true; // Note: because of rhino implementation details regarding expiry checking of sender cards.
|
||||
|
||||
public RhinoDocumentStore(IJsonSerializer jsonSerializer, ITopLevelExceptionHandler topLevelExceptionHandler)
|
||||
public RhinoDocumentStore(IJsonSerializer jsonSerializer, IEventAggregator eventAggregator)
|
||||
: base(jsonSerializer)
|
||||
{
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
RhinoDoc.BeginOpenDocument += (_, _) => topLevelExceptionHandler.CatchUnhandled(() => IsDocumentInit = false);
|
||||
RhinoDoc.EndOpenDocument += (_, e) =>
|
||||
topLevelExceptionHandler.CatchUnhandled(() =>
|
||||
{
|
||||
if (e.Document == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_eventAggregator = eventAggregator;
|
||||
eventAggregator.GetEvent<BeginOpenDocument>().Subscribe(OnBeginOpenDocument);
|
||||
eventAggregator.GetEvent<EndOpenDocument>().Subscribe(OnEndOpenDocument);
|
||||
}
|
||||
|
||||
IsDocumentInit = true;
|
||||
LoadState();
|
||||
OnDocumentChanged();
|
||||
});
|
||||
private void OnBeginOpenDocument(object _) => IsDocumentInit = false;
|
||||
|
||||
private async Task OnEndOpenDocument(DocumentOpenEventArgs e)
|
||||
{
|
||||
if (e.Document == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IsDocumentInit = true;
|
||||
LoadState();
|
||||
await _eventAggregator.GetEvent<DocumentStoreChangedEvent>().PublishAsync(new object());
|
||||
}
|
||||
|
||||
protected override void HostAppSaveState(string modelCardState)
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
using Rhino;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.HostApp;
|
||||
|
||||
/// <summary>
|
||||
/// Rhino Idle Manager is a helper util to manage deferred actions.
|
||||
/// </summary>
|
||||
public sealed class RhinoIdleManager(IIdleCallManager idleCallManager) : AppIdleManager(idleCallManager)
|
||||
{
|
||||
private readonly IIdleCallManager _idleCallManager = idleCallManager;
|
||||
|
||||
protected override void AddEvent()
|
||||
{
|
||||
RhinoApp.Idle += RhinoAppOnIdle;
|
||||
}
|
||||
|
||||
private void RhinoAppOnIdle(object? sender, EventArgs e) =>
|
||||
_idleCallManager.AppOnIdle(() => RhinoApp.Idle -= RhinoAppOnIdle);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Rhino;
|
||||
using Rhino.DocObjects;
|
||||
using Rhino.Geometry;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Rhino;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.Rhino;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user