Compare commits
119 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| de275dcf02 | |||
| 9d25e61043 | |||
| 0debe8f7f9 | |||
| 9e68b55018 | |||
| 5783b83168 | |||
| 6158739df0 | |||
| f7060c7287 | |||
| e2866d2595 | |||
| 76701627b6 | |||
| af7bc47cbf | |||
| a14b0a6fd0 | |||
| 855fedf3aa | |||
| 900427ad30 | |||
| 08bf19f74f | |||
| 68f7cb8f41 | |||
| 3088fae8a2 | |||
| 6d375312ae | |||
| 797a2b70f3 | |||
| 29cf1327ff | |||
| 613d45da37 | |||
| f29926748c | |||
| 9855ca8c15 | |||
| 7644decc64 | |||
| 81bf501c85 | |||
| ecf508ca93 | |||
| 2724b03301 | |||
| b2eb5efa12 | |||
| 661273f7bd | |||
| 5e37195591 | |||
| 0d85ad48de | |||
| 02ad0445b9 | |||
| 2bfe780faf | |||
| 284c1cfaf6 | |||
| a37d1c5f85 | |||
| 639e2c05bf | |||
| 7e5fb055c8 | |||
| 528c692f13 | |||
| dd17d364c7 | |||
| 6e56c3c190 | |||
| 617bb5f12d | |||
| fa1fa359fc | |||
| e9084847cf | |||
| da0a35a5d1 | |||
| 5fb3616c1a | |||
| 4f04e9e1b5 | |||
| 0c5b5ed59c | |||
| de167cdfb6 | |||
| 0a27fc1c2b | |||
| 1e537009e0 | |||
| 188f23faf4 | |||
| dca243825a | |||
| 650022ee10 | |||
| 98a7064f43 | |||
| 9804acd10c | |||
| 51550c96a6 | |||
| 491490c559 | |||
| ec1f13754d | |||
| b840988bbe | |||
| bd4b565799 | |||
| 102a7cbd9e | |||
| 8c34416b1a | |||
| 77af0b4ae4 | |||
| ed2d3ed931 | |||
| 0d584bb0ac | |||
| a95e7cc225 | |||
| c2caeb5900 | |||
| fe6e195c0a | |||
| 027a550c97 | |||
| 1074932eb5 | |||
| 9f0b0837d8 | |||
| d3f32288bf | |||
| c251db709e | |||
| 56d0eb0d0b | |||
| bbd4beeafe | |||
| 460719e0f0 | |||
| eed7f913e5 | |||
| e153eebe87 | |||
| c7eee14f7c | |||
| 48b4be68bd | |||
| 685da9af3e | |||
| ddaf329167 | |||
| 794af5e501 | |||
| 3028e9e29d | |||
| 704a75a2b4 | |||
| 63ae8e3ca5 | |||
| 0f09a15f20 | |||
| 23fbe106a7 | |||
| c7665a7845 | |||
| 41da92e43a | |||
| 9780cb6e35 | |||
| 7d2f5a4385 | |||
| 7144d81059 | |||
| ae162e3a46 | |||
| 311963f8ea | |||
| 2e70c24f29 | |||
| 7300d53a50 | |||
| b338f7750d | |||
| b9bb8d52f4 | |||
| 48396e7eaa | |||
| 27f959990f | |||
| e7d165d99b | |||
| 7df01df8fc | |||
| 896de431be | |||
| e0e6f416c0 | |||
| 07ded4986d | |||
| 0eb2b867c8 | |||
| aaf6759075 | |||
| bce9ed7a6f | |||
| 9edba5d992 | |||
| f9bcb47903 | |||
| 4333bfbeb3 | |||
| 5b2ab8b401 | |||
| 7bf287f706 | |||
| 94117e0345 | |||
| 6defdbe353 | |||
| ac1e402d1d | |||
| d358a75769 | |||
| c42ad3f042 | |||
| e75ca72abd |
@@ -2,7 +2,7 @@ name: .NET Build and Publish
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main", "dev"] # Continuous delivery on every long-lived branch
|
||||
branches: ["main", "dev", "release/*"] # Continuous delivery on every long-lived branch
|
||||
tags: ["v3.*"] # Manual delivery on every 3.x tag
|
||||
|
||||
jobs:
|
||||
@@ -49,6 +49,7 @@ jobs:
|
||||
needs: build
|
||||
env:
|
||||
IS_TAG_BUILD: ${{ github.ref_type == 'tag' }}
|
||||
IS_RELEASE_BRANCH: ${{ startsWith(github.ref_name, 'release/') || github.ref_name == 'main'}}
|
||||
steps:
|
||||
- name: 🔫 Trigger Build Installers
|
||||
uses: ALEEF02/workflow-dispatch@v3.0.0
|
||||
@@ -57,7 +58,7 @@ jobs:
|
||||
workflow: Build Installers
|
||||
repo: specklesystems/connector-installers
|
||||
token: ${{ secrets.CONNECTORS_GH_TOKEN }}
|
||||
inputs: '{ "run_id": "${{ github.run_id }}", "version": "${{ needs.build.outputs.version }}", "public_release": ${{ env.IS_TAG_BUILD }} }'
|
||||
inputs: '{ "run_id": "${{ github.run_id }}", "version": "${{ needs.build.outputs.version }}", "public_release": ${{ env.IS_TAG_BUILD }}, "store_artifacts": ${{ env.IS_RELEASE_BRANCH }} }'
|
||||
ref: main
|
||||
wait-for-completion: true
|
||||
wait-for-completion-interval: 10s
|
||||
|
||||
@@ -31,6 +31,15 @@ public static class Consts
|
||||
new("Connectors/Autocad/Speckle.Connectors.Autocad2024", "net48"),
|
||||
new("Connectors/Autocad/Speckle.Connectors.Autocad2025", "net8.0-windows")
|
||||
]
|
||||
),
|
||||
new(
|
||||
"civil3d",
|
||||
[
|
||||
new("Connectors/Autocad/Speckle.Connectors.Civil3d2022", "net48"),
|
||||
new("Connectors/Autocad/Speckle.Connectors.Civil3d2023", "net48"),
|
||||
new("Connectors/Autocad/Speckle.Connectors.Civil3d2024", "net48"),
|
||||
new("Connectors/Autocad/Speckle.Connectors.Civil3d2025", "net8.0-windows")
|
||||
]
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -76,23 +76,19 @@ public sealed class ArcGISReceiveBinding : IReceiveBinding
|
||||
.ServiceProvider.GetRequiredService<ReceiveOperation>()
|
||||
.Execute(
|
||||
modelCard.GetReceiveInfo("ArcGIS"), // POC: get host app name from settings? same for GetSendInfo
|
||||
cancellationToken,
|
||||
(status, progress) =>
|
||||
_operationProgressManager.SetModelProgress(
|
||||
Parent,
|
||||
modelCardId,
|
||||
new ModelCardProgress(modelCardId, status, progress),
|
||||
cancellationToken
|
||||
)
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
modelCard.BakedObjectIds = receiveOperationResults.BakedObjectIds.ToList();
|
||||
Commands.SetModelReceiveResult(
|
||||
modelCardId,
|
||||
receiveOperationResults.BakedObjectIds,
|
||||
receiveOperationResults.ConversionResults
|
||||
);
|
||||
await Commands
|
||||
.SetModelReceiveResult(
|
||||
modelCardId,
|
||||
receiveOperationResults.BakedObjectIds,
|
||||
receiveOperationResults.ConversionResults
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -104,7 +100,7 @@ public sealed class ArcGISReceiveBinding : IReceiveBinding
|
||||
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);
|
||||
Commands.SetModelError(modelCardId, ex);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using ArcGIS.Desktop.Mapping.Events;
|
||||
using Speckle.Connectors.ArcGIS.Utils;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
|
||||
@@ -7,11 +8,13 @@ namespace Speckle.Connectors.ArcGIS.Bindings;
|
||||
|
||||
public class ArcGISSelectionBinding : ISelectionBinding
|
||||
{
|
||||
private readonly MapMembersUtils _mapMemberUtils;
|
||||
public string Name => "selectionBinding";
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
public ArcGISSelectionBinding(IBrowserBridge parent)
|
||||
public ArcGISSelectionBinding(IBrowserBridge parent, MapMembersUtils mapMemberUtils)
|
||||
{
|
||||
_mapMemberUtils = mapMemberUtils;
|
||||
Parent = parent;
|
||||
var topLevelHandler = parent.TopLevelExceptionHandler;
|
||||
|
||||
@@ -52,14 +55,8 @@ public class ArcGISSelectionBinding : ISelectionBinding
|
||||
List<MapMember> allNestedMembers = new();
|
||||
foreach (MapMember member in selectedMembers)
|
||||
{
|
||||
if (member is GroupLayer group)
|
||||
{
|
||||
GetLayersFromGroup(group, allNestedMembers);
|
||||
}
|
||||
else
|
||||
{
|
||||
allNestedMembers.Add(member);
|
||||
}
|
||||
var layerMapMembers = _mapMemberUtils.UnpackMapLayers(selectedMembers);
|
||||
allNestedMembers.AddRange(layerMapMembers);
|
||||
}
|
||||
|
||||
List<string> objectTypes = allNestedMembers
|
||||
|
||||
@@ -9,6 +9,7 @@ using ArcGIS.Desktop.Mapping.Events;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.ArcGIS.Filters;
|
||||
using Speckle.Connectors.ArcGIS.Utils;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
@@ -54,6 +55,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
|
||||
private List<FeatureLayer> SubscribedLayers { get; set; } = new();
|
||||
private List<StandaloneTable> SubscribedTables { get; set; } = new();
|
||||
private readonly MapMembersUtils _mapMemberUtils;
|
||||
|
||||
public ArcGISSendBinding(
|
||||
DocumentModelStore store,
|
||||
@@ -64,7 +66,8 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
ISendConversionCache sendConversionCache,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<ArcGISSendBinding> logger,
|
||||
IArcGISConversionSettingsFactory arcGisConversionSettingsFactory
|
||||
IArcGISConversionSettingsFactory arcGisConversionSettingsFactory,
|
||||
MapMembersUtils mapMemberUtils
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
@@ -76,6 +79,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
_logger = logger;
|
||||
_topLevelExceptionHandler = parent.TopLevelExceptionHandler;
|
||||
_arcGISConversionSettingsFactory = arcGisConversionSettingsFactory;
|
||||
_mapMemberUtils = mapMemberUtils;
|
||||
|
||||
Parent = parent;
|
||||
Commands = new SendBindingUICommands(parent);
|
||||
@@ -89,22 +93,32 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
private void SubscribeToArcGISEvents()
|
||||
{
|
||||
LayersRemovedEvent.Subscribe(
|
||||
a => _topLevelExceptionHandler.CatchUnhandled(() => GetIdsForLayersRemovedEvent(a)),
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () => await GetIdsForLayersRemovedEvent(a).ConfigureAwait(false)),
|
||||
true
|
||||
);
|
||||
|
||||
StandaloneTablesRemovedEvent.Subscribe(
|
||||
a => _topLevelExceptionHandler.CatchUnhandled(() => GetIdsForStandaloneTablesRemovedEvent(a)),
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await GetIdsForStandaloneTablesRemovedEvent(a).ConfigureAwait(false)
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
MapPropertyChangedEvent.Subscribe(
|
||||
a => _topLevelExceptionHandler.CatchUnhandled(() => GetIdsForMapPropertyChangedEvent(a)),
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await GetIdsForMapPropertyChangedEvent(a).ConfigureAwait(false)
|
||||
),
|
||||
true
|
||||
); // Map units, CRS etc.
|
||||
|
||||
MapMemberPropertiesChangedEvent.Subscribe(
|
||||
a => _topLevelExceptionHandler.CatchUnhandled(() => GetIdsForMapMemberPropertiesChangedEvent(a)),
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await GetIdsForMapMemberPropertiesChangedEvent(a).ConfigureAwait(false)
|
||||
),
|
||||
true
|
||||
); // e.g. Layer name
|
||||
|
||||
@@ -181,28 +195,31 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
{
|
||||
RowCreatedEvent.Subscribe(
|
||||
(args) =>
|
||||
{
|
||||
OnRowChanged(args);
|
||||
},
|
||||
Parent.TopLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await OnRowChanged(args).ConfigureAwait(false);
|
||||
}),
|
||||
layerTable
|
||||
);
|
||||
RowChangedEvent.Subscribe(
|
||||
(args) =>
|
||||
{
|
||||
OnRowChanged(args);
|
||||
},
|
||||
Parent.TopLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await OnRowChanged(args).ConfigureAwait(false);
|
||||
}),
|
||||
layerTable
|
||||
);
|
||||
RowDeletedEvent.Subscribe(
|
||||
(args) =>
|
||||
{
|
||||
OnRowChanged(args);
|
||||
},
|
||||
Parent.TopLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await OnRowChanged(args).ConfigureAwait(false);
|
||||
}),
|
||||
layerTable
|
||||
);
|
||||
}
|
||||
|
||||
private void OnRowChanged(RowChangedEventArgs args)
|
||||
private async Task OnRowChanged(RowChangedEventArgs args)
|
||||
{
|
||||
if (args == null || MapView.Active == null)
|
||||
{
|
||||
@@ -241,60 +258,38 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
}
|
||||
}
|
||||
|
||||
RunExpirationChecks(false);
|
||||
await RunExpirationChecks(false).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void GetIdsForLayersRemovedEvent(LayerEventsArgs args)
|
||||
private async Task GetIdsForLayersRemovedEvent(LayerEventsArgs args)
|
||||
{
|
||||
foreach (Layer layer in args.Layers)
|
||||
{
|
||||
ChangedObjectIds[layer.URI] = 1;
|
||||
}
|
||||
RunExpirationChecks(true);
|
||||
await RunExpirationChecks(true).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void GetIdsForStandaloneTablesRemovedEvent(StandaloneTableEventArgs args)
|
||||
private async Task GetIdsForStandaloneTablesRemovedEvent(StandaloneTableEventArgs args)
|
||||
{
|
||||
foreach (StandaloneTable table in args.Tables)
|
||||
{
|
||||
ChangedObjectIds[table.URI] = 1;
|
||||
}
|
||||
RunExpirationChecks(true);
|
||||
await RunExpirationChecks(true).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void AddChangedNestedObjectIds(GroupLayer group)
|
||||
private async Task GetIdsForMapPropertyChangedEvent(MapPropertyChangedEventArgs args)
|
||||
{
|
||||
ChangedObjectIds[group.URI] = 1;
|
||||
foreach (var member in group.Layers)
|
||||
foreach (Map map in args.Maps)
|
||||
{
|
||||
if (member is GroupLayer subGroup)
|
||||
{
|
||||
AddChangedNestedObjectIds(subGroup);
|
||||
}
|
||||
else
|
||||
List<MapMember> allMapMembers = _mapMemberUtils.GetAllMapMembers(map);
|
||||
foreach (MapMember member in allMapMembers)
|
||||
{
|
||||
ChangedObjectIds[member.URI] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GetIdsForMapPropertyChangedEvent(MapPropertyChangedEventArgs args)
|
||||
{
|
||||
foreach (Map map in args.Maps)
|
||||
{
|
||||
foreach (MapMember member in map.Layers)
|
||||
{
|
||||
if (member is GroupLayer group)
|
||||
{
|
||||
AddChangedNestedObjectIds(group);
|
||||
}
|
||||
else
|
||||
{
|
||||
ChangedObjectIds[member.URI] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
RunExpirationChecks(false);
|
||||
await RunExpirationChecks(false).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void GetIdsForLayersAddedEvent(LayerEventsArgs args)
|
||||
@@ -316,7 +311,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
}
|
||||
}
|
||||
|
||||
private void GetIdsForMapMemberPropertiesChangedEvent(MapMemberPropertiesChangedEventArgs args)
|
||||
private async Task GetIdsForMapMemberPropertiesChangedEvent(MapMemberPropertiesChangedEventArgs args)
|
||||
{
|
||||
// don't subscribe to all events (e.g. expanding group, changing visibility etc.)
|
||||
bool validEvent = false;
|
||||
@@ -344,7 +339,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
{
|
||||
ChangedObjectIds[member.URI] = 1;
|
||||
}
|
||||
RunExpirationChecks(false);
|
||||
await RunExpirationChecks(false).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,13 +412,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
.Execute(
|
||||
mapMembers,
|
||||
modelCard.GetSendInfo("ArcGIS"), // POC: get host app name from settings? same for GetReceiveInfo
|
||||
(status, progress) =>
|
||||
_operationProgressManager.SetModelProgress(
|
||||
Parent,
|
||||
modelCardId,
|
||||
new ModelCardProgress(modelCardId, status, progress),
|
||||
cancellationToken
|
||||
),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
@@ -432,7 +421,9 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Commands.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults);
|
||||
await Commands
|
||||
.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -444,7 +435,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
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);
|
||||
Commands.SetModelError(modelCardId, ex);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,7 +444,7 @@ public sealed class ArcGISSendBinding : 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 void RunExpirationChecks(bool idsDeleted)
|
||||
private async Task RunExpirationChecks(bool idsDeleted)
|
||||
{
|
||||
var senders = _store.GetSenders();
|
||||
List<string> expiredSenderIds = new();
|
||||
@@ -465,7 +456,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
{
|
||||
var objIds = sender.SendFilter.NotNull().GetObjectIds();
|
||||
var intersection = objIds.Intersect(objectIdsList).ToList();
|
||||
bool isExpired = sender.SendFilter.NotNull().CheckExpiry(objectIdsList);
|
||||
bool isExpired = intersection.Count != 0;
|
||||
if (isExpired)
|
||||
{
|
||||
expiredSenderIds.Add(sender.ModelCardId.NotNull());
|
||||
@@ -479,7 +470,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
}
|
||||
}
|
||||
|
||||
Commands.SetModelsExpired(expiredSenderIds);
|
||||
await Commands.SetModelsExpired(expiredSenderIds).ConfigureAwait(false);
|
||||
ChangedObjectIds = new();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,9 +30,10 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
Commands = new BasicConnectorBindingCommands(parent);
|
||||
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
{
|
||||
Commands.NotifyDocumentChanged();
|
||||
};
|
||||
parent.TopLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await Commands.NotifyDocumentChanged().ConfigureAwait(false);
|
||||
});
|
||||
}
|
||||
|
||||
public string GetSourceApplicationName() => _speckleApplication.Slug;
|
||||
@@ -59,10 +60,10 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
|
||||
|
||||
public void HighlightObjects(List<string> objectIds) =>
|
||||
HighlightObjectsOnView(objectIds.Select(x => new ObjectID(x)).ToList());
|
||||
public async Task HighlightObjects(IReadOnlyList<string> objectIds) =>
|
||||
await HighlightObjectsOnView(objectIds.Select(x => new ObjectID(x)).ToList()).ConfigureAwait(false);
|
||||
|
||||
public void HighlightModel(string modelCardId)
|
||||
public async Task HighlightModel(string modelCardId)
|
||||
{
|
||||
var model = _store.GetModelById(modelCardId);
|
||||
|
||||
@@ -87,27 +88,27 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
{
|
||||
return;
|
||||
}
|
||||
HighlightObjectsOnView(objectIds);
|
||||
await HighlightObjectsOnView(objectIds).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async void HighlightObjectsOnView(List<ObjectID> objectIds)
|
||||
private async Task HighlightObjectsOnView(IReadOnlyList<ObjectID> objectIds)
|
||||
{
|
||||
MapView mapView = MapView.Active;
|
||||
|
||||
await QueuedTask
|
||||
.Run(() =>
|
||||
.Run(async () =>
|
||||
{
|
||||
List<MapMemberFeature> mapMembersFeatures = GetMapMembers(objectIds, mapView);
|
||||
ClearSelectionInTOC();
|
||||
ClearSelection();
|
||||
SelectMapMembersInTOC(mapMembersFeatures);
|
||||
await SelectMapMembersInTOC(mapMembersFeatures).ConfigureAwait(false);
|
||||
SelectMapMembersAndFeatures(mapMembersFeatures);
|
||||
mapView.ZoomToSelected();
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private List<MapMemberFeature> GetMapMembers(List<ObjectID> objectIds, MapView mapView)
|
||||
private List<MapMemberFeature> GetMapMembers(IReadOnlyList<ObjectID> objectIds, MapView mapView)
|
||||
{
|
||||
// find the layer on the map (from the objectID) and add the featureID is available
|
||||
List<MapMemberFeature> mapMembersFeatures = new();
|
||||
@@ -145,7 +146,7 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
MapView.Active.ClearTOCSelection();
|
||||
}
|
||||
|
||||
private void SelectMapMembersAndFeatures(List<MapMemberFeature> mapMembersFeatures)
|
||||
private void SelectMapMembersAndFeatures(IReadOnlyList<MapMemberFeature> mapMembersFeatures)
|
||||
{
|
||||
foreach (MapMemberFeature mapMemberFeat in mapMembersFeatures)
|
||||
{
|
||||
@@ -170,7 +171,7 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectMapMembersInTOC(List<MapMemberFeature> mapMembersFeatures)
|
||||
private async Task SelectMapMembersInTOC(IReadOnlyList<MapMemberFeature> mapMembersFeatures)
|
||||
{
|
||||
List<Layer> layers = new();
|
||||
List<StandaloneTable> tables = new();
|
||||
@@ -186,7 +187,7 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
}
|
||||
else
|
||||
{
|
||||
QueuedTask.Run(() => layer.SetExpanded(true));
|
||||
await QueuedTask.Run(() => layer.SetExpanded(true)).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
else if (member is StandaloneTable table)
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.Filters;
|
||||
|
||||
public class ArcGISEverythingFilter : EverythingSendFilter
|
||||
{
|
||||
public override List<string> GetObjectIds() => new(); // TODO
|
||||
|
||||
public override bool CheckExpiry(string[] changedObjectIds) => true;
|
||||
}
|
||||
@@ -4,7 +4,10 @@ namespace Speckle.Connectors.ArcGIS.Filters;
|
||||
|
||||
public class ArcGISSelectionFilter : DirectSelectionSendFilter
|
||||
{
|
||||
public override List<string> GetObjectIds() => SelectedObjectIds;
|
||||
public ArcGISSelectionFilter()
|
||||
{
|
||||
IsDefault = true;
|
||||
}
|
||||
|
||||
public override bool CheckExpiry(string[] changedObjectIds) => SelectedObjectIds.Intersect(changedObjectIds).Any();
|
||||
public override List<string> GetObjectIds() => SelectedObjectIds;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Drawing;
|
||||
using ArcGIS.Core.CIM;
|
||||
using ArcGIS.Core.Data;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Converters.ArcGIS3.Utils;
|
||||
using Speckle.Objects;
|
||||
using Speckle.Objects.Other;
|
||||
@@ -55,14 +56,15 @@ public class ArcGISColorManager
|
||||
/// </summary>
|
||||
/// <param name="colorProxies"></param>
|
||||
/// <param name="onOperationProgressed"></param>
|
||||
public void ParseColors(List<ColorProxy> colorProxies, Action<string, double?>? onOperationProgressed)
|
||||
public async Task ParseColors(List<ColorProxy> colorProxies, IProgress<CardProgress> onOperationProgressed)
|
||||
{
|
||||
// injected as Singleton, so we need to clean existing proxies first
|
||||
ObjectColorsIdMap = new();
|
||||
var count = 0;
|
||||
foreach (ColorProxy colorProxy in colorProxies)
|
||||
{
|
||||
onOperationProgressed?.Invoke("Converting colors", (double)++count / colorProxies.Count);
|
||||
onOperationProgressed.Report(new("Converting colors", (double)++count / colorProxies.Count));
|
||||
await Task.Yield();
|
||||
foreach (string objectId in colorProxy.objects)
|
||||
{
|
||||
Color convertedColor = Color.FromArgb(colorProxy.value);
|
||||
@@ -76,14 +78,18 @@ public class ArcGISColorManager
|
||||
/// </summary>
|
||||
/// <param name="materialProxies"></param>
|
||||
/// <param name="onOperationProgressed"></param>
|
||||
public void ParseMaterials(List<RenderMaterialProxy> materialProxies, Action<string, double?>? onOperationProgressed)
|
||||
public async Task ParseMaterials(
|
||||
List<RenderMaterialProxy> materialProxies,
|
||||
IProgress<CardProgress> onOperationProgressed
|
||||
)
|
||||
{
|
||||
// injected as Singleton, so we need to clean existing proxies first
|
||||
ObjectMaterialsIdMap = new();
|
||||
var count = 0;
|
||||
foreach (RenderMaterialProxy colorProxy in materialProxies)
|
||||
{
|
||||
onOperationProgressed?.Invoke("Converting materials", (double)++count / materialProxies.Count);
|
||||
onOperationProgressed.Report(new("Converting materials", (double)++count / materialProxies.Count));
|
||||
await Task.Yield();
|
||||
foreach (string objectId in colorProxy.objects)
|
||||
{
|
||||
Color convertedColor = Color.FromArgb(colorProxy.value.diffuse);
|
||||
@@ -310,6 +316,11 @@ public class ArcGISColorManager
|
||||
int count = 1;
|
||||
using (RowCursor rowCursor = layer.Search())
|
||||
{
|
||||
// if layer doesn't have a valid data source (and the conversion likely failed), don't create a colorProxy
|
||||
if (rowCursor is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
while (rowCursor.MoveNext())
|
||||
{
|
||||
string elementAppId = $"{layer.URI}_{count}";
|
||||
@@ -445,6 +456,11 @@ public class ArcGISColorManager
|
||||
out int color
|
||||
)
|
||||
{
|
||||
if (uniqueRenderer.DefaultSymbol is null)
|
||||
{
|
||||
color = RbgToInt(255, 255, 255, 255);
|
||||
return false;
|
||||
}
|
||||
if (!TryGetSymbolColor(uniqueRenderer.DefaultSymbol.Symbol, out color)) // get default color
|
||||
{
|
||||
return false;
|
||||
@@ -487,6 +503,11 @@ public class ArcGISColorManager
|
||||
// set the group color to class symbol color if conditions are met
|
||||
if (groupConditionsMet)
|
||||
{
|
||||
if (groupClass.Symbol is null)
|
||||
{
|
||||
color = RbgToInt(255, 255, 255, 255);
|
||||
return false;
|
||||
}
|
||||
if (!TryGetSymbolColor(groupClass.Symbol.Symbol, out color))
|
||||
{
|
||||
return false;
|
||||
@@ -538,6 +559,11 @@ public class ArcGISColorManager
|
||||
out int color
|
||||
)
|
||||
{
|
||||
if (graduatedRenderer.DefaultSymbol is null)
|
||||
{
|
||||
color = RbgToInt(255, 255, 255, 255);
|
||||
return false;
|
||||
}
|
||||
if (!TryGetSymbolColor(graduatedRenderer.DefaultSymbol.Symbol, out color)) // get default color
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.HostApp;
|
||||
|
||||
public class SyncToQueuedTask : ISyncToThread
|
||||
{
|
||||
public Task<T> RunOnThread<T>(Func<T> func) => QueuedTask.Run(func);
|
||||
}
|
||||
+80
-69
@@ -62,7 +62,7 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
Action<string, double?>? onOperationProgressed,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
@@ -70,7 +70,7 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
// ATM, GIS commit CRS is stored per layer (in FeatureClass converter), but should be moved to the Root level too
|
||||
|
||||
// Prompt the UI conversion started. Progress bar will swoosh.
|
||||
onOperationProgressed?.Invoke("Converting", null);
|
||||
onOperationProgressed.Report(new("Converting", null));
|
||||
|
||||
// get materials
|
||||
List<RenderMaterialProxy>? materials = (rootObject[ProxyKeys.RENDER_MATERIAL] as List<object>)
|
||||
@@ -78,14 +78,14 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
.ToList();
|
||||
if (materials != null)
|
||||
{
|
||||
_colorManager.ParseMaterials(materials, onOperationProgressed);
|
||||
await _colorManager.ParseMaterials(materials, onOperationProgressed).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// get colors
|
||||
List<ColorProxy>? colors = (rootObject[ProxyKeys.COLOR] as List<object>)?.Cast<ColorProxy>().ToList();
|
||||
if (colors != null)
|
||||
{
|
||||
_colorManager.ParseColors(colors, onOperationProgressed);
|
||||
await _colorManager.ParseColors(colors, onOperationProgressed).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
@@ -125,24 +125,32 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
{
|
||||
results.Add(new(Status.ERROR, obj, null, null, ex));
|
||||
}
|
||||
onOperationProgressed?.Invoke("Converting", (double)++count / objectsToConvert.Count);
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / objectsToConvert.Count));
|
||||
}
|
||||
|
||||
// 2.1. Group conversionTrackers (to write into datasets)
|
||||
onOperationProgressed?.Invoke("Grouping features into layers", null);
|
||||
onOperationProgressed.Report(new("Grouping features into layers", null));
|
||||
Dictionary<string, List<(TraversalContext, ObjectConversionTracker)>> convertedGroups = await QueuedTask
|
||||
.Run(() =>
|
||||
.Run(async () =>
|
||||
{
|
||||
return _featureClassUtils.GroupConversionTrackers(conversionTracker, onOperationProgressed);
|
||||
return await _featureClassUtils
|
||||
.GroupConversionTrackers(conversionTracker, (s, progres) => onOperationProgressed.Report(new(s, progres)))
|
||||
.ConfigureAwait(false);
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// 2.2. Write groups of objects to Datasets
|
||||
onOperationProgressed?.Invoke("Writing to Database", null);
|
||||
onOperationProgressed.Report(new("Writing to Database", null));
|
||||
await QueuedTask
|
||||
.Run(() =>
|
||||
.Run(async () =>
|
||||
{
|
||||
_featureClassUtils.CreateDatasets(conversionTracker, convertedGroups, onOperationProgressed);
|
||||
await _featureClassUtils
|
||||
.CreateDatasets(
|
||||
conversionTracker,
|
||||
convertedGroups,
|
||||
(s, progres) => onOperationProgressed.Report(new(s, progres))
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
|
||||
@@ -153,7 +161,7 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
|
||||
int bakeCount = 0;
|
||||
Dictionary<string, (MapMember, CIMUniqueValueRenderer?)> bakedMapMembers = new();
|
||||
onOperationProgressed?.Invoke("Adding to Map", bakeCount);
|
||||
onOperationProgressed.Report(new("Adding to Map", bakeCount));
|
||||
|
||||
foreach (var item in conversionTracker)
|
||||
{
|
||||
@@ -215,7 +223,8 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
// add report item
|
||||
AddResultsFromTracker(trackerItem, results);
|
||||
}
|
||||
onOperationProgressed?.Invoke("Adding to Map", (double)++bakeCount / conversionTracker.Count);
|
||||
|
||||
onOperationProgressed.Report(new("Adding to Map", (double)++bakeCount / conversionTracker.Count));
|
||||
}
|
||||
|
||||
// apply renderers to baked layers
|
||||
@@ -295,78 +304,80 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
}
|
||||
}
|
||||
|
||||
private Task<MapMember> AddDatasetsToMap(
|
||||
private async Task<MapMember> AddDatasetsToMap(
|
||||
ObjectConversionTracker trackerItem,
|
||||
Dictionary<string, GroupLayer> createdLayerGroups,
|
||||
string projectName,
|
||||
string modelName
|
||||
)
|
||||
{
|
||||
return QueuedTask.Run(() =>
|
||||
{
|
||||
// get layer details
|
||||
string? datasetId = trackerItem.DatasetId; // should not be null here
|
||||
Uri uri = new($"{_settingsStore.Current.SpeckleDatabasePath.AbsolutePath.Replace('/', '\\')}\\{datasetId}");
|
||||
string nestedLayerName = trackerItem.NestedLayerName;
|
||||
|
||||
// add group for the current layer
|
||||
string shortName = nestedLayerName.Split("\\")[^1];
|
||||
string nestedLayerPath = string.Join("\\", nestedLayerName.Split("\\").SkipLast(1));
|
||||
|
||||
// if no general group layer found
|
||||
if (createdLayerGroups.Count == 0)
|
||||
return await QueuedTask
|
||||
.Run(() =>
|
||||
{
|
||||
Map map = _settingsStore.Current.Map;
|
||||
GroupLayer mainGroupLayer = LayerFactory.Instance.CreateGroupLayer(map, 0, $"{projectName}: {modelName}");
|
||||
mainGroupLayer.SetExpanded(true);
|
||||
createdLayerGroups["Basic Speckle Group"] = mainGroupLayer; // key doesn't really matter here
|
||||
}
|
||||
// get layer details
|
||||
string? datasetId = trackerItem.DatasetId; // should not be null here
|
||||
Uri uri = new($"{_settingsStore.Current.SpeckleDatabasePath.AbsolutePath.Replace('/', '\\')}\\{datasetId}");
|
||||
string nestedLayerName = trackerItem.NestedLayerName;
|
||||
|
||||
var groupLayer = CreateNestedGroupLayer(nestedLayerPath, createdLayerGroups);
|
||||
// add group for the current layer
|
||||
string shortName = nestedLayerName.Split("\\")[^1];
|
||||
string nestedLayerPath = string.Join("\\", nestedLayerName.Split("\\").SkipLast(1));
|
||||
|
||||
// Most of the Speckle-written datasets will be containing geometry and added as Layers
|
||||
// although, some datasets might be just tables (e.g. native GIS Tables, in the future maybe Revit schedules etc.
|
||||
// We can create a connection to the dataset in advance and determine its type, but this will be more
|
||||
// expensive, than assuming by default that it's a layer with geometry (which in most cases it's expected to be)
|
||||
try
|
||||
{
|
||||
var layer = LayerFactory.Instance.CreateLayer(uri, groupLayer, layerName: shortName);
|
||||
if (layer == null)
|
||||
// if no general group layer found
|
||||
if (createdLayerGroups.Count == 0)
|
||||
{
|
||||
throw new SpeckleException($"Layer '{shortName}' was not created");
|
||||
Map map = _settingsStore.Current.Map;
|
||||
GroupLayer mainGroupLayer = LayerFactory.Instance.CreateGroupLayer(map, 0, $"{projectName}: {modelName}");
|
||||
mainGroupLayer.SetExpanded(true);
|
||||
createdLayerGroups["Basic Speckle Group"] = mainGroupLayer; // key doesn't really matter here
|
||||
}
|
||||
layer.SetExpanded(false);
|
||||
|
||||
// if Scene
|
||||
// https://community.esri.com/t5/arcgis-pro-sdk-questions/sdk-equivalent-to-changing-layer-s-elevation/td-p/1346139
|
||||
if (_settingsStore.Current.Map.IsScene)
|
||||
var groupLayer = CreateNestedGroupLayer(nestedLayerPath, createdLayerGroups);
|
||||
|
||||
// Most of the Speckle-written datasets will be containing geometry and added as Layers
|
||||
// although, some datasets might be just tables (e.g. native GIS Tables, in the future maybe Revit schedules etc.
|
||||
// We can create a connection to the dataset in advance and determine its type, but this will be more
|
||||
// expensive, than assuming by default that it's a layer with geometry (which in most cases it's expected to be)
|
||||
try
|
||||
{
|
||||
var groundSurfaceLayer = _settingsStore.Current.Map.GetGroundElevationSurfaceLayer();
|
||||
var layerElevationSurface = new CIMLayerElevationSurface
|
||||
var layer = LayerFactory.Instance.CreateLayer(uri, groupLayer, layerName: shortName);
|
||||
if (layer == null)
|
||||
{
|
||||
ElevationSurfaceLayerURI = groundSurfaceLayer.URI,
|
||||
};
|
||||
|
||||
// for Feature Layers
|
||||
if (layer.GetDefinition() is CIMFeatureLayer cimLyr)
|
||||
{
|
||||
cimLyr.LayerElevation = layerElevationSurface;
|
||||
layer.SetDefinition(cimLyr);
|
||||
throw new SpeckleException($"Layer '{shortName}' was not created");
|
||||
}
|
||||
}
|
||||
layer.SetExpanded(false);
|
||||
|
||||
return (MapMember)layer;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
StandaloneTable table = StandaloneTableFactory.Instance.CreateStandaloneTable(
|
||||
uri,
|
||||
groupLayer,
|
||||
tableName: shortName
|
||||
);
|
||||
return table;
|
||||
}
|
||||
});
|
||||
// if Scene
|
||||
// https://community.esri.com/t5/arcgis-pro-sdk-questions/sdk-equivalent-to-changing-layer-s-elevation/td-p/1346139
|
||||
if (_settingsStore.Current.Map.IsScene)
|
||||
{
|
||||
var groundSurfaceLayer = _settingsStore.Current.Map.GetGroundElevationSurfaceLayer();
|
||||
var layerElevationSurface = new CIMLayerElevationSurface
|
||||
{
|
||||
ElevationSurfaceLayerURI = groundSurfaceLayer.URI,
|
||||
};
|
||||
|
||||
// for Feature Layers
|
||||
if (layer.GetDefinition() is CIMFeatureLayer cimLyr)
|
||||
{
|
||||
cimLyr.LayerElevation = layerElevationSurface;
|
||||
layer.SetDefinition(cimLyr);
|
||||
}
|
||||
}
|
||||
|
||||
return (MapMember)layer;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
StandaloneTable table = StandaloneTableFactory.Instance.CreateStandaloneTable(
|
||||
uri,
|
||||
groupLayer,
|
||||
tableName: shortName
|
||||
);
|
||||
return table;
|
||||
}
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private GroupLayer CreateNestedGroupLayer(string nestedLayerPath, Dictionary<string, GroupLayer> createdLayerGroups)
|
||||
|
||||
+7
-7
@@ -57,7 +57,7 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<MapMember>
|
||||
#pragma warning restore CA1506
|
||||
IReadOnlyList<MapMember> objects,
|
||||
SendInfo sendInfo,
|
||||
Action<string, double?>? onOperationProgressed = null,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken ct = default
|
||||
)
|
||||
{
|
||||
@@ -71,7 +71,7 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<MapMember>
|
||||
|
||||
List<SendConversionResult> results = new(objects.Count);
|
||||
var cacheHitCount = 0;
|
||||
List<(GroupLayer, Collection)> nestedGroups = new();
|
||||
List<(ILayerContainer, Collection)> nestedGroups = new();
|
||||
|
||||
// reorder selected layers by Table of Content (TOC) order
|
||||
List<(MapMember, int)> layersWithDisplayPriority = _mapMemberUtils.GetLayerDisplayPriority(
|
||||
@@ -79,7 +79,7 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<MapMember>
|
||||
objects
|
||||
);
|
||||
|
||||
onOperationProgressed?.Invoke("Converting", null);
|
||||
onOperationProgressed.Report(new("Converting", null));
|
||||
using (var __ = _activityFactory.Start("Converting objects"))
|
||||
{
|
||||
foreach ((MapMember mapMember, _) in layersWithDisplayPriority)
|
||||
@@ -112,7 +112,7 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<MapMember>
|
||||
|
||||
// don't use cache for group layers
|
||||
if (
|
||||
mapMember is not GroupLayer
|
||||
mapMember is not ILayerContainer
|
||||
&& _sendConversionCache.TryGetValue(sendInfo.ProjectId, applicationId, out ObjectReference? value)
|
||||
)
|
||||
{
|
||||
@@ -121,7 +121,7 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<MapMember>
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mapMember is GroupLayer group)
|
||||
if (mapMember is ILayerContainer group)
|
||||
{
|
||||
// group layer will always come before it's contained layers
|
||||
// keep active group last in the list
|
||||
@@ -183,13 +183,13 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<MapMember>
|
||||
}
|
||||
}
|
||||
|
||||
onOperationProgressed?.Invoke("Converting", (double)++count / objects.Count);
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / objects.Count));
|
||||
}
|
||||
}
|
||||
|
||||
if (results.All(x => x.Status == Status.ERROR))
|
||||
{
|
||||
throw new SpeckleConversionException("Failed to convert all objects."); // fail fast instead creating empty commit! It will appear as model card error with red color.
|
||||
throw new SpeckleException("Failed to convert all objects."); // fail fast instead creating empty commit! It will appear as model card error with red color.
|
||||
}
|
||||
|
||||
// POC: Add Color Proxies
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using ArcGIS.Desktop.Internal.Mapping;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.Utils;
|
||||
@@ -28,21 +27,13 @@ public class MapMembersUtils
|
||||
List<MapMember> mapMembers = new();
|
||||
foreach (var layer in mapMembersToUnpack)
|
||||
{
|
||||
mapMembers.Add(layer);
|
||||
switch (layer)
|
||||
{
|
||||
case GroupLayer subGroup:
|
||||
mapMembers.Add(layer);
|
||||
var subGroupMapMembers = UnpackMapLayers(subGroup.Layers);
|
||||
mapMembers.AddRange(subGroupMapMembers);
|
||||
break;
|
||||
case ILayerContainerInternal subLayerContainerInternal:
|
||||
mapMembers.Add(layer);
|
||||
var subLayerMapMembers = UnpackMapLayers(subLayerContainerInternal.InternalLayers);
|
||||
case ILayerContainer subGroup:
|
||||
var subLayerMapMembers = UnpackMapLayers(subGroup.Layers);
|
||||
mapMembers.AddRange(subLayerMapMembers);
|
||||
break;
|
||||
default:
|
||||
mapMembers.Add(layer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,11 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -161,24 +166,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -244,8 +231,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -253,7 +241,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -278,7 +267,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -310,31 +299,36 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "VpMlOcApkQPLn90Xb5K+2nH64wN3NJ906u/YaM1oGAMw7v1SoYPbb5i03bFLuOw/Ho1KSGI0ccU82Jpi9p+n8A==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "KGbynDH2vFca7NqpVTp3KvNDE5zdX/ZuCtjdtqGG7rS8r5x2YMT6Ptk2RKJrpPNCaNL/YnuiZ425JLWua4lfqw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "LOV43Wn6IYWfK+ifz/XfcYDaL5ZFF6wLVJQGgSkaNEpGOBitCg6bQc2AuNuy5QHk85dbB1QS9XXEXjeoMxugLg=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
@@ -71,6 +71,14 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -156,24 +164,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -274,8 +264,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -283,7 +274,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -308,7 +300,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -346,31 +338,36 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "VpMlOcApkQPLn90Xb5K+2nH64wN3NJ906u/YaM1oGAMw7v1SoYPbb5i03bFLuOw/Ho1KSGI0ccU82Jpi9p+n8A==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "KGbynDH2vFca7NqpVTp3KvNDE5zdX/ZuCtjdtqGG7rS8r5x2YMT6Ptk2RKJrpPNCaNL/YnuiZ425JLWua4lfqw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "LOV43Wn6IYWfK+ifz/XfcYDaL5ZFF6wLVJQGgSkaNEpGOBitCg6bQc2AuNuy5QHk85dbB1QS9XXEXjeoMxugLg=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
@@ -71,6 +71,14 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -156,24 +164,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -274,8 +264,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -283,7 +274,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -308,7 +300,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -346,31 +338,36 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "VpMlOcApkQPLn90Xb5K+2nH64wN3NJ906u/YaM1oGAMw7v1SoYPbb5i03bFLuOw/Ho1KSGI0ccU82Jpi9p+n8A==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "KGbynDH2vFca7NqpVTp3KvNDE5zdX/ZuCtjdtqGG7rS8r5x2YMT6Ptk2RKJrpPNCaNL/YnuiZ425JLWua4lfqw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "LOV43Wn6IYWfK+ifz/XfcYDaL5ZFF6wLVJQGgSkaNEpGOBitCg6bQc2AuNuy5QHk85dbB1QS9XXEXjeoMxugLg=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
@@ -71,6 +71,14 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -156,24 +164,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -274,8 +264,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -283,7 +274,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -309,7 +301,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -347,31 +339,36 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "VpMlOcApkQPLn90Xb5K+2nH64wN3NJ906u/YaM1oGAMw7v1SoYPbb5i03bFLuOw/Ho1KSGI0ccU82Jpi9p+n8A==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "KGbynDH2vFca7NqpVTp3KvNDE5zdX/ZuCtjdtqGG7rS8r5x2YMT6Ptk2RKJrpPNCaNL/YnuiZ425JLWua4lfqw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "LOV43Wn6IYWfK+ifz/XfcYDaL5ZFF6wLVJQGgSkaNEpGOBitCg6bQc2AuNuy5QHk85dbB1QS9XXEXjeoMxugLg=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
@@ -70,6 +70,11 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -155,24 +160,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -238,8 +225,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -247,7 +235,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -273,7 +262,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -311,31 +300,36 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "VpMlOcApkQPLn90Xb5K+2nH64wN3NJ906u/YaM1oGAMw7v1SoYPbb5i03bFLuOw/Ho1KSGI0ccU82Jpi9p+n8A==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "KGbynDH2vFca7NqpVTp3KvNDE5zdX/ZuCtjdtqGG7rS8r5x2YMT6Ptk2RKJrpPNCaNL/YnuiZ425JLWua4lfqw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "LOV43Wn6IYWfK+ifz/XfcYDaL5ZFF6wLVJQGgSkaNEpGOBitCg6bQc2AuNuy5QHk85dbB1QS9XXEXjeoMxugLg=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
+62
-56
@@ -37,10 +37,10 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
|
||||
_speckleApplication = speckleApplication;
|
||||
Commands = new BasicConnectorBindingCommands(parent);
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
{
|
||||
Commands.NotifyDocumentChanged();
|
||||
};
|
||||
|
||||
parent.TopLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await Commands.NotifyDocumentChanged().ConfigureAwait(false);
|
||||
});
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@@ -72,17 +72,17 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
|
||||
|
||||
public void HighlightObjects(List<string> objectIds)
|
||||
public async Task HighlightObjects(IReadOnlyList<string> objectIds)
|
||||
{
|
||||
// POC: Will be addressed to move it into AutocadContext!
|
||||
var doc = Application.DocumentManager.MdiActiveDocument;
|
||||
|
||||
var dbObjects = doc.GetObjects(objectIds);
|
||||
var acadObjectIds = dbObjects.Select(tuple => tuple.Root.Id).ToArray();
|
||||
HighlightObjectsOnView(acadObjectIds);
|
||||
await HighlightObjectsOnView(acadObjectIds).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public void HighlightModel(string modelCardId)
|
||||
public async Task HighlightModel(string modelCardId)
|
||||
{
|
||||
// POC: Will be addressed to move it into AutocadContext!
|
||||
var doc = Application.DocumentManager.MdiActiveDocument;
|
||||
@@ -116,72 +116,78 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
if (objectIds.Length == 0)
|
||||
{
|
||||
Commands.SetModelError(modelCardId, new OperationCanceledException("No objects found to highlight."));
|
||||
await Commands
|
||||
.SetModelError(modelCardId, new OperationCanceledException("No objects found to highlight."))
|
||||
.ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
HighlightObjectsOnView(objectIds, modelCardId);
|
||||
await HighlightObjectsOnView(objectIds, modelCardId).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void HighlightObjectsOnView(ObjectId[] objectIds, string? modelCardId = null)
|
||||
private async Task HighlightObjectsOnView(ObjectId[] objectIds, string? modelCardId = null)
|
||||
{
|
||||
var doc = Application.DocumentManager.MdiActiveDocument;
|
||||
|
||||
Parent.RunOnMainThread(() =>
|
||||
{
|
||||
try
|
||||
await Parent
|
||||
.RunOnMainThreadAsync(async () =>
|
||||
{
|
||||
doc.Editor.SetImpliedSelection(Array.Empty<ObjectId>()); // Deselects
|
||||
try
|
||||
{
|
||||
doc.Editor.SetImpliedSelection(objectIds);
|
||||
}
|
||||
catch (Exception e) when (!e.IsFatal())
|
||||
{
|
||||
// SWALLOW REASON:
|
||||
// If the objects under the blocks, it won't be able to select them.
|
||||
// If we try, API will throw the invalid input error, because we request something from API that Autocad doesn't
|
||||
// handle it on its current canvas. Block elements only selectable when in its scope.
|
||||
}
|
||||
doc.Editor.UpdateScreen();
|
||||
|
||||
Extents3d selectedExtents = new();
|
||||
|
||||
var tr = doc.TransactionManager.StartTransaction();
|
||||
foreach (ObjectId objectId in objectIds)
|
||||
{
|
||||
doc.Editor.SetImpliedSelection(Array.Empty<ObjectId>()); // Deselects
|
||||
try
|
||||
{
|
||||
var entity = (Entity?)tr.GetObject(objectId, OpenMode.ForRead);
|
||||
if (entity?.GeometricExtents != null)
|
||||
{
|
||||
selectedExtents.AddExtents(entity.GeometricExtents);
|
||||
}
|
||||
doc.Editor.SetImpliedSelection(objectIds);
|
||||
}
|
||||
catch (Exception e) when (!e.IsFatal())
|
||||
{
|
||||
// Note: we're swallowing exeptions here because of a weird case when receiving blocks, we would have
|
||||
// acad api throw an error on accessing entity.GeometricExtents.
|
||||
// SWALLOW REASON:
|
||||
// If the objects under the blocks, it won't be able to select them.
|
||||
// If we try, API will throw the invalid input error, because we request something from API that Autocad doesn't
|
||||
// handle it on its current canvas. Block elements only selectable when in its scope.
|
||||
}
|
||||
doc.Editor.UpdateScreen();
|
||||
|
||||
Extents3d selectedExtents = new();
|
||||
|
||||
var tr = doc.TransactionManager.StartTransaction();
|
||||
foreach (ObjectId objectId in objectIds)
|
||||
{
|
||||
try
|
||||
{
|
||||
var entity = (Entity?)tr.GetObject(objectId, OpenMode.ForRead);
|
||||
if (entity?.GeometricExtents != null)
|
||||
{
|
||||
selectedExtents.AddExtents(entity.GeometricExtents);
|
||||
}
|
||||
}
|
||||
catch (Exception e) when (!e.IsFatal())
|
||||
{
|
||||
// Note: we're swallowing exeptions here because of a weird case when receiving blocks, we would have
|
||||
// acad api throw an error on accessing entity.GeometricExtents.
|
||||
}
|
||||
}
|
||||
|
||||
doc.Editor.Zoom(selectedExtents);
|
||||
tr.Commit();
|
||||
Autodesk.AutoCAD.Internal.Utils.FlushGraphics();
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
if (modelCardId != null)
|
||||
{
|
||||
await Commands
|
||||
.SetModelError(modelCardId, new OperationCanceledException("Failed to highlight objects."))
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This will happen, in some cases, where we highlight individual objects. Should be caught by the top level handler and not
|
||||
// crash the host app.
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
doc.Editor.Zoom(selectedExtents);
|
||||
tr.Commit();
|
||||
Autodesk.AutoCAD.Internal.Utils.FlushGraphics();
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
if (modelCardId != null)
|
||||
{
|
||||
Commands.SetModelError(modelCardId, new OperationCanceledException("Failed to highlight objects."));
|
||||
}
|
||||
else
|
||||
{
|
||||
// This will happen, in some cases, where we highlight individual objects. Should be caught by the top level handler and not
|
||||
// crash the host app.
|
||||
throw;
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-10
@@ -79,18 +79,14 @@ public sealed class AutocadReceiveBinding : IReceiveBinding
|
||||
.ServiceProvider.GetRequiredService<ReceiveOperation>()
|
||||
.Execute(
|
||||
modelCard.GetReceiveInfo(_speckleApplication.Slug),
|
||||
cancellationToken,
|
||||
(status, progress) =>
|
||||
_operationProgressManager.SetModelProgress(
|
||||
Parent,
|
||||
modelCardId,
|
||||
new ModelCardProgress(modelCardId, status, progress),
|
||||
cancellationToken
|
||||
)
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Commands.SetModelReceiveResult(modelCardId, operationResults.BakedObjectIds, operationResults.ConversionResults);
|
||||
await Commands
|
||||
.SetModelReceiveResult(modelCardId, operationResults.BakedObjectIds, operationResults.ConversionResults)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -102,7 +98,7 @@ public sealed class AutocadReceiveBinding : IReceiveBinding
|
||||
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);
|
||||
Commands.SetModelError(modelCardId, ex);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
+5
-3
@@ -41,7 +41,9 @@ public class AutocadSelectionBinding : ISelectionBinding
|
||||
if (!_visitedDocuments.Contains(document))
|
||||
{
|
||||
document.ImpliedSelectionChanged += (_, _) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => Parent.RunOnMainThread(OnSelectionChanged));
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await Parent.RunOnMainThreadAsync(OnSelectionChanged).ConfigureAwait(false)
|
||||
);
|
||||
|
||||
_visitedDocuments.Add(document);
|
||||
}
|
||||
@@ -52,10 +54,10 @@ public class AutocadSelectionBinding : ISelectionBinding
|
||||
// Ui requests to GetSelection() should just return this local copy that is kept up to date by the event handler.
|
||||
private SelectionInfo _selectionInfo;
|
||||
|
||||
private void OnSelectionChanged()
|
||||
private async Task OnSelectionChanged()
|
||||
{
|
||||
_selectionInfo = GetSelectionInternal();
|
||||
Parent.Send(SELECTION_EVENT, _selectionInfo);
|
||||
await Parent.Send(SELECTION_EVENT, _selectionInfo).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public SelectionInfo GetSelection() => _selectionInfo;
|
||||
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Autocad.HostApp.Extensions;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
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.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Bindings;
|
||||
|
||||
public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
{
|
||||
public string Name => "sendBinding";
|
||||
public SendBindingUICommands Commands { get; }
|
||||
private OperationProgressManager OperationProgressManager { get; }
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly IAutocadIdleManager _idleManager;
|
||||
private readonly List<ISendFilter> _sendFilters;
|
||||
private readonly CancellationManager _cancellationManager;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly IOperationProgressManager _operationProgressManager;
|
||||
private readonly ILogger<AutocadSendBinding> _logger;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
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:
|
||||
/// [CNX-202: Unhandled Exception Occurred when receiving in Rhino](https://linear.app/speckle/issue/CNX-202/unhandled-exception-occurred-when-receiving-in-rhino)
|
||||
/// As to why a concurrent dictionary, it's because it's the cheapest/easiest way to do so.
|
||||
/// https://stackoverflow.com/questions/18922985/concurrent-hashsett-in-net-framework
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<string, byte> ChangedObjectIds { get; set; } = new();
|
||||
|
||||
protected AutocadSendBaseBinding(
|
||||
DocumentModelStore store,
|
||||
IAutocadIdleManager idleManager,
|
||||
IBrowserBridge parent,
|
||||
IEnumerable<ISendFilter> sendFilters,
|
||||
CancellationManager cancellationManager,
|
||||
IServiceProvider serviceProvider,
|
||||
ISendConversionCache sendConversionCache,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<AutocadSendBinding> logger,
|
||||
ISpeckleApplication speckleApplication
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
_idleManager = idleManager;
|
||||
_serviceProvider = serviceProvider;
|
||||
_cancellationManager = cancellationManager;
|
||||
_sendFilters = sendFilters.ToList();
|
||||
_sendConversionCache = sendConversionCache;
|
||||
_operationProgressManager = operationProgressManager;
|
||||
_logger = logger;
|
||||
_speckleApplication = speckleApplication;
|
||||
_topLevelExceptionHandler = parent.TopLevelExceptionHandler;
|
||||
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);
|
||||
}
|
||||
// Since ids of the objects generates from same seed, we should clear the cache always whenever doc swapped.
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
{
|
||||
_sendConversionCache.ClearCache();
|
||||
};
|
||||
}
|
||||
|
||||
private readonly List<string> _docSubsTracker = new();
|
||||
|
||||
private void SubscribeToObjectChanges(Document doc)
|
||||
{
|
||||
if (doc == null || doc.Database == null || _docSubsTracker.Contains(doc.Name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_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);
|
||||
}
|
||||
|
||||
private void OnObjectChanged(DBObject dbObject)
|
||||
{
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => OnChangeChangedObjectIds(dbObject));
|
||||
}
|
||||
|
||||
private void OnChangeChangedObjectIds(DBObject dBObject)
|
||||
{
|
||||
ChangedObjectIds[dBObject.GetSpeckleApplicationId()] = 1;
|
||||
_idleManager.SubscribeToIdle(nameof(AutocadSendBinding), RunExpirationChecks);
|
||||
}
|
||||
|
||||
private void RunExpirationChecks()
|
||||
{
|
||||
var senders = _store.GetSenders();
|
||||
string[] objectIdsList = ChangedObjectIds.Keys.ToArray();
|
||||
List<string> expiredSenderIds = new();
|
||||
|
||||
_sendConversionCache.EvictObjects(objectIdsList);
|
||||
|
||||
foreach (SenderModelCard modelCard in senders)
|
||||
{
|
||||
var intersection = modelCard.SendFilter.NotNull().GetObjectIds().Intersect(objectIdsList).ToList();
|
||||
bool isExpired = intersection.Count != 0;
|
||||
if (isExpired)
|
||||
{
|
||||
expiredSenderIds.Add(modelCard.ModelCardId.NotNull());
|
||||
}
|
||||
}
|
||||
|
||||
Commands.SetModelsExpired(expiredSenderIds);
|
||||
ChangedObjectIds = new();
|
||||
}
|
||||
|
||||
public List<ISendFilter> GetSendFilters() => _sendFilters;
|
||||
|
||||
public List<ICardSetting> GetSendSettings() => [];
|
||||
|
||||
public async Task Send(string modelCardId) =>
|
||||
await Parent
|
||||
.RunOnMainThreadAsync(async () => await SendInternal(modelCardId).ConfigureAwait(false))
|
||||
.ConfigureAwait(false);
|
||||
|
||||
protected abstract void InitializeSettings(IServiceProvider serviceProvider);
|
||||
|
||||
private async Task SendInternal(string modelCardId)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_store.GetModelById(modelCardId) is not SenderModelCard modelCard)
|
||||
{
|
||||
// Handle as GLOBAL ERROR at BrowserBridge
|
||||
throw new InvalidOperationException("No publish model card was found.");
|
||||
}
|
||||
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
InitializeSettings(scope.ServiceProvider);
|
||||
|
||||
CancellationToken cancellationToken = _cancellationManager.InitCancellationTokenSource(modelCardId);
|
||||
|
||||
// Disable document activation (document creation and document switch)
|
||||
// Not disabling results in DUI model card being out of sync with the active document
|
||||
// The DocumentActivated event isn't usable probably because it is pushed to back of main thread queue
|
||||
Application.DocumentManager.DocumentActivationEnabled = false;
|
||||
|
||||
// Get elements to convert
|
||||
List<AutocadRootObject> autocadObjects = Application.DocumentManager.CurrentDocument.GetObjects(
|
||||
modelCard.SendFilter.NotNull().GetObjectIds()
|
||||
);
|
||||
|
||||
if (autocadObjects.Count == 0)
|
||||
{
|
||||
// Handle as CARD ERROR in this function
|
||||
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
|
||||
}
|
||||
|
||||
var sendResult = await scope
|
||||
.ServiceProvider.GetRequiredService<SendOperation<AutocadRootObject>>()
|
||||
.Execute(
|
||||
autocadObjects,
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
await Commands
|
||||
.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (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;
|
||||
}
|
||||
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);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// renable document activation
|
||||
Application.DocumentManager.DocumentActivationEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void CancelSend(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
|
||||
}
|
||||
+17
-187
@@ -1,54 +1,21 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Autocad.HostApp.Extensions;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
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.Converters.Autocad;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Bindings;
|
||||
|
||||
public sealed class AutocadSendBinding : ISendBinding
|
||||
public sealed class AutocadSendBinding : AutocadSendBaseBinding
|
||||
{
|
||||
public string Name => "sendBinding";
|
||||
public SendBindingUICommands Commands { get; }
|
||||
private OperationProgressManager OperationProgressManager { get; }
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly IAutocadIdleManager _idleManager;
|
||||
private readonly List<ISendFilter> _sendFilters;
|
||||
private readonly CancellationManager _cancellationManager;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly IOperationProgressManager _operationProgressManager;
|
||||
private readonly ILogger<AutocadSendBinding> _logger;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IAutocadConversionSettingsFactory _autocadConversionSettingsFactory;
|
||||
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:
|
||||
/// [CNX-202: Unhandled Exception Occurred when receiving in Rhino](https://linear.app/speckle/issue/CNX-202/unhandled-exception-occurred-when-receiving-in-rhino)
|
||||
/// As to why a concurrent dictionary, it's because it's the cheapest/easiest way to do so.
|
||||
/// https://stackoverflow.com/questions/18922985/concurrent-hashsett-in-net-framework
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<string, byte> ChangedObjectIds { get; set; } = new();
|
||||
|
||||
public AutocadSendBinding(
|
||||
DocumentModelStore store,
|
||||
@@ -63,163 +30,26 @@ public sealed class AutocadSendBinding : ISendBinding
|
||||
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
|
||||
ISpeckleApplication speckleApplication
|
||||
)
|
||||
: base(
|
||||
store,
|
||||
idleManager,
|
||||
parent,
|
||||
sendFilters,
|
||||
cancellationManager,
|
||||
serviceProvider,
|
||||
sendConversionCache,
|
||||
operationProgressManager,
|
||||
logger,
|
||||
speckleApplication
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
_idleManager = idleManager;
|
||||
_serviceProvider = serviceProvider;
|
||||
_cancellationManager = cancellationManager;
|
||||
_sendFilters = sendFilters.ToList();
|
||||
_sendConversionCache = sendConversionCache;
|
||||
_operationProgressManager = operationProgressManager;
|
||||
_logger = logger;
|
||||
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
|
||||
_speckleApplication = speckleApplication;
|
||||
_topLevelExceptionHandler = parent.TopLevelExceptionHandler;
|
||||
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);
|
||||
}
|
||||
// Since ids of the objects generates from same seed, we should clear the cache always whenever doc swapped.
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
{
|
||||
_sendConversionCache.ClearCache();
|
||||
};
|
||||
}
|
||||
|
||||
private readonly List<string> _docSubsTracker = new();
|
||||
|
||||
private void SubscribeToObjectChanges(Document doc)
|
||||
protected override void InitializeSettings(IServiceProvider serviceProvider)
|
||||
{
|
||||
if (doc == null || doc.Database == null || _docSubsTracker.Contains(doc.Name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_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);
|
||||
serviceProvider
|
||||
.GetRequiredService<IConverterSettingsStore<AutocadConversionSettings>>()
|
||||
.Initialize(_autocadConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument));
|
||||
}
|
||||
|
||||
private void OnObjectChanged(DBObject dbObject)
|
||||
{
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => OnChangeChangedObjectIds(dbObject));
|
||||
}
|
||||
|
||||
private void OnChangeChangedObjectIds(DBObject dBObject)
|
||||
{
|
||||
ChangedObjectIds[dBObject.GetSpeckleApplicationId()] = 1;
|
||||
_idleManager.SubscribeToIdle(nameof(AutocadSendBinding), RunExpirationChecks);
|
||||
}
|
||||
|
||||
private void RunExpirationChecks()
|
||||
{
|
||||
var senders = _store.GetSenders();
|
||||
string[] objectIdsList = ChangedObjectIds.Keys.ToArray();
|
||||
List<string> expiredSenderIds = new();
|
||||
|
||||
_sendConversionCache.EvictObjects(objectIdsList);
|
||||
|
||||
foreach (SenderModelCard modelCard in senders)
|
||||
{
|
||||
var intersection = modelCard.SendFilter.NotNull().GetObjectIds().Intersect(objectIdsList).ToList();
|
||||
bool isExpired = intersection.Count != 0;
|
||||
if (isExpired)
|
||||
{
|
||||
expiredSenderIds.Add(modelCard.ModelCardId.NotNull());
|
||||
}
|
||||
}
|
||||
|
||||
Commands.SetModelsExpired(expiredSenderIds);
|
||||
ChangedObjectIds = new();
|
||||
}
|
||||
|
||||
public List<ISendFilter> GetSendFilters() => _sendFilters;
|
||||
|
||||
public List<ICardSetting> GetSendSettings() => [];
|
||||
|
||||
public Task Send(string modelCardId)
|
||||
{
|
||||
Parent.RunOnMainThread(async () => await SendInternal(modelCardId).ConfigureAwait(false));
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task SendInternal(string modelCardId)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_store.GetModelById(modelCardId) is not SenderModelCard modelCard)
|
||||
{
|
||||
// Handle as GLOBAL ERROR at BrowserBridge
|
||||
throw new InvalidOperationException("No publish model card was found.");
|
||||
}
|
||||
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
scope
|
||||
.ServiceProvider.GetRequiredService<IConverterSettingsStore<AutocadConversionSettings>>()
|
||||
.Initialize(_autocadConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument));
|
||||
|
||||
CancellationToken cancellationToken = _cancellationManager.InitCancellationTokenSource(modelCardId);
|
||||
|
||||
// Disable document activation (document creation and document switch)
|
||||
// Not disabling results in DUI model card being out of sync with the active document
|
||||
// The DocumentActivated event isn't usable probably because it is pushed to back of main thread queue
|
||||
Application.DocumentManager.DocumentActivationEnabled = false;
|
||||
|
||||
// Get elements to convert
|
||||
List<AutocadRootObject> autocadObjects = Application.DocumentManager.CurrentDocument.GetObjects(
|
||||
modelCard.SendFilter.NotNull().GetObjectIds()
|
||||
);
|
||||
|
||||
if (autocadObjects.Count == 0)
|
||||
{
|
||||
// Handle as CARD ERROR in this function
|
||||
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
|
||||
}
|
||||
|
||||
var sendResult = await scope
|
||||
.ServiceProvider.GetRequiredService<SendOperation<AutocadRootObject>>()
|
||||
.Execute(
|
||||
autocadObjects,
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
(status, progress) =>
|
||||
_operationProgressManager.SetModelProgress(
|
||||
Parent,
|
||||
modelCardId,
|
||||
new ModelCardProgress(modelCardId, status, progress),
|
||||
cancellationToken
|
||||
),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Commands.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults);
|
||||
}
|
||||
catch (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;
|
||||
}
|
||||
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);
|
||||
Commands.SetModelError(modelCardId, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// renable document activation
|
||||
Application.DocumentManager.DocumentActivationEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void CancelSend(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
|
||||
}
|
||||
|
||||
+14
-1
@@ -1,5 +1,11 @@
|
||||
#if AUTOCAD
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.Autocad.Bindings;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.DependencyInjection;
|
||||
|
||||
@@ -9,9 +15,16 @@ public static class AutocadConnectorModule
|
||||
{
|
||||
serviceCollection.AddAutocadBase();
|
||||
|
||||
// Operations
|
||||
// Send
|
||||
serviceCollection.LoadSend();
|
||||
serviceCollection.AddScoped<IRootObjectBuilder<AutocadRootObject>, AutocadRootObjectBuilder>();
|
||||
|
||||
// Receive
|
||||
serviceCollection.LoadReceive();
|
||||
|
||||
// Register vertical specific bindings
|
||||
serviceCollection.AddSingleton<IBinding, AutocadSendBinding>();
|
||||
serviceCollection.AddMatchingInterfacesAsTransient(Assembly.GetExecutingAssembly());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
+5
@@ -1,5 +1,7 @@
|
||||
#if CIVIL3D
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.DependencyInjection;
|
||||
|
||||
@@ -8,7 +10,10 @@ public static class Civil3dConnectorModule
|
||||
public static void AddCivil3d(this IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddAutocadBase();
|
||||
|
||||
// send
|
||||
serviceCollection.LoadSend();
|
||||
serviceCollection.AddScoped<IRootObjectBuilder<AutocadRootObject>, Civil3dRootObjectBuilder>();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
+2
-7
@@ -12,6 +12,7 @@ using Speckle.Connectors.Common.Instances;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
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;
|
||||
@@ -49,7 +50,7 @@ public static class SharedRegistration
|
||||
serviceCollection.AddScoped<AutocadMaterialUnpacker>();
|
||||
serviceCollection.AddScoped<AutocadMaterialBaker>();
|
||||
|
||||
serviceCollection.AddSingleton<IAutocadIdleManager, AutocadIdleManager>();
|
||||
serviceCollection.AddSingleton<IAppIdleManager, AutocadIdleManager>();
|
||||
|
||||
// operation progress manager
|
||||
serviceCollection.AddSingleton<IOperationProgressManager, OperationProgressManager>();
|
||||
@@ -70,12 +71,6 @@ public static class SharedRegistration
|
||||
// Operations
|
||||
serviceCollection.AddScoped<SendOperation<AutocadRootObject>>();
|
||||
|
||||
// Object Builders
|
||||
serviceCollection.AddScoped<IRootObjectBuilder<AutocadRootObject>, AutocadRootObjectBuilder>();
|
||||
|
||||
// Register bindings
|
||||
serviceCollection.AddSingleton<IBinding, AutocadSendBinding>();
|
||||
|
||||
// register send filters
|
||||
serviceCollection.AddTransient<ISendFilter, AutocadSelectionFilter>();
|
||||
|
||||
|
||||
+5
-2
@@ -4,7 +4,10 @@ namespace Speckle.Connectors.Autocad.Filters;
|
||||
|
||||
public class AutocadSelectionFilter : DirectSelectionSendFilter
|
||||
{
|
||||
public override List<string> GetObjectIds() => SelectedObjectIds;
|
||||
public AutocadSelectionFilter()
|
||||
{
|
||||
IsDefault = true;
|
||||
}
|
||||
|
||||
public override bool CheckExpiry(string[] changedObjectIds) => SelectedObjectIds.Intersect(changedObjectIds).Any();
|
||||
public override List<string> GetObjectIds() => SelectedObjectIds;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Autodesk.AutoCAD.Colors;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Models.Proxies;
|
||||
using AutocadColor = Autodesk.AutoCAD.Colors.Color;
|
||||
@@ -28,14 +29,17 @@ public class AutocadColorBaker
|
||||
/// </summary>
|
||||
/// <param name="colorProxies"></param>
|
||||
/// <param name="onOperationProgressed"></param>
|
||||
public void ParseColors(List<ColorProxy> colorProxies, Action<string, double?>? onOperationProgressed)
|
||||
public async Task ParseColors(
|
||||
IReadOnlyCollection<ColorProxy> colorProxies,
|
||||
IProgress<CardProgress> onOperationProgressed
|
||||
)
|
||||
{
|
||||
var count = 0;
|
||||
foreach (ColorProxy colorProxy in colorProxies)
|
||||
{
|
||||
try
|
||||
{
|
||||
onOperationProgressed?.Invoke("Converting colors", (double)++count / colorProxies.Count);
|
||||
onOperationProgressed.Report(new("Converting colors", (double)++count / colorProxies.Count));
|
||||
|
||||
// skip any colors with source = layer, since object color default source is by layer
|
||||
if (colorProxy["source"] is string source && source == "layer")
|
||||
@@ -60,6 +64,8 @@ public class AutocadColorBaker
|
||||
{
|
||||
_logger.LogError(ex, "Failed parsing color proxy");
|
||||
}
|
||||
|
||||
await Task.Yield();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,23 +3,20 @@ using Speckle.InterfaceGenerator;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.HostApp;
|
||||
|
||||
public partial interface IAutocadIdleManager : IAppIdleManager;
|
||||
|
||||
[GenerateAutoInterface]
|
||||
public class AutocadIdleManager(IIdleCallManager idleCallManager) : IAutocadIdleManager
|
||||
public sealed class AutocadIdleManager(IIdleCallManager idleCallManager)
|
||||
: AppIdleManager(idleCallManager),
|
||||
IAutocadIdleManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Subscribe deferred action to AutocadIdle event to run it whenever Autocad become idle.
|
||||
/// </summary>
|
||||
/// <param name="action"> Action to call whenever Autocad become Idle.</param>
|
||||
public void SubscribeToIdle(string id, Action action) =>
|
||||
idleCallManager.SubscribeToIdle(
|
||||
id,
|
||||
action,
|
||||
() =>
|
||||
{
|
||||
Application.Idle += AutocadAppOnIdle;
|
||||
}
|
||||
);
|
||||
private readonly IIdleCallManager _idleCallManager = idleCallManager;
|
||||
|
||||
protected override void AddEvent()
|
||||
{
|
||||
Application.Idle += AutocadAppOnIdle;
|
||||
}
|
||||
|
||||
private void AutocadAppOnIdle(object? sender, EventArgs e) =>
|
||||
idleCallManager.AppOnIdle(() => Application.Idle -= AutocadAppOnIdle);
|
||||
_idleCallManager.AppOnIdle(() => Application.Idle -= AutocadAppOnIdle);
|
||||
}
|
||||
|
||||
+10
-4
@@ -1,14 +1,17 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Autodesk.AutoCAD.Geometry;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp.Extensions;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Instances;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Converters.Autocad;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.DoubleNumerics;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
using Speckle.Sdk.Common.Exceptions;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
using Speckle.Sdk.Models.Instances;
|
||||
@@ -45,11 +48,12 @@ public class AutocadInstanceBaker : IInstanceBaker<List<Entity>>
|
||||
_converterSettings = converterSettings;
|
||||
}
|
||||
|
||||
public BakeResult BakeInstances(
|
||||
List<(Collection[] collectionPath, IInstanceComponent obj)> instanceComponents,
|
||||
[SuppressMessage("Maintainability", "CA1506:Avoid excessive class coupling")]
|
||||
public async Task<BakeResult> BakeInstances(
|
||||
IReadOnlyCollection<(Collection[] collectionPath, IInstanceComponent obj)> instanceComponents,
|
||||
Dictionary<string, List<Entity>> applicationIdMap,
|
||||
string baseLayerName,
|
||||
Action<string, double?>? onOperationProgressed
|
||||
IProgress<CardProgress> onOperationProgressed
|
||||
)
|
||||
{
|
||||
var sortedInstanceComponents = instanceComponents
|
||||
@@ -69,7 +73,8 @@ public class AutocadInstanceBaker : IInstanceBaker<List<Entity>>
|
||||
{
|
||||
try
|
||||
{
|
||||
onOperationProgressed?.Invoke("Converting blocks", (double)++count / sortedInstanceComponents.Count);
|
||||
onOperationProgressed.Report(new("Converting blocks", (double)++count / sortedInstanceComponents.Count));
|
||||
|
||||
if (instanceOrDefinition is InstanceDefinitionProxy { applicationId: not null } definitionProxy)
|
||||
{
|
||||
// TODO: create definition (block table record)
|
||||
@@ -162,6 +167,7 @@ public class AutocadInstanceBaker : IInstanceBaker<List<Entity>>
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
await Task.Yield();
|
||||
return new(createdObjectIds, consumedObjectIds, conversionResults);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Speckle.Connectors.Autocad.HostApp.Extensions;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.HostApp;
|
||||
@@ -19,14 +19,12 @@ public class AutocadLayerUnpacker
|
||||
}
|
||||
if (tr.GetObject(entity.LayerId, OpenMode.ForRead) is LayerTableRecord autocadLayer)
|
||||
{
|
||||
// Layers and geometries can have same application ids.....
|
||||
// We should prevent it for sketchup converter. Because when it happens "objects_to_bake" definition
|
||||
// is changing on the way if it happens.
|
||||
speckleLayer = new Layer(layerName) { applicationId = autocadLayer.GetSpeckleApplicationId() }; // Do not use handle directly, see note in the 'GetSpeckleApplicationId' method
|
||||
_layerCollectionCache[layerName] = speckleLayer;
|
||||
layer = autocadLayer;
|
||||
return speckleLayer;
|
||||
}
|
||||
throw new SpeckleConversionException("Unexpected condition in GetOrCreateSpeckleLayer");
|
||||
|
||||
throw new SpeckleException("Unexpected condition in GetOrCreateSpeckleLayer");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Autodesk.AutoCAD.GraphicsInterface;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Objects.Other;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Models;
|
||||
@@ -90,10 +91,10 @@ public class AutocadMaterialBaker
|
||||
transaction.Commit();
|
||||
}
|
||||
|
||||
public void ParseAndBakeRenderMaterials(
|
||||
public async Task ParseAndBakeRenderMaterials(
|
||||
List<RenderMaterialProxy> materialProxies,
|
||||
string baseLayerPrefix,
|
||||
Action<string, double?>? onOperationProgressed
|
||||
IProgress<CardProgress> onOperationProgressed
|
||||
)
|
||||
{
|
||||
using var transaction = Application.DocumentManager.CurrentDocument.Database.TransactionManager.StartTransaction();
|
||||
@@ -109,7 +110,7 @@ public class AutocadMaterialBaker
|
||||
var count = 0;
|
||||
foreach (RenderMaterialProxy materialProxy in materialProxies)
|
||||
{
|
||||
onOperationProgressed?.Invoke("Converting render materials", (double)++count / materialProxies.Count);
|
||||
onOperationProgressed.Report(new("Converting render materials", (double)++count / materialProxies.Count));
|
||||
|
||||
// bake render material
|
||||
RenderMaterial renderMaterial = materialProxy.value;
|
||||
@@ -139,6 +140,7 @@ public class AutocadMaterialBaker
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
await Task.Yield();
|
||||
}
|
||||
|
||||
private (ObjectId, ReceiveConversionResult) BakeMaterial(
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ public class AutocadMaterialUnpacker
|
||||
}
|
||||
}
|
||||
|
||||
// Stage 2: make sure we collect layer colors as well
|
||||
// Stage 2: make sure we collect layer materials as well
|
||||
foreach (LayerTableRecord layer in layers)
|
||||
{
|
||||
try
|
||||
|
||||
+104
-94
@@ -52,118 +52,127 @@ public class AutocadHostObjectBuilder : IHostObjectBuilder
|
||||
_rootObjectUnpacker = rootObjectUnpacker;
|
||||
}
|
||||
|
||||
public Task<HostObjectBuilderResult> Build(
|
||||
public async Task<HostObjectBuilderResult> Build(
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
Action<string, double?>? onOperationProgressed,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken _
|
||||
) =>
|
||||
)
|
||||
{
|
||||
// NOTE: This is the only place we apply ISyncToThread across connectors. We need to sync up with main thread here
|
||||
// after GetObject and Deserialization. It is anti-pattern now. Happiness level 3/10 but works.
|
||||
_syncToThread.RunOnThread(() =>
|
||||
return await _syncToThread
|
||||
.RunOnThread(
|
||||
async () => await BuildImpl(rootObject, projectName, modelName, onOperationProgressed).ConfigureAwait(false)
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task<HostObjectBuilderResult> BuildImpl(
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
IProgress<CardProgress> onOperationProgressed
|
||||
)
|
||||
{
|
||||
// Prompt the UI conversion started. Progress bar will swoosh.
|
||||
onOperationProgressed.Report(new("Converting", null));
|
||||
|
||||
// Layer filter for received commit with project and model name
|
||||
_layerBaker.CreateLayerFilter(projectName, modelName);
|
||||
|
||||
// 0 - Clean then Rock n Roll!
|
||||
string baseLayerPrefix = _autocadContext.RemoveInvalidChars($"SPK-{projectName}-{modelName}-");
|
||||
PreReceiveDeepClean(baseLayerPrefix);
|
||||
|
||||
// 1 - Unpack objects and proxies from root commit object
|
||||
var unpackedRoot = _rootObjectUnpacker.Unpack(rootObject);
|
||||
|
||||
// 2 - Split atomic objects and instance components with their path
|
||||
var (atomicObjects, instanceComponents) = _rootObjectUnpacker.SplitAtomicObjectsAndInstances(
|
||||
unpackedRoot.ObjectsToConvert
|
||||
);
|
||||
var atomicObjectsWithPath = _layerBaker.GetAtomicObjectsWithPath(atomicObjects);
|
||||
var instanceComponentsWithPath = _layerBaker.GetInstanceComponentsWithPath(instanceComponents);
|
||||
|
||||
// POC: these are not captured by traversal, so we need to re-add them here
|
||||
if (unpackedRoot.DefinitionProxies != null && unpackedRoot.DefinitionProxies.Count > 0)
|
||||
{
|
||||
// Prompt the UI conversion started. Progress bar will swoosh.
|
||||
onOperationProgressed?.Invoke("Converting", null);
|
||||
|
||||
// Layer filter for received commit with project and model name
|
||||
_layerBaker.CreateLayerFilter(projectName, modelName);
|
||||
|
||||
// 0 - Clean then Rock n Roll!
|
||||
string baseLayerPrefix = _autocadContext.RemoveInvalidChars($"SPK-{projectName}-{modelName}-");
|
||||
PreReceiveDeepClean(baseLayerPrefix);
|
||||
|
||||
// 1 - Unpack objects and proxies from root commit object
|
||||
var unpackedRoot = _rootObjectUnpacker.Unpack(rootObject);
|
||||
|
||||
// 2 - Split atomic objects and instance components with their path
|
||||
var (atomicObjects, instanceComponents) = _rootObjectUnpacker.SplitAtomicObjectsAndInstances(
|
||||
unpackedRoot.ObjectsToConvert
|
||||
var transformed = unpackedRoot.DefinitionProxies.Select(proxy =>
|
||||
(Array.Empty<Collection>(), proxy as IInstanceComponent)
|
||||
);
|
||||
var atomicObjectsWithPath = _layerBaker.GetAtomicObjectsWithPath(atomicObjects);
|
||||
var instanceComponentsWithPath = _layerBaker.GetInstanceComponentsWithPath(instanceComponents);
|
||||
instanceComponentsWithPath.AddRange(transformed);
|
||||
}
|
||||
|
||||
// POC: these are not captured by traversal, so we need to re-add them here
|
||||
if (unpackedRoot.DefinitionProxies != null && unpackedRoot.DefinitionProxies.Count > 0)
|
||||
// 3 - Bake materials and colors, as they are used later down the line by layers and objects
|
||||
if (unpackedRoot.RenderMaterialProxies != null)
|
||||
{
|
||||
await _materialBaker
|
||||
.ParseAndBakeRenderMaterials(unpackedRoot.RenderMaterialProxies, baseLayerPrefix, onOperationProgressed)
|
||||
.ConfigureAwait(true);
|
||||
}
|
||||
|
||||
if (unpackedRoot.ColorProxies != null)
|
||||
{
|
||||
await _colorBaker.ParseColors(unpackedRoot.ColorProxies, onOperationProgressed).ConfigureAwait(true);
|
||||
}
|
||||
|
||||
// 5 - Convert atomic objects
|
||||
List<ReceiveConversionResult> results = new();
|
||||
List<string> bakedObjectIds = new();
|
||||
Dictionary<string, List<Entity>> applicationIdMap = new();
|
||||
var count = 0;
|
||||
foreach (var (layerPath, atomicObject) in atomicObjectsWithPath)
|
||||
{
|
||||
string objectId = atomicObject.applicationId ?? atomicObject.id;
|
||||
onOperationProgressed.Report(new("Converting objects", (double)++count / atomicObjects.Count));
|
||||
try
|
||||
{
|
||||
var transformed = unpackedRoot.DefinitionProxies.Select(proxy =>
|
||||
(Array.Empty<Collection>(), proxy as IInstanceComponent)
|
||||
List<Entity> convertedObjects = await ConvertObject(atomicObject, layerPath, baseLayerPrefix)
|
||||
.ConfigureAwait(true);
|
||||
|
||||
applicationIdMap[objectId] = convertedObjects;
|
||||
|
||||
results.AddRange(
|
||||
convertedObjects.Select(e => new ReceiveConversionResult(
|
||||
Status.SUCCESS,
|
||||
atomicObject,
|
||||
e.GetSpeckleApplicationId(),
|
||||
e.GetType().ToString()
|
||||
))
|
||||
);
|
||||
instanceComponentsWithPath.AddRange(transformed);
|
||||
}
|
||||
|
||||
// 3 - Bake materials and colors, as they are used later down the line by layers and objects
|
||||
if (unpackedRoot.RenderMaterialProxies != null)
|
||||
bakedObjectIds.AddRange(convertedObjects.Select(e => e.GetSpeckleApplicationId()));
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_materialBaker.ParseAndBakeRenderMaterials(
|
||||
unpackedRoot.RenderMaterialProxies,
|
||||
baseLayerPrefix,
|
||||
onOperationProgressed
|
||||
);
|
||||
results.Add(new(Status.ERROR, atomicObject, null, null, ex));
|
||||
}
|
||||
}
|
||||
|
||||
if (unpackedRoot.ColorProxies != null)
|
||||
{
|
||||
_colorBaker.ParseColors(unpackedRoot.ColorProxies, onOperationProgressed);
|
||||
}
|
||||
// 6 - Convert instances
|
||||
var (createdInstanceIds, consumedObjectIds, instanceConversionResults) = await _instanceBaker
|
||||
.BakeInstances(instanceComponentsWithPath, applicationIdMap, baseLayerPrefix, onOperationProgressed)
|
||||
.ConfigureAwait(true);
|
||||
|
||||
// 5 - Convert atomic objects
|
||||
List<ReceiveConversionResult> results = new();
|
||||
List<string> bakedObjectIds = new();
|
||||
Dictionary<string, List<Entity>> applicationIdMap = new();
|
||||
var count = 0;
|
||||
foreach (var (layerPath, atomicObject) in atomicObjectsWithPath)
|
||||
{
|
||||
string objectId = atomicObject.applicationId ?? atomicObject.id;
|
||||
onOperationProgressed?.Invoke("Converting objects", (double)++count / atomicObjects.Count);
|
||||
try
|
||||
{
|
||||
List<Entity> convertedObjects = ConvertObject(atomicObject, layerPath, baseLayerPrefix).ToList();
|
||||
bakedObjectIds.RemoveAll(id => consumedObjectIds.Contains(id));
|
||||
bakedObjectIds.AddRange(createdInstanceIds);
|
||||
results.RemoveAll(result => result.ResultId != null && consumedObjectIds.Contains(result.ResultId));
|
||||
results.AddRange(instanceConversionResults);
|
||||
|
||||
applicationIdMap[objectId] = convertedObjects;
|
||||
|
||||
results.AddRange(
|
||||
convertedObjects.Select(e => new ReceiveConversionResult(
|
||||
Status.SUCCESS,
|
||||
atomicObject,
|
||||
e.GetSpeckleApplicationId(),
|
||||
e.GetType().ToString()
|
||||
))
|
||||
);
|
||||
|
||||
bakedObjectIds.AddRange(convertedObjects.Select(e => e.GetSpeckleApplicationId()));
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
results.Add(new(Status.ERROR, atomicObject, null, null, ex));
|
||||
}
|
||||
}
|
||||
|
||||
// 6 - Convert instances
|
||||
var (createdInstanceIds, consumedObjectIds, instanceConversionResults) = _instanceBaker.BakeInstances(
|
||||
instanceComponentsWithPath,
|
||||
applicationIdMap,
|
||||
baseLayerPrefix,
|
||||
onOperationProgressed
|
||||
// 7 - Create groups
|
||||
if (unpackedRoot.GroupProxies != null)
|
||||
{
|
||||
List<ReceiveConversionResult> groupResults = _groupBaker.CreateGroups(
|
||||
unpackedRoot.GroupProxies,
|
||||
applicationIdMap
|
||||
);
|
||||
results.AddRange(groupResults);
|
||||
}
|
||||
|
||||
bakedObjectIds.RemoveAll(id => consumedObjectIds.Contains(id));
|
||||
bakedObjectIds.AddRange(createdInstanceIds);
|
||||
results.RemoveAll(result => result.ResultId != null && consumedObjectIds.Contains(result.ResultId));
|
||||
results.AddRange(instanceConversionResults);
|
||||
|
||||
// 7 - Create groups
|
||||
if (unpackedRoot.GroupProxies != null)
|
||||
{
|
||||
List<ReceiveConversionResult> groupResults = _groupBaker.CreateGroups(
|
||||
unpackedRoot.GroupProxies,
|
||||
applicationIdMap
|
||||
);
|
||||
results.AddRange(groupResults);
|
||||
}
|
||||
|
||||
return new HostObjectBuilderResult(bakedObjectIds, results);
|
||||
});
|
||||
return new HostObjectBuilderResult(bakedObjectIds, results);
|
||||
}
|
||||
|
||||
private void PreReceiveDeepClean(string baseLayerPrefix)
|
||||
{
|
||||
@@ -172,7 +181,7 @@ public class AutocadHostObjectBuilder : IHostObjectBuilder
|
||||
_materialBaker.PurgeMaterials(baseLayerPrefix);
|
||||
}
|
||||
|
||||
private IEnumerable<Entity> ConvertObject(Base obj, Collection[] layerPath, string baseLayerNamePrefix)
|
||||
private async Task<List<Entity>> ConvertObject(Base obj, Collection[] layerPath, string baseLayerNamePrefix)
|
||||
{
|
||||
string layerName = _layerBaker.CreateLayerForReceive(layerPath, baseLayerNamePrefix);
|
||||
var convertedEntities = new List<Entity>();
|
||||
@@ -195,6 +204,7 @@ public class AutocadHostObjectBuilder : IHostObjectBuilder
|
||||
}
|
||||
|
||||
tr.Commit();
|
||||
await Task.Delay(10).ConfigureAwait(true);
|
||||
return convertedEntities;
|
||||
}
|
||||
|
||||
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Extensions;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Logging;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
using Speckle.Sdk.Models.Instances;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Operations.Send;
|
||||
|
||||
public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder<AutocadRootObject>
|
||||
{
|
||||
private readonly IRootToSpeckleConverter _converter;
|
||||
private readonly string[] _documentPathSeparator = ["\\"];
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly AutocadInstanceUnpacker _instanceUnpacker;
|
||||
private readonly AutocadMaterialUnpacker _materialUnpacker;
|
||||
private readonly AutocadColorUnpacker _colorUnpacker;
|
||||
private readonly AutocadGroupUnpacker _groupUnpacker;
|
||||
private readonly ILogger<AutocadRootObjectBuilder> _logger;
|
||||
private readonly ISdkActivityFactory _activityFactory;
|
||||
|
||||
protected AutocadRootObjectBaseBuilder(
|
||||
IRootToSpeckleConverter converter,
|
||||
ISendConversionCache sendConversionCache,
|
||||
AutocadInstanceUnpacker instanceObjectManager,
|
||||
AutocadMaterialUnpacker materialUnpacker,
|
||||
AutocadColorUnpacker colorUnpacker,
|
||||
AutocadGroupUnpacker groupUnpacker,
|
||||
ILogger<AutocadRootObjectBuilder> logger,
|
||||
ISdkActivityFactory activityFactory
|
||||
)
|
||||
{
|
||||
_converter = converter;
|
||||
_sendConversionCache = sendConversionCache;
|
||||
_instanceUnpacker = instanceObjectManager;
|
||||
_materialUnpacker = materialUnpacker;
|
||||
_colorUnpacker = colorUnpacker;
|
||||
_groupUnpacker = groupUnpacker;
|
||||
_logger = logger;
|
||||
_activityFactory = activityFactory;
|
||||
}
|
||||
|
||||
public Task<RootObjectBuilderResult> Build(
|
||||
IReadOnlyList<AutocadRootObject> objects,
|
||||
SendInfo sendInfo,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken ct = default
|
||||
) => Task.FromResult(BuildSync(objects, sendInfo, onOperationProgressed, ct));
|
||||
|
||||
[SuppressMessage(
|
||||
"Maintainability",
|
||||
"CA1506:Avoid excessive class coupling",
|
||||
Justification = """
|
||||
It is already simplified but has many different references since it is a builder. Do not know can we simplify it now.
|
||||
Later we might consider to refactor proxies from one proxy manager? but we do not know the shape of it all potential
|
||||
proxy classes yet. So I'm supressing this one now!!!
|
||||
"""
|
||||
)]
|
||||
private RootObjectBuilderResult BuildSync(
|
||||
IReadOnlyList<AutocadRootObject> objects,
|
||||
SendInfo sendInfo,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken ct = default
|
||||
)
|
||||
{
|
||||
// 0 - Init the root
|
||||
Collection root =
|
||||
new()
|
||||
{
|
||||
name = Application
|
||||
.DocumentManager.CurrentDocument.Name // POC: https://spockle.atlassian.net/browse/CNX-9319
|
||||
.Split(_documentPathSeparator, StringSplitOptions.None)
|
||||
.Reverse()
|
||||
.First()
|
||||
};
|
||||
|
||||
// TODO: better handling for document and transactions!!
|
||||
Document doc = Application.DocumentManager.CurrentDocument;
|
||||
using Transaction tr = doc.Database.TransactionManager.StartTransaction();
|
||||
|
||||
// 1 - Unpack the instances
|
||||
var (atomicObjects, instanceProxies, instanceDefinitionProxies) = _instanceUnpacker.UnpackSelection(objects);
|
||||
root[ProxyKeys.INSTANCE_DEFINITION] = instanceDefinitionProxies;
|
||||
|
||||
// 2 - Unpack the groups
|
||||
root[ProxyKeys.GROUP] = _groupUnpacker.UnpackGroups(atomicObjects);
|
||||
using (var _ = _activityFactory.Start("Converting objects"))
|
||||
{
|
||||
// 3 - Convert atomic objects
|
||||
List<LayerTableRecord> usedAcadLayers = new(); // Keeps track of autocad layers used, so we can pass them on later to the material and color unpacker.
|
||||
List<SendConversionResult> results = new();
|
||||
int count = 0;
|
||||
foreach (var (entity, applicationId) in atomicObjects)
|
||||
{
|
||||
ct.ThrowIfCancellationRequested();
|
||||
using (var convertActivity = _activityFactory.Start("Converting object"))
|
||||
{
|
||||
// Create and add a collection for this entity if not done so already.
|
||||
(Collection objectCollection, LayerTableRecord? autocadLayer) = CreateObjectCollection(entity, tr);
|
||||
|
||||
if (autocadLayer is not null)
|
||||
{
|
||||
usedAcadLayers.Add(autocadLayer);
|
||||
root.elements.Add(objectCollection);
|
||||
}
|
||||
|
||||
var result = ConvertAutocadEntity(
|
||||
entity,
|
||||
applicationId,
|
||||
objectCollection,
|
||||
instanceProxies,
|
||||
sendInfo.ProjectId
|
||||
);
|
||||
results.Add(result);
|
||||
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / atomicObjects.Count));
|
||||
}
|
||||
}
|
||||
|
||||
if (results.All(x => x.Status == Status.ERROR))
|
||||
{
|
||||
throw new SpeckleException("Failed to convert all objects."); // fail fast instead creating empty commit! It will appear as model card error with red color.
|
||||
}
|
||||
|
||||
// 4 - Unpack the render material proxies
|
||||
root[ProxyKeys.RENDER_MATERIAL] = _materialUnpacker.UnpackMaterials(atomicObjects, usedAcadLayers);
|
||||
|
||||
// 5 - Unpack the color proxies
|
||||
root[ProxyKeys.COLOR] = _colorUnpacker.UnpackColors(atomicObjects, usedAcadLayers);
|
||||
|
||||
// add any additional properties (most likely from verticals)
|
||||
AddAdditionalProxiesToRoot(root);
|
||||
|
||||
return new RootObjectBuilderResult(root, results);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual (Collection, LayerTableRecord?) CreateObjectCollection(Entity entity, Transaction tr)
|
||||
{
|
||||
return (new(), null);
|
||||
}
|
||||
|
||||
public virtual void AddAdditionalProxiesToRoot(Collection rootCollection)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
private SendConversionResult ConvertAutocadEntity(
|
||||
Entity entity,
|
||||
string applicationId,
|
||||
Collection collectionHost,
|
||||
IReadOnlyDictionary<string, InstanceProxy> instanceProxies,
|
||||
string projectId
|
||||
)
|
||||
{
|
||||
string sourceType = entity.GetType().ToString();
|
||||
try
|
||||
{
|
||||
Base converted;
|
||||
if (entity is BlockReference && instanceProxies.TryGetValue(applicationId, out InstanceProxy? instanceProxy))
|
||||
{
|
||||
converted = instanceProxy;
|
||||
}
|
||||
else if (_sendConversionCache.TryGetValue(projectId, applicationId, out ObjectReference? value))
|
||||
{
|
||||
converted = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
converted = _converter.Convert(entity);
|
||||
converted.applicationId = applicationId;
|
||||
}
|
||||
|
||||
collectionHost.elements.Add(converted);
|
||||
return new(Status.SUCCESS, applicationId, sourceType, converted);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogSendConversionError(ex, sourceType);
|
||||
return new(Status.ERROR, applicationId, sourceType, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-150
@@ -1,180 +1,46 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Extensions;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Converters.Autocad;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Logging;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
using Speckle.Sdk.Models.Instances;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Operations.Send;
|
||||
|
||||
public class AutocadRootObjectBuilder : IRootObjectBuilder<AutocadRootObject>
|
||||
public sealed class AutocadRootObjectBuilder : AutocadRootObjectBaseBuilder
|
||||
{
|
||||
private readonly IRootToSpeckleConverter _converter;
|
||||
private readonly string[] _documentPathSeparator = ["\\"];
|
||||
private readonly IConverterSettingsStore<AutocadConversionSettings> _converterSettings;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly AutocadInstanceUnpacker _instanceUnpacker;
|
||||
private readonly AutocadMaterialUnpacker _materialUnpacker;
|
||||
private readonly AutocadColorUnpacker _colorUnpacker;
|
||||
private readonly AutocadLayerUnpacker _layerUnpacker;
|
||||
private readonly AutocadGroupUnpacker _groupUnpacker;
|
||||
private readonly ILogger<AutocadRootObjectBuilder> _logger;
|
||||
private readonly ISdkActivityFactory _activityFactory;
|
||||
|
||||
public AutocadRootObjectBuilder(
|
||||
AutocadLayerUnpacker layerUnpacker,
|
||||
IRootToSpeckleConverter converter,
|
||||
ISendConversionCache sendConversionCache,
|
||||
AutocadInstanceUnpacker instanceObjectManager,
|
||||
AutocadMaterialUnpacker materialUnpacker,
|
||||
AutocadColorUnpacker colorUnpacker,
|
||||
AutocadLayerUnpacker layerUnpacker,
|
||||
AutocadGroupUnpacker groupUnpacker,
|
||||
ILogger<AutocadRootObjectBuilder> logger,
|
||||
ISdkActivityFactory activityFactory,
|
||||
IConverterSettingsStore<AutocadConversionSettings> converterSettings
|
||||
ISdkActivityFactory activityFactory
|
||||
)
|
||||
: base(
|
||||
converter,
|
||||
sendConversionCache,
|
||||
instanceObjectManager,
|
||||
materialUnpacker,
|
||||
colorUnpacker,
|
||||
groupUnpacker,
|
||||
logger,
|
||||
activityFactory
|
||||
)
|
||||
{
|
||||
_converter = converter;
|
||||
_sendConversionCache = sendConversionCache;
|
||||
_instanceUnpacker = instanceObjectManager;
|
||||
_materialUnpacker = materialUnpacker;
|
||||
_colorUnpacker = colorUnpacker;
|
||||
_layerUnpacker = layerUnpacker;
|
||||
_groupUnpacker = groupUnpacker;
|
||||
_logger = logger;
|
||||
_activityFactory = activityFactory;
|
||||
_converterSettings = converterSettings;
|
||||
}
|
||||
|
||||
public Task<RootObjectBuilderResult> Build(
|
||||
IReadOnlyList<AutocadRootObject> objects,
|
||||
SendInfo sendInfo,
|
||||
Action<string, double?>? onOperationProgressed = null,
|
||||
CancellationToken ct = default
|
||||
) => Task.FromResult(BuildSync(objects, sendInfo, onOperationProgressed, ct));
|
||||
|
||||
[SuppressMessage(
|
||||
"Maintainability",
|
||||
"CA1506:Avoid excessive class coupling",
|
||||
Justification = """
|
||||
It is already simplified but has many different references since it is a builder. Do not know can we simplify it now.
|
||||
Later we might consider to refactor proxies from one proxy manager? but we do not know the shape of it all potential
|
||||
proxy classes yet. So I'm supressing this one now!!!
|
||||
"""
|
||||
)]
|
||||
private RootObjectBuilderResult BuildSync(
|
||||
IReadOnlyList<AutocadRootObject> objects,
|
||||
SendInfo sendInfo,
|
||||
Action<string, double?>? onOperationProgressed,
|
||||
CancellationToken ct
|
||||
)
|
||||
public override (Collection, LayerTableRecord?) CreateObjectCollection(Entity entity, Transaction tr)
|
||||
{
|
||||
// 0 - Init the root
|
||||
Collection root =
|
||||
new()
|
||||
{
|
||||
name = Application
|
||||
.DocumentManager.CurrentDocument.Name // POC: https://spockle.atlassian.net/browse/CNX-9319
|
||||
.Split(_documentPathSeparator, StringSplitOptions.None)
|
||||
.Reverse()
|
||||
.First()
|
||||
};
|
||||
root["units"] = _converterSettings.Current.SpeckleUnits;
|
||||
Layer layer = _layerUnpacker.GetOrCreateSpeckleLayer(entity, tr, out LayerTableRecord? autocadLayer);
|
||||
|
||||
// TODO: better handling for document and transactions!!
|
||||
Document doc = Application.DocumentManager.CurrentDocument;
|
||||
using Transaction tr = doc.Database.TransactionManager.StartTransaction();
|
||||
|
||||
// 1 - Unpack the instances
|
||||
var (atomicObjects, instanceProxies, instanceDefinitionProxies) = _instanceUnpacker.UnpackSelection(objects);
|
||||
root[ProxyKeys.INSTANCE_DEFINITION] = instanceDefinitionProxies;
|
||||
|
||||
// 2 - Unpack the groups
|
||||
root[ProxyKeys.GROUP] = _groupUnpacker.UnpackGroups(atomicObjects);
|
||||
using (var _ = _activityFactory.Start("Converting objects"))
|
||||
{
|
||||
// 3 - Convert atomic objects
|
||||
List<LayerTableRecord> usedAcadLayers = new(); // Keeps track of autocad layers used, so we can pass them on later to the material and color unpacker.
|
||||
List<SendConversionResult> results = new();
|
||||
int count = 0;
|
||||
foreach (var (entity, applicationId) in atomicObjects)
|
||||
{
|
||||
ct.ThrowIfCancellationRequested();
|
||||
using (var convertActivity = _activityFactory.Start("Converting object"))
|
||||
{
|
||||
// Create and add a collection for each layer if not done so already.
|
||||
Layer layer = _layerUnpacker.GetOrCreateSpeckleLayer(entity, tr, out LayerTableRecord? autocadLayer);
|
||||
if (autocadLayer is not null)
|
||||
{
|
||||
usedAcadLayers.Add(autocadLayer);
|
||||
root.elements.Add(layer);
|
||||
}
|
||||
|
||||
var result = ConvertAutocadEntity(entity, applicationId, layer, instanceProxies, sendInfo.ProjectId);
|
||||
results.Add(result);
|
||||
|
||||
onOperationProgressed?.Invoke("Converting", (double)++count / atomicObjects.Count);
|
||||
}
|
||||
}
|
||||
|
||||
if (results.All(x => x.Status == Status.ERROR))
|
||||
{
|
||||
throw new SpeckleConversionException("Failed to convert all objects."); // fail fast instead creating empty commit! It will appear as model card error with red color.
|
||||
}
|
||||
|
||||
// 4 - Unpack the render material proxies
|
||||
root[ProxyKeys.RENDER_MATERIAL] = _materialUnpacker.UnpackMaterials(atomicObjects, usedAcadLayers);
|
||||
|
||||
// 5 - Unpack the color proxies
|
||||
root[ProxyKeys.COLOR] = _colorUnpacker.UnpackColors(atomicObjects, usedAcadLayers);
|
||||
|
||||
return new RootObjectBuilderResult(root, results);
|
||||
}
|
||||
}
|
||||
|
||||
private SendConversionResult ConvertAutocadEntity(
|
||||
Entity entity,
|
||||
string applicationId,
|
||||
Collection collectionHost,
|
||||
IReadOnlyDictionary<string, InstanceProxy> instanceProxies,
|
||||
string projectId
|
||||
)
|
||||
{
|
||||
string sourceType = entity.GetType().ToString();
|
||||
try
|
||||
{
|
||||
Base converted;
|
||||
if (entity is BlockReference && instanceProxies.TryGetValue(applicationId, out InstanceProxy? instanceProxy))
|
||||
{
|
||||
converted = instanceProxy;
|
||||
}
|
||||
else if (_sendConversionCache.TryGetValue(projectId, applicationId, out ObjectReference? value))
|
||||
{
|
||||
converted = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
converted = _converter.Convert(entity);
|
||||
converted.applicationId = applicationId;
|
||||
}
|
||||
|
||||
collectionHost.elements.Add(converted);
|
||||
return new(Status.SUCCESS, applicationId, sourceType, converted);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogSendConversionError(ex, sourceType);
|
||||
return new(Status.ERROR, applicationId, sourceType, null, ex);
|
||||
}
|
||||
return (layer, autocadLayer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,21 +10,19 @@ public static class AppUtils
|
||||
#elif AUTOCAD
|
||||
HostApplications.AutoCAD;
|
||||
#else
|
||||
throw new NotImplementedException();
|
||||
throw new NotSupportedException();
|
||||
#endif
|
||||
|
||||
public static HostAppVersion Version =>
|
||||
#if CIVIL3D2024
|
||||
HostAppVersion.v2024;
|
||||
#elif AUTOCAD2025
|
||||
#if AUTOCAD2025 || CIVIL3D2025
|
||||
HostAppVersion.v2025;
|
||||
#elif AUTOCAD2024
|
||||
#elif AUTOCAD2024 || CIVIL3D2024
|
||||
HostAppVersion.v2024;
|
||||
#elif AUTOCAD2023
|
||||
#elif AUTOCAD2023|| CIVIL3D2023
|
||||
HostAppVersion.v2023;
|
||||
#elif AUTOCAD2022
|
||||
#elif AUTOCAD2022 || CIVIL3D2022
|
||||
HostAppVersion.v2022;
|
||||
#else
|
||||
throw new NotImplementedException();
|
||||
throw new NotSupportedException();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2,14 +2,15 @@ using System.Drawing;
|
||||
using Autodesk.AutoCAD.Runtime;
|
||||
using Autodesk.AutoCAD.Windows;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.Autocad.DependencyInjection;
|
||||
using Speckle.Connectors.Common;
|
||||
using Speckle.Connectors.DUI;
|
||||
using Speckle.Connectors.DUI.WebView;
|
||||
#if AUTOCAD
|
||||
using Speckle.Connectors.Autocad.DependencyInjection;
|
||||
using Speckle.Converters.Autocad;
|
||||
#elif CIVIL3D
|
||||
using Speckle.Converters.Civil3d;
|
||||
using Speckle.Converters.Civil3dShared;
|
||||
using Speckle.Connectors.Civil3dShared.DependencyInjection;
|
||||
#endif
|
||||
namespace Speckle.Connectors.Autocad.Plugin;
|
||||
|
||||
@@ -30,7 +31,7 @@ public class AutocadCommand
|
||||
return;
|
||||
}
|
||||
|
||||
PaletteSet = new PaletteSet("Speckle (Beta) for Autocad", s_id)
|
||||
PaletteSet = new PaletteSet($"Speckle (Beta) for {AppUtils.App.Name}", s_id)
|
||||
{
|
||||
Size = new Size(400, 500),
|
||||
DockEnabled = (DockSides)((int)DockSides.Left + (int)DockSides.Right)
|
||||
@@ -51,7 +52,7 @@ public class AutocadCommand
|
||||
|
||||
var panelWebView = Container.GetRequiredService<DUI3ControlWebView>();
|
||||
|
||||
PaletteSet.AddVisual("Speckle (Beta) for Autocad WebView", panelWebView);
|
||||
PaletteSet.AddVisual($"Speckle (Beta) for {AppUtils.App.Name} WebView", panelWebView);
|
||||
|
||||
FocusPalette();
|
||||
}
|
||||
|
||||
+2
-1
@@ -13,9 +13,9 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\AutocadReceiveBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\AutocadSendBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\AutocadBasicConnectorBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\AutocadSendBaseBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)DependencyInjection\SharedRegistration.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)DependencyInjection\AutocadConnectorModule.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)DependencyInjection\Civil3dConnectorModule.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Filters\AutocadSelectionFilter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadColorBaker.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\AutocadColorUnpacker.cs" />
|
||||
@@ -39,6 +39,7 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\TransactionContext.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Receive\AutocadHostObjectBuilder.cs" />
|
||||
<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\AutocadRibbon.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\AutocadExtensionApplication.cs" />
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseWpf>true</UseWpf>
|
||||
<Civil3DVersion>2022</Civil3DVersion>
|
||||
<DefineConstants>$(DefineConstants);CIVIL3D;CIVIL3D2022;CIVIL3D2022_OR_GREATER</DefineConstants>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
<StartAction>Program</StartAction>
|
||||
<StartProgram>$(ProgramW6432)\Autodesk\AutoCAD $(Civil3DVersion)\acad.exe</StartProgram>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" />
|
||||
<PackageReference Include="Speckle.Civil3D.API" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Converters\Civil3d\Speckle.Converters.Civil3d2022\Speckle.Converters.Civil3d2022.csproj" />
|
||||
<ProjectReference Include="..\..\..\DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj" />
|
||||
<ProjectReference Include="..\..\..\Sdk\Speckle.Converters.Common\Speckle.Converters.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\..\Autocad\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.projitems" Label="Shared" />
|
||||
<Import Project="..\..\Autocad\Speckle.Connectors.Civil3dShared\Speckle.Connectors.Civil3dShared.projitems" Label="Shared" />
|
||||
</Project>
|
||||
@@ -0,0 +1,389 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
".NETFramework,Version=v4.8": {
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.0.3, )",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net48": "1.0.3"
|
||||
}
|
||||
},
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Build.Tasks.Git": "8.0.0",
|
||||
"Microsoft.SourceLink.Common": "8.0.0"
|
||||
}
|
||||
},
|
||||
"PolySharp": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.14.1, )",
|
||||
"resolved": "1.14.1",
|
||||
"contentHash": "mOOmFYwad3MIOL14VCjj02LljyF1GNw1wP0YVlxtcPvqdxjGGMNdNJJxHptlry3MOd8b40Flm8RPOM8JOlN2sQ=="
|
||||
},
|
||||
"Speckle.AutoCAD.API": {
|
||||
"type": "Direct",
|
||||
"requested": "[2022.0.2, )",
|
||||
"resolved": "2022.0.2",
|
||||
"contentHash": "NFHXnlkBjzM8Bau52d6eF6m0+etHddGx7qlWN8YyrfTtGyz+AmPvF8fgxcLgyjAcB3W4Wim11JeYuEoTNH1X0w=="
|
||||
},
|
||||
"Speckle.Civil3D.API": {
|
||||
"type": "Direct",
|
||||
"requested": "[2022.0.2, )",
|
||||
"resolved": "2022.0.2",
|
||||
"contentHash": "H36v9rA2Ynh4gDCzpBeUcWs4BQwWi3MwgTAnClM22vNbQXZlxjK85iO8i/mJsX57hh8VfqLB8EA7CUw94gBddw==",
|
||||
"dependencies": {
|
||||
"Speckle.AutoCAD.API": "2022.0.2"
|
||||
}
|
||||
},
|
||||
"Speckle.InterfaceGenerator": {
|
||||
"type": "Direct",
|
||||
"requested": "[0.9.6, )",
|
||||
"resolved": "0.9.6",
|
||||
"contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w=="
|
||||
},
|
||||
"GraphQL.Client": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "8yPNBbuVBpTptivyAlak4GZvbwbUcjeQTL4vN1HKHRuOykZ4r7l5fcLS6vpyPyLn0x8FsL31xbOIKyxbmR9rbA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0",
|
||||
"GraphQL.Client.Abstractions.Websocket": "6.0.0",
|
||||
"System.Net.WebSockets.Client.Managed": "1.0.22",
|
||||
"System.Reactive": "5.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "h7uzWFORHZ+CCjwr/ThAyXMr0DPpzEANDa4Uo54wqCQ+j7qUKwqYTgOrb1W40sqbvNaZm9v/X7It31SUw0maHA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Primitives": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client.Abstractions.Websocket": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "Nr9bPf8gIOvLuXpqEpqr9z9jslYFJOvd0feHth3/kPqeR3uMbjF5pjiwh4jxyMcxHdr8Pb6QiXkV3hsSyt0v7A==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
|
||||
},
|
||||
"Microsoft.CSharp": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.7.0",
|
||||
"contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "tiNmV1oPy+Z2R7Wd0bPB/FxCr8B+/5q11OpDMG751GA/YuOL7MZrBFfzv5oFRlFe08K6sjrnbrauzzGIeNrzLQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.7",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "21FRzcJhaTrlv7kTrqr/ltFcSQM2TyuTTPhUcjO8H73od7Bb3QraNW90c7lUucNI/245XPkKZG4fp7/7OsKCSg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "nOP8R1mVb/6mZtm2qgAJXn/LFm/2kMjHDAg/QJLFG6CuWYJtaD3p1BwQhufBVvRzL9ceJ/xF0SQ0qsI2GkDQAA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "65MrmXCziWaQFrI0UHkQbesrX5wTwf9XPjY5yFm/VkgJKFJ5gqvXRoXjIZcf2wLi5ZlwGz/oMYfyURVCWbM5iw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "vJ9xvOZCnUAIHcGC3SU35r3HKmHTVIeHzo6u/qzlHAqD8m6xv92MLin4oJntTvkpKxVX3vI1GFFkIQtU3AdlsQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "UpZLNLBpIZ0GTebShui7xXYh6DmBHjWM8NxGxZbdQh/bPZ5e6YswqI+bru6BnEL5eWiOdodsXtEz3FROcgi/qg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Primitives": "2.2.0",
|
||||
"System.ComponentModel.Annotations": "4.5.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "azyQtqbm4fSaDzZHD/J+V6oWMFaf2tWP4WEGIYePLCMw3+b2RQdj9ybgbQyjCshcitQKQ4lEDOZjmSlTTrHxUg==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.1",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.1"
|
||||
}
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net48": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "zMk4D+9zyiEWByyQ7oPImPN/Jhpj166Ky0Nlla4eXlNL8hI/BtSJsgR8Inldd4NNpIAH3oh8yym0W2DrhXdSLQ=="
|
||||
},
|
||||
"Microsoft.SourceLink.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Newtonsoft.Json": {
|
||||
"type": "Transitive",
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.lib.e_sqlite3": "2.1.4",
|
||||
"SQLitePCLRaw.provider.dynamic_cdecl": "2.1.4"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.3"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.lib.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
|
||||
},
|
||||
"SQLitePCLRaw.provider.dynamic_cdecl": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "ZsaKKhgYF9B1fvcnOGKl3EycNAwd9CRWX7v0rEfuPWhQQ5Jjpvf2VEHahiLIGHio3hxi3EIKFJw9KvyowWOUAw==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"System.Buffers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "AwarXzzoDwX6BgrhjoJsk6tUezZEozOT5Y9QKF94Gl4JK91I4PIIBkBco9068Y9/Dra8Dkbie99kXB8+1BaYKw=="
|
||||
},
|
||||
"System.ComponentModel.Annotations": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.0",
|
||||
"contentHash": "UxYQ3FGUOtzJ7LfSdnYSFd7+oEv6M8NgUatatIN2HxNtDdlcvFAf+VIq4Of9cDMJEJC0aSRv/x898RYhB4Yppg=="
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.3",
|
||||
"contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.4.0",
|
||||
"System.Numerics.Vectors": "4.4.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.2"
|
||||
}
|
||||
},
|
||||
"System.Net.WebSockets.Client.Managed": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.0.22",
|
||||
"contentHash": "WqEOxPlXjuZrIjUtXNE9NxEfU/n5E35iV2PtoZdJSUC4tlrqwHnTee+wvMIM4OUaJWmwrymeqcgYrE0IkGAgLA==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.4.0",
|
||||
"System.Numerics.Vectors": "4.4.0"
|
||||
}
|
||||
},
|
||||
"System.Numerics.Vectors": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
|
||||
},
|
||||
"System.Reactive": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.3",
|
||||
"contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw=="
|
||||
},
|
||||
"System.Threading.Tasks.Extensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.4",
|
||||
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.common": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Web.WebView2": "[1.0.1938.49, )",
|
||||
"Speckle.Connectors.DUI": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
"type": "Project"
|
||||
},
|
||||
"speckle.converters.civil3d2022": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Speckle.AutoCAD.API": "[2022.0.2, )",
|
||||
"Speckle.Civil3D.API": "[2022.0.2, )",
|
||||
"Speckle.Converters.Common": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.common": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "MZtBIwfDFork5vfjpJdG5g8wuJFt7d/y3LOSVVtDK/76wlbtz6cjltfKHqLx2TKVqTj5/c41t77m1+h20zqtPA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Binder": "2.2.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Options": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A=="
|
||||
},
|
||||
"Microsoft.Web.WebView2": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[1.0.1938.49, )",
|
||||
"resolved": "1.0.1938.49",
|
||||
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "VpMlOcApkQPLn90Xb5K+2nH64wN3NJ906u/YaM1oGAMw7v1SoYPbb5i03bFLuOw/Ho1KSGI0ccU82Jpi9p+n8A==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "KGbynDH2vFca7NqpVTp3KvNDE5zdX/ZuCtjdtqGG7rS8r5x2YMT6Ptk2RKJrpPNCaNL/YnuiZ425JLWua4lfqw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"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.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "LOV43Wn6IYWfK+ifz/XfcYDaL5ZFF6wLVJQGgSkaNEpGOBitCg6bQc2AuNuy5QHk85dbB1QS9XXEXjeoMxugLg=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseWpf>true</UseWpf>
|
||||
<Civil3DVersion>2023</Civil3DVersion>
|
||||
<DefineConstants>$(DefineConstants);CIVIL3D;CIVIL3D2023;CIVIL3D2022_OR_GREATER;CIVIL3D2023_OR_GREATER</DefineConstants>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
<StartAction>Program</StartAction>
|
||||
<StartProgram>$(ProgramW6432)\Autodesk\AutoCAD $(Civil3DVersion)\acad.exe</StartProgram>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2023.0.0" />
|
||||
<PackageReference Include="Speckle.Civil3D.API" VersionOverride="2023.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Converters\Civil3d\Speckle.Converters.Civil3d2023\Speckle.Converters.Civil3d2023.csproj" />
|
||||
<ProjectReference Include="..\..\..\DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj" />
|
||||
<ProjectReference Include="..\..\..\Sdk\Speckle.Converters.Common\Speckle.Converters.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\..\Autocad\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.projitems" Label="Shared" />
|
||||
<Import Project="..\..\Autocad\Speckle.Connectors.Civil3dShared\Speckle.Connectors.Civil3dShared.projitems" Label="Shared" />
|
||||
</Project>
|
||||
@@ -0,0 +1,389 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
".NETFramework,Version=v4.8": {
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.0.3, )",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net48": "1.0.3"
|
||||
}
|
||||
},
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Build.Tasks.Git": "8.0.0",
|
||||
"Microsoft.SourceLink.Common": "8.0.0"
|
||||
}
|
||||
},
|
||||
"PolySharp": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.14.1, )",
|
||||
"resolved": "1.14.1",
|
||||
"contentHash": "mOOmFYwad3MIOL14VCjj02LljyF1GNw1wP0YVlxtcPvqdxjGGMNdNJJxHptlry3MOd8b40Flm8RPOM8JOlN2sQ=="
|
||||
},
|
||||
"Speckle.AutoCAD.API": {
|
||||
"type": "Direct",
|
||||
"requested": "[2023.0.0, )",
|
||||
"resolved": "2023.0.0",
|
||||
"contentHash": "aNfiNw9zRW8pCl8AAQK7afEJuea4bJ4sFNsGVSDrdq1egaonZrwALU01dSyFNCE8tne86eVjlprpOGG6r0+G/A=="
|
||||
},
|
||||
"Speckle.Civil3D.API": {
|
||||
"type": "Direct",
|
||||
"requested": "[2023.0.0, )",
|
||||
"resolved": "2023.0.0",
|
||||
"contentHash": "URb0wfrxm4jcAApRxZ15a1dmxWDRry8WAuGmUwC7saP5+ltkJOVSOYb6WeJKYhDiJbO3UlVCesTFNnsNjMFd5A==",
|
||||
"dependencies": {
|
||||
"Speckle.AutoCAD.API": "2022.0.2"
|
||||
}
|
||||
},
|
||||
"Speckle.InterfaceGenerator": {
|
||||
"type": "Direct",
|
||||
"requested": "[0.9.6, )",
|
||||
"resolved": "0.9.6",
|
||||
"contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w=="
|
||||
},
|
||||
"GraphQL.Client": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "8yPNBbuVBpTptivyAlak4GZvbwbUcjeQTL4vN1HKHRuOykZ4r7l5fcLS6vpyPyLn0x8FsL31xbOIKyxbmR9rbA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0",
|
||||
"GraphQL.Client.Abstractions.Websocket": "6.0.0",
|
||||
"System.Net.WebSockets.Client.Managed": "1.0.22",
|
||||
"System.Reactive": "5.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "h7uzWFORHZ+CCjwr/ThAyXMr0DPpzEANDa4Uo54wqCQ+j7qUKwqYTgOrb1W40sqbvNaZm9v/X7It31SUw0maHA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Primitives": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client.Abstractions.Websocket": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "Nr9bPf8gIOvLuXpqEpqr9z9jslYFJOvd0feHth3/kPqeR3uMbjF5pjiwh4jxyMcxHdr8Pb6QiXkV3hsSyt0v7A==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
|
||||
},
|
||||
"Microsoft.CSharp": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.7.0",
|
||||
"contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "tiNmV1oPy+Z2R7Wd0bPB/FxCr8B+/5q11OpDMG751GA/YuOL7MZrBFfzv5oFRlFe08K6sjrnbrauzzGIeNrzLQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.7",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "21FRzcJhaTrlv7kTrqr/ltFcSQM2TyuTTPhUcjO8H73od7Bb3QraNW90c7lUucNI/245XPkKZG4fp7/7OsKCSg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "nOP8R1mVb/6mZtm2qgAJXn/LFm/2kMjHDAg/QJLFG6CuWYJtaD3p1BwQhufBVvRzL9ceJ/xF0SQ0qsI2GkDQAA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "65MrmXCziWaQFrI0UHkQbesrX5wTwf9XPjY5yFm/VkgJKFJ5gqvXRoXjIZcf2wLi5ZlwGz/oMYfyURVCWbM5iw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "vJ9xvOZCnUAIHcGC3SU35r3HKmHTVIeHzo6u/qzlHAqD8m6xv92MLin4oJntTvkpKxVX3vI1GFFkIQtU3AdlsQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "UpZLNLBpIZ0GTebShui7xXYh6DmBHjWM8NxGxZbdQh/bPZ5e6YswqI+bru6BnEL5eWiOdodsXtEz3FROcgi/qg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Primitives": "2.2.0",
|
||||
"System.ComponentModel.Annotations": "4.5.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "azyQtqbm4fSaDzZHD/J+V6oWMFaf2tWP4WEGIYePLCMw3+b2RQdj9ybgbQyjCshcitQKQ4lEDOZjmSlTTrHxUg==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.1",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.1"
|
||||
}
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net48": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "zMk4D+9zyiEWByyQ7oPImPN/Jhpj166Ky0Nlla4eXlNL8hI/BtSJsgR8Inldd4NNpIAH3oh8yym0W2DrhXdSLQ=="
|
||||
},
|
||||
"Microsoft.SourceLink.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Newtonsoft.Json": {
|
||||
"type": "Transitive",
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.lib.e_sqlite3": "2.1.4",
|
||||
"SQLitePCLRaw.provider.dynamic_cdecl": "2.1.4"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.3"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.lib.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
|
||||
},
|
||||
"SQLitePCLRaw.provider.dynamic_cdecl": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "ZsaKKhgYF9B1fvcnOGKl3EycNAwd9CRWX7v0rEfuPWhQQ5Jjpvf2VEHahiLIGHio3hxi3EIKFJw9KvyowWOUAw==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"System.Buffers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "AwarXzzoDwX6BgrhjoJsk6tUezZEozOT5Y9QKF94Gl4JK91I4PIIBkBco9068Y9/Dra8Dkbie99kXB8+1BaYKw=="
|
||||
},
|
||||
"System.ComponentModel.Annotations": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.0",
|
||||
"contentHash": "UxYQ3FGUOtzJ7LfSdnYSFd7+oEv6M8NgUatatIN2HxNtDdlcvFAf+VIq4Of9cDMJEJC0aSRv/x898RYhB4Yppg=="
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.3",
|
||||
"contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.4.0",
|
||||
"System.Numerics.Vectors": "4.4.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.2"
|
||||
}
|
||||
},
|
||||
"System.Net.WebSockets.Client.Managed": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.0.22",
|
||||
"contentHash": "WqEOxPlXjuZrIjUtXNE9NxEfU/n5E35iV2PtoZdJSUC4tlrqwHnTee+wvMIM4OUaJWmwrymeqcgYrE0IkGAgLA==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.4.0",
|
||||
"System.Numerics.Vectors": "4.4.0"
|
||||
}
|
||||
},
|
||||
"System.Numerics.Vectors": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
|
||||
},
|
||||
"System.Reactive": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.3",
|
||||
"contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw=="
|
||||
},
|
||||
"System.Threading.Tasks.Extensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.4",
|
||||
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.common": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Web.WebView2": "[1.0.1938.49, )",
|
||||
"Speckle.Connectors.DUI": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
"type": "Project"
|
||||
},
|
||||
"speckle.converters.civil3d2023": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Speckle.AutoCAD.API": "[2023.0.0, )",
|
||||
"Speckle.Civil3D.API": "[2023.0.0, )",
|
||||
"Speckle.Converters.Common": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.common": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "MZtBIwfDFork5vfjpJdG5g8wuJFt7d/y3LOSVVtDK/76wlbtz6cjltfKHqLx2TKVqTj5/c41t77m1+h20zqtPA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Binder": "2.2.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Options": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A=="
|
||||
},
|
||||
"Microsoft.Web.WebView2": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[1.0.1938.49, )",
|
||||
"resolved": "1.0.1938.49",
|
||||
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "VpMlOcApkQPLn90Xb5K+2nH64wN3NJ906u/YaM1oGAMw7v1SoYPbb5i03bFLuOw/Ho1KSGI0ccU82Jpi9p+n8A==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "KGbynDH2vFca7NqpVTp3KvNDE5zdX/ZuCtjdtqGG7rS8r5x2YMT6Ptk2RKJrpPNCaNL/YnuiZ425JLWua4lfqw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"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.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "LOV43Wn6IYWfK+ifz/XfcYDaL5ZFF6wLVJQGgSkaNEpGOBitCg6bQc2AuNuy5QHk85dbB1QS9XXEXjeoMxugLg=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -4,7 +4,7 @@
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseWpf>true</UseWpf>
|
||||
<Civil3DVersion>2024</Civil3DVersion>
|
||||
<DefineConstants>$(DefineConstants);CIVIL3D;CIVIL3D2024;CIVIL3D2024_OR_GREATER</DefineConstants>
|
||||
<DefineConstants>$(DefineConstants);CIVIL3D;CIVIL3D2024;CIVIL3D2022_OR_GREATER;CIVIL3D2023_OR_GREATER;CIVIL3D2024_OR_GREATER</DefineConstants>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
<StartAction>Program</StartAction>
|
||||
<StartProgram>$(ProgramW6432)\Autodesk\AutoCAD $(Civil3DVersion)\acad.exe</StartProgram>
|
||||
@@ -22,4 +22,5 @@
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\..\Autocad\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.projitems" Label="Shared" />
|
||||
<Import Project="..\..\Autocad\Speckle.Connectors.Civil3dShared\Speckle.Connectors.Civil3dShared.projitems" Label="Shared" />
|
||||
</Project>
|
||||
|
||||
@@ -80,6 +80,14 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -165,24 +173,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -283,8 +273,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -292,7 +283,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -318,7 +310,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -356,31 +348,36 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "VpMlOcApkQPLn90Xb5K+2nH64wN3NJ906u/YaM1oGAMw7v1SoYPbb5i03bFLuOw/Ho1KSGI0ccU82Jpi9p+n8A==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "KGbynDH2vFca7NqpVTp3KvNDE5zdX/ZuCtjdtqGG7rS8r5x2YMT6Ptk2RKJrpPNCaNL/YnuiZ425JLWua4lfqw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "LOV43Wn6IYWfK+ifz/XfcYDaL5ZFF6wLVJQGgSkaNEpGOBitCg6bQc2AuNuy5QHk85dbB1QS9XXEXjeoMxugLg=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseWpf>true</UseWpf>
|
||||
<Civil3DVersion>2025</Civil3DVersion>
|
||||
<DefineConstants>$(DefineConstants);CIVIL3D2025;CIVIL3D;CIVIL3D2022_OR_GREATER;CIVIL3D2023_OR_GREATER;CIVIL3D2024_OR_GREATER;CIVIL3D2025_OR_GREATER</DefineConstants>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <!-- .NET Core uses this to move native dependencies into a root for runtime selection and usage for non-windows development https://learn.microsoft.com/en-us/dotnet/core/project-sdk/msbuild-props#enablewindowstargeting -->
|
||||
<StartAction>Program</StartAction>
|
||||
<StartProgram>$(ProgramW6432)\Autodesk\AutoCAD $(Civil3DVersion)\acad.exe</StartProgram>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Speckle.AutoCAD.API" VersionOverride="2025.0.0" />
|
||||
<PackageReference Include="Speckle.Civil3d.API" VersionOverride="2025.0.0" />
|
||||
<FrameworkReference Include="Microsoft.WindowsDesktop.App" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Converters\Civil3d\Speckle.Converters.Civil3d2025\Speckle.Converters.Civil3d2025.csproj" />
|
||||
<ProjectReference Include="..\..\..\DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj" />
|
||||
<ProjectReference Include="..\..\..\Sdk\Speckle.Converters.Common\Speckle.Converters.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\Speckle.Connectors.Civil3dShared\Speckle.Connectors.Civil3dShared.projitems" Label="Shared" />
|
||||
|
||||
<Import Project="..\Speckle.Connectors.AutocadShared\Speckle.Connectors.AutocadShared.projitems" Label="Shared" />
|
||||
</Project>
|
||||
@@ -0,0 +1,364 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
"net8.0-windows7.0": {
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.0.3, )",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net461": "1.0.3"
|
||||
}
|
||||
},
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Build.Tasks.Git": "8.0.0",
|
||||
"Microsoft.SourceLink.Common": "8.0.0"
|
||||
}
|
||||
},
|
||||
"PolySharp": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.14.1, )",
|
||||
"resolved": "1.14.1",
|
||||
"contentHash": "mOOmFYwad3MIOL14VCjj02LljyF1GNw1wP0YVlxtcPvqdxjGGMNdNJJxHptlry3MOd8b40Flm8RPOM8JOlN2sQ=="
|
||||
},
|
||||
"Speckle.AutoCAD.API": {
|
||||
"type": "Direct",
|
||||
"requested": "[2025.0.0, )",
|
||||
"resolved": "2025.0.0",
|
||||
"contentHash": "dqEgZ+bTqAG0tx0WwdnTZcbNKH2igzhOr3SMXtRYai7yIqXiz5btZ4Mf2bmfxbmxLucww3GKVpdZoI+PSZlMuQ=="
|
||||
},
|
||||
"Speckle.Civil3D.API": {
|
||||
"type": "Direct",
|
||||
"requested": "[2025.0.0, )",
|
||||
"resolved": "2025.0.0",
|
||||
"contentHash": "zWxdzk7M2JE1+PgIpGrCycDUwbmTqJ+YCNMaJPbjUgVKoAiI5w7Ou9ynbFgmQkRuYrkTflbL+s799Fw62PJixQ==",
|
||||
"dependencies": {
|
||||
"Speckle.AutoCAD.API": "2025.0.0"
|
||||
}
|
||||
},
|
||||
"Speckle.InterfaceGenerator": {
|
||||
"type": "Direct",
|
||||
"requested": "[0.9.6, )",
|
||||
"resolved": "0.9.6",
|
||||
"contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w=="
|
||||
},
|
||||
"GraphQL.Client": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "8yPNBbuVBpTptivyAlak4GZvbwbUcjeQTL4vN1HKHRuOykZ4r7l5fcLS6vpyPyLn0x8FsL31xbOIKyxbmR9rbA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0",
|
||||
"GraphQL.Client.Abstractions.Websocket": "6.0.0",
|
||||
"System.Reactive": "5.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "h7uzWFORHZ+CCjwr/ThAyXMr0DPpzEANDa4Uo54wqCQ+j7qUKwqYTgOrb1W40sqbvNaZm9v/X7It31SUw0maHA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Primitives": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client.Abstractions.Websocket": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "Nr9bPf8gIOvLuXpqEpqr9z9jslYFJOvd0feHth3/kPqeR3uMbjF5pjiwh4jxyMcxHdr8Pb6QiXkV3hsSyt0v7A==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
|
||||
},
|
||||
"Microsoft.CSharp": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.7.0",
|
||||
"contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "tiNmV1oPy+Z2R7Wd0bPB/FxCr8B+/5q11OpDMG751GA/YuOL7MZrBFfzv5oFRlFe08K6sjrnbrauzzGIeNrzLQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.7",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.7",
|
||||
"contentHash": "21FRzcJhaTrlv7kTrqr/ltFcSQM2TyuTTPhUcjO8H73od7Bb3QraNW90c7lUucNI/245XPkKZG4fp7/7OsKCSg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "nOP8R1mVb/6mZtm2qgAJXn/LFm/2kMjHDAg/QJLFG6CuWYJtaD3p1BwQhufBVvRzL9ceJ/xF0SQ0qsI2GkDQAA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "65MrmXCziWaQFrI0UHkQbesrX5wTwf9XPjY5yFm/VkgJKFJ5gqvXRoXjIZcf2wLi5ZlwGz/oMYfyURVCWbM5iw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "vJ9xvOZCnUAIHcGC3SU35r3HKmHTVIeHzo6u/qzlHAqD8m6xv92MLin4oJntTvkpKxVX3vI1GFFkIQtU3AdlsQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "UpZLNLBpIZ0GTebShui7xXYh6DmBHjWM8NxGxZbdQh/bPZ5e6YswqI+bru6BnEL5eWiOdodsXtEz3FROcgi/qg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Primitives": "2.2.0",
|
||||
"System.ComponentModel.Annotations": "4.5.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "azyQtqbm4fSaDzZHD/J+V6oWMFaf2tWP4WEGIYePLCMw3+b2RQdj9ybgbQyjCshcitQKQ4lEDOZjmSlTTrHxUg==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.1",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.1"
|
||||
}
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net461": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "AmOJZwCqnOCNp6PPcf9joyogScWLtwy0M1WkqfEQ0M9nYwyDD7EX9ZjscKS5iYnyvteX7kzSKFCKt9I9dXA6mA=="
|
||||
},
|
||||
"Microsoft.SourceLink.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
},
|
||||
"Speckle.Newtonsoft.Json": {
|
||||
"type": "Transitive",
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.lib.e_sqlite3": "2.1.4",
|
||||
"SQLitePCLRaw.provider.e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.3"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.lib.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
|
||||
},
|
||||
"SQLitePCLRaw.provider.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "CSlb5dUp1FMIkez9Iv5EXzpeq7rHryVNqwJMWnpq87j9zWZexaEMdisDktMsnnrzKM6ahNrsTkjqNodTBPBxtQ==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"System.ComponentModel.Annotations": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.0",
|
||||
"contentHash": "UxYQ3FGUOtzJ7LfSdnYSFd7+oEv6M8NgUatatIN2HxNtDdlcvFAf+VIq4Of9cDMJEJC0aSRv/x898RYhB4Yppg=="
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.3",
|
||||
"contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA=="
|
||||
},
|
||||
"System.Reactive": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ=="
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.1",
|
||||
"contentHash": "Zh8t8oqolRaFa9vmOZfdQm/qKejdqz0J9kr7o2Fu0vPeoH3BL1EOXipKWwkWtLT1JPzjByrF19fGuFlNbmPpiw=="
|
||||
},
|
||||
"speckle.connectors.common": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Web.WebView2": "[1.0.1938.49, )",
|
||||
"Speckle.Connectors.DUI": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
"type": "Project"
|
||||
},
|
||||
"speckle.converters.civil3d2025": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Speckle.AutoCAD.API": "[2025.0.0, )",
|
||||
"Speckle.Civil3d.API": "[2025.0.0, )",
|
||||
"Speckle.Connectors.DUI.WebView": "[1.0.0, )",
|
||||
"Speckle.Converters.Common": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.common": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "MZtBIwfDFork5vfjpJdG5g8wuJFt7d/y3LOSVVtDK/76wlbtz6cjltfKHqLx2TKVqTj5/c41t77m1+h20zqtPA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Binder": "2.2.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Options": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A=="
|
||||
},
|
||||
"Microsoft.Web.WebView2": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[1.0.1938.49, )",
|
||||
"resolved": "1.0.1938.49",
|
||||
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "VpMlOcApkQPLn90Xb5K+2nH64wN3NJ906u/YaM1oGAMw7v1SoYPbb5i03bFLuOw/Ho1KSGI0ccU82Jpi9p+n8A==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "KGbynDH2vFca7NqpVTp3KvNDE5zdX/ZuCtjdtqGG7rS8r5x2YMT6Ptk2RKJrpPNCaNL/YnuiZ425JLWua4lfqw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"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.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "LOV43Wn6IYWfK+ifz/XfcYDaL5ZFF6wLVJQGgSkaNEpGOBitCg6bQc2AuNuy5QHk85dbB1QS9XXEXjeoMxugLg=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
"SQLitePCLRaw.lib.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
|
||||
},
|
||||
"Microsoft.Web.WebView2": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[1.0.1938.49, )",
|
||||
"resolved": "1.0.1938.49",
|
||||
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.Bindings;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Converters.Autocad;
|
||||
using Speckle.Converters.Civil3dShared;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Civil3dShared.Bindings;
|
||||
|
||||
public sealed class Civil3dSendBinding : AutocadSendBaseBinding
|
||||
{
|
||||
private readonly ICivil3dConversionSettingsFactory _civil3dConversionSettingsFactory;
|
||||
private readonly IAutocadConversionSettingsFactory _autocadConversionSettingsFactory;
|
||||
|
||||
public Civil3dSendBinding(
|
||||
DocumentModelStore store,
|
||||
IAutocadIdleManager idleManager,
|
||||
IBrowserBridge parent,
|
||||
IEnumerable<ISendFilter> sendFilters,
|
||||
CancellationManager cancellationManager,
|
||||
IServiceProvider serviceProvider,
|
||||
ISendConversionCache sendConversionCache,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<AutocadSendBinding> logger,
|
||||
ICivil3dConversionSettingsFactory civil3dConversionSettingsFactory,
|
||||
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
|
||||
ISpeckleApplication speckleApplication
|
||||
)
|
||||
: base(
|
||||
store,
|
||||
idleManager,
|
||||
parent,
|
||||
sendFilters,
|
||||
cancellationManager,
|
||||
serviceProvider,
|
||||
sendConversionCache,
|
||||
operationProgressManager,
|
||||
logger,
|
||||
speckleApplication
|
||||
)
|
||||
{
|
||||
_civil3dConversionSettingsFactory = civil3dConversionSettingsFactory;
|
||||
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
|
||||
}
|
||||
|
||||
// POC: we're registering the conversion settings for autocad here because we need the autocad conversion settings to be able to use the autocad typed converters.
|
||||
// POC: We need a separate send binding for civil3d due to using a different unit converter (needed for conversion settings construction)
|
||||
protected override void InitializeSettings(IServiceProvider serviceProvider)
|
||||
{
|
||||
serviceProvider
|
||||
.GetRequiredService<IConverterSettingsStore<Civil3dConversionSettings>>()
|
||||
.Initialize(_civil3dConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument));
|
||||
|
||||
serviceProvider
|
||||
.GetRequiredService<IConverterSettingsStore<AutocadConversionSettings>>()
|
||||
.Initialize(_autocadConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument));
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.Autocad.DependencyInjection;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
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;
|
||||
|
||||
namespace Speckle.Connectors.Civil3dShared.DependencyInjection;
|
||||
|
||||
public static class Civil3dConnectorModule
|
||||
{
|
||||
public static void AddCivil3d(this IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddAutocadBase();
|
||||
serviceCollection.LoadSend();
|
||||
|
||||
// register civil specific send classes
|
||||
serviceCollection.AddScoped<IRootObjectBuilder<AutocadRootObject>, Civil3dRootObjectBuilder>();
|
||||
serviceCollection.AddSingleton<IBinding, Civil3dSendBinding>();
|
||||
|
||||
// automatically detects the Class:IClass interface pattern to register all generated interfaces
|
||||
serviceCollection.AddMatchingInterfacesAsTransient(Assembly.GetExecutingAssembly());
|
||||
|
||||
// additional classes
|
||||
serviceCollection.AddScoped<PropertySetDefinitionHandler>();
|
||||
serviceCollection.AddScoped<CatchmentGroupHandler>();
|
||||
serviceCollection.AddScoped<PipeNetworkHandler>();
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Microsoft.Extensions.Logging;
|
||||
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;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
|
||||
namespace Speckle.Connectors.Civil3dShared.Operations.Send;
|
||||
|
||||
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,
|
||||
AutocadMaterialUnpacker materialUnpacker,
|
||||
AutocadColorUnpacker colorUnpacker,
|
||||
AutocadGroupUnpacker groupUnpacker,
|
||||
ILogger<AutocadRootObjectBuilder> logger,
|
||||
ISdkActivityFactory activityFactory
|
||||
)
|
||||
: base(
|
||||
converter,
|
||||
sendConversionCache,
|
||||
instanceObjectManager,
|
||||
materialUnpacker,
|
||||
colorUnpacker,
|
||||
groupUnpacker,
|
||||
logger,
|
||||
activityFactory
|
||||
)
|
||||
{
|
||||
_layerUnpacker = layerUnpacker;
|
||||
_propertySetDefinitionHandler = propertySetDefinitionHandler;
|
||||
_catchmentGroupHandler = catchmentGroupHandler;
|
||||
_pipeNetworkHandler = pipeNetworkHandler;
|
||||
}
|
||||
|
||||
public override (Collection, LayerTableRecord?) CreateObjectCollection(Entity entity, Transaction tr)
|
||||
{
|
||||
Layer layer = _layerUnpacker.GetOrCreateSpeckleLayer(entity, tr, out LayerTableRecord? autocadLayer);
|
||||
|
||||
return (layer, autocadLayer);
|
||||
}
|
||||
|
||||
// POC: probably will need to add Network proxies as well
|
||||
public override void AddAdditionalProxiesToRoot(Collection rootObject)
|
||||
{
|
||||
rootObject[ProxyKeys.PROPERTYSET_DEFINITIONS] = _propertySetDefinitionHandler.Definitions;
|
||||
rootObject["catchmentGroupProxies"] = _catchmentGroupHandler.CatchmentGroupProxiesCache.Values.ToList();
|
||||
rootObject["pipeNetworkProxies"] = _pipeNetworkHandler.PipeNetworkProxiesCache.Values.ToList();
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
<HasSharedItems>true</HasSharedItems>
|
||||
<SharedGUID>55E65D72-2FE8-4E61-891C-16A4D551CCF7</SharedGUID>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<Import_RootNamespace>Speckle.Connectors.Civil3dShared</Import_RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)DependencyInjection\Civil3dConnectorModule.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Civil3dRootObjectBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\Civil3dSendBinding.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="$(MSBuildThisFileDirectory)DependencyInjection\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Bindings\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Operations\Send\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{EFD01520-93E8-4CCA-8E03-9CDC635F55F4}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
|
||||
<Import Project="Speckle.Connectors.Civil3dShared.projitems" Label="Shared" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -99,6 +99,14 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -184,24 +192,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -302,8 +292,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -311,7 +302,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -322,7 +314,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2022": {
|
||||
@@ -361,11 +353,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "VpMlOcApkQPLn90Xb5K+2nH64wN3NJ906u/YaM1oGAMw7v1SoYPbb5i03bFLuOw/Ho1KSGI0ccU82Jpi9p+n8A==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -376,22 +368,27 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "KGbynDH2vFca7NqpVTp3KvNDE5zdX/ZuCtjdtqGG7rS8r5x2YMT6Ptk2RKJrpPNCaNL/YnuiZ425JLWua4lfqw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "LOV43Wn6IYWfK+ifz/XfcYDaL5ZFF6wLVJQGgSkaNEpGOBitCg6bQc2AuNuy5QHk85dbB1QS9XXEXjeoMxugLg=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
@@ -99,6 +99,14 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -184,24 +192,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -302,8 +292,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -311,7 +302,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -322,7 +314,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2023": {
|
||||
@@ -361,11 +353,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "VpMlOcApkQPLn90Xb5K+2nH64wN3NJ906u/YaM1oGAMw7v1SoYPbb5i03bFLuOw/Ho1KSGI0ccU82Jpi9p+n8A==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -376,22 +368,27 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "KGbynDH2vFca7NqpVTp3KvNDE5zdX/ZuCtjdtqGG7rS8r5x2YMT6Ptk2RKJrpPNCaNL/YnuiZ425JLWua4lfqw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "LOV43Wn6IYWfK+ifz/XfcYDaL5ZFF6wLVJQGgSkaNEpGOBitCg6bQc2AuNuy5QHk85dbB1QS9XXEXjeoMxugLg=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
@@ -99,6 +99,14 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -184,24 +192,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -302,8 +292,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -311,7 +302,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -322,7 +314,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2024": {
|
||||
@@ -361,11 +353,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "VpMlOcApkQPLn90Xb5K+2nH64wN3NJ906u/YaM1oGAMw7v1SoYPbb5i03bFLuOw/Ho1KSGI0ccU82Jpi9p+n8A==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -376,22 +368,27 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "KGbynDH2vFca7NqpVTp3KvNDE5zdX/ZuCtjdtqGG7rS8r5x2YMT6Ptk2RKJrpPNCaNL/YnuiZ425JLWua4lfqw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "LOV43Wn6IYWfK+ifz/XfcYDaL5ZFF6wLVJQGgSkaNEpGOBitCg6bQc2AuNuy5QHk85dbB1QS9XXEXjeoMxugLg=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
"profiles": {
|
||||
"ConnectorRevit2025": {
|
||||
"commandName": "Executable",
|
||||
"executablePath": "C:\\Program Files\\Autodesk\\Revit 2025\\Revit.exe"
|
||||
"executablePath": "C:\\Program Files\\Autodesk\\Revit 2025\\Revit.exe",
|
||||
"runtime": "net8.0-windows"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,11 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -177,24 +182,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -260,8 +247,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,7 +257,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -287,7 +276,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2025": {
|
||||
@@ -332,11 +321,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "VpMlOcApkQPLn90Xb5K+2nH64wN3NJ906u/YaM1oGAMw7v1SoYPbb5i03bFLuOw/Ho1KSGI0ccU82Jpi9p+n8A==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -347,22 +336,27 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "KGbynDH2vFca7NqpVTp3KvNDE5zdX/ZuCtjdtqGG7rS8r5x2YMT6Ptk2RKJrpPNCaNL/YnuiZ425JLWua4lfqw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "LOV43Wn6IYWfK+ifz/XfcYDaL5ZFF6wLVJQGgSkaNEpGOBitCg6bQc2AuNuy5QHk85dbB1QS9XXEXjeoMxugLg=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
@@ -13,8 +13,16 @@ public partial class CefSharpPanel : Page, Autodesk.Revit.UI.IDockablePaneProvid
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void ExecuteScriptAsyncMethod(string script) =>
|
||||
Browser.Dispatcher.Invoke(() => Browser.ExecuteScriptAsync(script), DispatcherPriority.Background);
|
||||
public Task ExecuteScriptAsyncMethod(string script, CancellationToken cancellationToken)
|
||||
{
|
||||
Browser.Dispatcher.Invoke(
|
||||
() => Browser.ExecuteScriptAsync(script),
|
||||
DispatcherPriority.Background,
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public bool IsBrowserInitialized => Browser.IsBrowserInitialized;
|
||||
public object BrowserElement => Browser;
|
||||
|
||||
+58
-19
@@ -4,7 +4,9 @@ using Revit.Async;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Connectors.Revit.HostApp;
|
||||
using Speckle.Connectors.RevitShared;
|
||||
using Speckle.Connectors.RevitShared.Operations.Send.Filters;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
@@ -19,12 +21,14 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
|
||||
public BasicConnectorBindingCommands Commands { get; }
|
||||
|
||||
private readonly APIContext _apiContext;
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly RevitContext _revitContext;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly ILogger<BasicConnectorBindingRevit> _logger;
|
||||
|
||||
public BasicConnectorBindingRevit(
|
||||
APIContext apiContext,
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
RevitContext revitContext,
|
||||
@@ -34,6 +38,7 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
{
|
||||
Name = "baseBinding";
|
||||
Parent = parent;
|
||||
_apiContext = apiContext;
|
||||
_store = store;
|
||||
_revitContext = revitContext;
|
||||
_speckleApplication = speckleApplication;
|
||||
@@ -42,9 +47,10 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
|
||||
// POC: event binding?
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
{
|
||||
Commands.NotifyDocumentChanged();
|
||||
};
|
||||
parent.TopLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await Commands.NotifyDocumentChanged().ConfigureAwait(false);
|
||||
});
|
||||
}
|
||||
|
||||
public string GetConnectorVersion() => _speckleApplication.SpeckleVersion;
|
||||
@@ -82,7 +88,7 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
|
||||
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
|
||||
|
||||
public void HighlightModel(string modelCardId)
|
||||
public async Task HighlightModel(string modelCardId)
|
||||
{
|
||||
var model = _store.GetModelById(modelCardId);
|
||||
|
||||
@@ -100,10 +106,30 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
|
||||
if (model is SenderModelCard senderModelCard)
|
||||
{
|
||||
elementIds = senderModelCard
|
||||
.SendFilter.NotNull()
|
||||
.GetObjectIds()
|
||||
if (senderModelCard.SendFilter is RevitViewsFilter revitViewsFilter)
|
||||
{
|
||||
revitViewsFilter.SetContext(_revitContext, _apiContext);
|
||||
await _apiContext
|
||||
.Run(() =>
|
||||
{
|
||||
var view = revitViewsFilter.GetView();
|
||||
if (view is not null)
|
||||
{
|
||||
_revitContext.UIApplication.ActiveUIDocument.ActiveView = view;
|
||||
}
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedObjects = await _apiContext
|
||||
.Run(_ => senderModelCard.SendFilter.NotNull().GetObjectIds())
|
||||
.ConfigureAwait(false);
|
||||
|
||||
elementIds = selectedObjects
|
||||
.Select(uid => ElementIdHelper.GetElementIdFromUniqueId(activeUIDoc.Document, uid))
|
||||
.Where(el => el is not null)
|
||||
.Cast<ElementId>()
|
||||
.ToList();
|
||||
}
|
||||
|
||||
@@ -112,34 +138,44 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
elementIds = receiverModelCard
|
||||
.BakedObjectIds.NotNull()
|
||||
.Select(uid => ElementIdHelper.GetElementIdFromUniqueId(activeUIDoc.Document, uid))
|
||||
.Where(el => el is not null)
|
||||
.Cast<ElementId>()
|
||||
.ToList();
|
||||
}
|
||||
|
||||
if (elementIds.Count == 0)
|
||||
{
|
||||
Commands.SetModelError(modelCardId, new InvalidOperationException("No objects found to highlight."));
|
||||
await Commands
|
||||
.SetModelError(modelCardId, new InvalidOperationException("No objects found to highlight."))
|
||||
.ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
HighlightObjectsOnView(elementIds);
|
||||
await HighlightObjectsOnView(elementIds).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Highlights the objects from the given ids.
|
||||
/// </summary>
|
||||
/// <param name="objectIds"> UniqueId's of the DB.Elements.</param>
|
||||
public void HighlightObjects(List<string> objectIds)
|
||||
public async Task HighlightObjects(IReadOnlyList<string> objectIds)
|
||||
{
|
||||
var activeUIDoc =
|
||||
_revitContext.UIApplication?.ActiveUIDocument
|
||||
?? throw new SpeckleException("Unable to retrieve active UI document");
|
||||
|
||||
HighlightObjectsOnView(
|
||||
objectIds.Select(uid => ElementIdHelper.GetElementIdFromUniqueId(activeUIDoc.Document, uid)).ToList()
|
||||
);
|
||||
await HighlightObjectsOnView(
|
||||
objectIds
|
||||
.Select(uid => ElementIdHelper.GetElementIdFromUniqueId(activeUIDoc.Document, uid))
|
||||
.Where(el => el is not null)
|
||||
.Cast<ElementId>()
|
||||
.ToList()
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
;
|
||||
}
|
||||
|
||||
private void HighlightObjectsOnView(List<ElementId> objectIds)
|
||||
private async Task HighlightObjectsOnView(List<ElementId> objectIds)
|
||||
{
|
||||
// POC: don't know if we can rely on storing the ActiveUIDocument, hence getting it each time
|
||||
var activeUIDoc =
|
||||
@@ -147,10 +183,13 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
?? throw new SpeckleException("Unable to retrieve active UI document");
|
||||
|
||||
// UiDocument operations should be wrapped into RevitTask, otherwise doesn't work on other tasks.
|
||||
RevitTask.RunAsync(() =>
|
||||
{
|
||||
activeUIDoc.Selection.SetElementIds(objectIds);
|
||||
activeUIDoc.ShowElements(objectIds);
|
||||
});
|
||||
await RevitTask
|
||||
.RunAsync(() =>
|
||||
{
|
||||
activeUIDoc.Selection.SetElementIds(objectIds);
|
||||
activeUIDoc.ShowElements(objectIds);
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
|
||||
namespace Speckle.Connectors.Revit.Bindings;
|
||||
|
||||
public class RevitEverythingFilter : EverythingSendFilter
|
||||
{
|
||||
public override List<string> GetObjectIds()
|
||||
{
|
||||
// TODO
|
||||
return new List<string>();
|
||||
}
|
||||
|
||||
public override bool CheckExpiry(string[] changedObjectIds)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class RevitSelectionFilter : DirectSelectionSendFilter
|
||||
{
|
||||
public override List<string> GetObjectIds()
|
||||
{
|
||||
return SelectedObjectIds;
|
||||
}
|
||||
|
||||
public override bool CheckExpiry(string[] changedObjectIds)
|
||||
{
|
||||
return SelectedObjectIds.Intersect(changedObjectIds).Any();
|
||||
}
|
||||
}
|
||||
@@ -81,23 +81,15 @@ internal sealed class RevitReceiveBinding : IReceiveBinding
|
||||
.ServiceProvider.GetRequiredService<ReceiveOperation>()
|
||||
.Execute(
|
||||
modelCard.GetReceiveInfo(_speckleApplication.Slug),
|
||||
cancellationToken,
|
||||
(status, progress) =>
|
||||
_operationProgressManager.SetModelProgress(
|
||||
Parent,
|
||||
modelCardId,
|
||||
new ModelCardProgress(modelCardId, status, progress),
|
||||
cancellationToken
|
||||
)
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
modelCard.BakedObjectIds = conversionResults.BakedObjectIds.ToList();
|
||||
Commands.SetModelReceiveResult(
|
||||
modelCardId,
|
||||
conversionResults.BakedObjectIds,
|
||||
conversionResults.ConversionResults
|
||||
);
|
||||
await Commands
|
||||
.SetModelReceiveResult(modelCardId, conversionResults.BakedObjectIds, conversionResults.ConversionResults)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -108,7 +100,7 @@ internal sealed class RevitReceiveBinding : IReceiveBinding
|
||||
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);
|
||||
Commands.SetModelError(modelCardId, ex);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ using Speckle.Connectors.DUI.Settings;
|
||||
using Speckle.Connectors.Revit.HostApp;
|
||||
using Speckle.Connectors.Revit.Operations.Send.Settings;
|
||||
using Speckle.Connectors.Revit.Plugin;
|
||||
using Speckle.Connectors.RevitShared.Operations.Send.Filters;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
using Speckle.Converters.RevitShared.Settings;
|
||||
@@ -27,6 +28,7 @@ namespace Speckle.Connectors.Revit.Bindings;
|
||||
internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
{
|
||||
private readonly IRevitIdleManager _idleManager;
|
||||
private readonly APIContext _apiContext;
|
||||
private readonly CancellationManager _cancellationManager;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
@@ -43,11 +45,17 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
/// As to why a concurrent dictionary, it's because it's the cheapest/easiest way to do so.
|
||||
/// https://stackoverflow.com/questions/18922985/concurrent-hashsett-in-net-framework
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<string, byte> ChangedObjectIds { get; set; } = new();
|
||||
private ConcurrentDictionary<ElementId, byte> ChangedObjectIds { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// We need it to get UniqueId whenever it is not available i.e. GetDeletedElementIds returns ElementId and cannot find its Element to get UniqueId. We store them both just before send to remember later.
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<string, string> IdMap { get; } = new();
|
||||
|
||||
public RevitSendBinding(
|
||||
IRevitIdleManager idleManager,
|
||||
RevitContext revitContext,
|
||||
APIContext apiContext,
|
||||
DocumentModelStore store,
|
||||
CancellationManager cancellationManager,
|
||||
IBrowserBridge bridge,
|
||||
@@ -63,6 +71,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
: base("sendBinding", store, bridge, revitContext)
|
||||
{
|
||||
_idleManager = idleManager;
|
||||
_apiContext = apiContext;
|
||||
_cancellationManager = cancellationManager;
|
||||
_serviceProvider = serviceProvider;
|
||||
_sendConversionCache = sendConversionCache;
|
||||
@@ -82,13 +91,12 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
revitContext.UIApplication.NotNull().Application.DocumentChanged += (_, e) =>
|
||||
topLevelExceptionHandler.CatchUnhandled(() => DocChangeHandler(e));
|
||||
});
|
||||
Store.DocumentChanged += (_, _) => topLevelExceptionHandler.CatchUnhandled(OnDocumentChanged);
|
||||
Store.DocumentChanged += (_, _) =>
|
||||
topLevelExceptionHandler.FireAndForget(async () => await OnDocumentChanged().ConfigureAwait(false));
|
||||
}
|
||||
|
||||
public List<ISendFilter> GetSendFilters()
|
||||
{
|
||||
return new List<ISendFilter> { new RevitSelectionFilter() { IsDefault = true } };
|
||||
}
|
||||
public List<ISendFilter> GetSendFilters() =>
|
||||
[new RevitSelectionFilter() { IsDefault = true }, new RevitViewsFilter(RevitContext, _apiContext)];
|
||||
|
||||
public List<ICardSetting> GetSendSettings() =>
|
||||
[
|
||||
@@ -101,7 +109,6 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
|
||||
public SendBindingUICommands Commands { get; }
|
||||
|
||||
// yes we know Send function calls many different namespace, we know. But currently I don't see any simplification area we can work on!
|
||||
#pragma warning disable CA1506
|
||||
public async Task Send(string modelCardId)
|
||||
#pragma warning restore CA1506
|
||||
@@ -122,22 +129,38 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
.ServiceProvider.GetRequiredService<IConverterSettingsStore<RevitConversionSettings>>()
|
||||
.Initialize(
|
||||
_revitConversionSettingsFactory.Create(
|
||||
_toSpeckleSettingsManager.GetDetailLevelSetting(modelCard),
|
||||
_toSpeckleSettingsManager.GetReferencePointSetting(modelCard),
|
||||
_toSpeckleSettingsManager.GetSendParameterNullOrEmptyStringsSetting(modelCard)
|
||||
await _toSpeckleSettingsManager.GetDetailLevelSetting(modelCard).ConfigureAwait(false),
|
||||
await _toSpeckleSettingsManager.GetReferencePointSetting(modelCard).ConfigureAwait(false),
|
||||
await _toSpeckleSettingsManager.GetSendParameterNullOrEmptyStringsSetting(modelCard).ConfigureAwait(false)
|
||||
)
|
||||
);
|
||||
|
||||
var activeUIDoc =
|
||||
RevitContext.UIApplication?.ActiveUIDocument
|
||||
?? throw new SpeckleException("Unable to retrieve active UI document");
|
||||
List<ElementId> revitObjects = modelCard
|
||||
.SendFilter.NotNull()
|
||||
.GetObjectIds()
|
||||
.Select(uid => activeUIDoc.Document.GetElement(uid).Id)
|
||||
|
||||
if (modelCard.SendFilter is RevitViewsFilter viewFilter)
|
||||
{
|
||||
viewFilter.SetContext(RevitContext, _apiContext);
|
||||
}
|
||||
|
||||
var selectedObjects = await _apiContext
|
||||
.Run(_ => modelCard.SendFilter.NotNull().GetObjectIds())
|
||||
.ConfigureAwait(false);
|
||||
|
||||
List<Element> elements = selectedObjects
|
||||
.Select(uid => activeUIDoc.Document.GetElement(uid))
|
||||
.Where(el => el is not null)
|
||||
.ToList();
|
||||
|
||||
if (revitObjects.Count == 0)
|
||||
foreach (Element element in elements)
|
||||
{
|
||||
IdMap[element.Id.ToString()] = element.UniqueId;
|
||||
}
|
||||
|
||||
List<ElementId> elementIds = elements.Select(el => el.Id).ToList();
|
||||
|
||||
if (elementIds.Count == 0)
|
||||
{
|
||||
// Handle as CARD ERROR in this function
|
||||
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
|
||||
@@ -146,20 +169,16 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
var sendResult = await scope
|
||||
.ServiceProvider.GetRequiredService<SendOperation<ElementId>>()
|
||||
.Execute(
|
||||
revitObjects,
|
||||
elementIds,
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
(status, progress) =>
|
||||
_operationProgressManager.SetModelProgress(
|
||||
Parent,
|
||||
modelCardId,
|
||||
new ModelCardProgress(modelCardId, status, progress),
|
||||
cancellationToken
|
||||
),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Commands.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults);
|
||||
await Commands
|
||||
.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -170,7 +189,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
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);
|
||||
Commands.SetModelError(modelCardId, ex);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +198,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
/// a filter refresh (e.g., views being added).
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
private void DocChangeHandler(Autodesk.Revit.DB.Events.DocumentChangedEventArgs e)
|
||||
private async Task DocChangeHandler(Autodesk.Revit.DB.Events.DocumentChangedEventArgs e)
|
||||
{
|
||||
ICollection<ElementId> addedElementIds = e.GetAddedElementIds();
|
||||
ICollection<ElementId> deletedElementIds = e.GetDeletedElementIds();
|
||||
@@ -187,26 +206,39 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
|
||||
foreach (ElementId elementId in addedElementIds)
|
||||
{
|
||||
ChangedObjectIds[elementId.ToString()] = 1;
|
||||
ChangedObjectIds[elementId] = 1;
|
||||
}
|
||||
|
||||
foreach (ElementId elementId in deletedElementIds)
|
||||
{
|
||||
ChangedObjectIds[elementId.ToString()] = 1;
|
||||
ChangedObjectIds[elementId] = 1;
|
||||
}
|
||||
|
||||
foreach (ElementId elementId in modifiedElementIds)
|
||||
{
|
||||
ChangedObjectIds[elementId.ToString()] = 1;
|
||||
ChangedObjectIds[elementId] = 1;
|
||||
}
|
||||
|
||||
if (HaveUnitsChanged(e.GetDocument()))
|
||||
{
|
||||
var objectIds = Store.GetSenders().SelectMany(s => s.SendFilter != null ? s.SendFilter.GetObjectIds() : []);
|
||||
var objectIds = new List<string>();
|
||||
foreach (var sender in Store.GetSenders())
|
||||
{
|
||||
if (sender.SendFilter is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var selectedObjects = await _apiContext
|
||||
.Run(_ => sender.SendFilter.NotNull().GetObjectIds())
|
||||
.ConfigureAwait(false);
|
||||
objectIds.AddRange(selectedObjects);
|
||||
}
|
||||
var unpackedObjectIds = _elementUnpacker.GetUnpackedElementIds(objectIds.ToList());
|
||||
_sendConversionCache.EvictObjects(unpackedObjectIds);
|
||||
}
|
||||
_idleManager.SubscribeToIdle(nameof(RevitSendBinding), RunExpirationChecks);
|
||||
|
||||
_idleManager.SubscribeToIdle(nameof(CheckFilterExpiration), CheckFilterExpiration);
|
||||
_idleManager.SubscribeToIdle(nameof(RunExpirationChecks), RunExpirationChecks);
|
||||
}
|
||||
|
||||
// Keeps track of doc and current units
|
||||
@@ -243,10 +275,30 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
return false;
|
||||
}
|
||||
|
||||
private void RunExpirationChecks()
|
||||
/// <summary>
|
||||
/// Notifies ui if any filters need refreshing. Currently, this only applies for view filters.
|
||||
/// </summary>
|
||||
private async Task CheckFilterExpiration()
|
||||
{
|
||||
// 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);
|
||||
// var views = viewCollector.OfClass(typeof(View)).Cast<View>().Select(v => v.Id).ToList();
|
||||
// var intersection = ChangedObjectIds.Keys.Intersect(views).ToList();
|
||||
// if (intersection.Count != 0)
|
||||
// {
|
||||
// await Commands.RefreshSendFilters().ConfigureAwait(false);
|
||||
// }
|
||||
|
||||
if (ChangedObjectIds.Keys.Any(e => RevitContext.UIApplication?.ActiveUIDocument.Document.GetElement(e) is View))
|
||||
{
|
||||
await Commands.RefreshSendFilters().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RunExpirationChecks()
|
||||
{
|
||||
var senders = Store.GetSenders();
|
||||
string[] objectIdsList = ChangedObjectIds.Keys.ToArray();
|
||||
// string[] objectIdsList = ChangedObjectIds.Keys.ToArray();
|
||||
var doc = RevitContext.UIApplication?.ActiveUIDocument.Document;
|
||||
|
||||
if (doc == null)
|
||||
@@ -254,20 +306,36 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
return;
|
||||
}
|
||||
|
||||
// Note: We're using unique ids as application ids in revit, so cache eviction must happen by those.
|
||||
var objUniqueIds = objectIdsList
|
||||
.Select(id => new ElementId(Convert.ToInt32(id)))
|
||||
.Select(doc.GetElement)
|
||||
.Where(el => el is not null)
|
||||
.Select(el => el.UniqueId)
|
||||
.ToList();
|
||||
_sendConversionCache.EvictObjects(objUniqueIds);
|
||||
var objUniqueIds = new List<string>();
|
||||
foreach (var changedElementId in ChangedObjectIds.Keys.ToArray())
|
||||
{
|
||||
if (IdMap.TryGetValue(changedElementId.ToString(), out var uniqueId))
|
||||
{
|
||||
objUniqueIds.Add(uniqueId);
|
||||
}
|
||||
else
|
||||
{
|
||||
var uniqId = doc.GetElement(changedElementId).UniqueId;
|
||||
objUniqueIds.Add(uniqId);
|
||||
IdMap[changedElementId.ToString()] = uniqId;
|
||||
}
|
||||
}
|
||||
|
||||
var unpackedObjectIds = _elementUnpacker.GetUnpackedElementIds(objUniqueIds);
|
||||
_sendConversionCache.EvictObjects(unpackedObjectIds);
|
||||
|
||||
// Note: we're doing object selection and card expiry management by old school ids
|
||||
List<string> expiredSenderIds = new();
|
||||
foreach (SenderModelCard modelCard in senders)
|
||||
{
|
||||
var intersection = modelCard.SendFilter.NotNull().GetObjectIds().Intersect(objUniqueIds).ToList();
|
||||
if (modelCard.SendFilter is RevitViewsFilter viewFilter)
|
||||
{
|
||||
viewFilter.SetContext(RevitContext, _apiContext);
|
||||
}
|
||||
var selectedObjects = await _apiContext
|
||||
.Run(_ => modelCard.SendFilter.NotNull().GetObjectIds())
|
||||
.ConfigureAwait(false);
|
||||
var intersection = selectedObjects.Intersect(objUniqueIds).ToList();
|
||||
bool isExpired = intersection.Count != 0;
|
||||
if (isExpired)
|
||||
{
|
||||
@@ -275,22 +343,27 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
}
|
||||
}
|
||||
|
||||
Commands.SetModelsExpired(expiredSenderIds);
|
||||
await Commands.SetModelsExpired(expiredSenderIds).ConfigureAwait(false);
|
||||
ChangedObjectIds = new();
|
||||
}
|
||||
|
||||
// POC: Will be re-addressed later with better UX with host apps that are friendly on async doc operations.
|
||||
// That's why don't bother for now how to get rid of from dup logic in other bindings.
|
||||
private void OnDocumentChanged()
|
||||
private async Task OnDocumentChanged()
|
||||
{
|
||||
_sendConversionCache.ClearCache();
|
||||
IdMap.Clear();
|
||||
|
||||
if (_cancellationManager.NumberOfOperations > 0)
|
||||
{
|
||||
_cancellationManager.CancelAllOperations();
|
||||
Commands.SetGlobalNotification(
|
||||
ToastNotificationType.INFO,
|
||||
"Document Switch",
|
||||
"Operations cancelled because of document swap!"
|
||||
);
|
||||
await Commands
|
||||
.SetGlobalNotification(
|
||||
ToastNotificationType.INFO,
|
||||
"Document Switch",
|
||||
"Operations cancelled because of document swap!"
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -73,6 +73,9 @@ public static class ServiceRegistration
|
||||
|
||||
// operation progress manager
|
||||
serviceCollection.AddSingleton<IOperationProgressManager, OperationProgressManager>();
|
||||
|
||||
// API context helps us to run functions on Revit UI Thread (main)
|
||||
serviceCollection.AddSingleton<APIContext>();
|
||||
}
|
||||
|
||||
public static void RegisterUiDependencies(IServiceCollection serviceCollection)
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
using Autodesk.Revit.DB;
|
||||
using Speckle.Converters.Common;
|
||||
|
||||
namespace Speckle.Connectors.RevitShared;
|
||||
|
||||
public static class ElementIdHelper
|
||||
{
|
||||
public static ElementId GetElementIdFromUniqueId(Document doc, string uniqueId)
|
||||
public static ElementId? GetElementIdFromUniqueId(Document doc, string uniqueId)
|
||||
{
|
||||
Element element = doc.GetElement(uniqueId);
|
||||
if (element == null)
|
||||
{
|
||||
throw new SpeckleConversionException($"Cannot find element with UniqueId: {uniqueId}");
|
||||
}
|
||||
|
||||
return element.Id;
|
||||
return element?.Id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
using Autodesk.Revit.UI;
|
||||
|
||||
namespace Speckle.Connectors.Revit.HostApp;
|
||||
|
||||
/// <summary>
|
||||
/// This class gives access to the Revit API context from anywhere in your codebase. This is essentially a
|
||||
/// lite version of the Revit.Async package from Kennan Chan. Most of the functionality was taken from that code.
|
||||
/// The main difference is that this class does not subscribe to the applicationIdling event from revit
|
||||
/// which the docs say will impact the performance of Revit
|
||||
/// </summary>
|
||||
public sealed class APIContext : IDisposable
|
||||
{
|
||||
private readonly SemaphoreSlim _semaphore = new(1, 1);
|
||||
private readonly UIControlledApplication _uiApplication;
|
||||
private readonly ExternalEventHandler<IExternalEventHandler, ExternalEvent> _factoryExternalEventHandler;
|
||||
#pragma warning disable CA2213
|
||||
private readonly ExternalEvent _factoryExternalEvent;
|
||||
#pragma warning restore CA2213
|
||||
|
||||
public APIContext(UIControlledApplication application)
|
||||
{
|
||||
_uiApplication = application;
|
||||
_factoryExternalEventHandler = new(ExternalEvent.Create);
|
||||
_factoryExternalEvent = ExternalEvent.Create(_factoryExternalEventHandler);
|
||||
}
|
||||
|
||||
public async Task<TResult> Run<TResult>(Func<UIControlledApplication, TResult> func)
|
||||
{
|
||||
await _semaphore.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
var handler = new ExternalEventHandler<UIControlledApplication, TResult>(func);
|
||||
using var externalEvent = await Run(_factoryExternalEventHandler, handler, _factoryExternalEvent)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return await Run(handler, _uiApplication, externalEvent).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_semaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Run(Action<UIControlledApplication> action) =>
|
||||
await Run<object>(app =>
|
||||
{
|
||||
action(app);
|
||||
return null!;
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
|
||||
public async Task Run(Action action) =>
|
||||
await Run<object>(_ =>
|
||||
{
|
||||
action();
|
||||
return null!;
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
|
||||
private async Task<TResult> Run<TParameter, TResult>(
|
||||
ExternalEventHandler<TParameter, TResult> handler,
|
||||
TParameter parameter,
|
||||
ExternalEvent externalEvent
|
||||
)
|
||||
{
|
||||
var task = handler.GetTask(parameter);
|
||||
externalEvent.Raise();
|
||||
|
||||
return await task.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_factoryExternalEvent.Dispose();
|
||||
_semaphore.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public enum HandlerStatus
|
||||
{
|
||||
NotStarted,
|
||||
Started,
|
||||
IsCompleted,
|
||||
IsFaulted,
|
||||
}
|
||||
|
||||
internal sealed class ExternalEventHandler<TParameter, TResult> : IExternalEventHandler
|
||||
{
|
||||
private TaskCompletionSource<TResult> Result { get; set; }
|
||||
|
||||
public Task<TResult> GetTask(TParameter parameter)
|
||||
{
|
||||
Parameter = parameter;
|
||||
Result = new TaskCompletionSource<TResult>();
|
||||
return Result.Task;
|
||||
}
|
||||
|
||||
private readonly Func<TParameter, TResult> _func;
|
||||
|
||||
public ExternalEventHandler(Func<TParameter, TResult> func)
|
||||
{
|
||||
this._func = func;
|
||||
}
|
||||
|
||||
public HandlerStatus Status { get; private set; } = HandlerStatus.NotStarted;
|
||||
private TParameter Parameter { get; set; }
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage(
|
||||
"Design",
|
||||
"CA1031:Do not catch general exception types",
|
||||
Justification = "This is a very generic utility method for running things in a Revit context. If the result of the Run method is awaited, then the exception caught here will be raised there."
|
||||
)]
|
||||
public void Execute(UIApplication app)
|
||||
{
|
||||
Status = HandlerStatus.Started;
|
||||
try
|
||||
{
|
||||
var r = _func(Parameter);
|
||||
Result.SetResult(r);
|
||||
Status = HandlerStatus.IsCompleted;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Status = HandlerStatus.IsFaulted;
|
||||
Result.SetException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetName() => "SpeckleRevitContextEventHandler";
|
||||
}
|
||||
@@ -93,8 +93,15 @@ public class ElementUnpacker
|
||||
private List<Element> PackCurtainWallElements(List<Element> elements)
|
||||
{
|
||||
var ids = elements.Select(el => el.Id).ToArray();
|
||||
var doc = _revitContext.UIApplication?.ActiveUIDocument.Document!;
|
||||
elements.RemoveAll(element =>
|
||||
(element is Mullion m && ids.Contains(m.Host.Id)) || (element is Panel p && ids.Contains(p.Host.Id))
|
||||
(element is Mullion m && ids.Contains(m.Host.Id))
|
||||
|| (element is Panel p && ids.Contains(p.Host.Id))
|
||||
|| (
|
||||
element is FamilyInstance { Host: not null } f
|
||||
&& doc.GetElement(f.Host.Id) is Wall { CurtainGrid: not null }
|
||||
&& ids.Contains(f.Host.Id)
|
||||
)
|
||||
);
|
||||
return elements;
|
||||
}
|
||||
|
||||
@@ -2,13 +2,11 @@ using Autodesk.Revit.DB;
|
||||
using Speckle.Connectors.Common.Operations.Receive;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.RevitShared.Settings;
|
||||
using Speckle.Sdk.Models.GraphTraversal;
|
||||
|
||||
namespace Speckle.Connectors.Revit.HostApp;
|
||||
|
||||
/// <summary>
|
||||
/// <para>On receive, this class will help structure atomic objects into nested revit groups based on the hierarchy that they're coming from. Expects to be a scoped dependency per receive operation.</para>
|
||||
/// <para>How to use: during atomic object conversion, on each succesful conversion call <see cref="AddToGroupMapping"/>. Afterward, at the end of the recieve operation, call <see cref="BakeGroups"/> to actually create the groups in the revit document.</para>
|
||||
/// Bakes all objects into a single top level group and pins it.
|
||||
/// </summary>
|
||||
public class RevitGroupBaker : TraversalContextUnpacker
|
||||
{
|
||||
@@ -21,62 +19,15 @@ public class RevitGroupBaker : TraversalContextUnpacker
|
||||
_revitUtils = revitUtils;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the object to the correct group in preparation for <see cref="BakeGroups"/> at the end of the receive operation.
|
||||
/// </summary>
|
||||
/// <param name="traversalContext"></param>
|
||||
/// <param name="revitElement"></param>
|
||||
public void AddToGroupMapping(TraversalContext traversalContext, Element revitElement)
|
||||
private readonly List<ElementId> _elementIdsForTopLevelGroup = new();
|
||||
|
||||
public void AddToTopLevelGroup(Element revitElement) => _elementIdsForTopLevelGroup.Add(revitElement.Id);
|
||||
|
||||
public void BakeGroupForTopLevel(string baseGroupName)
|
||||
{
|
||||
var collectionPath = GetCollectionPath(traversalContext);
|
||||
var currentLayerName = string.Empty;
|
||||
FakeGroup? previousGroup = null;
|
||||
var currentDepth = 0;
|
||||
|
||||
foreach (var collection in collectionPath)
|
||||
{
|
||||
currentLayerName += collection.name + "-";
|
||||
if (_groupCache.TryGetValue(currentLayerName, out var g))
|
||||
{
|
||||
previousGroup = g;
|
||||
currentDepth++;
|
||||
continue;
|
||||
}
|
||||
|
||||
var group = new FakeGroup()
|
||||
{
|
||||
// POC group names should be unique
|
||||
Name = _revitUtils.RemoveInvalidChars(currentLayerName[..^1]),
|
||||
Depth = currentDepth++,
|
||||
Parent = previousGroup!
|
||||
};
|
||||
_groupCache[currentLayerName] = group;
|
||||
previousGroup = group;
|
||||
}
|
||||
|
||||
previousGroup!.Ids.Add(revitElement.Id);
|
||||
}
|
||||
|
||||
private readonly Dictionary<string, FakeGroup> _groupCache = new();
|
||||
|
||||
/// <summary>
|
||||
/// Bakes the accumulated groups in Revit, with their objects.
|
||||
/// </summary>
|
||||
/// <param name="baseGroupName"></param>
|
||||
public void BakeGroups(string baseGroupName)
|
||||
{
|
||||
var orderedGroups = _groupCache.Values.OrderByDescending(group => group.Depth);
|
||||
Group? lastGroup = null;
|
||||
|
||||
foreach (var group in orderedGroups)
|
||||
{
|
||||
var docGroup = _converterSettings.Current.Document.Create.NewGroup(group.Ids);
|
||||
group.Parent?.Ids.Add(docGroup.Id);
|
||||
docGroup.GroupType.Name = group.Name;
|
||||
lastGroup = docGroup;
|
||||
}
|
||||
|
||||
lastGroup!.GroupType.Name = _revitUtils.RemoveInvalidChars(baseGroupName);
|
||||
var docGroup = _converterSettings.Current.Document.Create.NewGroup(_elementIdsForTopLevelGroup);
|
||||
docGroup.GroupType.Name = _revitUtils.RemoveInvalidChars(baseGroupName);
|
||||
docGroup.Pinned = true;
|
||||
}
|
||||
|
||||
public void PurgeGroups(string baseGroupName)
|
||||
@@ -86,25 +37,23 @@ public class RevitGroupBaker : TraversalContextUnpacker
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
List<ElementId> subgroupTypeIds = new List<ElementId>();
|
||||
var subgroupTypeIds = new List<ElementId>() { group.GroupType.Id };
|
||||
CollectSubGroupTypeIds(document, group, subgroupTypeIds);
|
||||
document.Delete(subgroupTypeIds);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Group> GetGroupsByName(Autodesk.Revit.DB.Document doc, string groupName)
|
||||
private List<Group> GetGroupsByName(Document doc, string groupName)
|
||||
{
|
||||
var validGroupName = _revitUtils.RemoveInvalidChars(groupName);
|
||||
|
||||
using (var collector = new FilteredElementCollector(doc))
|
||||
{
|
||||
ICollection<Element> groupElements = collector.OfClass(typeof(Group)).ToElements();
|
||||
List<Group> groups = groupElements.Cast<Group>().Where(g => g.GroupType.Name == validGroupName).ToList();
|
||||
return groups;
|
||||
}
|
||||
using var collector = new FilteredElementCollector(doc);
|
||||
ICollection<Element> groupElements = collector.OfClass(typeof(Group)).ToElements();
|
||||
List<Group> groups = groupElements.Cast<Group>().Where(g => g.GroupType.Name == validGroupName).ToList();
|
||||
return groups;
|
||||
}
|
||||
|
||||
private void CollectSubGroupTypeIds(Autodesk.Revit.DB.Document document, Group group, List<ElementId> subGroupTypeIds)
|
||||
private void CollectSubGroupTypeIds(Document document, Group group, List<ElementId> subGroupTypeIds)
|
||||
{
|
||||
ICollection<ElementId> groupMemberIds = group.GetMemberIds();
|
||||
|
||||
@@ -119,15 +68,4 @@ public class RevitGroupBaker : TraversalContextUnpacker
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Little intermediate data structure that helps with the operations above.
|
||||
/// </summary>
|
||||
private sealed class FakeGroup
|
||||
{
|
||||
public List<ElementId> Ids { get; set; } = new();
|
||||
public int Depth { get; set; }
|
||||
public string Name { get; set; }
|
||||
public FakeGroup Parent { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -11,5 +11,5 @@ public interface ITransactionManager : IDisposable
|
||||
void StartSubtransaction();
|
||||
|
||||
// POC improve how the error handling behaviour is selected
|
||||
void StartTransaction(bool enableFailurePreprocessor = false);
|
||||
void StartTransaction(bool enableFailurePreprocessor = false, string name = "Speckle Transaction");
|
||||
}
|
||||
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
using Revit.Async;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
|
||||
namespace Speckle.Connectors.Revit.Operations.Receive;
|
||||
|
||||
internal sealed class RevitContextAccessor : ISyncToThread
|
||||
{
|
||||
public Task<T> RunOnThread<T>(Func<T> func) => RevitTask.RunAsync(func);
|
||||
}
|
||||
|
||||
+141
-71
@@ -4,14 +4,22 @@ using Revit.Async;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Instances;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Operations.Receive;
|
||||
using Speckle.Connectors.Revit.HostApp;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.Common.Objects;
|
||||
using Speckle.Converters.RevitShared;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
using Speckle.Converters.RevitShared.Settings;
|
||||
using Speckle.DoubleNumerics;
|
||||
using Speckle.Objects;
|
||||
using Speckle.Objects.Geometry;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common.Exceptions;
|
||||
using Speckle.Sdk.Logging;
|
||||
using Speckle.Sdk.Models;
|
||||
using Transform = Speckle.Objects.Other.Transform;
|
||||
|
||||
namespace Speckle.Connectors.Revit.Operations.Receive;
|
||||
|
||||
@@ -22,10 +30,13 @@ internal sealed class RevitHostObjectBuilder : IHostObjectBuilder, IDisposable
|
||||
private readonly RevitToHostCacheSingleton _revitToHostCacheSingleton;
|
||||
private readonly ITransactionManager _transactionManager;
|
||||
private readonly ILocalToGlobalUnpacker _localToGlobalUnpacker;
|
||||
private readonly LocalToGlobalConverterUtils _localToGlobalConverterUtils;
|
||||
private readonly RevitGroupBaker _groupBaker;
|
||||
private readonly RevitMaterialBaker _materialBaker;
|
||||
private readonly ILogger<RevitHostObjectBuilder> _logger;
|
||||
private readonly ITypedConverter<
|
||||
(Base atomicObject, List<Matrix4x4> matrix),
|
||||
DirectShape
|
||||
> _localToGlobalDirectShapeConverter;
|
||||
|
||||
private readonly RootObjectUnpacker _rootObjectUnpacker;
|
||||
private readonly ISdkActivityFactory _activityFactory;
|
||||
@@ -36,24 +47,24 @@ internal sealed class RevitHostObjectBuilder : IHostObjectBuilder, IDisposable
|
||||
ITransactionManager transactionManager,
|
||||
ISdkActivityFactory activityFactory,
|
||||
ILocalToGlobalUnpacker localToGlobalUnpacker,
|
||||
LocalToGlobalConverterUtils localToGlobalConverterUtils,
|
||||
RevitGroupBaker groupManager,
|
||||
RevitMaterialBaker materialBaker,
|
||||
RootObjectUnpacker rootObjectUnpacker,
|
||||
ILogger<RevitHostObjectBuilder> logger,
|
||||
RevitToHostCacheSingleton revitToHostCacheSingleton
|
||||
RevitToHostCacheSingleton revitToHostCacheSingleton,
|
||||
ITypedConverter<(Base atomicObject, List<Matrix4x4> matrix), DirectShape> localToGlobalDirectShapeConverter
|
||||
)
|
||||
{
|
||||
_converter = converter;
|
||||
_converterSettings = converterSettings;
|
||||
_transactionManager = transactionManager;
|
||||
_localToGlobalUnpacker = localToGlobalUnpacker;
|
||||
_localToGlobalConverterUtils = localToGlobalConverterUtils;
|
||||
_groupBaker = groupManager;
|
||||
_materialBaker = materialBaker;
|
||||
_rootObjectUnpacker = rootObjectUnpacker;
|
||||
_logger = logger;
|
||||
_revitToHostCacheSingleton = revitToHostCacheSingleton;
|
||||
_localToGlobalDirectShapeConverter = localToGlobalDirectShapeConverter;
|
||||
_activityFactory = activityFactory;
|
||||
}
|
||||
|
||||
@@ -61,7 +72,7 @@ internal sealed class RevitHostObjectBuilder : IHostObjectBuilder, IDisposable
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
Action<string, double?>? onOperationProgressed,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
) =>
|
||||
RevitTask.RunAsync(() => BuildSync(rootObject, projectName, modelName, onOperationProgressed, cancellationToken));
|
||||
@@ -70,33 +81,29 @@ internal sealed class RevitHostObjectBuilder : IHostObjectBuilder, IDisposable
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
Action<string, double?>? onOperationProgressed,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var baseGroupName = $"Project {projectName}: Model {modelName}"; // TODO: unify this across connectors!
|
||||
|
||||
onOperationProgressed?.Invoke("Converting", null);
|
||||
onOperationProgressed.Report(new("Converting", null));
|
||||
using var activity = _activityFactory.Start("Build");
|
||||
|
||||
// 0 - Clean then Rock n Roll! 🎸
|
||||
using TransactionGroup preReceiveCleanTransaction = new(_converterSettings.Current.Document, "Pre-receive clean");
|
||||
preReceiveCleanTransaction.Start();
|
||||
_transactionManager.StartTransaction(true);
|
||||
{
|
||||
_activityFactory.Start("Pre receive clean");
|
||||
_transactionManager.StartTransaction(true, "Pre receive clean");
|
||||
try
|
||||
{
|
||||
PreReceiveDeepClean(baseGroupName);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogError(ex, "Failed to clean up before receive in Revit");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
PreReceiveDeepClean(baseGroupName);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogError(ex, "Failed to clean up before receive in Revit");
|
||||
}
|
||||
|
||||
using (var _ = _activityFactory.Start("Commit"))
|
||||
{
|
||||
_transactionManager.CommitTransaction();
|
||||
preReceiveCleanTransaction.Assimilate();
|
||||
}
|
||||
|
||||
// 1 - Unpack objects and proxies from root commit object
|
||||
@@ -106,57 +113,56 @@ internal sealed class RevitHostObjectBuilder : IHostObjectBuilder, IDisposable
|
||||
unpackedRoot.ObjectsToConvert.ToList()
|
||||
);
|
||||
|
||||
using TransactionGroup transactionGroup =
|
||||
new(_converterSettings.Current.Document, $"Received data from {projectName}");
|
||||
transactionGroup.Start();
|
||||
_transactionManager.StartTransaction();
|
||||
|
||||
// 2 - Bake materials
|
||||
if (unpackedRoot.RenderMaterialProxies != null)
|
||||
{
|
||||
_transactionManager.StartTransaction(true, "Baking materials");
|
||||
_materialBaker.MapLayersRenderMaterials(unpackedRoot);
|
||||
// NOTE: do not set _contextStack.RenderMaterialProxyCache directly, things stop working. Ogu/Dim do not know why :) not a problem as we hopefully will refactor some of these hacks out.
|
||||
var map = _materialBaker.BakeMaterials(unpackedRoot.RenderMaterialProxies, baseGroupName);
|
||||
foreach (var kvp in map)
|
||||
{
|
||||
_revitToHostCacheSingleton.MaterialsByObjectId.Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
}
|
||||
|
||||
var conversionResults = BakeObjects(localToGlobalMaps, onOperationProgressed, cancellationToken);
|
||||
|
||||
using (var _ = _activityFactory.Start("Commit"))
|
||||
{
|
||||
_transactionManager.CommitTransaction();
|
||||
transactionGroup.Assimilate();
|
||||
}
|
||||
|
||||
using TransactionGroup createGroupTransaction = new(_converterSettings.Current.Document, "Creating group");
|
||||
createGroupTransaction.Start();
|
||||
_transactionManager.StartTransaction(true);
|
||||
|
||||
try
|
||||
{
|
||||
_groupBaker.BakeGroups(baseGroupName);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogError(ex, "Failed to create group after receiving elements in Revit");
|
||||
}
|
||||
|
||||
using (var _ = _activityFactory.Start("Commit"))
|
||||
// 3 - Bake objects
|
||||
(
|
||||
HostObjectBuilderResult builderResult,
|
||||
List<(DirectShape res, string applicationId)> postBakePaintTargets
|
||||
) conversionResults;
|
||||
{
|
||||
using var _ = _activityFactory.Start("Baking objects");
|
||||
_transactionManager.StartTransaction(true, "Baking objects");
|
||||
conversionResults = BakeObjects(localToGlobalMaps, onOperationProgressed, cancellationToken);
|
||||
_transactionManager.CommitTransaction();
|
||||
createGroupTransaction.Assimilate();
|
||||
}
|
||||
|
||||
_revitToHostCacheSingleton.MaterialsByObjectId.Clear(); // Massive hack!
|
||||
// 4 - Paint solids
|
||||
{
|
||||
using var _ = _activityFactory.Start("Painting solids");
|
||||
_transactionManager.StartTransaction(true, "Painting solids");
|
||||
PostBakePaint(conversionResults.postBakePaintTargets);
|
||||
_transactionManager.CommitTransaction();
|
||||
}
|
||||
|
||||
return conversionResults;
|
||||
// 5 - Create group
|
||||
{
|
||||
using var _ = _activityFactory.Start("Grouping");
|
||||
_transactionManager.StartTransaction(true, "Grouping");
|
||||
_groupBaker.BakeGroupForTopLevel(baseGroupName);
|
||||
_transactionManager.CommitTransaction();
|
||||
}
|
||||
|
||||
return conversionResults.builderResult;
|
||||
}
|
||||
|
||||
private HostObjectBuilderResult BakeObjects(
|
||||
private (
|
||||
HostObjectBuilderResult builderResult,
|
||||
List<(DirectShape res, string applicationId)> postBakePaintTargets
|
||||
) BakeObjects(
|
||||
List<LocalToGlobalMap> localToGlobalMaps,
|
||||
Action<string, double?>? onOperationProgressed,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
@@ -165,47 +171,111 @@ internal sealed class RevitHostObjectBuilder : IHostObjectBuilder, IDisposable
|
||||
var bakedObjectIds = new List<string>();
|
||||
int count = 0;
|
||||
|
||||
var postBakePaintTargets = new List<(DirectShape res, string applicationId)>();
|
||||
|
||||
foreach (LocalToGlobalMap localToGlobalMap in localToGlobalMaps)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
try
|
||||
{
|
||||
using var activity = _activityFactory.Start("BakeObject");
|
||||
var atomicObject = _localToGlobalConverterUtils.TransformObjects(
|
||||
localToGlobalMap.AtomicObject,
|
||||
localToGlobalMap.Matrix
|
||||
);
|
||||
var result = _converter.Convert(atomicObject);
|
||||
onOperationProgressed?.Invoke("Converting", (double)++count / localToGlobalMaps.Count);
|
||||
|
||||
// Note: our current converter always returns a DS for now
|
||||
if (result is DirectShape ds)
|
||||
// POC hack of the ages: try to pre transform curves before baking
|
||||
// we need to bypass the local to global converter as there we don't have access to what we want. that service will/should stop existing.
|
||||
if (
|
||||
localToGlobalMap.AtomicObject is ITransformable transformable and ICurve
|
||||
&& localToGlobalMap.Matrix.Count > 0
|
||||
&& localToGlobalMap.AtomicObject["units"] is string units
|
||||
)
|
||||
{
|
||||
bakedObjectIds.Add(ds.UniqueId.ToString());
|
||||
_groupBaker.AddToGroupMapping(localToGlobalMap.TraversalContext, ds);
|
||||
ITransformable? newTransformable = null;
|
||||
foreach (var mat in localToGlobalMap.Matrix)
|
||||
{
|
||||
transformable.TransformTo(new Transform(mat, units), out newTransformable);
|
||||
}
|
||||
|
||||
localToGlobalMap.AtomicObject = (newTransformable as Base)!;
|
||||
localToGlobalMap.Matrix = new(); // flush out the list, as we've applied the transforms already
|
||||
}
|
||||
|
||||
// actual conversion happens here!
|
||||
var result = _converter.Convert(localToGlobalMap.AtomicObject);
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / localToGlobalMaps.Count));
|
||||
if (result is DirectShapeDefinitionWrapper)
|
||||
{
|
||||
// direct shape creation happens here
|
||||
DirectShape directShapes = _localToGlobalDirectShapeConverter.Convert(
|
||||
(localToGlobalMap.AtomicObject, localToGlobalMap.Matrix)
|
||||
);
|
||||
|
||||
bakedObjectIds.Add(directShapes.UniqueId);
|
||||
_groupBaker.AddToTopLevelGroup(directShapes);
|
||||
|
||||
if (localToGlobalMap.AtomicObject is IRawEncodedObject and Base myBase)
|
||||
{
|
||||
postBakePaintTargets.Add((directShapes, myBase.applicationId ?? myBase.id));
|
||||
}
|
||||
|
||||
conversionResults.Add(
|
||||
new(Status.SUCCESS, localToGlobalMap.AtomicObject, directShapes.UniqueId, "Direct Shape")
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new SpeckleConversionException($"Failed to cast {result.GetType()} to Direct Shape.");
|
||||
throw new ConversionException($"Failed to cast {result.GetType()} to direct shape definition wrapper.");
|
||||
}
|
||||
conversionResults.Add(new(Status.SUCCESS, atomicObject, ds.UniqueId, "Direct Shape"));
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
conversionResults.Add(new(Status.ERROR, localToGlobalMap.AtomicObject, null, null, ex));
|
||||
_logger.LogError(ex, $"Failed to convert object of type {localToGlobalMap.AtomicObject.speckle_type}");
|
||||
}
|
||||
}
|
||||
return (new(bakedObjectIds, conversionResults), postBakePaintTargets);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We're using this to assign materials to solids coming via the shape importer.
|
||||
/// </summary>
|
||||
/// <param name="paintTargets"></param>
|
||||
private void PostBakePaint(List<(DirectShape res, string applicationId)> paintTargets)
|
||||
{
|
||||
foreach (var (res, applicationId) in paintTargets)
|
||||
{
|
||||
var elGeometry = res.get_Geometry(new Options() { DetailLevel = ViewDetailLevel.Undefined });
|
||||
var materialId = ElementId.InvalidElementId;
|
||||
if (_revitToHostCacheSingleton.MaterialsByObjectId.TryGetValue(applicationId, out var mappedElementId))
|
||||
{
|
||||
materialId = mappedElementId;
|
||||
}
|
||||
|
||||
if (materialId == ElementId.InvalidElementId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// NOTE: some geometries fail to convert as solids, and the api defaults back to meshes (from the shape importer). These cannot be painted, so don't bother.
|
||||
foreach (var geo in elGeometry)
|
||||
{
|
||||
if (geo is Solid s)
|
||||
{
|
||||
foreach (Face face in s.Faces)
|
||||
{
|
||||
_converterSettings.Current.Document.Paint(res.Id, face, materialId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new(bakedObjectIds, conversionResults);
|
||||
}
|
||||
|
||||
private void PreReceiveDeepClean(string baseGroupName)
|
||||
{
|
||||
DirectShapeLibrary.GetDirectShapeLibrary(_converterSettings.Current.Document).Reset(); // Note: this needs to be cleared, as it is being used in the converter
|
||||
|
||||
_revitToHostCacheSingleton.MaterialsByObjectId.Clear(); // Massive hack!
|
||||
_groupBaker.PurgeGroups(baseGroupName);
|
||||
_materialBaker.PurgeMaterials(baseGroupName);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_transactionManager?.Dispose();
|
||||
}
|
||||
public void Dispose() => _transactionManager?.Dispose();
|
||||
}
|
||||
|
||||
+2
-2
@@ -30,11 +30,11 @@ public sealed class TransactionManager : ITransactionManager
|
||||
#pragma warning restore CA2213 // Disposable fields should be disposed
|
||||
|
||||
// POC find a better way to use IFailuresPreprocessor
|
||||
public void StartTransaction(bool enableFailurePreprocessor = false)
|
||||
public void StartTransaction(bool enableFailurePreprocessor = false, string name = "Speckle Transaction")
|
||||
{
|
||||
if (_transaction == null || !_transaction.IsValidObject || _transaction.GetStatus() != TransactionStatus.Started)
|
||||
{
|
||||
_transaction = new Transaction(Document, "Speckle Transaction");
|
||||
_transaction = new Transaction(Document, name);
|
||||
|
||||
if (enableFailurePreprocessor)
|
||||
{
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
|
||||
namespace Speckle.Connectors.RevitShared.Operations.Send.Filters;
|
||||
|
||||
public class RevitSelectionFilter : DirectSelectionSendFilter
|
||||
{
|
||||
public RevitSelectionFilter()
|
||||
{
|
||||
IsDefault = true;
|
||||
}
|
||||
|
||||
public override List<string> GetObjectIds() => SelectedObjectIds;
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
using Autodesk.Revit.DB;
|
||||
using Speckle.Connectors.DUI.Exceptions;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
using Speckle.Connectors.Revit.HostApp;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
|
||||
namespace Speckle.Connectors.RevitShared.Operations.Send.Filters;
|
||||
|
||||
public class RevitViewsFilter : DiscriminatedObject, ISendFilter
|
||||
{
|
||||
private RevitContext _revitContext;
|
||||
private APIContext _apiContext;
|
||||
private Document? _doc;
|
||||
public string Id { get; set; } = "revitViews";
|
||||
public string Name { get; set; } = "Views";
|
||||
public string? Summary { get; set; }
|
||||
public bool IsDefault { get; set; }
|
||||
public string? SelectedView { get; set; }
|
||||
public List<string>? AvailableViews { get; set; }
|
||||
|
||||
public RevitViewsFilter() { }
|
||||
|
||||
public RevitViewsFilter(RevitContext revitContext, APIContext apiContext)
|
||||
{
|
||||
_revitContext = revitContext;
|
||||
_apiContext = apiContext;
|
||||
_doc = _revitContext.UIApplication?.ActiveUIDocument.Document;
|
||||
|
||||
GetViews();
|
||||
}
|
||||
|
||||
public View? GetView()
|
||||
{
|
||||
if (SelectedView is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
string[] result = SelectedView.Split(new string[] { " - " }, 2, StringSplitOptions.None);
|
||||
var viewFamilyString = result[0];
|
||||
var viewString = result[1];
|
||||
|
||||
using var collector = new FilteredElementCollector(_doc);
|
||||
return collector
|
||||
.OfClass(typeof(View))
|
||||
.Cast<View>()
|
||||
.FirstOrDefault(v => v.ViewType.ToString().Equals(viewFamilyString) && v.Name.Equals(viewString));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Always need to run on Revit UI thread (main) because of FilteredElementCollector.
|
||||
/// Use it with APIContext.Run
|
||||
/// </summary>
|
||||
/// <exception cref="SpeckleSendFilterException">Whenever no view is found.</exception>
|
||||
public List<string> GetObjectIds()
|
||||
{
|
||||
var objectIds = new List<string>();
|
||||
if (SelectedView is null)
|
||||
{
|
||||
return objectIds;
|
||||
}
|
||||
|
||||
// Paşa Bilal wants it like this... (three dots = important meaning for ogu)
|
||||
string[] result = SelectedView.Split(new string[] { " - " }, 2, StringSplitOptions.None);
|
||||
var viewFamilyString = result[0];
|
||||
var viewString = result[1];
|
||||
|
||||
using var collector = new FilteredElementCollector(_doc);
|
||||
View? view = collector
|
||||
.OfClass(typeof(View))
|
||||
.Cast<View>()
|
||||
.FirstOrDefault(v => v.ViewType.ToString().Equals(viewFamilyString) && v.Name.Equals(viewString));
|
||||
|
||||
if (view is null)
|
||||
{
|
||||
throw new SpeckleSendFilterException("View not found, please update your model send filter.");
|
||||
}
|
||||
using var viewCollector = new FilteredElementCollector(_doc, view.Id);
|
||||
List<Element> elementsInView = viewCollector.ToElements().ToList();
|
||||
objectIds = elementsInView.Select(e => e.UniqueId).ToList();
|
||||
return objectIds;
|
||||
}
|
||||
|
||||
private void GetViews()
|
||||
{
|
||||
using var collector = new FilteredElementCollector(_doc);
|
||||
var views = collector
|
||||
.OfClass(typeof(View))
|
||||
.Cast<View>()
|
||||
.Where(v => !v.IsTemplate)
|
||||
.Select(v => v.ViewType.ToString() + " - " + v.Name.ToString())
|
||||
.ToList();
|
||||
AvailableViews = views;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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, APIContext apiContext)
|
||||
{
|
||||
_revitContext = revitContext;
|
||||
_apiContext = apiContext;
|
||||
_doc = _revitContext.UIApplication?.ActiveUIDocument.Document;
|
||||
}
|
||||
}
|
||||
+13
-14
@@ -23,7 +23,6 @@ public class RevitRootObjectBuilder : IRootObjectBuilder<ElementId>
|
||||
// POC: SendSelection and RevitConversionContextStack should be interfaces, former needs interfaces
|
||||
private readonly IRootToSpeckleConverter _converter;
|
||||
private readonly IConverterSettingsStore<RevitConversionSettings> _converterSettings;
|
||||
private readonly Collection _rootObject;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly ElementUnpacker _elementUnpacker;
|
||||
private readonly SendCollectionManager _sendCollectionManager;
|
||||
@@ -50,18 +49,12 @@ public class RevitRootObjectBuilder : IRootObjectBuilder<ElementId>
|
||||
_revitToSpeckleCacheSingleton = revitToSpeckleCacheSingleton;
|
||||
_logger = logger;
|
||||
_parameterDefinitionHandler = parameterDefinitionHandler;
|
||||
|
||||
_rootObject = new Collection()
|
||||
{
|
||||
name = _converterSettings.Current.Document.PathName.Split('\\').Last().Split('.').First()
|
||||
};
|
||||
_rootObject["units"] = _converterSettings.Current.SpeckleUnits;
|
||||
}
|
||||
|
||||
public async Task<RootObjectBuilderResult> Build(
|
||||
IReadOnlyList<ElementId> objects,
|
||||
SendInfo sendInfo,
|
||||
Action<string, double?>? onOperationProgressed = null,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken ct = default
|
||||
)
|
||||
{
|
||||
@@ -72,6 +65,11 @@ public class RevitRootObjectBuilder : IRootObjectBuilder<ElementId>
|
||||
throw new SpeckleException("Family Environment documents are not supported.");
|
||||
}
|
||||
|
||||
// 0 - Init the root
|
||||
Collection rootObject =
|
||||
new() { name = _converterSettings.Current.Document.PathName.Split('\\').Last().Split('.').First() };
|
||||
rootObject["units"] = _converterSettings.Current.SpeckleUnits;
|
||||
|
||||
var revitElements = new List<Element>();
|
||||
|
||||
// Convert ids to actual revit elements
|
||||
@@ -116,7 +114,8 @@ public class RevitRootObjectBuilder : IRootObjectBuilder<ElementId>
|
||||
converted.applicationId = applicationId;
|
||||
}
|
||||
|
||||
var collection = _sendCollectionManager.GetAndCreateObjectHostCollection(revitElement, _rootObject);
|
||||
var collection = _sendCollectionManager.GetAndCreateObjectHostCollection(revitElement, rootObject);
|
||||
|
||||
collection.elements.Add(converted);
|
||||
results.Add(new(Status.SUCCESS, applicationId, sourceType, converted));
|
||||
}
|
||||
@@ -126,20 +125,20 @@ public class RevitRootObjectBuilder : IRootObjectBuilder<ElementId>
|
||||
results.Add(new(Status.ERROR, applicationId, sourceType, null, ex));
|
||||
}
|
||||
|
||||
onOperationProgressed?.Invoke("Converting", (double)++countProgress / atomicObjects.Count);
|
||||
onOperationProgressed.Report(new("Converting", (double)++countProgress / atomicObjects.Count));
|
||||
}
|
||||
|
||||
if (results.All(x => x.Status == Status.ERROR))
|
||||
{
|
||||
throw new SpeckleConversionException("Failed to convert all objects.");
|
||||
throw new SpeckleException("Failed to convert all objects.");
|
||||
}
|
||||
|
||||
var idsAndSubElementIds = _elementUnpacker.GetElementsAndSubelementIdsFromAtomicObjects(atomicObjects);
|
||||
var materialProxies = _revitToSpeckleCacheSingleton.GetRenderMaterialProxyListForObjects(idsAndSubElementIds);
|
||||
_rootObject[ProxyKeys.RENDER_MATERIAL] = materialProxies;
|
||||
rootObject[ProxyKeys.RENDER_MATERIAL] = materialProxies;
|
||||
// NOTE: these are currently not used anywhere, so we could even skip them (?).
|
||||
_rootObject[ProxyKeys.PARAMETER_DEFINITIONS] = _parameterDefinitionHandler.Definitions;
|
||||
rootObject[ProxyKeys.PARAMETER_DEFINITIONS] = _parameterDefinitionHandler.Definitions;
|
||||
|
||||
return new RootObjectBuilderResult(_rootObject, results);
|
||||
return new RootObjectBuilderResult(rootObject, results);
|
||||
}
|
||||
}
|
||||
|
||||
+14
-8
@@ -14,6 +14,7 @@ namespace Speckle.Connectors.Revit.Operations.Send.Settings;
|
||||
public class ToSpeckleSettingsManager : IToSpeckleSettingsManager
|
||||
{
|
||||
private readonly RevitContext _revitContext;
|
||||
private readonly APIContext _apiContext;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly ElementUnpacker _elementUnpacker;
|
||||
|
||||
@@ -24,16 +25,18 @@ public class ToSpeckleSettingsManager : IToSpeckleSettingsManager
|
||||
|
||||
public ToSpeckleSettingsManager(
|
||||
RevitContext revitContext,
|
||||
APIContext apiContext,
|
||||
ISendConversionCache sendConversionCache,
|
||||
ElementUnpacker elementUnpacker
|
||||
)
|
||||
{
|
||||
_revitContext = revitContext;
|
||||
_apiContext = apiContext;
|
||||
_elementUnpacker = elementUnpacker;
|
||||
_sendConversionCache = sendConversionCache;
|
||||
}
|
||||
|
||||
public DetailLevelType GetDetailLevelSetting(SenderModelCard modelCard)
|
||||
public async Task<DetailLevelType> GetDetailLevelSetting(SenderModelCard modelCard)
|
||||
{
|
||||
var fidelityString = modelCard.Settings?.First(s => s.Id == "detailLevel").Value as string;
|
||||
if (
|
||||
@@ -45,7 +48,7 @@ public class ToSpeckleSettingsManager : IToSpeckleSettingsManager
|
||||
{
|
||||
if (previousType != fidelity)
|
||||
{
|
||||
EvictCacheForModelCard(modelCard);
|
||||
await EvictCacheForModelCard(modelCard).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
_detailLevelCache[modelCard.ModelCardId.NotNull()] = fidelity;
|
||||
@@ -55,7 +58,7 @@ public class ToSpeckleSettingsManager : IToSpeckleSettingsManager
|
||||
throw new ArgumentException($"Invalid geometry fidelity value: {fidelityString}");
|
||||
}
|
||||
|
||||
public Transform? GetReferencePointSetting(SenderModelCard modelCard)
|
||||
public async Task<Transform?> GetReferencePointSetting(SenderModelCard modelCard)
|
||||
{
|
||||
var referencePointString = modelCard.Settings?.First(s => s.Id == "referencePoint").Value as string;
|
||||
if (
|
||||
@@ -75,7 +78,7 @@ public class ToSpeckleSettingsManager : IToSpeckleSettingsManager
|
||||
// invalidate conversion cache if the transform has changed
|
||||
if (previousTransform != currentTransform)
|
||||
{
|
||||
EvictCacheForModelCard(modelCard);
|
||||
await EvictCacheForModelCard(modelCard).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +89,7 @@ public class ToSpeckleSettingsManager : IToSpeckleSettingsManager
|
||||
throw new ArgumentException($"Invalid reference point value: {referencePointString}");
|
||||
}
|
||||
|
||||
public bool GetSendParameterNullOrEmptyStringsSetting(SenderModelCard modelCard)
|
||||
public async Task<bool> GetSendParameterNullOrEmptyStringsSetting(SenderModelCard modelCard)
|
||||
{
|
||||
var value = modelCard.Settings?.First(s => s.Id == "nullemptyparams").Value as bool?;
|
||||
var returnValue = value != null && value.NotNull();
|
||||
@@ -94,7 +97,7 @@ public class ToSpeckleSettingsManager : IToSpeckleSettingsManager
|
||||
{
|
||||
if (previousValue != returnValue)
|
||||
{
|
||||
EvictCacheForModelCard(modelCard);
|
||||
await EvictCacheForModelCard(modelCard).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,9 +105,12 @@ public class ToSpeckleSettingsManager : IToSpeckleSettingsManager
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private void EvictCacheForModelCard(SenderModelCard modelCard)
|
||||
private async Task EvictCacheForModelCard(SenderModelCard modelCard)
|
||||
{
|
||||
var objectIds = modelCard.SendFilter != null ? modelCard.SendFilter.GetObjectIds() : [];
|
||||
var objectIds =
|
||||
modelCard.SendFilter != null
|
||||
? await _apiContext.Run(_ => modelCard.SendFilter.NotNull().GetObjectIds()).ConfigureAwait(false)
|
||||
: [];
|
||||
var unpackedObjectIds = _elementUnpacker.GetUnpackedElementIds(objectIds);
|
||||
_sendConversionCache.EvictObjects(unpackedObjectIds);
|
||||
}
|
||||
|
||||
@@ -2,43 +2,46 @@ using Autodesk.Revit.UI;
|
||||
using Autodesk.Revit.UI.Events;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
using Speckle.InterfaceGenerator;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
|
||||
namespace Speckle.Connectors.Revit.Plugin;
|
||||
|
||||
[GenerateAutoInterface]
|
||||
public sealed class RevitIdleManager(RevitContext revitContext, IIdleCallManager idleCallManager) : IRevitIdleManager
|
||||
public interface IRevitIdleManager : IAppIdleManager
|
||||
{
|
||||
private readonly UIApplication _uiApplication = revitContext.UIApplication.NotNull();
|
||||
public void RunAsync(Action action);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe deferred action to Idling event to run it whenever Revit becomes idle.
|
||||
/// </summary>
|
||||
/// <param name="action"> Action to call whenever Revit becomes Idle.</param>
|
||||
/// some events in host app are trigerred many times, we might get 10x per object
|
||||
/// Making this more like a deferred action, so we don't update the UI many times
|
||||
public void SubscribeToIdle(string id, Action action) =>
|
||||
idleCallManager.SubscribeToIdle(
|
||||
id,
|
||||
action,
|
||||
() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
_uiApplication.Idling += RevitAppOnIdle;
|
||||
}
|
||||
catch (Exception e) when (!e.IsFatal())
|
||||
{
|
||||
// TODO: wrap this guy in the top level exception handler (?)
|
||||
// This happens very rarely, see previous report [CNX-125: Autodesk.Revit.Exceptions.InvalidOperationException: Can not subscribe to an event during execution of that event!](https://linear.app/speckle/issue/CNX-125/autodeskrevitexceptionsinvalidoperationexception-can-not-subscribe-to)
|
||||
}
|
||||
}
|
||||
);
|
||||
public sealed class RevitIdleManager : AppIdleManager, IRevitIdleManager
|
||||
{
|
||||
private readonly UIApplication _uiApplication;
|
||||
private readonly IIdleCallManager _idleCallManager;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
|
||||
private event EventHandler<IdlingEventArgs>? OnIdle;
|
||||
|
||||
public RevitIdleManager(
|
||||
RevitContext revitContext,
|
||||
IIdleCallManager idleCallManager,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
)
|
||||
: base(idleCallManager)
|
||||
{
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
_uiApplication = revitContext.UIApplication.NotNull();
|
||||
_idleCallManager = idleCallManager;
|
||||
_uiApplication.Idling += (s, e) => OnIdle?.Invoke(s, e); // will be called on the main thread always and fixing the Revit exceptions on subscribing/unsubscribing Idle events
|
||||
}
|
||||
|
||||
protected override void AddEvent()
|
||||
{
|
||||
_topLevelExceptionHandler.CatchUnhandled(() =>
|
||||
{
|
||||
OnIdle += RevitAppOnIdle;
|
||||
});
|
||||
}
|
||||
|
||||
private void RevitAppOnIdle(object? sender, IdlingEventArgs e) =>
|
||||
idleCallManager.AppOnIdle(() => _uiApplication.Idling -= RevitAppOnIdle);
|
||||
_idleCallManager.AppOnIdle(() => OnIdle -= RevitAppOnIdle);
|
||||
|
||||
public void RunAsync(Action action)
|
||||
{
|
||||
|
||||
+3
-2
@@ -14,12 +14,12 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\BasicConnectorBindingRevit.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\Filters.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\RevitBaseBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\RevitReceiveBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\SelectionBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\RevitSendBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ElementIdHelper.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\APIContext.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\DocumentModelStorageSchema.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Elements.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\RevitMaterialBaker.cs" />
|
||||
@@ -33,9 +33,10 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\SendCollectionManager.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\ElementUnpacker.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Receive\ITransactionManager.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Receive\RevitContextAccessor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Receive\RevitHostObjectBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Receive\TransactionManager.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Filters\RevitSelectionFilter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Filters\RevitViewsFilter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\RevitRootObjectBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\SendParameterNullOrEmptyStringsSetting.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\ToSpeckleSettingsManager.cs" />
|
||||
|
||||
@@ -80,6 +80,14 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -165,24 +173,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -283,8 +273,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -292,7 +283,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -310,7 +302,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.rhino7": {
|
||||
@@ -355,31 +347,36 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "VpMlOcApkQPLn90Xb5K+2nH64wN3NJ906u/YaM1oGAMw7v1SoYPbb5i03bFLuOw/Ho1KSGI0ccU82Jpi9p+n8A==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "KGbynDH2vFca7NqpVTp3KvNDE5zdX/ZuCtjdtqGG7rS8r5x2YMT6Ptk2RKJrpPNCaNL/YnuiZ425JLWua4lfqw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "LOV43Wn6IYWfK+ifz/XfcYDaL5ZFF6wLVJQGgSkaNEpGOBitCg6bQc2AuNuy5QHk85dbB1QS9XXEXjeoMxugLg=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"Speckle.Connectors.Rhino8": {
|
||||
"commandName": "Executable",
|
||||
"executablePath": "C:\\Program Files\\Rhino 8\\System\\Rhino.exe",
|
||||
"commandLineArgs": "\"$(TargetDir)Speckle.Connectors.Rhino8.rhp\""
|
||||
"commandLineArgs": "\"$(TargetDir)Speckle.Connectors.Rhino8.rhp\" /netfx"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,14 @@
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -165,24 +173,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.1",
|
||||
@@ -283,8 +273,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -292,7 +283,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.146, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.167, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.167, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
}
|
||||
},
|
||||
@@ -310,7 +302,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.146, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.167, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.rhino8": {
|
||||
@@ -355,31 +347,36 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "xuv5LaU6j8ODGHyClHbbK78bOJid8LGuwfVcEega1q3sYwmLWOWIDP9lO0QA1tyctE+2CZDH3sOUChleAFC4fg==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "VpMlOcApkQPLn90Xb5K+2nH64wN3NJ906u/YaM1oGAMw7v1SoYPbb5i03bFLuOw/Ho1KSGI0ccU82Jpi9p+n8A==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.146"
|
||||
"Speckle.Sdk": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.146, )",
|
||||
"resolved": "3.1.0-dev.146",
|
||||
"contentHash": "vNaWJkt7/xcIH/CraOrEumGn8A6gAlyl1RHfRI8B8qAGylSlEhuvuBSatS1gUPI35p9omO63yYQFKaIKEIsa3Q==",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "KGbynDH2vFca7NqpVTp3KvNDE5zdX/ZuCtjdtqGG7rS8r5x2YMT6Ptk2RKJrpPNCaNL/YnuiZ425JLWua4lfqw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.7",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Polly": "7.2.3",
|
||||
"Polly.Contrib.WaitAndRetry": "1.1.1",
|
||||
"Polly.Extensions.Http": "3.0.0",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2"
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.167"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.167, )",
|
||||
"resolved": "3.1.0-dev.167",
|
||||
"contentHash": "LOV43Wn6IYWfK+ifz/XfcYDaL5ZFF6wLVJQGgSkaNEpGOBitCg6bQc2AuNuy5QHk85dbB1QS9XXEXjeoMxugLg=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
|
||||
+21
-9
@@ -1,6 +1,7 @@
|
||||
using Rhino;
|
||||
using Rhino.DocObjects;
|
||||
using Rhino.Geometry;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
@@ -11,30 +12,36 @@ using Speckle.Sdk.Common;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.Bindings;
|
||||
|
||||
public class RhinoBasicConnectorBinding : IBasicConnectorBinding
|
||||
public sealed class RhinoBasicConnectorBinding : IBasicConnectorBinding
|
||||
{
|
||||
public string Name => "baseBinding";
|
||||
public IBrowserBridge Parent { get; }
|
||||
public BasicConnectorBindingCommands Commands { get; }
|
||||
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
|
||||
public RhinoBasicConnectorBinding(
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
ISendConversionCache sendConversionCache,
|
||||
ISpeckleApplication speckleApplication
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
Parent = parent;
|
||||
_sendConversionCache = sendConversionCache;
|
||||
_speckleApplication = speckleApplication;
|
||||
Commands = new BasicConnectorBindingCommands(parent);
|
||||
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
{
|
||||
Commands.NotifyDocumentChanged();
|
||||
};
|
||||
parent.TopLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await Commands.NotifyDocumentChanged().ConfigureAwait(false);
|
||||
// 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;
|
||||
@@ -60,7 +67,7 @@ public class RhinoBasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
|
||||
|
||||
public void HighlightObjects(List<string> objectIds)
|
||||
public Task HighlightObjects(IReadOnlyList<string> objectIds)
|
||||
{
|
||||
var objects = GetObjectsFromIds(objectIds);
|
||||
|
||||
@@ -73,9 +80,10 @@ public class RhinoBasicConnectorBinding : IBasicConnectorBinding
|
||||
}
|
||||
|
||||
HighlightObjectsOnView(objects.rhinoObjects, objects.groups);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void HighlightModel(string modelCardId)
|
||||
public async Task HighlightModel(string modelCardId)
|
||||
{
|
||||
var objectIds = new List<string>();
|
||||
var myModel = _store.GetModelById(modelCardId);
|
||||
@@ -92,7 +100,9 @@ public class RhinoBasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
if (objectIds.Count == 0)
|
||||
{
|
||||
Commands.SetModelError(modelCardId, new OperationCanceledException("No objects found to highlight."));
|
||||
await Commands
|
||||
.SetModelError(modelCardId, new OperationCanceledException("No objects found to highlight."))
|
||||
.ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -102,14 +112,16 @@ public class RhinoBasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
if (objects.rhinoObjects.Count == 0 && objects.groups.Count == 0)
|
||||
{
|
||||
Commands.SetModelError(modelCardId, new OperationCanceledException("No objects found to highlight."));
|
||||
await Commands
|
||||
.SetModelError(modelCardId, new OperationCanceledException("No objects found to highlight."))
|
||||
.ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
HighlightObjectsOnView(objects.rhinoObjects, objects.groups);
|
||||
}
|
||||
|
||||
private (List<RhinoObject> rhinoObjects, List<Group> groups) GetObjectsFromIds(List<string> objectIds)
|
||||
private (List<RhinoObject> rhinoObjects, List<Group> groups) GetObjectsFromIds(IReadOnlyList<string> objectIds)
|
||||
{
|
||||
List<RhinoObject> rhinoObjects = objectIds
|
||||
.Select((id) => RhinoDoc.ActiveDoc.Objects.FindId(new Guid(id)))
|
||||
|
||||
@@ -75,23 +75,15 @@ public class RhinoReceiveBinding : IReceiveBinding
|
||||
.ServiceProvider.GetRequiredService<ReceiveOperation>()
|
||||
.Execute(
|
||||
modelCard.GetReceiveInfo(_speckleApplication.Slug),
|
||||
cancellationToken,
|
||||
(status, progress) =>
|
||||
_operationProgressManager.SetModelProgress(
|
||||
Parent,
|
||||
modelCardId,
|
||||
new ModelCardProgress(modelCardId, status, progress),
|
||||
cancellationToken
|
||||
)
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
modelCard.BakedObjectIds = conversionResults.BakedObjectIds.ToList();
|
||||
Commands.SetModelReceiveResult(
|
||||
modelCardId,
|
||||
conversionResults.BakedObjectIds,
|
||||
conversionResults.ConversionResults
|
||||
);
|
||||
await Commands
|
||||
.SetModelReceiveResult(modelCardId, conversionResults.BakedObjectIds, conversionResults.ConversionResults)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -103,7 +95,7 @@ public class RhinoReceiveBinding : IReceiveBinding
|
||||
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);
|
||||
Commands.SetModelError(modelCardId, ex);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,19 +2,18 @@ using Rhino;
|
||||
using Rhino.DocObjects;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.Rhino.HostApp;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.Bindings;
|
||||
|
||||
public class RhinoSelectionBinding : ISelectionBinding
|
||||
{
|
||||
private readonly IRhinoIdleManager _idleManager;
|
||||
private readonly IAppIdleManager _idleManager;
|
||||
private const string SELECTION_EVENT = "setSelection";
|
||||
|
||||
public string Name => "selectionBinding";
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
public RhinoSelectionBinding(IRhinoIdleManager idleManager, IBrowserBridge parent)
|
||||
public RhinoSelectionBinding(IAppIdleManager idleManager, IBrowserBridge parent)
|
||||
{
|
||||
_idleManager = idleManager;
|
||||
Parent = parent;
|
||||
|
||||
@@ -15,11 +15,11 @@ 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.Rhino.HostApp;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.Rhino;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
using Speckle.Sdk.Logging;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.Bindings;
|
||||
|
||||
@@ -30,7 +30,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly IRhinoIdleManager _idleManager;
|
||||
private readonly IAppIdleManager _idleManager;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly List<ISendFilter> _sendFilters;
|
||||
private readonly CancellationManager _cancellationManager;
|
||||
@@ -40,6 +40,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IRhinoConversionSettingsFactory _rhinoConversionSettingsFactory;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly ISdkActivityFactory _activityFactory;
|
||||
|
||||
/// <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,7 +52,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
|
||||
public RhinoSendBinding(
|
||||
DocumentModelStore store,
|
||||
IRhinoIdleManager idleManager,
|
||||
IAppIdleManager idleManager,
|
||||
IBrowserBridge parent,
|
||||
IEnumerable<ISendFilter> sendFilters,
|
||||
IServiceProvider serviceProvider,
|
||||
@@ -60,7 +61,8 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<RhinoSendBinding> logger,
|
||||
IRhinoConversionSettingsFactory rhinoConversionSettingsFactory,
|
||||
ISpeckleApplication speckleApplication
|
||||
ISpeckleApplication speckleApplication,
|
||||
ISdkActivityFactory activityFactory
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
@@ -76,6 +78,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
_topLevelExceptionHandler = parent.TopLevelExceptionHandler.Parent.TopLevelExceptionHandler;
|
||||
Parent = parent;
|
||||
Commands = new SendBindingUICommands(parent); // POC: Commands are tightly coupled with their bindings, at least for now, saves us injecting a factory.
|
||||
_activityFactory = activityFactory;
|
||||
SubscribeToRhinoEvents();
|
||||
}
|
||||
|
||||
@@ -94,10 +97,11 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
_topLevelExceptionHandler.CatchUnhandled(() =>
|
||||
{
|
||||
// NOTE: This does not work if rhino starts and opens a blank doc;
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// These events always happen in a doc. Why guard agains a null doc?
|
||||
// if (!_store.IsDocumentInit)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
ChangedObjectIds[e.ObjectId.ToString()] = 1;
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
@@ -107,10 +111,11 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
_topLevelExceptionHandler.CatchUnhandled(() =>
|
||||
{
|
||||
// NOTE: This does not work if rhino starts and opens a blank doc;
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// These events always happen in a doc. Why guard agains a null doc?
|
||||
// if (!_store.IsDocumentInit)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
ChangedObjectIds[e.ObjectId.ToString()] = 1;
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
@@ -120,10 +125,11 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
_topLevelExceptionHandler.CatchUnhandled(() =>
|
||||
{
|
||||
// NOTE: This does not work if rhino starts and opens a blank doc;
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// These events always happen in a doc. Why guard agains a null doc?
|
||||
// if (!_store.IsDocumentInit)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// NOTE: not sure yet we want to track every attribute changes yet. TBD
|
||||
if (e.OldAttributes.LayerIndex != e.NewAttributes.LayerIndex)
|
||||
@@ -137,10 +143,11 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
_topLevelExceptionHandler.CatchUnhandled(() =>
|
||||
{
|
||||
// NOTE: This does not work if rhino starts and opens a blank doc;
|
||||
if (!_store.IsDocumentInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// These events always happen in a doc. Why guard agains a null doc?
|
||||
// if (!_store.IsDocumentInit)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
ChangedObjectIds[e.NewRhinoObject.Id.ToString()] = 1;
|
||||
ChangedObjectIds[e.OldRhinoObject.Id.ToString()] = 1;
|
||||
@@ -154,6 +161,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
|
||||
public async Task Send(string modelCardId)
|
||||
{
|
||||
using var activity = _activityFactory.Start();
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
scope
|
||||
.ServiceProvider.GetRequiredService<IConverterSettingsStore<RhinoConversionSettings>>()
|
||||
@@ -186,18 +194,14 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
.Execute(
|
||||
rhinoObjects,
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
(status, progress) =>
|
||||
_operationProgressManager.SetModelProgress(
|
||||
Parent,
|
||||
modelCardId,
|
||||
new ModelCardProgress(modelCardId, status, progress),
|
||||
cancellationToken
|
||||
),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Commands.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults);
|
||||
await Commands
|
||||
.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -209,7 +213,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
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);
|
||||
Commands.SetModelError(modelCardId, ex);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,8 +222,14 @@ 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 void RunExpirationChecks()
|
||||
private async Task RunExpirationChecks()
|
||||
{
|
||||
// Note: added here a guard against executing this if there's no active doc present.
|
||||
if (RhinoDoc.ActiveDoc == null)
|
||||
{
|
||||
_logger.LogError("Rhino expiration checks were running without an active doc.");
|
||||
return;
|
||||
}
|
||||
var senders = _store.GetSenders();
|
||||
string[] objectIdsList = ChangedObjectIds.Keys.ToArray(); // NOTE: could not copy to array happens here
|
||||
List<string> expiredSenderIds = new();
|
||||
@@ -236,7 +246,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
}
|
||||
}
|
||||
|
||||
Commands.SetModelsExpired(expiredSenderIds);
|
||||
await Commands.SetModelsExpired(expiredSenderIds).ConfigureAwait(false);
|
||||
ChangedObjectIds = new();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Rhino;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
using Speckle.Sdk.Common.Exceptions;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.Extensions;
|
||||
|
||||
@@ -31,7 +31,7 @@ public static class RhinoUnitsExtension
|
||||
case UnitSystem.Unset:
|
||||
return Units.Meters;
|
||||
default:
|
||||
throw new SpeckleException($"The Unit System \"{unitSystem}\" is unsupported.");
|
||||
throw new UnitNotSupportedException($"The Unit System \"{unitSystem}\" is unsupported.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.Filters;
|
||||
|
||||
public class RhinoEverythingFilter : EverythingSendFilter
|
||||
{
|
||||
public override List<string> GetObjectIds() => new(); // TODO
|
||||
|
||||
public override bool CheckExpiry(string[] changedObjectIds) => true;
|
||||
}
|
||||
@@ -4,7 +4,10 @@ namespace Speckle.Connectors.Rhino.Filters;
|
||||
|
||||
public class RhinoSelectionFilter : DirectSelectionSendFilter
|
||||
{
|
||||
public override List<string> GetObjectIds() => SelectedObjectIds;
|
||||
public RhinoSelectionFilter()
|
||||
{
|
||||
IsDefault = true;
|
||||
}
|
||||
|
||||
public override bool CheckExpiry(string[] changedObjectIds) => SelectedObjectIds.Intersect(changedObjectIds).Any();
|
||||
public override List<string> GetObjectIds() => SelectedObjectIds;
|
||||
}
|
||||
|
||||
@@ -1,29 +1,20 @@
|
||||
using Rhino;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.InterfaceGenerator;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.HostApp;
|
||||
|
||||
/// <summary>
|
||||
/// Rhino Idle Manager is a helper util to manage deferred actions.
|
||||
/// </summary>
|
||||
[GenerateAutoInterface]
|
||||
public class RhinoIdleManager(IIdleCallManager idleCallManager) : IRhinoIdleManager
|
||||
public sealed class RhinoIdleManager(IIdleCallManager idleCallManager) : AppIdleManager(idleCallManager)
|
||||
{
|
||||
/// <summary>
|
||||
/// Subscribe deferred action to RhinoIdle event to run it whenever Rhino become idle.
|
||||
/// </summary>
|
||||
/// <param name="action"> Action to call whenever Rhino become Idle.</param>
|
||||
public void SubscribeToIdle(string id, Action action) =>
|
||||
idleCallManager.SubscribeToIdle(
|
||||
id,
|
||||
action,
|
||||
() =>
|
||||
{
|
||||
RhinoApp.Idle += RhinoAppOnIdle;
|
||||
}
|
||||
);
|
||||
private readonly IIdleCallManager _idleCallManager = idleCallManager;
|
||||
|
||||
protected override void AddEvent()
|
||||
{
|
||||
RhinoApp.Idle += RhinoAppOnIdle;
|
||||
}
|
||||
|
||||
private void RhinoAppOnIdle(object? sender, EventArgs e) =>
|
||||
idleCallManager.AppOnIdle(() => RhinoApp.Idle -= RhinoAppOnIdle);
|
||||
_idleCallManager.AppOnIdle(() => RhinoApp.Idle -= RhinoAppOnIdle);
|
||||
}
|
||||
|
||||
@@ -4,10 +4,12 @@ using Rhino.DocObjects;
|
||||
using Rhino.Geometry;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Instances;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Rhino.Extensions;
|
||||
using Speckle.DoubleNumerics;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
using Speckle.Sdk.Common.Exceptions;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
using Speckle.Sdk.Models.Instances;
|
||||
@@ -40,11 +42,11 @@ public class RhinoInstanceBaker : IInstanceBaker<List<string>>
|
||||
/// <param name="instanceComponents">Instance definitions and instances that need creating.</param>
|
||||
/// <param name="applicationIdMap">A dict mapping { original application id -> [resulting application ids post conversion] }</param>
|
||||
/// <param name="onOperationProgressed"></param>
|
||||
public BakeResult BakeInstances(
|
||||
List<(Collection[] collectionPath, IInstanceComponent obj)> instanceComponents,
|
||||
public async Task<BakeResult> BakeInstances(
|
||||
IReadOnlyCollection<(Collection[] collectionPath, IInstanceComponent obj)> instanceComponents,
|
||||
Dictionary<string, List<string>> applicationIdMap,
|
||||
string baseLayerName,
|
||||
Action<string, double?>? onOperationProgressed
|
||||
IProgress<CardProgress> onOperationProgressed
|
||||
)
|
||||
{
|
||||
// var doc = _contextStack.Current.Document;
|
||||
@@ -62,7 +64,7 @@ public class RhinoInstanceBaker : IInstanceBaker<List<string>>
|
||||
var consumedObjectIds = new List<string>();
|
||||
foreach (var (layerCollection, instanceOrDefinition) in sortedInstanceComponents)
|
||||
{
|
||||
onOperationProgressed?.Invoke("Converting blocks", (double)++count / sortedInstanceComponents.Count);
|
||||
onOperationProgressed.Report(new("Converting blocks", (double)++count / sortedInstanceComponents.Count));
|
||||
try
|
||||
{
|
||||
if (instanceOrDefinition is InstanceDefinitionProxy definitionProxy)
|
||||
@@ -154,6 +156,7 @@ public class RhinoInstanceBaker : IInstanceBaker<List<string>>
|
||||
}
|
||||
}
|
||||
|
||||
await Task.Yield();
|
||||
return new(createdObjectIds, consumedObjectIds, conversionResults);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,8 +46,7 @@ public class RhinoLayerBaker : TraversalContextUnpacker
|
||||
|
||||
var currentLayerName = baseLayerName;
|
||||
var currentDocument = RhinoDoc.ActiveDoc; // POC: too much effort right now to wrap around the interfaced layers
|
||||
Layer previousLayer = currentDocument.Layers.FindName(currentLayerName);
|
||||
|
||||
Layer? previousLayer = currentDocument.Layers.FindName(currentLayerName);
|
||||
foreach (Collection collection in collectionPath)
|
||||
{
|
||||
currentLayerName += Layer.PathSeparator + collection.name;
|
||||
@@ -59,7 +58,7 @@ public class RhinoLayerBaker : TraversalContextUnpacker
|
||||
}
|
||||
|
||||
var cleanNewLayerName = collection.name.Replace("{", "").Replace("}", "");
|
||||
Layer newLayer = new() { Name = cleanNewLayerName, ParentLayerId = previousLayer.Id };
|
||||
Layer newLayer = new() { Name = cleanNewLayerName, ParentLayerId = previousLayer?.Id ?? Guid.Empty };
|
||||
|
||||
// set material
|
||||
if (
|
||||
|
||||
@@ -4,7 +4,7 @@ using Speckle.Converters.Common;
|
||||
using Speckle.Converters.Rhino;
|
||||
using Speckle.Objects.Other;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
using Speckle.Sdk.Common.Exceptions;
|
||||
using Material = Rhino.DocObjects.Material;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.HostApp;
|
||||
|
||||
+48
-22
@@ -3,6 +3,7 @@ using Rhino.DocObjects;
|
||||
using Rhino.Geometry;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Operations.Receive;
|
||||
using Speckle.Connectors.Rhino.HostApp;
|
||||
using Speckle.Converters.Common;
|
||||
@@ -53,11 +54,11 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
|
||||
_activityFactory = activityFactory;
|
||||
}
|
||||
|
||||
public Task<HostObjectBuilderResult> Build(
|
||||
public async Task<HostObjectBuilderResult> Build(
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
Action<string, double?>? onOperationProgressed,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
@@ -89,7 +90,7 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
|
||||
}
|
||||
|
||||
// 3 - Bake materials and colors, as they are used later down the line by layers and objects
|
||||
onOperationProgressed?.Invoke("Converting materials and colors", null);
|
||||
onOperationProgressed.Report(new("Converting materials and colors", null));
|
||||
if (unpackedRoot.RenderMaterialProxies != null)
|
||||
{
|
||||
using var _ = _activityFactory.Start("Render Materials");
|
||||
@@ -103,7 +104,7 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
|
||||
|
||||
// 4 - Bake layers
|
||||
// See [CNX-325: Rhino: Change receive operation order to increase performance](https://linear.app/speckle/issue/CNX-325/rhino-change-receive-operation-order-to-increase-performance)
|
||||
onOperationProgressed?.Invoke("Baking layers (redraw disabled)", null);
|
||||
onOperationProgressed.Report(new("Baking layers (redraw disabled)", null));
|
||||
using (var _ = _activityFactory.Start("Pre baking layers"))
|
||||
{
|
||||
using var layerNoDraw = new DisableRedrawScope(_converterSettings.Current.Document.Views);
|
||||
@@ -125,12 +126,16 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
|
||||
{
|
||||
using (var convertActivity = _activityFactory.Start("Converting object"))
|
||||
{
|
||||
onOperationProgressed?.Invoke("Converting objects", (double)++count / atomicObjects.Count);
|
||||
onOperationProgressed.Report(new("Converting objects", (double)++count / atomicObjects.Count));
|
||||
try
|
||||
{
|
||||
// 1: get pre-created layer from cache in layer baker
|
||||
// 0: get pre-created layer from cache in layer baker
|
||||
int layerIndex = _layerBaker.GetAndCreateLayerFromPath(path, baseLayerName);
|
||||
|
||||
// 1: create object attributes for baking
|
||||
string name = obj["name"] as string ?? "";
|
||||
using ObjectAttributes atts = new() { LayerIndex = layerIndex, Name = name };
|
||||
|
||||
// 2: convert
|
||||
var result = _converter.Convert(obj);
|
||||
|
||||
@@ -138,18 +143,30 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
|
||||
var conversionIds = new List<string>();
|
||||
if (result is GeometryBase geometryBase)
|
||||
{
|
||||
var guid = BakeObject(geometryBase, obj, layerIndex);
|
||||
var guid = BakeObject(geometryBase, obj, atts);
|
||||
conversionIds.Add(guid.ToString());
|
||||
}
|
||||
else if (result is IEnumerable<(object, Base)> fallbackConversionResult)
|
||||
else if (result is List<GeometryBase> geometryBases) // one to many raw encoding case
|
||||
{
|
||||
var guids = BakeObjectsAsGroup(fallbackConversionResult, obj, layerIndex, baseLayerName);
|
||||
// NOTE: I'm unhappy about this case (dim). It's needed as the raw encoder approach can hypothetically return
|
||||
// multiple "geometry bases" - but this is not a fallback conversion.
|
||||
// EXTRA NOTE: Oguzhan says i shouldn't be unhappy about this - it's a legitimate case
|
||||
// EXTRA EXTRA NOTE: TY Ogu, i am no longer than unhappy about it. It's legit "mess".
|
||||
foreach (var gb in geometryBases)
|
||||
{
|
||||
var guid = BakeObject(gb, obj, atts);
|
||||
conversionIds.Add(guid.ToString());
|
||||
}
|
||||
}
|
||||
else if (result is IEnumerable<(object, Base)> fallbackConversionResult) // one to many fallback conversion
|
||||
{
|
||||
var guids = BakeObjectsAsFallbackGroup(fallbackConversionResult, obj, atts, baseLayerName);
|
||||
conversionIds.AddRange(guids.Select(id => id.ToString()));
|
||||
}
|
||||
|
||||
if (conversionIds.Count == 0)
|
||||
{
|
||||
throw new SpeckleConversionException($"Failed to convert object.");
|
||||
throw new SpeckleException($"Failed to convert object.");
|
||||
}
|
||||
|
||||
// 4: log
|
||||
@@ -183,12 +200,9 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
|
||||
// 6 - Convert instances
|
||||
using (var _ = _activityFactory.Start("Converting instances"))
|
||||
{
|
||||
var (createdInstanceIds, consumedObjectIds, instanceConversionResults) = _instanceBaker.BakeInstances(
|
||||
instanceComponentsWithPath,
|
||||
applicationIdMap,
|
||||
baseLayerName,
|
||||
onOperationProgressed
|
||||
);
|
||||
var (createdInstanceIds, consumedObjectIds, instanceConversionResults) = await _instanceBaker
|
||||
.BakeInstances(instanceComponentsWithPath, applicationIdMap, baseLayerName, onOperationProgressed)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
bakedObjectIds.RemoveAll(id => consumedObjectIds.Contains(id)); // remove all objects that have been "consumed"
|
||||
bakedObjectIds.AddRange(createdInstanceIds); // add instance ids
|
||||
@@ -204,7 +218,7 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
|
||||
|
||||
_converterSettings.Current.Document.Views.Redraw();
|
||||
|
||||
return Task.FromResult(new HostObjectBuilderResult(bakedObjectIds, conversionResults));
|
||||
return new HostObjectBuilderResult(bakedObjectIds, conversionResults);
|
||||
}
|
||||
|
||||
private void PreReceiveDeepClean(string baseLayerName)
|
||||
@@ -243,9 +257,19 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
|
||||
_groupBaker.PurgeGroups(baseLayerName);
|
||||
}
|
||||
|
||||
private Guid BakeObject(GeometryBase obj, Base originalObject, int layerIndex)
|
||||
/// <summary>
|
||||
/// Bakes an object to the document.
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <param name="originalObject"></param>
|
||||
/// <param name="atts"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// Material and Color attributes are processed here due to those properties existing sometimes on fallback geometry (instead of parent).
|
||||
/// and this method is called by <see cref="BakeObjectsAsFallbackGroup(IEnumerable{ValueTuple{object, Base}}, Base, ObjectAttributes, string)"/>
|
||||
/// </remarks>
|
||||
private Guid BakeObject(GeometryBase obj, Base originalObject, ObjectAttributes atts)
|
||||
{
|
||||
ObjectAttributes atts = new() { LayerIndex = layerIndex };
|
||||
var objectId = originalObject.applicationId ?? originalObject.id;
|
||||
|
||||
if (_materialBaker.ObjectIdAndMaterialIndexMap.TryGetValue(objectId, out int mIndex))
|
||||
@@ -263,10 +287,10 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
|
||||
return _converterSettings.Current.Document.Objects.Add(obj, atts);
|
||||
}
|
||||
|
||||
private List<Guid> BakeObjectsAsGroup(
|
||||
private List<Guid> BakeObjectsAsFallbackGroup(
|
||||
IEnumerable<(object, Base)> fallbackConversionResult,
|
||||
Base originatingObject,
|
||||
int layerIndex,
|
||||
ObjectAttributes atts,
|
||||
string baseLayerName
|
||||
)
|
||||
{
|
||||
@@ -279,7 +303,7 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
|
||||
continue;
|
||||
}
|
||||
|
||||
var id = BakeObject(geometryBase, originalBaseObject, layerIndex);
|
||||
var id = BakeObject(geometryBase, originalBaseObject, atts);
|
||||
objectIds.Add(id);
|
||||
}
|
||||
|
||||
@@ -287,7 +311,9 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
|
||||
$@"{originatingObject.speckle_type.Split('.').Last()} - {originatingObject.applicationId ?? originatingObject.id} ({baseLayerName})",
|
||||
objectIds
|
||||
);
|
||||
|
||||
var group = _converterSettings.Current.Document.Groups.FindIndex(groupIndex);
|
||||
|
||||
objectIds.Insert(0, group.Id);
|
||||
return objectIds;
|
||||
}
|
||||
|
||||
+8
-12
@@ -60,18 +60,11 @@ public class RhinoRootObjectBuilder : IRootObjectBuilder<RhinoObject>
|
||||
_activityFactory = activityFactory;
|
||||
}
|
||||
|
||||
public Task<RootObjectBuilderResult> Build(
|
||||
public async Task<RootObjectBuilderResult> Build(
|
||||
IReadOnlyList<RhinoObject> rhinoObjects,
|
||||
SendInfo sendInfo,
|
||||
Action<string, double?>? onOperationProgressed = null,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken = default
|
||||
) => Task.FromResult(BuildSync(rhinoObjects, sendInfo, onOperationProgressed, cancellationToken));
|
||||
|
||||
private RootObjectBuilderResult BuildSync(
|
||||
IReadOnlyList<RhinoObject> rhinoObjects,
|
||||
SendInfo sendInfo,
|
||||
Action<string, double?>? onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
using var activity = _activityFactory.Start("Build");
|
||||
@@ -114,7 +107,7 @@ public class RhinoRootObjectBuilder : IRootObjectBuilder<RhinoObject>
|
||||
results.Add(result);
|
||||
|
||||
++count;
|
||||
onOperationProgressed?.Invoke("Converting", (double)count / atomicObjects.Count);
|
||||
onOperationProgressed.Report(new("Converting", (double)count / atomicObjects.Count));
|
||||
|
||||
// NOTE: useful for testing ui states, pls keep for now so we can easily uncomment
|
||||
// Thread.Sleep(550);
|
||||
@@ -123,18 +116,21 @@ public class RhinoRootObjectBuilder : IRootObjectBuilder<RhinoObject>
|
||||
|
||||
if (results.All(x => x.Status == Status.ERROR))
|
||||
{
|
||||
throw new SpeckleConversionException("Failed to convert all objects."); // fail fast instead creating empty commit! It will appear as model card error with red color.
|
||||
throw new SpeckleException("Failed to convert all objects."); // fail fast instead creating empty commit! It will appear as model card error with red color.
|
||||
}
|
||||
|
||||
using (var _ = _activityFactory.Start("UnpackRenderMaterials"))
|
||||
{
|
||||
// 4 - Unpack the render material proxies
|
||||
rootObjectCollection[ProxyKeys.RENDER_MATERIAL] = _materialUnpacker.UnpackRenderMaterial(atomicObjects);
|
||||
|
||||
}
|
||||
using (var _ = _activityFactory.Start("UnpackColors"))
|
||||
{
|
||||
// 5 - Unpack the color proxies
|
||||
rootObjectCollection[ProxyKeys.COLOR] = _colorUnpacker.UnpackColors(atomicObjects, versionLayers.ToList());
|
||||
}
|
||||
|
||||
await Task.Yield();
|
||||
return new RootObjectBuilderResult(rootObjectCollection, results);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Rhino;
|
||||
using Speckle.Connectors.Rhino.HostApp;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.Rhino.Plugin;
|
||||
using Speckle.InterfaceGenerator;
|
||||
|
||||
@@ -8,9 +8,9 @@ namespace Speckle.Connectors.Rhino.DependencyInjection;
|
||||
[GenerateAutoInterface]
|
||||
public class RhinoPlugin : IRhinoPlugin
|
||||
{
|
||||
private readonly IRhinoIdleManager _idleManager;
|
||||
private readonly IAppIdleManager _idleManager;
|
||||
|
||||
public RhinoPlugin(IRhinoIdleManager idleManager)
|
||||
public RhinoPlugin(IAppIdleManager idleManager)
|
||||
{
|
||||
_idleManager = idleManager;
|
||||
}
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ public class SpeckleConnectorsRhinoPlugin : PlugIn
|
||||
services.AddRhino();
|
||||
services.AddRhinoConverters();
|
||||
|
||||
// but the Rhino connector has `.rhp` as it's extension.
|
||||
// but the Rhino connector has `.rhp` as it is extension.
|
||||
Container = services.BuildServiceProvider();
|
||||
Container.UseDUI();
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ using Speckle.Connectors.Common.Instances;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
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;
|
||||
@@ -41,7 +42,7 @@ public static class ServiceRegistration
|
||||
// Register other connector specific types
|
||||
serviceCollection.AddSingleton<IRhinoPlugin, RhinoPlugin>();
|
||||
serviceCollection.AddSingleton<DocumentModelStore, RhinoDocumentStore>();
|
||||
serviceCollection.AddSingleton<IRhinoIdleManager, RhinoIdleManager>();
|
||||
serviceCollection.AddSingleton<IAppIdleManager, RhinoIdleManager>();
|
||||
|
||||
// Register bindings
|
||||
serviceCollection.AddSingleton<IBinding, TestBinding>();
|
||||
|
||||
-1
@@ -25,7 +25,6 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Extensions\BoundingBox.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SpeckleApplicationIdExtensions.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Extensions\RhinoUnitsExtension.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Filters\RhinoEverythingFilter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Filters\RhinoSelectionFilter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\RhinoColorBaker.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\RhinoColorUnpacker.cs" />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
@@ -34,15 +34,15 @@ public class TeklaBasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
public DocumentModelStore GetDocumentState() => _store;
|
||||
|
||||
public void AddModel(ModelCard model) => throw new NotImplementedException();
|
||||
public void AddModel(ModelCard model) => _store.Models.Add(model);
|
||||
|
||||
public void UpdateModel(ModelCard model) => throw new NotImplementedException();
|
||||
public void UpdateModel(ModelCard model) => _store.UpdateModel(model);
|
||||
|
||||
public void RemoveModel(ModelCard model) => throw new NotImplementedException();
|
||||
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
|
||||
|
||||
public void HighlightModel(string modelCardId) => throw new NotImplementedException();
|
||||
public Task HighlightModel(string modelCardId) => throw new NotImplementedException();
|
||||
|
||||
public void HighlightObjects(List<string> objectIds) => throw new NotImplementedException();
|
||||
public Task HighlightObjects(IReadOnlyList<string> objectIds) => throw new NotImplementedException();
|
||||
|
||||
public BasicConnectorBindingCommands Commands { get; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Tekla.Structures.Model;
|
||||
|
||||
namespace Speckle.Connector.Tekla2024.Bindings;
|
||||
|
||||
public class TeklaSelectionBinding : ISelectionBinding
|
||||
{
|
||||
private readonly IAppIdleManager _idleManager;
|
||||
private const string SELECTION_EVENT = "setSelection";
|
||||
private readonly Tekla.Structures.Model.Events _events;
|
||||
private readonly object _selectionEventHandlerLock = new object();
|
||||
private readonly Tekla.Structures.Model.UI.ModelObjectSelector _selector;
|
||||
|
||||
public string Name => "selectionBinding";
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
public TeklaSelectionBinding(
|
||||
IAppIdleManager idleManager,
|
||||
IBrowserBridge parent,
|
||||
Events events,
|
||||
Tekla.Structures.Model.UI.ModelObjectSelector selector
|
||||
)
|
||||
{
|
||||
_idleManager = idleManager;
|
||||
Parent = parent;
|
||||
_events = events;
|
||||
_selector = selector;
|
||||
|
||||
_events.SelectionChange += Events_SelectionChangeEvent;
|
||||
_events.Register();
|
||||
|
||||
UpdateSelection();
|
||||
}
|
||||
|
||||
private void Events_SelectionChangeEvent()
|
||||
{
|
||||
lock (_selectionEventHandlerLock)
|
||||
{
|
||||
_idleManager.SubscribeToIdle(nameof(TeklaSelectionBinding), UpdateSelection);
|
||||
UpdateSelection();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSelection()
|
||||
{
|
||||
SelectionInfo selInfo = GetSelection();
|
||||
Parent.Send(SELECTION_EVENT, selInfo);
|
||||
}
|
||||
|
||||
public SelectionInfo GetSelection()
|
||||
{
|
||||
ModelObjectEnumerator selectedObjects = _selector.GetSelectedObjects();
|
||||
List<string> objectIds = new List<string>();
|
||||
List<string> objectTypes = new List<string>();
|
||||
|
||||
while (selectedObjects.MoveNext())
|
||||
{
|
||||
ModelObject modelObject = selectedObjects.Current;
|
||||
string globalId = modelObject.Identifier.GUID.ToString();
|
||||
objectIds.Add(globalId);
|
||||
objectTypes.Add(modelObject.GetType().Name);
|
||||
}
|
||||
|
||||
string typesString = string.Join(", ", objectTypes.Distinct());
|
||||
|
||||
return new SelectionInfo(
|
||||
objectIds,
|
||||
objectIds.Count == 0 ? "No objects selected." : $"{objectIds.Count} objects ({typesString})"
|
||||
);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user