Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6c74f55679 | |||
| 7eb1de4709 | |||
| e52df074a1 | |||
| 9846817c7f | |||
| c9ca1c0a25 | |||
| fd2dd9a165 | |||
| 83efebfed9 | |||
| 00669ea3c5 | |||
| f02bf2630a | |||
| db4d2f7eb0 | |||
| b9d2f376d6 | |||
| 49baeae780 | |||
| d76865e621 | |||
| bedf363810 | |||
| 48670c4030 | |||
| ba0cdd307f | |||
| 2a508e6302 | |||
| 9d70579c40 | |||
| e4ac573631 | |||
| 11327cf544 | |||
| 029e10b661 | |||
| c1c8b645e0 | |||
| 49ef7d1353 | |||
| 745886e9dd | |||
| 825945a547 | |||
| e9556170f5 | |||
| 87ffe5b5f8 | |||
| 9466d8b883 | |||
| 25e37e257e | |||
| 165c0c9f0d | |||
| 98cfebf5bc | |||
| 1d910bfc45 | |||
| 94104c2365 | |||
| c5d37a1250 | |||
| 5812e1c976 | |||
| 01bc8bf929 | |||
| dbefb1b290 | |||
| b5b9d061ef | |||
| 20e08bba76 | |||
| 23710ee3fb | |||
| 9b5cc21aa4 | |||
| 1016c9b82b | |||
| c6b9651d08 | |||
| 73302f101a | |||
| 516b4d785f | |||
| a9850c2eec | |||
| 64c5503637 | |||
| d15ea4310a | |||
| 9fa3ef83e5 | |||
| 724e8fe029 | |||
| 3ea5677497 | |||
| a1e3e509fd | |||
| 95b3731df2 | |||
| dcc29f3461 | |||
| 13740de72f | |||
| f2f11c3f2b |
@@ -254,6 +254,9 @@ dotnet_diagnostic.ca1508.severity = warning # Avoid dead conditional code
|
||||
dotnet_diagnostic.ca1509.severity = warning # Invalid entry in code metrics configuration file
|
||||
dotnet_diagnostic.ca1861.severity = none # Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1861)
|
||||
|
||||
# CA2007: Consider calling ConfigureAwait on the awaited task (this is not needed for application code, in fact we don't want to call anything but ConfigureAwait(true) which is the default)
|
||||
dotnet_diagnostic.CA2007.severity = none
|
||||
|
||||
dotnet_diagnostic.cs8618.severity = suggestion # nullable problem
|
||||
|
||||
|
||||
|
||||
@@ -46,7 +46,10 @@ jobs:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
||||
|
||||
- name: ⚒️ Run build
|
||||
- name: ⚒️ Run Build on Linux
|
||||
run: ./build.sh build-linux
|
||||
|
||||
- name: ⚒️ Run tests
|
||||
run: ./build.sh test-only
|
||||
|
||||
- name: Upload coverage reports to Codecov with GitHub Action
|
||||
|
||||
@@ -6,7 +6,7 @@ on:
|
||||
tags: ["v3.*"] # Manual delivery on every 3.x tag
|
||||
|
||||
jobs:
|
||||
build:
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
outputs:
|
||||
version: ${{ steps.set-version.outputs.version }}
|
||||
@@ -27,10 +27,10 @@ jobs:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
||||
|
||||
- name: ⚒️ Run GitVersion
|
||||
- name: ⚒️ Run GitVersion on Windows
|
||||
run: ./build.ps1 build-server-version
|
||||
|
||||
- name: ⚒️ Run build
|
||||
- name: ⚒️ Run build on Windows
|
||||
run: ./build.ps1
|
||||
|
||||
- name: ⬆️ Upload artifacts
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
|
||||
deploy-installers:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
needs: build-windows
|
||||
env:
|
||||
IS_TAG_BUILD: ${{ github.ref_type == 'tag' }}
|
||||
IS_RELEASE_BRANCH: ${{ startsWith(github.ref_name, 'release/') || github.ref_name == 'main'}}
|
||||
@@ -58,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 }}, "store_artifacts": ${{ env.IS_RELEASE_BRANCH }} }'
|
||||
inputs: '{ "run_id": "${{ github.run_id }}", "version": "${{ needs.build-windows.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
|
||||
@@ -70,11 +70,13 @@ jobs:
|
||||
with:
|
||||
name: output-*
|
||||
|
||||
test:
|
||||
build-linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
@@ -87,11 +89,20 @@ jobs:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
||||
|
||||
- name: ⚒️ Run build
|
||||
- name: ⚒️ Run GitVersion on Linux
|
||||
run: ./build.sh build-server-version
|
||||
|
||||
- name: ⚒️ Run tests on Linux
|
||||
run: ./build.sh test-only
|
||||
|
||||
- name: ⚒️ Run Build and Pack on Linux
|
||||
run: ./build.sh build-linux
|
||||
|
||||
- name: Upload coverage reports to Codecov with GitHub Action
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
file: Converters/**/coverage.xml
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
- name: Push to nuget.org
|
||||
run: dotnet nuget push output/*.nupkg --source "https://api.nuget.org/v3/index.json" --api-key ${{secrets.CONNECTORS_NUGET_TOKEN }} --skip-duplicate
|
||||
|
||||
+2
-2
@@ -28,11 +28,11 @@ public static class Github
|
||||
Content = content
|
||||
};
|
||||
request.Headers.Add("X-GitHub-Api-Version", "2022-11-28");
|
||||
var response = await client.SendAsync(request).ConfigureAwait(false);
|
||||
var response = await client.SendAsync(request);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"{response.StatusCode} {response.ReasonPhrase} {await response.Content.ReadAsStringAsync().ConfigureAwait(false)}"
|
||||
$"{response.StatusCode} {response.ReasonPhrase} {await response.Content.ReadAsStringAsync()}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+24
-1
@@ -7,6 +7,7 @@ using static SimpleExec.Command;
|
||||
const string CLEAN = "clean";
|
||||
const string RESTORE = "restore";
|
||||
const string BUILD = "build";
|
||||
const string BUILD_LINUX = "build-linux";
|
||||
const string TEST = "test";
|
||||
const string TEST_ONLY = "test-only";
|
||||
const string FORMAT = "format";
|
||||
@@ -98,7 +99,7 @@ Target(
|
||||
VERSION,
|
||||
async () =>
|
||||
{
|
||||
var (output, _) = await ReadAsync("dotnet", "minver -v w").ConfigureAwait(false);
|
||||
var (output, _) = await ReadAsync("dotnet", "minver -v w");
|
||||
output = output.Trim();
|
||||
Console.WriteLine($"Version: {output}");
|
||||
Run("echo", $"\"version={output}\" >> $GITHUB_OUTPUT");
|
||||
@@ -183,6 +184,28 @@ Target(
|
||||
}
|
||||
);
|
||||
|
||||
Target(
|
||||
BUILD_LINUX,
|
||||
DependsOn(FORMAT),
|
||||
Glob.Files(".", "**/Speckle.Importers.Ifc.csproj"),
|
||||
file =>
|
||||
{
|
||||
Run("dotnet", $"restore {file} --locked-mode");
|
||||
var version = Environment.GetEnvironmentVariable("GitVersion_FullSemVer") ?? "3.0.0-localBuild";
|
||||
var fileVersion = Environment.GetEnvironmentVariable("GitVersion_AssemblySemFileVer") ?? "3.0.0.0";
|
||||
Console.WriteLine($"Version: {version} & {fileVersion}");
|
||||
Run(
|
||||
"dotnet",
|
||||
$"build {file} -c Release --no-restore -warnaserror -p:Version={version} -p:FileVersion={fileVersion} -v:m"
|
||||
);
|
||||
|
||||
RunAsync(
|
||||
"dotnet",
|
||||
$"pack {file} -c Release -o output --no-build -p:Version={version} -p:FileVersion={fileVersion} -v:m"
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Target(
|
||||
ZIP,
|
||||
DependsOn(TEST),
|
||||
|
||||
@@ -78,17 +78,14 @@ public sealed class ArcGISReceiveBinding : IReceiveBinding
|
||||
modelCard.GetReceiveInfo("ArcGIS"), // POC: get host app name from settings? same for GetSendInfo
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
);
|
||||
|
||||
modelCard.BakedObjectIds = receiveOperationResults.BakedObjectIds.ToList();
|
||||
await Commands
|
||||
.SetModelReceiveResult(
|
||||
modelCardId,
|
||||
receiveOperationResults.BakedObjectIds,
|
||||
receiveOperationResults.ConversionResults
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
await Commands.SetModelReceiveResult(
|
||||
modelCardId,
|
||||
receiveOperationResults.BakedObjectIds,
|
||||
receiveOperationResults.ConversionResults
|
||||
);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -100,7 +97,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);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
await Commands.SetModelError(modelCardId, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,15 +12,18 @@ public class ArcGISSelectionBinding : ISelectionBinding
|
||||
public string Name => "selectionBinding";
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
public ArcGISSelectionBinding(IBrowserBridge parent, MapMembersUtils mapMemberUtils)
|
||||
public ArcGISSelectionBinding(
|
||||
IBrowserBridge parent,
|
||||
MapMembersUtils mapMemberUtils,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
)
|
||||
{
|
||||
_mapMemberUtils = mapMemberUtils;
|
||||
Parent = parent;
|
||||
var topLevelHandler = parent.TopLevelExceptionHandler;
|
||||
|
||||
// example: https://github.com/Esri/arcgis-pro-sdk-community-samples/blob/master/Map-Authoring/QueryBuilderControl/DefinitionQueryDockPaneViewModel.cs
|
||||
// MapViewEventArgs args = new(MapView.Active);
|
||||
TOCSelectionChangedEvent.Subscribe(_ => topLevelHandler.CatchUnhandled(OnSelectionChanged), true);
|
||||
TOCSelectionChangedEvent.Subscribe(_ => topLevelExceptionHandler.CatchUnhandled(OnSelectionChanged), true);
|
||||
}
|
||||
|
||||
private void OnSelectionChanged()
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using ArcGIS.Core.Data;
|
||||
using ArcGIS.Desktop.Core;
|
||||
using ArcGIS.Desktop.Editing.Events;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using ArcGIS.Desktop.Mapping.Events;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -13,8 +12,10 @@ using Speckle.Connectors.ArcGIS.Utils;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Exceptions;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
@@ -44,6 +45,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
private readonly ILogger<ArcGISSendBinding> _logger;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IArcGISConversionSettingsFactory _arcGISConversionSettingsFactory;
|
||||
private readonly IThreadContext _threadContext;
|
||||
|
||||
/// <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:
|
||||
@@ -67,7 +69,10 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<ArcGISSendBinding> logger,
|
||||
IArcGISConversionSettingsFactory arcGisConversionSettingsFactory,
|
||||
MapMembersUtils mapMemberUtils
|
||||
MapMembersUtils mapMemberUtils,
|
||||
IThreadContext threadContext,
|
||||
IEventAggregator eventAggregator,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
@@ -77,31 +82,33 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
_sendConversionCache = sendConversionCache;
|
||||
_operationProgressManager = operationProgressManager;
|
||||
_logger = logger;
|
||||
_topLevelExceptionHandler = parent.TopLevelExceptionHandler;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
_arcGISConversionSettingsFactory = arcGisConversionSettingsFactory;
|
||||
_mapMemberUtils = mapMemberUtils;
|
||||
_threadContext = threadContext;
|
||||
|
||||
Parent = parent;
|
||||
Commands = new SendBindingUICommands(parent);
|
||||
SubscribeToArcGISEvents();
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
{
|
||||
_sendConversionCache.ClearCache();
|
||||
};
|
||||
eventAggregator.GetEvent<DocumentStoreChangedEvent>().Subscribe(OnDocumentStoreChangedEvent);
|
||||
}
|
||||
|
||||
private void OnDocumentStoreChangedEvent(object _) => _sendConversionCache.ClearCache();
|
||||
|
||||
private void SubscribeToArcGISEvents()
|
||||
{
|
||||
LayersRemovedEvent.Subscribe(
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () => await GetIdsForLayersRemovedEvent(a).ConfigureAwait(false)),
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await _threadContext.RunOnWorkerAsync(async () => await GetIdsForLayersRemovedEvent(a))
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
StandaloneTablesRemovedEvent.Subscribe(
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await GetIdsForStandaloneTablesRemovedEvent(a).ConfigureAwait(false)
|
||||
async () => await _threadContext.RunOnWorkerAsync(async () => await GetIdsForStandaloneTablesRemovedEvent(a))
|
||||
),
|
||||
true
|
||||
);
|
||||
@@ -109,7 +116,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
MapPropertyChangedEvent.Subscribe(
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await GetIdsForMapPropertyChangedEvent(a).ConfigureAwait(false)
|
||||
async () => await _threadContext.RunOnWorkerAsync(async () => await GetIdsForMapPropertyChangedEvent(a))
|
||||
),
|
||||
true
|
||||
); // Map units, CRS etc.
|
||||
@@ -117,13 +124,18 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
MapMemberPropertiesChangedEvent.Subscribe(
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await GetIdsForMapMemberPropertiesChangedEvent(a).ConfigureAwait(false)
|
||||
async () =>
|
||||
await _threadContext.RunOnWorkerAsync(async () => await GetIdsForMapMemberPropertiesChangedEvent(a))
|
||||
),
|
||||
true
|
||||
); // e.g. Layer name
|
||||
|
||||
ActiveMapViewChangedEvent.Subscribe(
|
||||
_ => _topLevelExceptionHandler.CatchUnhandled(SubscribeToMapMembersDataSourceChange),
|
||||
_ =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await _threadContext.RunOnWorker(SubscribeToMapMembersDataSourceChange);
|
||||
}),
|
||||
true
|
||||
);
|
||||
|
||||
@@ -139,28 +151,24 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
|
||||
private void SubscribeToMapMembersDataSourceChange()
|
||||
{
|
||||
var task = QueuedTask.Run(() =>
|
||||
if (MapView.Active == null)
|
||||
{
|
||||
if (MapView.Active == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// subscribe to layers
|
||||
foreach (Layer layer in MapView.Active.Map.Layers)
|
||||
// subscribe to layers
|
||||
foreach (Layer layer in MapView.Active.Map.Layers)
|
||||
{
|
||||
if (layer is FeatureLayer featureLayer)
|
||||
{
|
||||
if (layer is FeatureLayer featureLayer)
|
||||
{
|
||||
SubscribeToFeatureLayerDataSourceChange(featureLayer);
|
||||
}
|
||||
SubscribeToFeatureLayerDataSourceChange(featureLayer);
|
||||
}
|
||||
// subscribe to tables
|
||||
foreach (StandaloneTable table in MapView.Active.Map.StandaloneTables)
|
||||
{
|
||||
SubscribeToTableDataSourceChange(table);
|
||||
}
|
||||
});
|
||||
task.Wait();
|
||||
}
|
||||
// subscribe to tables
|
||||
foreach (StandaloneTable table in MapView.Active.Map.StandaloneTables)
|
||||
{
|
||||
SubscribeToTableDataSourceChange(table);
|
||||
}
|
||||
}
|
||||
|
||||
private void SubscribeToFeatureLayerDataSourceChange(FeatureLayer layer)
|
||||
@@ -195,25 +203,25 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
{
|
||||
RowCreatedEvent.Subscribe(
|
||||
(args) =>
|
||||
Parent.TopLevelExceptionHandler.FireAndForget(async () =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await OnRowChanged(args).ConfigureAwait(false);
|
||||
await OnRowChanged(args);
|
||||
}),
|
||||
layerTable
|
||||
);
|
||||
RowChangedEvent.Subscribe(
|
||||
(args) =>
|
||||
Parent.TopLevelExceptionHandler.FireAndForget(async () =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await OnRowChanged(args).ConfigureAwait(false);
|
||||
await OnRowChanged(args);
|
||||
}),
|
||||
layerTable
|
||||
);
|
||||
RowDeletedEvent.Subscribe(
|
||||
(args) =>
|
||||
Parent.TopLevelExceptionHandler.FireAndForget(async () =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await OnRowChanged(args).ConfigureAwait(false);
|
||||
await OnRowChanged(args);
|
||||
}),
|
||||
layerTable
|
||||
);
|
||||
@@ -258,7 +266,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
}
|
||||
}
|
||||
|
||||
await RunExpirationChecks(false).ConfigureAwait(false);
|
||||
await RunExpirationChecks(false);
|
||||
}
|
||||
|
||||
private async Task GetIdsForLayersRemovedEvent(LayerEventsArgs args)
|
||||
@@ -267,7 +275,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
{
|
||||
ChangedObjectIds[layer.URI] = 1;
|
||||
}
|
||||
await RunExpirationChecks(true).ConfigureAwait(false);
|
||||
await RunExpirationChecks(true);
|
||||
}
|
||||
|
||||
private async Task GetIdsForStandaloneTablesRemovedEvent(StandaloneTableEventArgs args)
|
||||
@@ -276,7 +284,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
{
|
||||
ChangedObjectIds[table.URI] = 1;
|
||||
}
|
||||
await RunExpirationChecks(true).ConfigureAwait(false);
|
||||
await RunExpirationChecks(true);
|
||||
}
|
||||
|
||||
private async Task GetIdsForMapPropertyChangedEvent(MapPropertyChangedEventArgs args)
|
||||
@@ -289,7 +297,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
ChangedObjectIds[member.URI] = 1;
|
||||
}
|
||||
}
|
||||
await RunExpirationChecks(false).ConfigureAwait(false);
|
||||
await RunExpirationChecks(false);
|
||||
}
|
||||
|
||||
private void GetIdsForLayersAddedEvent(LayerEventsArgs args)
|
||||
@@ -339,7 +347,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
{
|
||||
ChangedObjectIds[member.URI] = 1;
|
||||
}
|
||||
await RunExpirationChecks(false).ConfigureAwait(false);
|
||||
await RunExpirationChecks(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,64 +374,52 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
|
||||
CancellationToken cancellationToken = _cancellationManager.InitCancellationTokenSource(modelCardId);
|
||||
|
||||
var sendResult = await QueuedTask
|
||||
.Run(async () =>
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
scope
|
||||
.ServiceProvider.GetRequiredService<IConverterSettingsStore<ArcGISConversionSettings>>()
|
||||
.Initialize(
|
||||
_arcGISConversionSettingsFactory.Create(
|
||||
Project.Current,
|
||||
MapView.Active.Map,
|
||||
new CRSoffsetRotation(MapView.Active.Map)
|
||||
)
|
||||
);
|
||||
List<MapMember> mapMembers = modelCard
|
||||
.SendFilter.NotNull()
|
||||
.RefreshObjectIds()
|
||||
.Select(id => (MapMember)MapView.Active.Map.FindLayer(id) ?? MapView.Active.Map.FindStandaloneTable(id))
|
||||
.Where(obj => obj != null)
|
||||
.ToList();
|
||||
|
||||
if (mapMembers.Count == 0)
|
||||
{
|
||||
// Handle as CARD ERROR in this function
|
||||
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
|
||||
}
|
||||
|
||||
// subscribe to the selected layer events
|
||||
foreach (MapMember mapMember in mapMembers)
|
||||
{
|
||||
if (mapMember is FeatureLayer featureLayer)
|
||||
{
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
scope
|
||||
.ServiceProvider.GetRequiredService<IConverterSettingsStore<ArcGISConversionSettings>>()
|
||||
.Initialize(
|
||||
_arcGISConversionSettingsFactory.Create(
|
||||
Project.Current,
|
||||
MapView.Active.Map,
|
||||
new CRSoffsetRotation(MapView.Active.Map)
|
||||
)
|
||||
);
|
||||
List<MapMember> mapMembers = modelCard
|
||||
.SendFilter.NotNull()
|
||||
.RefreshObjectIds()
|
||||
.Select(id => (MapMember)MapView.Active.Map.FindLayer(id) ?? MapView.Active.Map.FindStandaloneTable(id))
|
||||
.Where(obj => obj != null)
|
||||
.ToList();
|
||||
SubscribeToFeatureLayerDataSourceChange(featureLayer);
|
||||
}
|
||||
else if (mapMember is StandaloneTable table)
|
||||
{
|
||||
SubscribeToTableDataSourceChange(table);
|
||||
}
|
||||
}
|
||||
|
||||
if (mapMembers.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<MapMember>>()
|
||||
.Execute(
|
||||
mapMembers,
|
||||
modelCard.GetSendInfo("ArcGIS"), // POC: get host app name from settings? same for GetReceiveInfo
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
// subscribe to the selected layer events
|
||||
foreach (MapMember mapMember in mapMembers)
|
||||
{
|
||||
if (mapMember is FeatureLayer featureLayer)
|
||||
{
|
||||
SubscribeToFeatureLayerDataSourceChange(featureLayer);
|
||||
}
|
||||
else if (mapMember is StandaloneTable table)
|
||||
{
|
||||
SubscribeToTableDataSourceChange(table);
|
||||
}
|
||||
}
|
||||
|
||||
var result = await scope
|
||||
.ServiceProvider.GetRequiredService<SendOperation<MapMember>>()
|
||||
.Execute(
|
||||
mapMembers,
|
||||
modelCard.GetSendInfo("ArcGIS"), // POC: get host app name from settings? same for GetReceiveInfo
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return result;
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
|
||||
await Commands
|
||||
.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults)
|
||||
.ConfigureAwait(false);
|
||||
await Commands.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -435,7 +431,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);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
await Commands.SetModelError(modelCardId, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,7 +466,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
}
|
||||
}
|
||||
|
||||
await Commands.SetModelsExpired(expiredSenderIds).ConfigureAwait(false);
|
||||
await Commands.SetModelsExpired(expiredSenderIds);
|
||||
ChangedObjectIds = new();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using ArcGIS.Core.Data;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using Speckle.Connectors.ArcGIS.Utils;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Sdk;
|
||||
@@ -22,20 +22,23 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
|
||||
public BasicConnectorBinding(DocumentModelStore store, IBrowserBridge parent, ISpeckleApplication speckleApplication)
|
||||
public BasicConnectorBinding(
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
ISpeckleApplication speckleApplication,
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
_speckleApplication = speckleApplication;
|
||||
Parent = parent;
|
||||
Commands = new BasicConnectorBindingCommands(parent);
|
||||
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
parent.TopLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await Commands.NotifyDocumentChanged().ConfigureAwait(false);
|
||||
});
|
||||
eventAggregator.GetEvent<DocumentStoreChangedEvent>().Subscribe(OnDocumentStoreChangedEvent);
|
||||
}
|
||||
|
||||
private async Task OnDocumentStoreChangedEvent(object _) => await Commands.NotifyDocumentChanged();
|
||||
|
||||
public string GetSourceApplicationName() => _speckleApplication.Slug;
|
||||
|
||||
public string GetSourceApplicationVersion() => _speckleApplication.HostApplicationVersion;
|
||||
@@ -60,16 +63,19 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
|
||||
|
||||
public async Task HighlightObjects(IReadOnlyList<string> objectIds) =>
|
||||
await HighlightObjectsOnView(objectIds.Select(x => new ObjectID(x)).ToList()).ConfigureAwait(false);
|
||||
public Task HighlightObjects(IReadOnlyList<string> objectIds)
|
||||
{
|
||||
HighlightObjectsOnView(objectIds.Select(x => new ObjectID(x)).ToList());
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task HighlightModel(string modelCardId)
|
||||
public Task HighlightModel(string modelCardId)
|
||||
{
|
||||
var model = _store.GetModelById(modelCardId);
|
||||
|
||||
if (model is null)
|
||||
{
|
||||
return;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
var objectIds = new List<ObjectID>();
|
||||
@@ -86,26 +92,22 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
if (objectIds is null)
|
||||
{
|
||||
return;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
await HighlightObjectsOnView(objectIds).ConfigureAwait(false);
|
||||
HighlightObjectsOnView(objectIds);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task HighlightObjectsOnView(IReadOnlyList<ObjectID> objectIds)
|
||||
private void HighlightObjectsOnView(IReadOnlyList<ObjectID> objectIds)
|
||||
{
|
||||
MapView mapView = MapView.Active;
|
||||
|
||||
await QueuedTask
|
||||
.Run(async () =>
|
||||
{
|
||||
List<MapMemberFeature> mapMembersFeatures = GetMapMembers(objectIds, mapView);
|
||||
ClearSelectionInTOC();
|
||||
ClearSelection();
|
||||
await SelectMapMembersInTOC(mapMembersFeatures).ConfigureAwait(false);
|
||||
SelectMapMembersAndFeatures(mapMembersFeatures);
|
||||
mapView.ZoomToSelected();
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
List<MapMemberFeature> mapMembersFeatures = GetMapMembers(objectIds, mapView);
|
||||
ClearSelectionInTOC();
|
||||
ClearSelection();
|
||||
SelectMapMembersInTOC(mapMembersFeatures);
|
||||
SelectMapMembersAndFeatures(mapMembersFeatures);
|
||||
mapView.ZoomToSelected();
|
||||
}
|
||||
|
||||
private List<MapMemberFeature> GetMapMembers(IReadOnlyList<ObjectID> objectIds, MapView mapView)
|
||||
@@ -171,7 +173,7 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SelectMapMembersInTOC(IReadOnlyList<MapMemberFeature> mapMembersFeatures)
|
||||
private void SelectMapMembersInTOC(IReadOnlyList<MapMemberFeature> mapMembersFeatures)
|
||||
{
|
||||
List<Layer> layers = new();
|
||||
List<StandaloneTable> tables = new();
|
||||
@@ -187,7 +189,7 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
}
|
||||
else
|
||||
{
|
||||
await QueuedTask.Run(() => layer.SetExpanded(true)).ConfigureAwait(false);
|
||||
layer.SetExpanded(true);
|
||||
}
|
||||
}
|
||||
else if (member is StandaloneTable table)
|
||||
|
||||
+1
-2
@@ -27,7 +27,7 @@ public static class ArcGISConnectorModule
|
||||
public static void AddArcGIS(this IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddConnectorUtils();
|
||||
serviceCollection.AddDUI<ArcGISDocumentStore>();
|
||||
serviceCollection.AddDUI<ArcGISThreadContext, ArcGISDocumentStore>();
|
||||
serviceCollection.AddDUIView();
|
||||
|
||||
// Register bindings
|
||||
@@ -37,7 +37,6 @@ public static class ArcGISConnectorModule
|
||||
serviceCollection.AddSingleton<IBinding>(sp => sp.GetRequiredService<IBasicConnectorBinding>());
|
||||
serviceCollection.AddSingleton<IBasicConnectorBinding, BasicConnectorBinding>();
|
||||
|
||||
serviceCollection.RegisterTopLevelExceptionHandler();
|
||||
serviceCollection.AddSingleton(DefaultTraversal.CreateTraversalFunc());
|
||||
|
||||
// register send operation and dependencies
|
||||
|
||||
@@ -25,7 +25,7 @@ public class ArcGISColorManager
|
||||
/// </summary>
|
||||
/// <param name="colorProxies"></param>
|
||||
/// <param name="onOperationProgressed"></param>
|
||||
public async Task ParseColors(List<ColorProxy> colorProxies, IProgress<CardProgress> onOperationProgressed)
|
||||
public void ParseColors(List<ColorProxy> colorProxies, IProgress<CardProgress> onOperationProgressed)
|
||||
{
|
||||
// injected as Singleton, so we need to clean existing proxies first
|
||||
ObjectColorsIdMap = new();
|
||||
@@ -33,7 +33,6 @@ public class ArcGISColorManager
|
||||
foreach (ColorProxy colorProxy in colorProxies)
|
||||
{
|
||||
onOperationProgressed.Report(new("Converting colors", (double)++count / colorProxies.Count));
|
||||
await Task.Yield();
|
||||
foreach (string objectId in colorProxy.objects)
|
||||
{
|
||||
Color convertedColor = Color.FromArgb(colorProxy.value);
|
||||
@@ -47,10 +46,7 @@ public class ArcGISColorManager
|
||||
/// </summary>
|
||||
/// <param name="materialProxies"></param>
|
||||
/// <param name="onOperationProgressed"></param>
|
||||
public async Task ParseMaterials(
|
||||
List<RenderMaterialProxy> materialProxies,
|
||||
IProgress<CardProgress> onOperationProgressed
|
||||
)
|
||||
public void ParseMaterials(List<RenderMaterialProxy> materialProxies, IProgress<CardProgress> onOperationProgressed)
|
||||
{
|
||||
// injected as Singleton, so we need to clean existing proxies first
|
||||
ObjectMaterialsIdMap = new();
|
||||
@@ -58,7 +54,6 @@ public class ArcGISColorManager
|
||||
foreach (RenderMaterialProxy colorProxy in materialProxies)
|
||||
{
|
||||
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);
|
||||
|
||||
@@ -18,7 +18,7 @@ public class ArcGISLayerUnpacker
|
||||
/// <param name="parentCollection"></param>
|
||||
/// <returns>List of layers containing objects.</returns>
|
||||
/// <exception cref="AC.CalledOnWrongThreadException">Thrown when this method is *not* called on the MCT, because this method accesses mapmember fields</exception>
|
||||
public async Task<List<ADM.MapMember>> UnpackSelectionAsync(
|
||||
public List<ADM.MapMember> UnpackSelection(
|
||||
IEnumerable<ADM.MapMember> mapMembers,
|
||||
Collection parentCollection,
|
||||
List<ADM.MapMember>? objects = null
|
||||
@@ -37,7 +37,7 @@ public class ArcGISLayerUnpacker
|
||||
Collection containerCollection = CreateAndCacheMapMemberCollection(mapMember, true);
|
||||
parentCollection.elements.Add(containerCollection);
|
||||
|
||||
await UnpackSelectionAsync(container.Layers, containerCollection, objects).ConfigureAwait(false);
|
||||
UnpackSelection(container.Layers, containerCollection, objects);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
+71
-90
@@ -1,7 +1,6 @@
|
||||
using System.Diagnostics.Contracts;
|
||||
using ArcGIS.Core.CIM;
|
||||
using ArcGIS.Core.Geometry;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using Speckle.Connectors.ArcGIS.HostApp;
|
||||
using Speckle.Connectors.ArcGIS.Utils;
|
||||
@@ -54,7 +53,7 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
_colorManager = colorManager;
|
||||
}
|
||||
|
||||
public async Task<HostObjectBuilderResult> Build(
|
||||
public HostObjectBuilderResult Build(
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
@@ -74,14 +73,14 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
.ToList();
|
||||
if (materials != null)
|
||||
{
|
||||
await _colorManager.ParseMaterials(materials, onOperationProgressed).ConfigureAwait(false);
|
||||
_colorManager.ParseMaterials(materials, onOperationProgressed);
|
||||
}
|
||||
|
||||
// get colors
|
||||
List<ColorProxy>? colors = (rootObject[ProxyKeys.COLOR] as List<object>)?.Cast<ColorProxy>().ToList();
|
||||
if (colors != null)
|
||||
{
|
||||
await _colorManager.ParseColors(colors, onOperationProgressed).ConfigureAwait(false);
|
||||
_colorManager.ParseColors(colors, onOperationProgressed);
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
@@ -100,7 +99,7 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
try
|
||||
{
|
||||
obj = _localToGlobalConverterUtils.TransformObjects(objectToConvert.AtomicObject, objectToConvert.Matrix);
|
||||
object? conversionResult = await QueuedTask.Run(() => _converter.Convert(obj)).ConfigureAwait(false);
|
||||
object conversionResult = _converter.Convert(obj);
|
||||
|
||||
string nestedLayerPath = $"{string.Join("\\", path)}";
|
||||
|
||||
@@ -128,29 +127,20 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
|
||||
// 2.1. Group conversionTrackers (to write into datasets)
|
||||
onOperationProgressed.Report(new("Grouping features into layers", null));
|
||||
Dictionary<string, List<(TraversalContext, ObjectConversionTracker)>> convertedGroups = await QueuedTask
|
||||
.Run(async () =>
|
||||
{
|
||||
return await _featureClassUtils
|
||||
.GroupConversionTrackers(conversionTracker, (s, progres) => onOperationProgressed.Report(new(s, progres)))
|
||||
.ConfigureAwait(false);
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
Dictionary<string, List<(TraversalContext, ObjectConversionTracker)>> convertedGroups =
|
||||
_featureClassUtils.GroupConversionTrackers(
|
||||
conversionTracker,
|
||||
(s, progres) => onOperationProgressed.Report(new(s, progres))
|
||||
);
|
||||
|
||||
// 2.2. Write groups of objects to Datasets
|
||||
onOperationProgressed.Report(new("Writing to Database", null));
|
||||
await QueuedTask
|
||||
.Run(async () =>
|
||||
{
|
||||
await _featureClassUtils
|
||||
.CreateDatasets(
|
||||
conversionTracker,
|
||||
convertedGroups,
|
||||
(s, progres) => onOperationProgressed.Report(new(s, progres))
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
|
||||
_featureClassUtils.CreateDatasets(
|
||||
conversionTracker,
|
||||
convertedGroups,
|
||||
(s, progres) => onOperationProgressed.Report(new(s, progres))
|
||||
);
|
||||
|
||||
// 3. add layer and tables to the Map and Table Of Content
|
||||
|
||||
@@ -202,8 +192,7 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
else
|
||||
{
|
||||
// no layer yet, create and add layer to Map
|
||||
MapMember mapMember = await AddDatasetsToMap(trackerItem, createdLayerGroups, projectName, modelName)
|
||||
.ConfigureAwait(false);
|
||||
MapMember mapMember = AddDatasetsToMap(trackerItem, createdLayerGroups, projectName, modelName);
|
||||
|
||||
// add layer and layer URI to tracker
|
||||
trackerItem.AddConvertedMapMember(mapMember);
|
||||
@@ -231,7 +220,7 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
if (bakedMember.Value.Item1 is FeatureLayer fLayer)
|
||||
{
|
||||
// Set the feature layer's renderer.
|
||||
await QueuedTask.Run(() => fLayer.SetRenderer(bakedMember.Value.Item2)).ConfigureAwait(false);
|
||||
fLayer.SetRenderer(bakedMember.Value.Item2);
|
||||
}
|
||||
}
|
||||
bakedObjectIds.AddRange(createdLayerGroups.Values.Select(x => x.URI));
|
||||
@@ -298,80 +287,72 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<MapMember> AddDatasetsToMap(
|
||||
private MapMember AddDatasetsToMap(
|
||||
ObjectConversionTracker trackerItem,
|
||||
Dictionary<string, GroupLayer> createdLayerGroups,
|
||||
string projectName,
|
||||
string modelName
|
||||
)
|
||||
{
|
||||
return await 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)
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
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 layer = LayerFactory.Instance.CreateLayer(uri, groupLayer, layerName: shortName);
|
||||
if (layer == null)
|
||||
{
|
||||
// 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;
|
||||
throw new SpeckleException($"Layer '{shortName}' was not created");
|
||||
}
|
||||
layer.SetExpanded(false);
|
||||
|
||||
// add group for the current layer
|
||||
string shortName = nestedLayerName.Split("\\")[^1];
|
||||
string nestedLayerPath = string.Join("\\", nestedLayerName.Split("\\").SkipLast(1));
|
||||
// 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, };
|
||||
|
||||
// if no general group layer found
|
||||
if (createdLayerGroups.Count == 0)
|
||||
// for Feature Layers
|
||||
if (layer.GetDefinition() is CIMFeatureLayer cimLyr)
|
||||
{
|
||||
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
|
||||
cimLyr.LayerElevation = layerElevationSurface;
|
||||
layer.SetDefinition(cimLyr);
|
||||
}
|
||||
}
|
||||
|
||||
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 layer = LayerFactory.Instance.CreateLayer(uri, groupLayer, layerName: shortName);
|
||||
if (layer == null)
|
||||
{
|
||||
throw new SpeckleException($"Layer '{shortName}' was not created");
|
||||
}
|
||||
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 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);
|
||||
return layer;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
StandaloneTable table = StandaloneTableFactory.Instance.CreateStandaloneTable(
|
||||
uri,
|
||||
groupLayer,
|
||||
tableName: shortName
|
||||
);
|
||||
return table;
|
||||
}
|
||||
}
|
||||
|
||||
private GroupLayer CreateNestedGroupLayer(string nestedLayerPath, Dictionary<string, GroupLayer> createdLayerGroups)
|
||||
|
||||
+52
-82
@@ -1,12 +1,10 @@
|
||||
using ArcGIS.Core.Data.Raster;
|
||||
using ArcGIS.Core.Geometry;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.ArcGIS.HostApp;
|
||||
using Speckle.Connectors.ArcGIS.HostApp.Extensions;
|
||||
using Speckle.Connectors.ArcGIS.Utils;
|
||||
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;
|
||||
@@ -25,7 +23,6 @@ namespace Speckle.Connectors.ArcGis.Operations.Send;
|
||||
public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
{
|
||||
private readonly IRootToSpeckleConverter _rootToSpeckleConverter;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly ArcGISLayerUnpacker _layerUnpacker;
|
||||
private readonly ArcGISColorUnpacker _colorUnpacker;
|
||||
private readonly IConverterSettingsStore<ArcGISConversionSettings> _converterSettings;
|
||||
@@ -34,7 +31,6 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
private readonly MapMembersUtils _mapMemberUtils;
|
||||
|
||||
public ArcGISRootObjectBuilder(
|
||||
ISendConversionCache sendConversionCache,
|
||||
ArcGISLayerUnpacker layerUnpacker,
|
||||
ArcGISColorUnpacker colorUnpacker,
|
||||
IConverterSettingsStore<ArcGISConversionSettings> converterSettings,
|
||||
@@ -44,7 +40,6 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
MapMembersUtils mapMemberUtils
|
||||
)
|
||||
{
|
||||
_sendConversionCache = sendConversionCache;
|
||||
_layerUnpacker = layerUnpacker;
|
||||
_colorUnpacker = colorUnpacker;
|
||||
_converterSettings = converterSettings;
|
||||
@@ -54,11 +49,11 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
_mapMemberUtils = mapMemberUtils;
|
||||
}
|
||||
|
||||
public async Task<RootObjectBuilderResult> Build(
|
||||
public async Task<RootObjectBuilderResult> BuildAsync(
|
||||
IReadOnlyList<ADM.MapMember> layers,
|
||||
SendInfo sendInfo,
|
||||
SendInfo __,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken ct = default
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
// TODO: add a warning if Geographic CRS is set
|
||||
@@ -103,9 +98,7 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
IEnumerable<ADM.MapMember> layersOrdered = _mapMemberUtils.GetMapMembersInOrder(map, layers);
|
||||
using (var _ = _activityFactory.Start("Unpacking selection"))
|
||||
{
|
||||
unpackedLayers = await QueuedTask
|
||||
.Run(() => _layerUnpacker.UnpackSelectionAsync(layersOrdered, rootCollection))
|
||||
.ConfigureAwait(false);
|
||||
unpackedLayers = _layerUnpacker.UnpackSelection(layersOrdered, rootCollection);
|
||||
}
|
||||
|
||||
List<SendConversionResult> results = new(unpackedLayers.Count);
|
||||
@@ -115,7 +108,7 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
int count = 0;
|
||||
foreach (ADM.MapMember layer in unpackedLayers)
|
||||
{
|
||||
ct.ThrowIfCancellationRequested();
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
string layerApplicationId = layer.GetSpeckleApplicationId();
|
||||
|
||||
try
|
||||
@@ -141,21 +134,15 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
switch (layer)
|
||||
{
|
||||
case ADM.FeatureLayer featureLayer:
|
||||
List<Base> convertedFeatureLayerObjects = await QueuedTask
|
||||
.Run(() => ConvertFeatureLayerObjectsAsync(featureLayer))
|
||||
.ConfigureAwait(false);
|
||||
List<Base> convertedFeatureLayerObjects = ConvertFeatureLayerObjects(featureLayer);
|
||||
layerCollection.elements.AddRange(convertedFeatureLayerObjects);
|
||||
break;
|
||||
case ADM.RasterLayer rasterLayer:
|
||||
List<Base> convertedRasterLayerObjects = await QueuedTask
|
||||
.Run(() => ConvertRasterLayerObjectsAsync(rasterLayer))
|
||||
.ConfigureAwait(false);
|
||||
List<Base> convertedRasterLayerObjects = ConvertRasterLayerObjects(rasterLayer);
|
||||
layerCollection.elements.AddRange(convertedRasterLayerObjects);
|
||||
break;
|
||||
case ADM.LasDatasetLayer lasDatasetLayer:
|
||||
List<Base> convertedLasDatasetObjects = await QueuedTask
|
||||
.Run(() => ConvertLasDatasetLayerObjectsAsync(lasDatasetLayer))
|
||||
.ConfigureAwait(false);
|
||||
List<Base> convertedLasDatasetObjects = ConvertLasDatasetLayerObjects(lasDatasetLayer);
|
||||
layerCollection.elements.AddRange(convertedLasDatasetObjects);
|
||||
break;
|
||||
default:
|
||||
@@ -180,6 +167,7 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
}
|
||||
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / layers.Count));
|
||||
await Task.Yield();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,96 +182,78 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
return new RootObjectBuilderResult(rootCollection, results);
|
||||
}
|
||||
|
||||
private async Task<List<Base>> ConvertFeatureLayerObjectsAsync(ADM.FeatureLayer featureLayer)
|
||||
private List<Base> ConvertFeatureLayerObjects(ADM.FeatureLayer featureLayer)
|
||||
{
|
||||
string layerApplicationId = featureLayer.GetSpeckleApplicationId();
|
||||
List<Base> convertedObjects = new();
|
||||
await QueuedTask
|
||||
.Run(() =>
|
||||
// store the layer renderer for color unpacking
|
||||
_colorUnpacker.StoreRendererAndFields(featureLayer);
|
||||
|
||||
// search the rows of the layer, where each row is treated like an object
|
||||
// RowCursor is IDisposable but is not being correctly picked up by IDE warnings.
|
||||
// This means we need to be carefully adding using statements based on the API documentation coming from each method/class
|
||||
using (ACD.RowCursor rowCursor = featureLayer.Search())
|
||||
{
|
||||
while (rowCursor.MoveNext())
|
||||
{
|
||||
// store the layer renderer for color unpacking
|
||||
_colorUnpacker.StoreRendererAndFields(featureLayer);
|
||||
|
||||
// search the rows of the layer, where each row is treated like an object
|
||||
// RowCursor is IDisposable but is not being correctly picked up by IDE warnings.
|
||||
// This means we need to be carefully adding using statements based on the API documentation coming from each method/class
|
||||
using (ACD.RowCursor rowCursor = featureLayer.Search())
|
||||
// Same IDisposable issue appears to happen on Row class too. Docs say it should always be disposed of manually by the caller.
|
||||
using (ACD.Row row = rowCursor.Current)
|
||||
{
|
||||
while (rowCursor.MoveNext())
|
||||
{
|
||||
// Same IDisposable issue appears to happen on Row class too. Docs say it should always be disposed of manually by the caller.
|
||||
using (ACD.Row row = rowCursor.Current)
|
||||
{
|
||||
// get application id. test for subtypes before defaulting to base type.
|
||||
Base converted = _rootToSpeckleConverter.Convert(row);
|
||||
string applicationId = row.GetSpeckleApplicationId(layerApplicationId);
|
||||
converted.applicationId = applicationId;
|
||||
// get application id. test for subtypes before defaulting to base type.
|
||||
Base converted = _rootToSpeckleConverter.Convert(row);
|
||||
string applicationId = row.GetSpeckleApplicationId(layerApplicationId);
|
||||
converted.applicationId = applicationId;
|
||||
|
||||
convertedObjects.Add(converted);
|
||||
convertedObjects.Add(converted);
|
||||
|
||||
// process the object color
|
||||
_colorUnpacker.ProcessFeatureLayerColor(row, applicationId);
|
||||
}
|
||||
}
|
||||
// process the object color
|
||||
_colorUnpacker.ProcessFeatureLayerColor(row, applicationId);
|
||||
}
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
return convertedObjects;
|
||||
}
|
||||
|
||||
// POC: raster colors are stored as mesh vertex colors in RasterToSpeckleConverter. Should probably move to color unpacker.
|
||||
private async Task<List<Base>> ConvertRasterLayerObjectsAsync(ADM.RasterLayer rasterLayer)
|
||||
private List<Base> ConvertRasterLayerObjects(ADM.RasterLayer rasterLayer)
|
||||
{
|
||||
string layerApplicationId = rasterLayer.GetSpeckleApplicationId();
|
||||
List<Base> convertedObjects = new();
|
||||
await QueuedTask
|
||||
.Run(() =>
|
||||
{
|
||||
Raster raster = rasterLayer.GetRaster();
|
||||
Base converted = _rootToSpeckleConverter.Convert(raster);
|
||||
string applicationId = raster.GetSpeckleApplicationId(layerApplicationId);
|
||||
converted.applicationId = applicationId;
|
||||
convertedObjects.Add(converted);
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Raster raster = rasterLayer.GetRaster();
|
||||
Base converted = _rootToSpeckleConverter.Convert(raster);
|
||||
string applicationId = raster.GetSpeckleApplicationId(layerApplicationId);
|
||||
converted.applicationId = applicationId;
|
||||
convertedObjects.Add(converted);
|
||||
return convertedObjects;
|
||||
}
|
||||
|
||||
private async Task<List<Base>> ConvertLasDatasetLayerObjectsAsync(ADM.LasDatasetLayer lasDatasetLayer)
|
||||
private List<Base> ConvertLasDatasetLayerObjects(ADM.LasDatasetLayer lasDatasetLayer)
|
||||
{
|
||||
string layerApplicationId = lasDatasetLayer.GetSpeckleApplicationId();
|
||||
List<Base> convertedObjects = new();
|
||||
|
||||
try
|
||||
{
|
||||
await QueuedTask
|
||||
.Run(() =>
|
||||
// store the layer renderer for color unpacking
|
||||
_colorUnpacker.StoreRenderer(lasDatasetLayer);
|
||||
|
||||
using (ACD.Analyst3D.LasPointCursor ptCursor = lasDatasetLayer.SearchPoints(new ACD.Analyst3D.LasPointFilter()))
|
||||
{
|
||||
while (ptCursor.MoveNext())
|
||||
{
|
||||
// store the layer renderer for color unpacking
|
||||
_colorUnpacker.StoreRenderer(lasDatasetLayer);
|
||||
|
||||
using (
|
||||
ACD.Analyst3D.LasPointCursor ptCursor = lasDatasetLayer.SearchPoints(new ACD.Analyst3D.LasPointFilter())
|
||||
)
|
||||
using (ACD.Analyst3D.LasPoint pt = ptCursor.Current)
|
||||
{
|
||||
while (ptCursor.MoveNext())
|
||||
{
|
||||
using (ACD.Analyst3D.LasPoint pt = ptCursor.Current)
|
||||
{
|
||||
Base converted = _rootToSpeckleConverter.Convert(pt);
|
||||
string applicationId = pt.GetSpeckleApplicationId(layerApplicationId);
|
||||
converted.applicationId = applicationId;
|
||||
convertedObjects.Add(converted);
|
||||
Base converted = _rootToSpeckleConverter.Convert(pt);
|
||||
string applicationId = pt.GetSpeckleApplicationId(layerApplicationId);
|
||||
converted.applicationId = applicationId;
|
||||
convertedObjects.Add(converted);
|
||||
|
||||
// process the object color
|
||||
_colorUnpacker.ProcessLasLayerColor(pt, applicationId);
|
||||
}
|
||||
}
|
||||
// process the object color
|
||||
_colorUnpacker.ProcessLasLayerColor(pt, applicationId);
|
||||
}
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ACD.Exceptions.TinException ex)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@ internal sealed class SpeckleDUI3ViewModel : DockPane
|
||||
/// </summary>
|
||||
protected override async Task InitializeAsync()
|
||||
{
|
||||
await base.InitializeAsync().ConfigureAwait(false);
|
||||
await base.InitializeAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -26,7 +26,7 @@ internal sealed class SpeckleDUI3ViewModel : DockPane
|
||||
/// </summary>
|
||||
protected override async Task UninitializeAsync()
|
||||
{
|
||||
await base.UninitializeAsync().ConfigureAwait(false);
|
||||
await base.UninitializeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.Utils;
|
||||
|
||||
//don't check for GUI as it's the same check we do in ThreadContext
|
||||
public class ArcGISThreadContext : ThreadContext
|
||||
{
|
||||
protected override Task<T> MainToWorkerAsync<T>(Func<Task<T>> action)
|
||||
{
|
||||
if (QueuedTask.OnWorker)
|
||||
{
|
||||
return action();
|
||||
}
|
||||
else
|
||||
{
|
||||
return QueuedTask.Run(async () => await action());
|
||||
}
|
||||
}
|
||||
|
||||
protected override Task<T> WorkerToMainAsync<T>(Func<Task<T>> action) => QueuedTask.Run(async () => await action());
|
||||
|
||||
protected override Task<T> MainToWorker<T>(Func<T> action)
|
||||
{
|
||||
if (QueuedTask.OnWorker)
|
||||
{
|
||||
return Task.FromResult(action());
|
||||
}
|
||||
else
|
||||
{
|
||||
return QueuedTask.Run(action);
|
||||
}
|
||||
}
|
||||
|
||||
protected override Task<T> WorkerToMain<T>(Func<T> action) => QueuedTask.Run(action);
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
using System.Xml.Linq;
|
||||
using ArcGIS.Desktop.Core.Events;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using ArcGIS.Desktop.Mapping.Events;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
|
||||
@@ -11,9 +12,19 @@ namespace Speckle.Connectors.ArcGIS.Utils;
|
||||
|
||||
public class ArcGISDocumentStore : DocumentModelStore
|
||||
{
|
||||
public ArcGISDocumentStore(IJsonSerializer jsonSerializer, ITopLevelExceptionHandler topLevelExceptionHandler)
|
||||
private readonly IThreadContext _threadContext;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
|
||||
public ArcGISDocumentStore(
|
||||
IJsonSerializer jsonSerializer,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IThreadContext threadContext,
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
: base(jsonSerializer)
|
||||
{
|
||||
_threadContext = threadContext;
|
||||
_eventAggregator = eventAggregator;
|
||||
ActiveMapViewChangedEvent.Subscribe(a => topLevelExceptionHandler.CatchUnhandled(() => OnMapViewChanged(a)), true);
|
||||
ProjectSavingEvent.Subscribe(
|
||||
_ =>
|
||||
@@ -31,13 +42,16 @@ public class ArcGISDocumentStore : DocumentModelStore
|
||||
},
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
public override async Task OnDocumentStoreInitialized()
|
||||
{
|
||||
// in case plugin was loaded into already opened Map, read metadata from the current Map
|
||||
if (!IsDocumentInit && MapView.Active != null)
|
||||
{
|
||||
IsDocumentInit = true;
|
||||
LoadState();
|
||||
OnDocumentChanged();
|
||||
await _eventAggregator.GetEvent<DocumentStoreChangedEvent>().PublishAsync(new object());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +76,7 @@ public class ArcGISDocumentStore : DocumentModelStore
|
||||
/// <summary>
|
||||
/// On map view switch, this event trigger twice, first for outgoing view, second for incoming view.
|
||||
/// </summary>
|
||||
private void OnMapViewChanged(ActiveMapViewChangedEventArgs args)
|
||||
private async void OnMapViewChanged(ActiveMapViewChangedEventArgs args)
|
||||
{
|
||||
if (args.IncomingView is null)
|
||||
{
|
||||
@@ -71,55 +85,55 @@ public class ArcGISDocumentStore : DocumentModelStore
|
||||
|
||||
IsDocumentInit = true;
|
||||
LoadState();
|
||||
OnDocumentChanged();
|
||||
await _eventAggregator.GetEvent<DocumentStoreChangedEvent>().PublishAsync(new object());
|
||||
}
|
||||
|
||||
protected override void HostAppSaveState(string modelCardState)
|
||||
{
|
||||
Map map = MapView.Active.Map;
|
||||
QueuedTask.Run(() =>
|
||||
{
|
||||
// Read existing metadata - To prevent messing existing metadata. 🤞 Hope other add-in developers will do same :D
|
||||
var existingMetadata = map.GetMetadata();
|
||||
|
||||
// Parse existing metadata
|
||||
XDocument existingXmlDocument = !string.IsNullOrEmpty(existingMetadata)
|
||||
? XDocument.Parse(existingMetadata)
|
||||
: new XDocument(new XElement("metadata"));
|
||||
|
||||
XElement xmlModelCards = new("SpeckleModelCards", modelCardState);
|
||||
|
||||
// Check if SpeckleModelCards element already exists at root and update it
|
||||
var speckleModelCardsElement = existingXmlDocument.Root?.Element("SpeckleModelCards");
|
||||
if (speckleModelCardsElement != null)
|
||||
protected override void HostAppSaveState(string modelCardState) =>
|
||||
_threadContext
|
||||
.RunOnWorker(() =>
|
||||
{
|
||||
speckleModelCardsElement.ReplaceWith(xmlModelCards);
|
||||
}
|
||||
else
|
||||
Map map = MapView.Active.Map;
|
||||
// Read existing metadata - To prevent messing existing metadata. 🤞 Hope other add-in developers will do same :D
|
||||
var existingMetadata = map.GetMetadata();
|
||||
|
||||
// Parse existing metadata
|
||||
XDocument existingXmlDocument = !string.IsNullOrEmpty(existingMetadata)
|
||||
? XDocument.Parse(existingMetadata)
|
||||
: new XDocument(new XElement("metadata"));
|
||||
|
||||
XElement xmlModelCards = new("SpeckleModelCards", modelCardState);
|
||||
|
||||
// Check if SpeckleModelCards element already exists at root and update it
|
||||
var speckleModelCardsElement = existingXmlDocument.Root?.Element("SpeckleModelCards");
|
||||
if (speckleModelCardsElement != null)
|
||||
{
|
||||
speckleModelCardsElement.ReplaceWith(xmlModelCards);
|
||||
}
|
||||
else
|
||||
{
|
||||
existingXmlDocument.Root?.Add(xmlModelCards);
|
||||
}
|
||||
|
||||
map.SetMetadata(existingXmlDocument.ToString());
|
||||
})
|
||||
.FireAndForget();
|
||||
|
||||
protected override void LoadState() =>
|
||||
_threadContext
|
||||
.RunOnWorker(() =>
|
||||
{
|
||||
existingXmlDocument.Root?.Add(xmlModelCards);
|
||||
}
|
||||
Map map = MapView.Active.Map;
|
||||
var metadata = map.GetMetadata();
|
||||
var root = XDocument.Parse(metadata).Root;
|
||||
var element = root?.Element("SpeckleModelCards");
|
||||
if (element is null)
|
||||
{
|
||||
ClearAndSave();
|
||||
return;
|
||||
}
|
||||
|
||||
map.SetMetadata(existingXmlDocument.ToString());
|
||||
});
|
||||
}
|
||||
|
||||
protected override void LoadState()
|
||||
{
|
||||
Map map = MapView.Active.Map;
|
||||
QueuedTask.Run(() =>
|
||||
{
|
||||
var metadata = map.GetMetadata();
|
||||
var root = XDocument.Parse(metadata).Root;
|
||||
var element = root?.Element("SpeckleModelCards");
|
||||
if (element is null)
|
||||
{
|
||||
ClearAndSave();
|
||||
return;
|
||||
}
|
||||
|
||||
string modelsString = element.Value;
|
||||
LoadFromString(modelsString);
|
||||
});
|
||||
}
|
||||
string modelsString = element.Value;
|
||||
LoadFromString(modelsString);
|
||||
})
|
||||
.FireAndForget();
|
||||
}
|
||||
|
||||
@@ -231,9 +231,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -241,9 +241,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -267,7 +266,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -299,41 +298,35 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
},
|
||||
"net6.0-windows7.0/win-x64": {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project>
|
||||
<Target AfterTargets="Clean" Name="CleanAddinAutocad" Condition="'$(AutoCADVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
|
||||
<RemoveDir Directories="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Autocad$(AutoCADVersion);" />
|
||||
</Target>
|
||||
|
||||
<Target AfterTargets="Build" Name="AfterBuildAutoCAD" Condition="'$(AutoCADVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
|
||||
<ItemGroup>
|
||||
<AutoCADDLLs Include="$(TargetDir)\**\*.*" />
|
||||
</ItemGroup>
|
||||
<Message Text="AutoCAD Version $(AutoCADVersion)" Importance="high"/>
|
||||
<Copy DestinationFolder="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Autocad$(AutoCADVersion)\%(RecursiveDir)" SourceFiles="@(AutoCADDLLs)" />
|
||||
</Target>
|
||||
|
||||
<Target AfterTargets="Clean" Name="CleanAddinCivil3D" Condition="'$(Civil3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
|
||||
<RemoveDir Directories="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Civil3d$(Civil3DVersion);" />
|
||||
</Target>
|
||||
|
||||
<Target AfterTargets="Build" Name="AfterBuildCivil3D" Condition="'$(Civil3DVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
|
||||
<ItemGroup>
|
||||
<Civil3DDLLs Include="$(TargetDir)\**\*.*" />
|
||||
</ItemGroup>
|
||||
<Message Text="Civil3D Version $(Civil3DVersion)" Importance="high"/>
|
||||
<Copy DestinationFolder="$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Civil3d$(Civil3DVersion)\%(RecursiveDir)" SourceFiles="@(Civil3DDLLs)" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -264,9 +264,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -274,9 +274,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -300,7 +299,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -338,41 +337,35 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,9 +264,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -274,9 +274,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -300,7 +299,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -338,41 +337,35 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,9 +264,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -274,9 +274,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -301,7 +300,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -339,41 +338,35 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,9 +220,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -230,9 +230,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -257,7 +256,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -295,40 +294,34 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
|
||||
+58
-60
@@ -1,8 +1,10 @@
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp.Extensions;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Sdk;
|
||||
@@ -19,6 +21,7 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly IThreadContext _threadContext;
|
||||
private readonly ILogger<AutocadBasicConnectorBinding> _logger;
|
||||
|
||||
public BasicConnectorBindingCommands Commands { get; }
|
||||
@@ -28,7 +31,9 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
|
||||
IBrowserBridge parent,
|
||||
IAccountManager accountManager,
|
||||
ISpeckleApplication speckleApplication,
|
||||
ILogger<AutocadBasicConnectorBinding> logger
|
||||
ILogger<AutocadBasicConnectorBinding> logger,
|
||||
IEventAggregator eventAggregator,
|
||||
IThreadContext threadContext
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
@@ -36,14 +41,13 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
|
||||
_accountManager = accountManager;
|
||||
_speckleApplication = speckleApplication;
|
||||
Commands = new BasicConnectorBindingCommands(parent);
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
parent.TopLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await Commands.NotifyDocumentChanged().ConfigureAwait(false);
|
||||
});
|
||||
eventAggregator.GetEvent<DocumentStoreChangedEvent>().Subscribe(OnDocumentStoreChangedEvent);
|
||||
_logger = logger;
|
||||
_threadContext = threadContext;
|
||||
}
|
||||
|
||||
private async Task OnDocumentStoreChangedEvent(object _) => await Commands.NotifyDocumentChanged();
|
||||
|
||||
public string GetConnectorVersion() => _speckleApplication.SpeckleVersion;
|
||||
|
||||
public string GetSourceApplicationName() => _speckleApplication.Slug;
|
||||
@@ -79,7 +83,7 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
var dbObjects = doc.GetObjects(objectIds);
|
||||
var acadObjectIds = dbObjects.Select(tuple => tuple.Root.Id).ToArray();
|
||||
await HighlightObjectsOnView(acadObjectIds).ConfigureAwait(false);
|
||||
await HighlightObjectsOnView(acadObjectIds);
|
||||
}
|
||||
|
||||
public async Task HighlightModel(string modelCardId)
|
||||
@@ -116,79 +120,73 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
if (objectIds.Length == 0)
|
||||
{
|
||||
await Commands
|
||||
.SetModelError(modelCardId, new OperationCanceledException("No objects found to highlight."))
|
||||
.ConfigureAwait(false);
|
||||
await Commands.SetModelError(modelCardId, new OperationCanceledException("No objects found to highlight."));
|
||||
return;
|
||||
}
|
||||
|
||||
await HighlightObjectsOnView(objectIds, modelCardId).ConfigureAwait(false);
|
||||
await HighlightObjectsOnView(objectIds, modelCardId);
|
||||
}
|
||||
|
||||
private async Task HighlightObjectsOnView(ObjectId[] objectIds, string? modelCardId = null)
|
||||
{
|
||||
var doc = Application.DocumentManager.MdiActiveDocument;
|
||||
|
||||
await Parent
|
||||
.RunOnMainThreadAsync(async () =>
|
||||
await _threadContext.RunOnMainAsync(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
doc.Editor.SetImpliedSelection([]); // Deselects
|
||||
try
|
||||
{
|
||||
doc.Editor.SetImpliedSelection(Array.Empty<ObjectId>()); // Deselects
|
||||
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)
|
||||
{
|
||||
try
|
||||
{
|
||||
doc.Editor.SetImpliedSelection(objectIds);
|
||||
var entity = (Entity?)tr.GetObject(objectId, OpenMode.ForRead);
|
||||
if (entity?.GeometricExtents != null)
|
||||
{
|
||||
selectedExtents.AddExtents(entity.GeometricExtents);
|
||||
}
|
||||
}
|
||||
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.
|
||||
// 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.
|
||||
// may also throw Autodesk.AutoCAD.Runtime.Exception for invalid extents on objects like rays and xlines
|
||||
}
|
||||
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.
|
||||
// may also throw Autodesk.AutoCAD.Runtime.Exception for invalid extents on objects like rays and xlines
|
||||
}
|
||||
}
|
||||
|
||||
doc.Editor.Zoom(selectedExtents);
|
||||
tr.Commit();
|
||||
Autodesk.AutoCAD.Internal.Utils.FlushGraphics();
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
|
||||
doc.Editor.Zoom(selectedExtents);
|
||||
tr.Commit();
|
||||
Autodesk.AutoCAD.Internal.Utils.FlushGraphics();
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
if (modelCardId != null)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+7
-6
@@ -81,12 +81,13 @@ public sealed class AutocadReceiveBinding : IReceiveBinding
|
||||
modelCard.GetReceiveInfo(_speckleApplication.Slug),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
);
|
||||
|
||||
await Commands
|
||||
.SetModelReceiveResult(modelCardId, operationResults.BakedObjectIds, operationResults.ConversionResults)
|
||||
.ConfigureAwait(false);
|
||||
await Commands.SetModelReceiveResult(
|
||||
modelCardId,
|
||||
operationResults.BakedObjectIds,
|
||||
operationResults.ConversionResults
|
||||
);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -98,7 +99,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);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
await Commands.SetModelError(modelCardId, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
+11
-6
@@ -1,6 +1,7 @@
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Autodesk.AutoCAD.EditorInput;
|
||||
using Speckle.Connectors.Autocad.HostApp.Extensions;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
|
||||
@@ -10,16 +11,22 @@ public class AutocadSelectionBinding : ISelectionBinding
|
||||
{
|
||||
private const string SELECTION_EVENT = "setSelection";
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IThreadContext _threadContext;
|
||||
private readonly HashSet<Document> _visitedDocuments = new();
|
||||
|
||||
public string Name => "selectionBinding";
|
||||
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
public AutocadSelectionBinding(IBrowserBridge parent)
|
||||
public AutocadSelectionBinding(
|
||||
IBrowserBridge parent,
|
||||
IThreadContext threadContext,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
)
|
||||
{
|
||||
_topLevelExceptionHandler = parent.TopLevelExceptionHandler;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
Parent = parent;
|
||||
_threadContext = threadContext;
|
||||
|
||||
// POC: Use here Context for doc. In converters it's OK but we are still lacking to use context into bindings.
|
||||
// It is with the case of if binding created with already a document
|
||||
@@ -41,9 +48,7 @@ public class AutocadSelectionBinding : ISelectionBinding
|
||||
if (!_visitedDocuments.Contains(document))
|
||||
{
|
||||
document.ImpliedSelectionChanged += (_, _) =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await Parent.RunOnMainThreadAsync(OnSelectionChanged).ConfigureAwait(false)
|
||||
);
|
||||
_topLevelExceptionHandler.FireAndForget(async () => await _threadContext.RunOnMainAsync(OnSelectionChanged));
|
||||
|
||||
_visitedDocuments.Add(document);
|
||||
}
|
||||
@@ -57,7 +62,7 @@ public class AutocadSelectionBinding : ISelectionBinding
|
||||
private async Task OnSelectionChanged()
|
||||
{
|
||||
_selectionInfo = GetSelectionInternal();
|
||||
await Parent.Send(SELECTION_EVENT, _selectionInfo).ConfigureAwait(false);
|
||||
await Parent.Send(SELECTION_EVENT, _selectionInfo);
|
||||
}
|
||||
|
||||
public SelectionInfo GetSelection() => _selectionInfo;
|
||||
|
||||
+20
-21
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Concurrent;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -8,8 +8,10 @@ using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Exceptions;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
@@ -38,6 +40,7 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
private readonly ILogger<AutocadSendBinding> _logger;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly IThreadContext _threadContext;
|
||||
|
||||
/// <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:
|
||||
@@ -57,7 +60,10 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
ISendConversionCache sendConversionCache,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<AutocadSendBinding> logger,
|
||||
ISpeckleApplication speckleApplication
|
||||
ISpeckleApplication speckleApplication,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IThreadContext threadContext,
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
@@ -69,7 +75,8 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
_operationProgressManager = operationProgressManager;
|
||||
_logger = logger;
|
||||
_speckleApplication = speckleApplication;
|
||||
_topLevelExceptionHandler = parent.TopLevelExceptionHandler;
|
||||
_threadContext = threadContext;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
Parent = parent;
|
||||
Commands = new SendBindingUICommands(parent);
|
||||
|
||||
@@ -82,12 +89,12 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
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();
|
||||
};
|
||||
|
||||
eventAggregator.GetEvent<DocumentStoreChangedEvent>().Subscribe(OnDocumentStoreChangedEvent);
|
||||
}
|
||||
|
||||
private void OnDocumentStoreChangedEvent(object _) => _sendConversionCache.ClearCache();
|
||||
|
||||
private readonly List<string> _docSubsTracker = new();
|
||||
|
||||
private void SubscribeToObjectChanges(Document doc)
|
||||
@@ -111,10 +118,7 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
private void OnChangeChangedObjectIds(DBObject dBObject)
|
||||
{
|
||||
ChangedObjectIds[dBObject.GetSpeckleApplicationId()] = 1;
|
||||
_idleManager.SubscribeToIdle(
|
||||
nameof(AutocadSendBinding),
|
||||
async () => await RunExpirationChecks().ConfigureAwait(false)
|
||||
);
|
||||
_idleManager.SubscribeToIdle(nameof(AutocadSendBinding), async () => await RunExpirationChecks());
|
||||
}
|
||||
|
||||
private async Task RunExpirationChecks()
|
||||
@@ -135,7 +139,7 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
}
|
||||
}
|
||||
|
||||
await Commands.SetModelsExpired(expiredSenderIds).ConfigureAwait(false);
|
||||
await Commands.SetModelsExpired(expiredSenderIds);
|
||||
ChangedObjectIds = new();
|
||||
}
|
||||
|
||||
@@ -144,9 +148,7 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
public List<ICardSetting> GetSendSettings() => [];
|
||||
|
||||
public async Task Send(string modelCardId) =>
|
||||
await Parent
|
||||
.RunOnMainThreadAsync(async () => await SendInternal(modelCardId).ConfigureAwait(false))
|
||||
.ConfigureAwait(false);
|
||||
await _threadContext.RunOnWorkerAsync(async () => await SendInternal(modelCardId));
|
||||
|
||||
protected abstract void InitializeSettings(IServiceProvider serviceProvider);
|
||||
|
||||
@@ -188,12 +190,9 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
);
|
||||
|
||||
await Commands
|
||||
.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults)
|
||||
.ConfigureAwait(false);
|
||||
await Commands.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -205,7 +204,7 @@ public abstract class AutocadSendBaseBinding : 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);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
await Commands.SetModelError(modelCardId, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -3,8 +3,10 @@ using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Converters.Autocad;
|
||||
@@ -28,7 +30,10 @@ public sealed class AutocadSendBinding : AutocadSendBaseBinding
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<AutocadSendBinding> logger,
|
||||
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
|
||||
ISpeckleApplication speckleApplication
|
||||
ISpeckleApplication speckleApplication,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IThreadContext threadContext,
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
: base(
|
||||
store,
|
||||
@@ -40,7 +45,10 @@ public sealed class AutocadSendBinding : AutocadSendBaseBinding
|
||||
sendConversionCache,
|
||||
operationProgressManager,
|
||||
logger,
|
||||
speckleApplication
|
||||
speckleApplication,
|
||||
topLevelExceptionHandler,
|
||||
threadContext,
|
||||
eventAggregator
|
||||
)
|
||||
{
|
||||
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
|
||||
|
||||
+4
-5
@@ -10,6 +10,7 @@ using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Instances;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
@@ -24,7 +25,7 @@ public static class SharedRegistration
|
||||
public static void AddAutocadBase(this IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddConnectorUtils();
|
||||
serviceCollection.AddDUI<AutocadDocumentStore>();
|
||||
serviceCollection.AddDUI<DefaultThreadContext, AutocadDocumentStore>();
|
||||
serviceCollection.AddDUIView();
|
||||
|
||||
// Register other connector specific types
|
||||
@@ -43,10 +44,10 @@ public static class SharedRegistration
|
||||
serviceCollection.AddScoped<AutocadGroupBaker>();
|
||||
|
||||
serviceCollection.AddScoped<AutocadColorUnpacker>();
|
||||
serviceCollection.AddScoped<AutocadColorBaker>();
|
||||
serviceCollection.AddScoped<IAutocadColorBaker, AutocadColorBaker>();
|
||||
|
||||
serviceCollection.AddScoped<AutocadMaterialUnpacker>();
|
||||
serviceCollection.AddScoped<AutocadMaterialBaker>();
|
||||
serviceCollection.AddScoped<IAutocadMaterialBaker, AutocadMaterialBaker>();
|
||||
|
||||
serviceCollection.AddSingleton<IAppIdleManager, AutocadIdleManager>();
|
||||
|
||||
@@ -60,8 +61,6 @@ public static class SharedRegistration
|
||||
serviceCollection.AddSingleton<IBinding>(sp => sp.GetRequiredService<IBasicConnectorBinding>());
|
||||
serviceCollection.AddSingleton<IBasicConnectorBinding, AutocadBasicConnectorBinding>();
|
||||
serviceCollection.AddSingleton<IBinding, ConfigBinding>();
|
||||
|
||||
serviceCollection.RegisterTopLevelExceptionHandler();
|
||||
}
|
||||
|
||||
public static void LoadSend(this IServiceCollection serviceCollection)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Autodesk.AutoCAD.Colors;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.InterfaceGenerator;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Models.Proxies;
|
||||
using AutocadColor = Autodesk.AutoCAD.Colors.Color;
|
||||
@@ -10,15 +11,9 @@ namespace Speckle.Connectors.Autocad.HostApp;
|
||||
/// <summary>
|
||||
/// Expects to be a scoped dependency for a given operation and helps with layer creation and cleanup.
|
||||
/// </summary>
|
||||
public class AutocadColorBaker
|
||||
[GenerateAutoInterface]
|
||||
public class AutocadColorBaker(ILogger<AutocadColorBaker> logger) : IAutocadColorBaker
|
||||
{
|
||||
private readonly ILogger<AutocadColorBaker> _logger;
|
||||
|
||||
public AutocadColorBaker(ILogger<AutocadColorBaker> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For receive operations
|
||||
/// </summary>
|
||||
@@ -59,7 +54,7 @@ public class AutocadColorBaker
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogError(ex, "Failed parsing color proxy");
|
||||
logger.LogError(ex, "Failed parsing color proxy");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-3
@@ -1,4 +1,5 @@
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
|
||||
@@ -9,15 +10,18 @@ public class AutocadDocumentStore : DocumentModelStore
|
||||
private readonly string _nullDocumentName = "Null Doc";
|
||||
private string _previousDocName;
|
||||
private readonly AutocadDocumentManager _autocadDocumentManager;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
|
||||
public AutocadDocumentStore(
|
||||
IJsonSerializer jsonSerializer,
|
||||
AutocadDocumentManager autocadDocumentManager,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
: base(jsonSerializer)
|
||||
{
|
||||
_autocadDocumentManager = autocadDocumentManager;
|
||||
_eventAggregator = eventAggregator;
|
||||
_previousDocName = _nullDocumentName;
|
||||
|
||||
// POC: Will be addressed to move it into AutocadContext!
|
||||
@@ -38,7 +42,7 @@ public class AutocadDocumentStore : DocumentModelStore
|
||||
// OnDocChangeInternal((Document)args.DocumentWindow.Document);
|
||||
}
|
||||
|
||||
private void OnDocChangeInternal(Document? doc)
|
||||
private async void OnDocChangeInternal(Document? doc)
|
||||
{
|
||||
var currentDocName = doc != null ? doc.Name : _nullDocumentName;
|
||||
if (_previousDocName == currentDocName)
|
||||
@@ -48,7 +52,7 @@ public class AutocadDocumentStore : DocumentModelStore
|
||||
|
||||
_previousDocName = currentDocName;
|
||||
LoadState();
|
||||
OnDocumentChanged();
|
||||
await _eventAggregator.GetEvent<DocumentStoreChangedEvent>().PublishAsync(new object());
|
||||
}
|
||||
|
||||
protected override void LoadState()
|
||||
|
||||
@@ -26,16 +26,16 @@ namespace Speckle.Connectors.Autocad.HostApp;
|
||||
public class AutocadInstanceBaker : IInstanceBaker<IReadOnlyCollection<Entity>>
|
||||
{
|
||||
private readonly AutocadLayerBaker _layerBaker;
|
||||
private readonly AutocadColorBaker _colorBaker;
|
||||
private readonly AutocadMaterialBaker _materialBaker;
|
||||
private readonly IAutocadColorBaker _colorBaker;
|
||||
private readonly IAutocadMaterialBaker _materialBaker;
|
||||
private readonly AutocadContext _autocadContext;
|
||||
private readonly ILogger<AutocadInstanceBaker> _logger;
|
||||
private readonly IConverterSettingsStore<AutocadConversionSettings> _converterSettings;
|
||||
|
||||
public AutocadInstanceBaker(
|
||||
AutocadLayerBaker layerBaker,
|
||||
AutocadColorBaker colorBaker,
|
||||
AutocadMaterialBaker materialBaker,
|
||||
IAutocadColorBaker colorBaker,
|
||||
IAutocadMaterialBaker materialBaker,
|
||||
AutocadContext autocadContext,
|
||||
ILogger<AutocadInstanceBaker> logger,
|
||||
IConverterSettingsStore<AutocadConversionSettings> converterSettings
|
||||
|
||||
@@ -12,15 +12,15 @@ public class AutocadLayerBaker : TraversalContextUnpacker
|
||||
{
|
||||
private readonly string _layerFilterName = "Speckle";
|
||||
private readonly AutocadContext _autocadContext;
|
||||
private readonly AutocadMaterialBaker _materialBaker;
|
||||
private readonly AutocadColorBaker _colorBaker;
|
||||
private readonly IAutocadMaterialBaker _materialBaker;
|
||||
private readonly IAutocadColorBaker _colorBaker;
|
||||
private Document Doc => Application.DocumentManager.MdiActiveDocument;
|
||||
private readonly HashSet<string> _uniqueLayerNames = new();
|
||||
|
||||
public AutocadLayerBaker(
|
||||
AutocadContext autocadContext,
|
||||
AutocadMaterialBaker materialBaker,
|
||||
AutocadColorBaker colorBaker
|
||||
IAutocadMaterialBaker materialBaker,
|
||||
IAutocadColorBaker colorBaker
|
||||
)
|
||||
{
|
||||
_autocadContext = autocadContext;
|
||||
|
||||
@@ -4,6 +4,7 @@ using Autodesk.AutoCAD.GraphicsInterface;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.InterfaceGenerator;
|
||||
using Speckle.Objects.Other;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
@@ -16,7 +17,8 @@ namespace Speckle.Connectors.Autocad.HostApp;
|
||||
/// <summary>
|
||||
/// Expects to be a scoped dependency for a given operation and helps with layer creation and cleanup.
|
||||
/// </summary>
|
||||
public class AutocadMaterialBaker
|
||||
[GenerateAutoInterface]
|
||||
public class AutocadMaterialBaker : IAutocadMaterialBaker
|
||||
{
|
||||
private readonly ILogger<AutocadMaterialBaker> _logger;
|
||||
private readonly AutocadContext _autocadContext;
|
||||
|
||||
+31
-72
@@ -20,86 +20,44 @@ namespace Speckle.Connectors.Autocad.Operations.Receive;
|
||||
/// <summary>
|
||||
/// <para>Expects to be a scoped dependency per receive operation.</para>
|
||||
/// </summary>
|
||||
public class AutocadHostObjectBuilder : IHostObjectBuilder
|
||||
public class AutocadHostObjectBuilder(
|
||||
IRootToHostConverter converter,
|
||||
AutocadLayerBaker layerBaker,
|
||||
AutocadGroupBaker groupBaker,
|
||||
AutocadInstanceBaker instanceBaker,
|
||||
IAutocadMaterialBaker materialBaker,
|
||||
IAutocadColorBaker colorBaker,
|
||||
AutocadContext autocadContext,
|
||||
RootObjectUnpacker rootObjectUnpacker
|
||||
) : IHostObjectBuilder
|
||||
{
|
||||
private readonly AutocadLayerBaker _layerBaker;
|
||||
private readonly IRootToHostConverter _converter;
|
||||
private readonly ISyncToThread _syncToThread;
|
||||
private readonly AutocadGroupBaker _groupBaker;
|
||||
private readonly AutocadMaterialBaker _materialBaker;
|
||||
private readonly AutocadColorBaker _colorBaker;
|
||||
private readonly AutocadInstanceBaker _instanceBaker;
|
||||
private readonly AutocadContext _autocadContext;
|
||||
private readonly RootObjectUnpacker _rootObjectUnpacker;
|
||||
|
||||
public AutocadHostObjectBuilder(
|
||||
IRootToHostConverter converter,
|
||||
AutocadLayerBaker layerBaker,
|
||||
AutocadGroupBaker groupBaker,
|
||||
AutocadInstanceBaker instanceBaker,
|
||||
AutocadMaterialBaker materialBaker,
|
||||
AutocadColorBaker colorBaker,
|
||||
ISyncToThread syncToThread,
|
||||
AutocadContext autocadContext,
|
||||
RootObjectUnpacker rootObjectUnpacker
|
||||
)
|
||||
{
|
||||
_converter = converter;
|
||||
_layerBaker = layerBaker;
|
||||
_groupBaker = groupBaker;
|
||||
_instanceBaker = instanceBaker;
|
||||
_materialBaker = materialBaker;
|
||||
_colorBaker = colorBaker;
|
||||
_syncToThread = syncToThread;
|
||||
_autocadContext = autocadContext;
|
||||
_rootObjectUnpacker = rootObjectUnpacker;
|
||||
}
|
||||
|
||||
public async Task<HostObjectBuilderResult> Build(
|
||||
public HostObjectBuilderResult Build(
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
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.
|
||||
return await _syncToThread
|
||||
.RunOnThread(async () =>
|
||||
{
|
||||
await Task.CompletedTask.ConfigureAwait(true);
|
||||
return BuildSync(rootObject, projectName, modelName, onOperationProgressed);
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private HostObjectBuilderResult BuildSync(
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
IProgress<CardProgress> onOperationProgressed
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
// 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);
|
||||
layerBaker.CreateLayerFilter(projectName, modelName);
|
||||
|
||||
// 0 - Clean then Rock n Roll!
|
||||
string baseLayerPrefix = _autocadContext.RemoveInvalidChars($"SPK-{projectName}-{modelName}-");
|
||||
string baseLayerPrefix = autocadContext.RemoveInvalidChars($"SPK-{projectName}-{modelName}-");
|
||||
PreReceiveDeepClean(baseLayerPrefix);
|
||||
|
||||
// 1 - Unpack objects and proxies from root commit object
|
||||
var unpackedRoot = _rootObjectUnpacker.Unpack(rootObject);
|
||||
var unpackedRoot = rootObjectUnpacker.Unpack(rootObject);
|
||||
|
||||
// 2 - Split atomic objects and instance components with their path
|
||||
var (atomicObjects, instanceComponents) = _rootObjectUnpacker.SplitAtomicObjectsAndInstances(
|
||||
var (atomicObjects, instanceComponents) = rootObjectUnpacker.SplitAtomicObjectsAndInstances(
|
||||
unpackedRoot.ObjectsToConvert
|
||||
);
|
||||
var atomicObjectsWithPath = _layerBaker.GetAtomicObjectsWithPath(atomicObjects);
|
||||
var instanceComponentsWithPath = _layerBaker.GetInstanceComponentsWithPath(instanceComponents);
|
||||
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)
|
||||
@@ -113,7 +71,7 @@ public class AutocadHostObjectBuilder : IHostObjectBuilder
|
||||
// 3 - Bake materials and colors, as they are used later down the line by layers and objects
|
||||
if (unpackedRoot.RenderMaterialProxies != null)
|
||||
{
|
||||
_materialBaker.ParseAndBakeRenderMaterials(
|
||||
materialBaker.ParseAndBakeRenderMaterials(
|
||||
unpackedRoot.RenderMaterialProxies,
|
||||
baseLayerPrefix,
|
||||
onOperationProgressed
|
||||
@@ -122,7 +80,7 @@ public class AutocadHostObjectBuilder : IHostObjectBuilder
|
||||
|
||||
if (unpackedRoot.ColorProxies != null)
|
||||
{
|
||||
_colorBaker.ParseColors(unpackedRoot.ColorProxies, onOperationProgressed);
|
||||
colorBaker.ParseColors(unpackedRoot.ColorProxies, onOperationProgressed);
|
||||
}
|
||||
|
||||
// 5 - Convert atomic objects
|
||||
@@ -134,6 +92,7 @@ public class AutocadHostObjectBuilder : IHostObjectBuilder
|
||||
{
|
||||
string objectId = atomicObject.applicationId ?? atomicObject.id.NotNull();
|
||||
onOperationProgressed.Report(new("Converting objects", (double)++count / atomicObjects.Count));
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
try
|
||||
{
|
||||
IReadOnlyCollection<Entity> convertedObjects = ConvertObject(atomicObject, layerPath, baseLayerPrefix);
|
||||
@@ -158,7 +117,7 @@ public class AutocadHostObjectBuilder : IHostObjectBuilder
|
||||
}
|
||||
|
||||
// 6 - Convert instances
|
||||
var (createdInstanceIds, consumedObjectIds, instanceConversionResults) = _instanceBaker.BakeInstances(
|
||||
var (createdInstanceIds, consumedObjectIds, instanceConversionResults) = instanceBaker.BakeInstances(
|
||||
instanceComponentsWithPath,
|
||||
applicationIdMap,
|
||||
baseLayerPrefix,
|
||||
@@ -173,7 +132,7 @@ public class AutocadHostObjectBuilder : IHostObjectBuilder
|
||||
// 7 - Create groups
|
||||
if (unpackedRoot.GroupProxies != null)
|
||||
{
|
||||
IReadOnlyCollection<ReceiveConversionResult> groupResults = _groupBaker.CreateGroups(
|
||||
IReadOnlyCollection<ReceiveConversionResult> groupResults = groupBaker.CreateGroups(
|
||||
unpackedRoot.GroupProxies,
|
||||
applicationIdMap
|
||||
);
|
||||
@@ -185,20 +144,20 @@ public class AutocadHostObjectBuilder : IHostObjectBuilder
|
||||
|
||||
private void PreReceiveDeepClean(string baseLayerPrefix)
|
||||
{
|
||||
_layerBaker.DeleteAllLayersByPrefix(baseLayerPrefix);
|
||||
_instanceBaker.PurgeInstances(baseLayerPrefix);
|
||||
_materialBaker.PurgeMaterials(baseLayerPrefix);
|
||||
layerBaker.DeleteAllLayersByPrefix(baseLayerPrefix);
|
||||
instanceBaker.PurgeInstances(baseLayerPrefix);
|
||||
materialBaker.PurgeMaterials(baseLayerPrefix);
|
||||
}
|
||||
|
||||
private IReadOnlyCollection<Entity> ConvertObject(Base obj, Collection[] layerPath, string baseLayerNamePrefix)
|
||||
{
|
||||
string layerName = _layerBaker.CreateLayerForReceive(layerPath, baseLayerNamePrefix);
|
||||
string layerName = layerBaker.CreateLayerForReceive(layerPath, baseLayerNamePrefix);
|
||||
var convertedEntities = new HashSet<Entity>();
|
||||
|
||||
using var tr = Application.DocumentManager.CurrentDocument.Database.TransactionManager.StartTransaction();
|
||||
|
||||
// 1: convert
|
||||
var converted = _converter.Convert(obj);
|
||||
var converted = converter.Convert(obj);
|
||||
|
||||
// 2: handle result
|
||||
if (converted is Entity entity)
|
||||
@@ -219,12 +178,12 @@ public class AutocadHostObjectBuilder : IHostObjectBuilder
|
||||
private Entity BakeObject(Entity entity, Base originalObject, string layerName, Base? parentObject = null)
|
||||
{
|
||||
var objId = originalObject.applicationId ?? originalObject.id.NotNull();
|
||||
if (_colorBaker.ObjectColorsIdMap.TryGetValue(objId, out AutocadColor? color))
|
||||
if (colorBaker.ObjectColorsIdMap.TryGetValue(objId, out AutocadColor? color))
|
||||
{
|
||||
entity.Color = color;
|
||||
}
|
||||
|
||||
if (_materialBaker.TryGetMaterialId(originalObject, parentObject, out ObjectId matId))
|
||||
if (materialBaker.TryGetMaterialId(originalObject, parentObject, out ObjectId matId))
|
||||
{
|
||||
entity.MaterialId = matId;
|
||||
}
|
||||
@@ -253,7 +212,7 @@ public class AutocadHostObjectBuilder : IHostObjectBuilder
|
||||
var groupDictionary = (DBDictionary)
|
||||
tr.GetObject(Application.DocumentManager.CurrentDocument.Database.GroupDictionaryId, OpenMode.ForWrite);
|
||||
|
||||
var groupName = _autocadContext.RemoveInvalidChars(
|
||||
var groupName = autocadContext.RemoveInvalidChars(
|
||||
$@"{parentObject.speckle_type.Split('.').Last()} - {parentObject.applicationId ?? parentObject.id} ({baseLayerName})"
|
||||
);
|
||||
|
||||
|
||||
+4
-11
@@ -16,7 +16,7 @@ using Speckle.Sdk.Models.Instances;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Operations.Send;
|
||||
|
||||
public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder<AutocadRootObject>
|
||||
public abstract class AutocadRootObjectBaseBuilder : RootObjectBuilderBase<AutocadRootObject>
|
||||
{
|
||||
private readonly IRootToSpeckleConverter _converter;
|
||||
private readonly string[] _documentPathSeparator = ["\\"];
|
||||
@@ -49,13 +49,6 @@ public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder<AutocadR
|
||||
_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",
|
||||
@@ -65,11 +58,11 @@ public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder<AutocadR
|
||||
proxy classes yet. So I'm supressing this one now!!!
|
||||
"""
|
||||
)]
|
||||
private RootObjectBuilderResult BuildSync(
|
||||
public override RootObjectBuilderResult Build(
|
||||
IReadOnlyList<AutocadRootObject> objects,
|
||||
SendInfo sendInfo,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken ct = default
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
// 0 - Init the root
|
||||
@@ -101,7 +94,7 @@ public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder<AutocadR
|
||||
int count = 0;
|
||||
foreach (var (entity, applicationId) in atomicObjects)
|
||||
{
|
||||
ct.ThrowIfCancellationRequested();
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
using (var convertActivity = _activityFactory.Start("Converting object"))
|
||||
{
|
||||
// Create and add a collection for this entity if not done so already.
|
||||
|
||||
@@ -273,9 +273,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -283,9 +283,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -310,7 +309,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -348,41 +347,35 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,9 +273,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -283,9 +283,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -310,7 +309,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -348,41 +347,35 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,9 +273,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -283,9 +283,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -310,7 +309,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -348,41 +347,35 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,9 +229,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -239,9 +239,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -267,7 +266,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -305,40 +304,34 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
|
||||
@@ -4,8 +4,10 @@ using Speckle.Connectors.Autocad.Bindings;
|
||||
using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Converters.Autocad;
|
||||
@@ -32,7 +34,10 @@ public sealed class Civil3dSendBinding : AutocadSendBaseBinding
|
||||
ILogger<AutocadSendBinding> logger,
|
||||
ICivil3dConversionSettingsFactory civil3dConversionSettingsFactory,
|
||||
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
|
||||
ISpeckleApplication speckleApplication
|
||||
ISpeckleApplication speckleApplication,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IThreadContext threadContext,
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
: base(
|
||||
store,
|
||||
@@ -44,7 +49,10 @@ public sealed class Civil3dSendBinding : AutocadSendBaseBinding
|
||||
sendConversionCache,
|
||||
operationProgressManager,
|
||||
logger,
|
||||
speckleApplication
|
||||
speckleApplication,
|
||||
topLevelExceptionHandler,
|
||||
threadContext,
|
||||
eventAggregator
|
||||
)
|
||||
{
|
||||
_civil3dConversionSettingsFactory = civil3dConversionSettingsFactory;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Speckle.Connectors.CSiShared.Utils;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Converters.CSiShared.Utils;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared.Bindings;
|
||||
|
||||
@@ -25,18 +26,6 @@ public class CsiSharedSelectionBinding : ISelectionBinding
|
||||
/// </remarks>
|
||||
public SelectionInfo GetSelection()
|
||||
{
|
||||
// TODO: Since this is standard across CSi Suite - better stored in an enum?
|
||||
var objectTypeMap = new Dictionary<int, string>
|
||||
{
|
||||
{ 1, "Point" },
|
||||
{ 2, "Frame" },
|
||||
{ 3, "Cable" },
|
||||
{ 4, "Tendon" },
|
||||
{ 5, "Area" },
|
||||
{ 6, "Solid" },
|
||||
{ 7, "Link" }
|
||||
};
|
||||
|
||||
int numberItems = 0;
|
||||
int[] objectType = Array.Empty<int>();
|
||||
string[] objectName = Array.Empty<string>();
|
||||
@@ -48,10 +37,10 @@ public class CsiSharedSelectionBinding : ISelectionBinding
|
||||
|
||||
for (int i = 0; i < numberItems; i++)
|
||||
{
|
||||
var typeKey = objectType[i];
|
||||
var typeName = objectTypeMap.TryGetValue(typeKey, out var name) ? name : $"Unknown ({typeKey})";
|
||||
var typeKey = (ModelObjectType)objectType[i];
|
||||
var typeName = typeKey.ToString();
|
||||
|
||||
encodedIds.Add(ObjectIdentifier.Encode(typeKey, objectName[i]));
|
||||
encodedIds.Add(ObjectIdentifier.Encode(objectType[i], objectName[i]));
|
||||
typeCounts[typeName] = (typeCounts.TryGetValue(typeName, out var count) ? count : 0) + 1; // NOTE: Cross-framework compatibility (net 48 and net8)
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ public sealed class CsiSharedSendBinding : ISendBinding
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly IAppIdleManager _idleManager;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly List<ISendFilter> _sendFilters;
|
||||
private readonly CancellationManager _cancellationManager;
|
||||
@@ -40,7 +39,6 @@ public sealed class CsiSharedSendBinding : ISendBinding
|
||||
|
||||
public CsiSharedSendBinding(
|
||||
DocumentModelStore store,
|
||||
IAppIdleManager idleManager,
|
||||
IBrowserBridge parent,
|
||||
IEnumerable<ISendFilter> sendFilters,
|
||||
IServiceProvider serviceProvider,
|
||||
@@ -54,7 +52,6 @@ public sealed class CsiSharedSendBinding : ISendBinding
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
_idleManager = idleManager;
|
||||
_serviceProvider = serviceProvider;
|
||||
_sendFilters = sendFilters.ToList();
|
||||
_cancellationManager = cancellationManager;
|
||||
@@ -107,12 +104,9 @@ public sealed class CsiSharedSendBinding : ISendBinding
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
);
|
||||
|
||||
await Commands
|
||||
.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults)
|
||||
.ConfigureAwait(false);
|
||||
await Commands.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -121,7 +115,7 @@ public sealed class CsiSharedSendBinding : ISendBinding
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogModelCardHandledError(ex);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
await Commands.SetModelError(modelCardId, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using Speckle.Sdk.Common;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared.HostApp;
|
||||
|
||||
/// <summary>
|
||||
@@ -18,17 +20,14 @@ public interface ICsiApplicationService
|
||||
|
||||
public class CsiApplicationService : ICsiApplicationService
|
||||
{
|
||||
public cSapModel SapModel { get; private set; }
|
||||
private cPluginCallback _pluginCallback;
|
||||
private cSapModel? _sapModel;
|
||||
public cSapModel SapModel => _sapModel.NotNull();
|
||||
|
||||
public CsiApplicationService()
|
||||
{
|
||||
SapModel = null!;
|
||||
}
|
||||
private cPluginCallback? _pluginCallback;
|
||||
|
||||
public void Initialize(cSapModel sapModel, cPluginCallback pluginCallback)
|
||||
{
|
||||
SapModel = sapModel;
|
||||
_sapModel = sapModel;
|
||||
_pluginCallback = pluginCallback;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared.HostApp;
|
||||
|
||||
public sealed class CsiIdleManager : AppIdleManager
|
||||
{
|
||||
private readonly IIdleCallManager _idleCallManager;
|
||||
|
||||
public CsiIdleManager(IIdleCallManager idleCallManager)
|
||||
: base(idleCallManager)
|
||||
{
|
||||
_idleCallManager = idleCallManager;
|
||||
}
|
||||
|
||||
protected override void AddEvent()
|
||||
{
|
||||
// TODO: CSi specific idle handling can be added here if needed
|
||||
_idleCallManager.AppOnIdle(() => { });
|
||||
}
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.CSiShared;
|
||||
using Speckle.Converters.CSiShared.Utils;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared.HostApp.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Base frame section property extractor for CSi products.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Handles common Csi API calls for frame section properties
|
||||
/// Provides foundation for application-specific extractors.
|
||||
/// </remarks>
|
||||
public class CsiFrameSectionPropertyExtractor : IFrameSectionPropertyExtractor
|
||||
{
|
||||
private readonly IConverterSettingsStore<CsiConversionSettings> _settingsStore;
|
||||
|
||||
public CsiFrameSectionPropertyExtractor(IConverterSettingsStore<CsiConversionSettings> settingsStore)
|
||||
{
|
||||
_settingsStore = settingsStore;
|
||||
}
|
||||
|
||||
public void ExtractProperties(string sectionName, Dictionary<string, object?> properties)
|
||||
{
|
||||
GetMaterialName(sectionName, properties);
|
||||
GetSectionProperties(sectionName, properties);
|
||||
GetPropertyModifiers(sectionName, properties);
|
||||
}
|
||||
|
||||
private void GetMaterialName(string sectionName, Dictionary<string, object?> properties)
|
||||
{
|
||||
// get material name
|
||||
string materialName = string.Empty;
|
||||
_settingsStore.Current.SapModel.PropFrame.GetMaterial(sectionName, ref materialName);
|
||||
|
||||
// append to General Data of properties dictionary
|
||||
Dictionary<string, object?> generalData = DictionaryUtils.EnsureNestedDictionary(
|
||||
properties,
|
||||
SectionPropertyCategory.GENERAL_DATA
|
||||
);
|
||||
generalData["material"] = materialName;
|
||||
}
|
||||
|
||||
private void GetSectionProperties(string sectionName, Dictionary<string, object?> properties)
|
||||
{
|
||||
double crossSectionalArea = 0,
|
||||
shearAreaInMajorAxisDirection = 0,
|
||||
shearAreaInMinorAxisDirection = 0,
|
||||
torsionalConstant = 0,
|
||||
momentOfInertiaAboutMajorAxis = 0,
|
||||
momentOfInertiaAboutMinorAxis = 0,
|
||||
sectionModulusAboutMajorAxis = 0,
|
||||
sectionModulusAboutMinorAxis = 0,
|
||||
plasticModulusAboutMajorAxis = 0,
|
||||
plasticModulusAboutMinorAxis = 0,
|
||||
radiusOfGyrationAboutMajorAxis = 0,
|
||||
radiusOfGyrationAboutMinorAxis = 0;
|
||||
|
||||
_settingsStore.Current.SapModel.PropFrame.GetSectProps(
|
||||
sectionName,
|
||||
ref crossSectionalArea,
|
||||
ref shearAreaInMajorAxisDirection,
|
||||
ref shearAreaInMinorAxisDirection,
|
||||
ref torsionalConstant,
|
||||
ref momentOfInertiaAboutMajorAxis,
|
||||
ref momentOfInertiaAboutMinorAxis,
|
||||
ref sectionModulusAboutMajorAxis,
|
||||
ref sectionModulusAboutMinorAxis,
|
||||
ref plasticModulusAboutMajorAxis,
|
||||
ref plasticModulusAboutMinorAxis,
|
||||
ref radiusOfGyrationAboutMajorAxis,
|
||||
ref radiusOfGyrationAboutMinorAxis
|
||||
);
|
||||
|
||||
Dictionary<string, object?> mechanicalProperties = DictionaryUtils.EnsureNestedDictionary(
|
||||
properties,
|
||||
SectionPropertyCategory.SECTION_PROPERTIES
|
||||
);
|
||||
mechanicalProperties["area"] = crossSectionalArea;
|
||||
mechanicalProperties["As2"] = shearAreaInMajorAxisDirection;
|
||||
mechanicalProperties["As3"] = shearAreaInMinorAxisDirection;
|
||||
mechanicalProperties["torsion"] = torsionalConstant;
|
||||
mechanicalProperties["I22"] = momentOfInertiaAboutMajorAxis;
|
||||
mechanicalProperties["I33"] = momentOfInertiaAboutMinorAxis;
|
||||
mechanicalProperties["S22"] = sectionModulusAboutMajorAxis;
|
||||
mechanicalProperties["S33"] = sectionModulusAboutMinorAxis;
|
||||
mechanicalProperties["Z22"] = plasticModulusAboutMajorAxis;
|
||||
mechanicalProperties["Z33"] = plasticModulusAboutMinorAxis;
|
||||
mechanicalProperties["R22"] = radiusOfGyrationAboutMajorAxis;
|
||||
mechanicalProperties["R33"] = radiusOfGyrationAboutMinorAxis;
|
||||
}
|
||||
|
||||
private void GetPropertyModifiers(string sectionName, Dictionary<string, object?> properties)
|
||||
{
|
||||
double[] stiffnessModifiersArray = [];
|
||||
_settingsStore.Current.SapModel.PropFrame.GetModifiers(sectionName, ref stiffnessModifiersArray);
|
||||
|
||||
Dictionary<string, object?> modifiers =
|
||||
new()
|
||||
{
|
||||
["crossSectionalAreaModifier"] = stiffnessModifiersArray[0],
|
||||
["shearAreaInLocal2DirectionModifier"] = stiffnessModifiersArray[1],
|
||||
["shearAreaInLocal3DirectionModifier"] = stiffnessModifiersArray[2],
|
||||
["torsionalConstantModifier"] = stiffnessModifiersArray[3],
|
||||
["momentOfInertiaAboutLocal2AxisModifier"] = stiffnessModifiersArray[4],
|
||||
["momentOfInertiaAboutLocal3AxisModifier"] = stiffnessModifiersArray[5],
|
||||
["mass"] = stiffnessModifiersArray[6],
|
||||
["weight"] = stiffnessModifiersArray[7],
|
||||
};
|
||||
|
||||
Dictionary<string, object?> generalData = DictionaryUtils.EnsureNestedDictionary(
|
||||
properties,
|
||||
SectionPropertyCategory.GENERAL_DATA
|
||||
);
|
||||
generalData["modifiers"] = modifiers;
|
||||
}
|
||||
}
|
||||
+212
@@ -0,0 +1,212 @@
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.CSiShared;
|
||||
using Speckle.Converters.CSiShared.Utils;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared.HostApp.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Base material property extractor for CSi products.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Currently, all material property extraction can happen on a CsiShared level which simplifies things a lot.
|
||||
/// Properties depend on the directional symmetry of the material, hence the switch statements.
|
||||
/// </remarks>
|
||||
public class CsiMaterialPropertyExtractor
|
||||
{
|
||||
/// <summary>
|
||||
/// Property strings for all mechanical properties, used by numerous methods.
|
||||
/// </summary>
|
||||
private static class MechanicalPropertyNames
|
||||
{
|
||||
public const string MODULUS_OF_ELASTICITY = "modulusOfElasticity";
|
||||
public const string MODULUS_OF_ELASTICITY_ARRAY = "modulusOfElasticityArray";
|
||||
public const string POISSON_RATIO = "poissonRatio";
|
||||
public const string POISSON_RATIO_ARRAY = "poissonRatioArray";
|
||||
public const string THERMAL_COEFFICIENT = "thermalCoefficient";
|
||||
public const string THERMAL_COEFFICIENT_ARRAY = "thermalCoefficientArray";
|
||||
public const string SHEAR_MODULUS = "shearModulus";
|
||||
public const string SHEAR_MODULUS_ARRAY = "shearModulusArray";
|
||||
}
|
||||
|
||||
private readonly IConverterSettingsStore<CsiConversionSettings> _settingsStore;
|
||||
|
||||
public CsiMaterialPropertyExtractor(IConverterSettingsStore<CsiConversionSettings> settingsStore)
|
||||
{
|
||||
_settingsStore = settingsStore;
|
||||
}
|
||||
|
||||
public void ExtractProperties(string materialName, Dictionary<string, object?> properties)
|
||||
{
|
||||
GetGeneralProperties(materialName, properties);
|
||||
GetWeightAndMassProperties(materialName, properties);
|
||||
GetMechanicalProperties(materialName, properties);
|
||||
}
|
||||
|
||||
private void GetGeneralProperties(string materialName, Dictionary<string, object?> properties)
|
||||
{
|
||||
{
|
||||
eMatType materialType = default;
|
||||
int materialColor = 0;
|
||||
string materialNotes = string.Empty;
|
||||
string materialGuid = string.Empty;
|
||||
|
||||
_settingsStore.Current.SapModel.PropMaterial.GetMaterial(
|
||||
materialName,
|
||||
ref materialType,
|
||||
ref materialColor,
|
||||
ref materialNotes,
|
||||
ref materialGuid
|
||||
);
|
||||
|
||||
var generalData = DictionaryUtils.EnsureNestedDictionary(properties, SectionPropertyCategory.GENERAL_DATA);
|
||||
generalData["name"] = materialName;
|
||||
generalData["type"] = materialType.ToString();
|
||||
generalData["notes"] = materialNotes;
|
||||
}
|
||||
}
|
||||
|
||||
private void GetWeightAndMassProperties(string materialName, Dictionary<string, object?> properties)
|
||||
{
|
||||
double weightPerUnitVolume = double.NaN;
|
||||
double massPerUnitVolume = double.NaN;
|
||||
|
||||
_settingsStore.Current.SapModel.PropMaterial.GetWeightAndMass(
|
||||
materialName,
|
||||
ref weightPerUnitVolume,
|
||||
ref massPerUnitVolume
|
||||
);
|
||||
|
||||
var weightAndMass = DictionaryUtils.EnsureNestedDictionary(properties, "Weight and Mass");
|
||||
weightAndMass["w"] = weightPerUnitVolume;
|
||||
weightAndMass["m"] = massPerUnitVolume;
|
||||
}
|
||||
|
||||
private void GetMechanicalProperties(string materialName, Dictionary<string, object?> properties)
|
||||
{
|
||||
int materialDirectionalSymmetryKey = 0;
|
||||
eMatType materialType = default;
|
||||
|
||||
_settingsStore.Current.SapModel.PropMaterial.GetTypeOAPI(
|
||||
materialName,
|
||||
ref materialType,
|
||||
ref materialDirectionalSymmetryKey
|
||||
);
|
||||
|
||||
var materialDirectionalSymmetryValue = materialDirectionalSymmetryKey switch
|
||||
{
|
||||
0 => DirectionalSymmetryType.ISOTROPIC,
|
||||
1 => DirectionalSymmetryType.ORTHOTROPIC,
|
||||
2 => DirectionalSymmetryType.ANISOTROPIC,
|
||||
3 => DirectionalSymmetryType.UNIAXIAL,
|
||||
_ => throw new ArgumentException($"Unknown symmetry type: {materialDirectionalSymmetryKey}")
|
||||
};
|
||||
|
||||
var mechanicalProperties = DictionaryUtils.EnsureNestedDictionary(properties, "Mechanical Properties");
|
||||
mechanicalProperties["directionalSymmetryType"] = materialDirectionalSymmetryValue.ToString();
|
||||
|
||||
GetMechanicalPropertiesByType(materialName, materialDirectionalSymmetryValue, mechanicalProperties);
|
||||
}
|
||||
|
||||
private void GetMechanicalPropertiesByType(
|
||||
string materialName,
|
||||
DirectionalSymmetryType directionalSymmetryType,
|
||||
Dictionary<string, object?> mechanicalProperties
|
||||
)
|
||||
{
|
||||
switch (directionalSymmetryType)
|
||||
{
|
||||
case DirectionalSymmetryType.ISOTROPIC:
|
||||
ExtractIsotropicProperties(materialName, mechanicalProperties);
|
||||
break;
|
||||
case DirectionalSymmetryType.ORTHOTROPIC:
|
||||
ExtractOrthotropicProperties(materialName, mechanicalProperties);
|
||||
break;
|
||||
case DirectionalSymmetryType.ANISOTROPIC:
|
||||
ExtractAnisotropicProperties(materialName, mechanicalProperties);
|
||||
break;
|
||||
case DirectionalSymmetryType.UNIAXIAL:
|
||||
ExtractUniaxialProperties(materialName, mechanicalProperties);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException($"Unknown directional symmetry type: {directionalSymmetryType}");
|
||||
}
|
||||
}
|
||||
|
||||
private void ExtractIsotropicProperties(string materialName, Dictionary<string, object?> mechanicalProperties)
|
||||
{
|
||||
double modulusOfElasticity = double.NaN;
|
||||
double poissonRatio = double.NaN;
|
||||
double thermalCoefficient = double.NaN;
|
||||
double shearModulus = double.NaN;
|
||||
|
||||
_settingsStore.Current.SapModel.PropMaterial.GetMPIsotropic(
|
||||
materialName,
|
||||
ref modulusOfElasticity,
|
||||
ref poissonRatio,
|
||||
ref thermalCoefficient,
|
||||
ref shearModulus
|
||||
);
|
||||
|
||||
mechanicalProperties[MechanicalPropertyNames.MODULUS_OF_ELASTICITY] = modulusOfElasticity;
|
||||
mechanicalProperties[MechanicalPropertyNames.POISSON_RATIO] = poissonRatio;
|
||||
mechanicalProperties[MechanicalPropertyNames.THERMAL_COEFFICIENT] = thermalCoefficient;
|
||||
mechanicalProperties[MechanicalPropertyNames.SHEAR_MODULUS] = shearModulus;
|
||||
}
|
||||
|
||||
private void ExtractOrthotropicProperties(string materialName, Dictionary<string, object?> mechanicalProperties)
|
||||
{
|
||||
double[] modulusOfElasticityArray = [];
|
||||
double[] poissonRatioArray = [];
|
||||
double[] thermalCoefficientArray = [];
|
||||
double[] shearModulusArray = [];
|
||||
|
||||
_settingsStore.Current.SapModel.PropMaterial.GetMPOrthotropic(
|
||||
materialName,
|
||||
ref modulusOfElasticityArray,
|
||||
ref poissonRatioArray,
|
||||
ref thermalCoefficientArray,
|
||||
ref shearModulusArray
|
||||
);
|
||||
|
||||
mechanicalProperties[MechanicalPropertyNames.MODULUS_OF_ELASTICITY_ARRAY] = modulusOfElasticityArray;
|
||||
mechanicalProperties[MechanicalPropertyNames.POISSON_RATIO_ARRAY] = poissonRatioArray;
|
||||
mechanicalProperties[MechanicalPropertyNames.THERMAL_COEFFICIENT_ARRAY] = thermalCoefficientArray;
|
||||
mechanicalProperties[MechanicalPropertyNames.SHEAR_MODULUS_ARRAY] = shearModulusArray;
|
||||
}
|
||||
|
||||
private void ExtractAnisotropicProperties(string materialName, Dictionary<string, object?> mechanicalProperties)
|
||||
{
|
||||
double[] modulusOfElasticityArray = [];
|
||||
double[] poissonRatioArray = [];
|
||||
double[] thermalCoefficientArray = [];
|
||||
double[] shearModulusArray = [];
|
||||
|
||||
_settingsStore.Current.SapModel.PropMaterial.GetMPAnisotropic(
|
||||
materialName,
|
||||
ref modulusOfElasticityArray,
|
||||
ref poissonRatioArray,
|
||||
ref thermalCoefficientArray,
|
||||
ref shearModulusArray
|
||||
);
|
||||
|
||||
mechanicalProperties[MechanicalPropertyNames.MODULUS_OF_ELASTICITY_ARRAY] = modulusOfElasticityArray;
|
||||
mechanicalProperties[MechanicalPropertyNames.POISSON_RATIO_ARRAY] = poissonRatioArray;
|
||||
mechanicalProperties[MechanicalPropertyNames.THERMAL_COEFFICIENT_ARRAY] = thermalCoefficientArray;
|
||||
mechanicalProperties[MechanicalPropertyNames.SHEAR_MODULUS_ARRAY] = shearModulusArray;
|
||||
}
|
||||
|
||||
private void ExtractUniaxialProperties(string materialName, Dictionary<string, object?> mechanicalProperties)
|
||||
{
|
||||
double modulusOfElasticity = double.NaN;
|
||||
double thermalCoefficient = double.NaN;
|
||||
|
||||
_settingsStore.Current.SapModel.PropMaterial.GetMPUniaxial(
|
||||
materialName,
|
||||
ref modulusOfElasticity,
|
||||
ref thermalCoefficient
|
||||
);
|
||||
|
||||
mechanicalProperties[MechanicalPropertyNames.MODULUS_OF_ELASTICITY] = modulusOfElasticity;
|
||||
mechanicalProperties[MechanicalPropertyNames.THERMAL_COEFFICIENT] = thermalCoefficient;
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.CSiShared;
|
||||
using Speckle.Converters.CSiShared.Utils;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared.HostApp.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Base shell section property extractor for CSi products.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Handles common Csi API calls for shell section properties.
|
||||
/// Provides foundation for application-specific extractors.
|
||||
/// </remarks>
|
||||
public class CsiShellSectionPropertyExtractor : IShellSectionPropertyExtractor
|
||||
{
|
||||
private readonly IConverterSettingsStore<CsiConversionSettings> _settingsStore;
|
||||
|
||||
public CsiShellSectionPropertyExtractor(IConverterSettingsStore<CsiConversionSettings> settingsStore)
|
||||
{
|
||||
_settingsStore = settingsStore;
|
||||
}
|
||||
|
||||
public void ExtractProperties(string sectionName, Dictionary<string, object?> properties)
|
||||
{
|
||||
GetPropertyType(sectionName, properties);
|
||||
GetPropertyModifiers(sectionName, properties);
|
||||
}
|
||||
|
||||
private void GetPropertyType(string sectionName, Dictionary<string, object?> properties)
|
||||
{
|
||||
int propertyTypeKey = 1;
|
||||
_settingsStore.Current.SapModel.PropArea.GetTypeOAPI(sectionName, ref propertyTypeKey);
|
||||
var propertyTypeValue = propertyTypeKey switch
|
||||
{
|
||||
1 => AreaPropertyType.SHELL,
|
||||
2 => AreaPropertyType.PLANE,
|
||||
3 => AreaPropertyType.ASOLID,
|
||||
_ => throw new ArgumentException($"Unknown property type: {propertyTypeKey}"),
|
||||
};
|
||||
|
||||
var generalData = DictionaryUtils.EnsureNestedDictionary(properties, SectionPropertyCategory.GENERAL_DATA);
|
||||
generalData["propertyType"] = propertyTypeValue;
|
||||
}
|
||||
|
||||
private void GetPropertyModifiers(string sectionName, Dictionary<string, object?> properties)
|
||||
{
|
||||
double[] stiffnessModifiersArray = [];
|
||||
_settingsStore.Current.SapModel.PropArea.GetModifiers(sectionName, ref stiffnessModifiersArray);
|
||||
|
||||
Dictionary<string, object?> modifiers =
|
||||
new()
|
||||
{
|
||||
["f11"] = stiffnessModifiersArray[0],
|
||||
["f22"] = stiffnessModifiersArray[1],
|
||||
["f12"] = stiffnessModifiersArray[2],
|
||||
["m11"] = stiffnessModifiersArray[3],
|
||||
["m22"] = stiffnessModifiersArray[3],
|
||||
["m12"] = stiffnessModifiersArray[4],
|
||||
["v13"] = stiffnessModifiersArray[5],
|
||||
["v23"] = stiffnessModifiersArray[6],
|
||||
["mass"] = stiffnessModifiersArray[7],
|
||||
["weight"] = stiffnessModifiersArray[8]
|
||||
};
|
||||
|
||||
var generalData = DictionaryUtils.EnsureNestedDictionary(properties, SectionPropertyCategory.GENERAL_DATA);
|
||||
generalData["modifiers"] = modifiers;
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
namespace Speckle.Connectors.CSiShared.HostApp.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Contract for host application specific section property extraction.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Mirrors property extraction system pattern by composing with base extractor.
|
||||
/// Enables both shared and application-specific property extraction in one call.
|
||||
/// </remarks>
|
||||
public interface IApplicationSectionPropertyExtractor
|
||||
{
|
||||
void ExtractProperties(string sectionName, Dictionary<string, object?> properties);
|
||||
}
|
||||
|
||||
// NOTE: Seemingly silly, but allows us to register the correct extractor for the correct type.
|
||||
public interface IApplicationFrameSectionPropertyExtractor : IApplicationSectionPropertyExtractor { }
|
||||
|
||||
public interface IApplicationShellSectionPropertyExtractor : IApplicationSectionPropertyExtractor { }
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
namespace Speckle.Connectors.CSiShared.HostApp.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Core contract for section property extraction common across CSi products.
|
||||
/// </summary>
|
||||
public interface ISectionPropertyExtractor
|
||||
{
|
||||
void ExtractProperties(string sectionName, Dictionary<string, object?> properties);
|
||||
}
|
||||
|
||||
// NOTE: Seemingly silly, but allows us to register the correct extractor for the correct type.
|
||||
public interface IFrameSectionPropertyExtractor : ISectionPropertyExtractor { }
|
||||
|
||||
public interface IShellSectionPropertyExtractor : ISectionPropertyExtractor { }
|
||||
@@ -0,0 +1,10 @@
|
||||
using Speckle.Sdk.Models.Proxies;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared.HostApp.Helpers;
|
||||
|
||||
// NOTE: Interface because Etabs and Sap2000 section unpacking and extraction is different.
|
||||
// At ServiceRegistration, we inject the correct implementation of the ISectionUnpacker
|
||||
public interface ISectionUnpacker
|
||||
{
|
||||
IEnumerable<GroupProxy> UnpackSections();
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using Speckle.Connectors.CSiShared.HostApp.Helpers;
|
||||
using Speckle.Converters.CSiShared.ToSpeckle.Helpers;
|
||||
using Speckle.Sdk.Models.Proxies;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared.HostApp;
|
||||
|
||||
/// <summary>
|
||||
/// Creates material proxies based on stored entries from the materials cache
|
||||
/// </summary>
|
||||
public class MaterialUnpacker
|
||||
{
|
||||
private readonly CsiMaterialPropertyExtractor _propertyExtractor;
|
||||
private readonly CsiToSpeckleCacheSingleton _csiToSpeckleCacheSingleton;
|
||||
|
||||
public MaterialUnpacker(
|
||||
CsiMaterialPropertyExtractor propertyExtractor,
|
||||
CsiToSpeckleCacheSingleton csiToSpeckleCacheSingleton
|
||||
)
|
||||
{
|
||||
_propertyExtractor = propertyExtractor;
|
||||
_csiToSpeckleCacheSingleton = csiToSpeckleCacheSingleton;
|
||||
}
|
||||
|
||||
// Creates a list of material proxies from the csi materials cache
|
||||
public IEnumerable<IProxyCollection> UnpackMaterials()
|
||||
{
|
||||
foreach (var kvp in _csiToSpeckleCacheSingleton.MaterialCache)
|
||||
{
|
||||
// get the cached entry
|
||||
string materialName = kvp.Key;
|
||||
List<string> sectionIds = kvp.Value;
|
||||
|
||||
// get the properties of the material
|
||||
Dictionary<string, object?> properties = new(); // create empty dictionary
|
||||
_propertyExtractor.ExtractProperties(materialName, properties); // dictionary mutated with respective properties
|
||||
|
||||
// create the material proxy
|
||||
GroupProxy materialProxy =
|
||||
new()
|
||||
{
|
||||
id = materialName,
|
||||
name = materialName,
|
||||
applicationId = materialName,
|
||||
objects = sectionIds,
|
||||
["properties"] = properties
|
||||
};
|
||||
|
||||
yield return materialProxy;
|
||||
}
|
||||
}
|
||||
}
|
||||
+49
-9
@@ -4,6 +4,7 @@ using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Conversion;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.CSiShared.HostApp;
|
||||
using Speckle.Connectors.CSiShared.HostApp.Helpers;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.CSiShared;
|
||||
using Speckle.Sdk;
|
||||
@@ -13,12 +14,27 @@ using Speckle.Sdk.Models.Collections;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared.Builders;
|
||||
|
||||
/// <summary>
|
||||
/// Manages the conversion of CSi model objects and establishes proxy-based relationships.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Core responsibilities:
|
||||
/// - Converts ICsiWrappers to Speckle objects through caching-aware conversion
|
||||
/// - Creates proxy objects for materials and sections from model data
|
||||
/// - Establishes relationships between objects and their dependencies
|
||||
///
|
||||
/// The builder follows a two-phase process:
|
||||
/// 1. Conversion Phase: ICsiWrappers → Speckle objects with cached results handling
|
||||
/// 2. Relationship Phase: Material/section proxy creation and relationship mapping
|
||||
/// </remarks>
|
||||
public class CsiRootObjectBuilder : IRootObjectBuilder<ICsiWrapper>
|
||||
{
|
||||
private readonly IRootToSpeckleConverter _rootToSpeckleConverter;
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly IConverterSettingsStore<CsiConversionSettings> _converterSettings;
|
||||
private readonly CsiSendCollectionManager _sendCollectionManager;
|
||||
private readonly MaterialUnpacker _materialUnpacker;
|
||||
private readonly ISectionUnpacker _sectionUnpacker;
|
||||
private readonly ILogger<CsiRootObjectBuilder> _logger;
|
||||
private readonly ISdkActivityFactory _activityFactory;
|
||||
private readonly ICsiApplicationService _csiApplicationService;
|
||||
@@ -28,6 +44,8 @@ public class CsiRootObjectBuilder : IRootObjectBuilder<ICsiWrapper>
|
||||
ISendConversionCache sendConversionCache,
|
||||
IConverterSettingsStore<CsiConversionSettings> converterSettings,
|
||||
CsiSendCollectionManager sendCollectionManager,
|
||||
MaterialUnpacker materialUnpacker,
|
||||
ISectionUnpacker sectionUnpacker,
|
||||
ILogger<CsiRootObjectBuilder> logger,
|
||||
ISdkActivityFactory activityFactory,
|
||||
ICsiApplicationService csiApplicationService
|
||||
@@ -36,24 +54,35 @@ public class CsiRootObjectBuilder : IRootObjectBuilder<ICsiWrapper>
|
||||
_sendConversionCache = sendConversionCache;
|
||||
_converterSettings = converterSettings;
|
||||
_sendCollectionManager = sendCollectionManager;
|
||||
_materialUnpacker = materialUnpacker;
|
||||
_sectionUnpacker = sectionUnpacker;
|
||||
_rootToSpeckleConverter = rootToSpeckleConverter;
|
||||
_logger = logger;
|
||||
_activityFactory = activityFactory;
|
||||
_csiApplicationService = csiApplicationService;
|
||||
}
|
||||
|
||||
public async Task<RootObjectBuilderResult> Build(
|
||||
/// <summary>
|
||||
/// Converts Csi objects into a Speckle-compatible object hierarchy with established relationships.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Operation sequence:
|
||||
/// 1. Creates root collection with model metadata
|
||||
/// 2. Converts each object with caching and progress tracking
|
||||
/// 3. Creates proxies for materials and sections
|
||||
/// </remarks>
|
||||
public async Task<RootObjectBuilderResult> BuildAsync(
|
||||
IReadOnlyList<ICsiWrapper> csiObjects,
|
||||
SendInfo sendInfo,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken = default
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
using var activity = _activityFactory.Start("Build");
|
||||
|
||||
string modelFileName = _csiApplicationService.SapModel.GetModelFilename(false) ?? "Unnamed model";
|
||||
Collection rootObjectCollection = new() { name = modelFileName };
|
||||
rootObjectCollection["units"] = _converterSettings.Current.SpeckleUnits;
|
||||
Collection rootObjectCollection =
|
||||
new() { name = modelFileName, ["units"] = _converterSettings.Current.SpeckleUnits };
|
||||
|
||||
List<SendConversionResult> results = new(csiObjects.Count);
|
||||
int count = 0;
|
||||
@@ -62,14 +91,15 @@ public class CsiRootObjectBuilder : IRootObjectBuilder<ICsiWrapper>
|
||||
{
|
||||
foreach (ICsiWrapper csiObject in csiObjects)
|
||||
{
|
||||
using var _2 = _activityFactory.Start("Convert");
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
using var _2 = _activityFactory.Start("Convert");
|
||||
|
||||
var result = ConvertCSiObject(csiObject, rootObjectCollection, sendInfo.ProjectId);
|
||||
var result = ConvertCsiObject(csiObject, rootObjectCollection, sendInfo.ProjectId);
|
||||
results.Add(result);
|
||||
|
||||
count++;
|
||||
onOperationProgressed.Report(new("Converting", (double)count / csiObjects.Count));
|
||||
await Task.Yield();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,11 +108,22 @@ public class CsiRootObjectBuilder : IRootObjectBuilder<ICsiWrapper>
|
||||
throw new SpeckleException("Failed to convert all objects.");
|
||||
}
|
||||
|
||||
await Task.Yield();
|
||||
using (var _ = _activityFactory.Start("Process Proxies"))
|
||||
{
|
||||
// Create and add material proxies
|
||||
rootObjectCollection[ProxyKeys.MATERIAL] = _materialUnpacker.UnpackMaterials().ToList();
|
||||
|
||||
// Create and all section proxies (frame and shell)
|
||||
rootObjectCollection[ProxyKeys.SECTION] = _sectionUnpacker.UnpackSections().ToList();
|
||||
}
|
||||
|
||||
return new RootObjectBuilderResult(rootObjectCollection, results);
|
||||
}
|
||||
|
||||
private SendConversionResult ConvertCSiObject(ICsiWrapper csiObject, Collection typeCollection, string projectId)
|
||||
/// <summary>
|
||||
/// Converts a single Csi wrapper "object" to a data object with appropriate collection management.
|
||||
/// </summary>
|
||||
private SendConversionResult ConvertCsiObject(ICsiWrapper csiObject, Collection typeCollection, string projectId)
|
||||
{
|
||||
string applicationId = $"{csiObject.ObjectType}{csiObject.Name}"; // TODO: NO! Use GUID
|
||||
string sourceType = csiObject.ObjectName;
|
||||
@@ -100,7 +141,6 @@ public class CsiRootObjectBuilder : IRootObjectBuilder<ICsiWrapper>
|
||||
}
|
||||
|
||||
var collection = _sendCollectionManager.AddObjectCollectionToRoot(converted, typeCollection);
|
||||
collection.elements ??= new List<Base>();
|
||||
collection.elements.Add(converted);
|
||||
|
||||
return new(Status.SUCCESS, applicationId, sourceType, converted);
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Windows.Forms.Integration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.Common;
|
||||
using Speckle.Connectors.CSiShared.HostApp;
|
||||
using Speckle.Connectors.DUI;
|
||||
using Speckle.Connectors.DUI.WebView;
|
||||
using Speckle.Converters.CSiShared;
|
||||
using Speckle.Sdk.Host;
|
||||
@@ -25,6 +26,7 @@ public abstract class SpeckleFormBase : Form
|
||||
ConfigureServices(services);
|
||||
|
||||
Container = services.BuildServiceProvider();
|
||||
Container.UseDUI(false);
|
||||
|
||||
var webview = Container.GetRequiredService<DUI3ControlWebView>();
|
||||
Host = new() { Child = webview, Dock = DockStyle.Fill };
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.Common;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.CSiShared.Bindings;
|
||||
using Speckle.Connectors.CSiShared.Builders;
|
||||
using Speckle.Connectors.CSiShared.Filters;
|
||||
using Speckle.Connectors.CSiShared.HostApp;
|
||||
using Speckle.Connectors.CSiShared.HostApp.Helpers;
|
||||
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;
|
||||
using Speckle.Converters.CSiShared;
|
||||
using Speckle.Converters.CSiShared.ToSpeckle.Helpers;
|
||||
|
||||
namespace Speckle.Connectors.CSiShared;
|
||||
|
||||
@@ -24,18 +26,15 @@ public static class ServiceRegistration
|
||||
services.AddSingleton<ICsiApplicationService, CsiApplicationService>();
|
||||
|
||||
services.AddConnectorUtils();
|
||||
services.AddDUI<CsiDocumentModelStore>();
|
||||
services.AddDUI<DefaultThreadContext, CsiDocumentModelStore>();
|
||||
services.AddDUIView();
|
||||
|
||||
services.AddSingleton<DocumentModelStore, CsiDocumentModelStore>();
|
||||
|
||||
services.AddSingleton<IBinding, TestBinding>();
|
||||
services.AddSingleton<IBinding, ConfigBinding>();
|
||||
services.AddSingleton<IBinding, AccountBinding>();
|
||||
|
||||
services.AddSingleton<IBinding>(sp => sp.GetRequiredService<IBasicConnectorBinding>());
|
||||
services.AddSingleton<IBasicConnectorBinding, CsiSharedBasicConnectorBinding>();
|
||||
services.AddSingleton<IAppIdleManager, CsiIdleManager>();
|
||||
|
||||
services.AddSingleton<IBinding, CsiSharedSelectionBinding>();
|
||||
services.AddSingleton<IBinding, CsiSharedSendBinding>();
|
||||
@@ -45,7 +44,13 @@ public static class ServiceRegistration
|
||||
services.AddScoped<IRootObjectBuilder<ICsiWrapper>, CsiRootObjectBuilder>();
|
||||
services.AddScoped<SendOperation<ICsiWrapper>>();
|
||||
|
||||
services.RegisterTopLevelExceptionHandler();
|
||||
services.AddScoped<CsiMaterialPropertyExtractor>();
|
||||
services.AddScoped<MaterialUnpacker>();
|
||||
services.AddScoped<IFrameSectionPropertyExtractor, CsiFrameSectionPropertyExtractor>();
|
||||
services.AddScoped<IShellSectionPropertyExtractor, CsiShellSectionPropertyExtractor>();
|
||||
|
||||
// add converter caches
|
||||
services.AddScoped<CsiToSpeckleCacheSingleton>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
@@ -13,14 +13,20 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\CsiSharedSelectionBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\CsiSharedSendBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Filters\CsiSharedSelectionFilter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\MaterialUnpacker.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\CsiSendCollectionManager.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Helpers\CsiFrameSectionPropertyExtractor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Helpers\CsiMaterialPropertyExtractor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Helpers\CsiShellSectionPropertyExtractor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Helpers\IApplicationSectionPropertyExtractor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Helpers\ISectionPropertyExtractor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Helpers\ISectionUnpacker.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\CsiRootObjectBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\CsiPluginBase.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\SpeckleFormBase.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)GlobalUsing.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\CsiApplicationService.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\CsiDocumentModelStore.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\CsiIdleManager.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ServiceRegistration.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Utils\ObjectIdentifiers.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -8,5 +8,5 @@ namespace Speckle.Connectors.ETABS21;
|
||||
|
||||
public class SpeckleForm : EtabsSpeckleFormBase
|
||||
{
|
||||
protected override HostAppVersion GetVersion() => HostAppVersion.v2021; // TODO: We need a v21
|
||||
protected override HostAppVersion GetVersion() => HostAppVersion.v21;
|
||||
}
|
||||
|
||||
@@ -264,9 +264,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -274,9 +274,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -293,7 +292,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.etabs21": {
|
||||
@@ -337,41 +336,35 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@ namespace Speckle.Connectors.ETABS22;
|
||||
|
||||
public class SpeckleForm : EtabsSpeckleFormBase
|
||||
{
|
||||
protected override HostAppVersion GetVersion() => HostAppVersion.v2021; // TODO: v22
|
||||
protected override HostAppVersion GetVersion() => HostAppVersion.v22;
|
||||
}
|
||||
|
||||
@@ -220,9 +220,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -230,9 +230,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -249,7 +248,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.etabs22": {
|
||||
@@ -293,40 +292,34 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
using Speckle.Connectors.CSiShared.HostApp.Helpers;
|
||||
using Speckle.Connectors.ETABSShared.HostApp.Helpers;
|
||||
using Speckle.Converters.CSiShared.ToSpeckle.Helpers;
|
||||
using Speckle.Sdk.Models.Proxies;
|
||||
|
||||
namespace Speckle.Connectors.ETABSShared.HostApp;
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks and creates proxies for frame and shell sections from the model.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Provides a unified approach to section extraction across different section types.
|
||||
/// Leverages specialized extractors to handle complex property retrieval. Centralizes
|
||||
/// section proxy creation with robust error handling and logging mechanisms.
|
||||
/// </remarks>
|
||||
public class EtabsSectionUnpacker : ISectionUnpacker
|
||||
{
|
||||
private readonly EtabsSectionPropertyExtractor _propertyExtractor;
|
||||
private readonly CsiToSpeckleCacheSingleton _csiToSpeckleCacheSingleton;
|
||||
|
||||
public EtabsSectionUnpacker(
|
||||
EtabsSectionPropertyExtractor propertyExtractor,
|
||||
CsiToSpeckleCacheSingleton csiToSpeckleCacheSingleton
|
||||
)
|
||||
{
|
||||
_propertyExtractor = propertyExtractor;
|
||||
_csiToSpeckleCacheSingleton = csiToSpeckleCacheSingleton;
|
||||
}
|
||||
|
||||
public IEnumerable<GroupProxy> UnpackSections()
|
||||
{
|
||||
foreach (GroupProxy frameSectionProxy in UnpackFrameSections())
|
||||
{
|
||||
yield return frameSectionProxy;
|
||||
}
|
||||
|
||||
foreach (GroupProxy shellSectionProxy in UnpackShellSections())
|
||||
{
|
||||
yield return shellSectionProxy;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<GroupProxy> UnpackFrameSections()
|
||||
{
|
||||
foreach (var entry in _csiToSpeckleCacheSingleton.FrameSectionCache)
|
||||
{
|
||||
string sectionName = entry.Key;
|
||||
List<string> frameIds = entry.Value;
|
||||
|
||||
// Initialize properties outside the if statement
|
||||
Dictionary<string, object?> properties = new Dictionary<string, object?>();
|
||||
|
||||
// get the properties of the section
|
||||
// openings will have objects assigned to them, but won't have properties
|
||||
// sectionName is initialized with string.Empty, but api ref returns string "None"
|
||||
if (sectionName != "None")
|
||||
{
|
||||
properties = _propertyExtractor.ExtractFrameSectionProperties(sectionName);
|
||||
}
|
||||
|
||||
// create the section proxy
|
||||
GroupProxy sectionProxy =
|
||||
new()
|
||||
{
|
||||
id = sectionName,
|
||||
name = sectionName,
|
||||
applicationId = sectionName,
|
||||
objects = frameIds,
|
||||
["type"] = "Frame Section", // since sectionProxies are a flat list, need some way to distinguish from shell
|
||||
["properties"] = properties // openings will just have an empty dict here
|
||||
};
|
||||
|
||||
yield return sectionProxy;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<GroupProxy> UnpackShellSections()
|
||||
{
|
||||
foreach (var entry in _csiToSpeckleCacheSingleton.ShellSectionCache)
|
||||
{
|
||||
string sectionName = entry.Key;
|
||||
List<string> frameIds = entry.Value;
|
||||
|
||||
// Initialize properties outside the if statement
|
||||
Dictionary<string, object?> properties = new Dictionary<string, object?>();
|
||||
|
||||
// get the properties of the section
|
||||
// openings will have objects assigned to them, but won't have properties
|
||||
// sectionName is initialized with string.Empty, but api ref returns string "None"
|
||||
if (sectionName != "None")
|
||||
{
|
||||
properties = _propertyExtractor.ExtractShellSectionProperties(sectionName);
|
||||
}
|
||||
|
||||
// create the section proxy
|
||||
GroupProxy sectionProxy =
|
||||
new()
|
||||
{
|
||||
id = sectionName,
|
||||
name = sectionName,
|
||||
applicationId = sectionName,
|
||||
objects = frameIds,
|
||||
["type"] = "Shell Section", // since sectionProxies are a flat list, need some way to distinguish from frame
|
||||
["properties"] = properties // openings will just have an empty dict here
|
||||
};
|
||||
|
||||
yield return sectionProxy;
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-20
@@ -1,6 +1,7 @@
|
||||
using Speckle.Connectors.CSiShared.HostApp;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.CSiShared;
|
||||
using Speckle.Converters.CSiShared.Utils;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
|
||||
@@ -66,7 +67,10 @@ public class EtabsSendCollectionManager : CsiSendCollectionManager
|
||||
}
|
||||
|
||||
// For frames and shells, get design orientation from Object ID
|
||||
if ((type == "Frame" || type == "Shell") && obj["properties"] is Dictionary<string, object> properties)
|
||||
if (
|
||||
(type == ModelObjectType.FRAME.ToString() || type == ModelObjectType.SHELL.ToString())
|
||||
&& obj["properties"] is Dictionary<string, object> properties
|
||||
)
|
||||
{
|
||||
if (properties.TryGetValue("Object ID", out var objectId) && objectId is Dictionary<string, object> parameters)
|
||||
{
|
||||
@@ -78,7 +82,7 @@ public class EtabsSendCollectionManager : CsiSendCollectionManager
|
||||
}
|
||||
|
||||
// For joints, simply categorize as joints
|
||||
return type == "Joint" ? ElementCategory.JOINT : ElementCategory.OTHER;
|
||||
return type == ModelObjectType.JOINT.ToString() ? ElementCategory.JOINT : ElementCategory.OTHER;
|
||||
}
|
||||
|
||||
private ElementCategory GetCategoryFromDesignOrientation(string? orientation, string type)
|
||||
@@ -90,12 +94,12 @@ public class EtabsSendCollectionManager : CsiSendCollectionManager
|
||||
|
||||
return (orientation, type) switch
|
||||
{
|
||||
("Column", "Frame") => ElementCategory.COLUMN,
|
||||
("Beam", "Frame") => ElementCategory.BEAM,
|
||||
("Brace", "Frame") => ElementCategory.BRACE,
|
||||
("Wall", "Shell") => ElementCategory.WALL,
|
||||
("Floor", "Shell") => ElementCategory.FLOOR,
|
||||
("Ramp", "Shell") => ElementCategory.RAMP,
|
||||
("Column", nameof(ModelObjectType.FRAME)) => ElementCategory.COLUMN,
|
||||
("Beam", nameof(ModelObjectType.FRAME)) => ElementCategory.BEAM,
|
||||
("Brace", nameof(ModelObjectType.FRAME)) => ElementCategory.BRACE,
|
||||
("Wall", nameof(ModelObjectType.SHELL)) => ElementCategory.WALL,
|
||||
("Floor", nameof(ModelObjectType.SHELL)) => ElementCategory.FLOOR,
|
||||
("Ramp", nameof(ModelObjectType.SHELL)) => ElementCategory.RAMP,
|
||||
_ => ElementCategory.OTHER
|
||||
};
|
||||
}
|
||||
@@ -138,16 +142,4 @@ public class EtabsSendCollectionManager : CsiSendCollectionManager
|
||||
levelCollection.elements.Add(categoryCollection);
|
||||
return categoryCollection;
|
||||
}
|
||||
|
||||
private enum ElementCategory
|
||||
{
|
||||
COLUMN,
|
||||
BEAM,
|
||||
BRACE,
|
||||
WALL,
|
||||
FLOOR,
|
||||
RAMP,
|
||||
JOINT,
|
||||
OTHER
|
||||
}
|
||||
}
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
using Speckle.Connectors.CSiShared.HostApp.Helpers;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.CSiShared;
|
||||
using Speckle.Converters.CSiShared.Utils;
|
||||
|
||||
namespace Speckle.Connectors.ETABSShared.HostApp.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Extracts ETABS-specific frame section properties.
|
||||
/// </summary>
|
||||
public class EtabsFrameSectionPropertyExtractor : IApplicationFrameSectionPropertyExtractor
|
||||
{
|
||||
private readonly IConverterSettingsStore<CsiConversionSettings> _settingsStore;
|
||||
|
||||
public EtabsFrameSectionPropertyExtractor(IConverterSettingsStore<CsiConversionSettings> settingsStore)
|
||||
{
|
||||
_settingsStore = settingsStore;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets generalised frame section properties
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Sap2000 doesn't support this method, unfortunately
|
||||
/// Alternative is to account for extraction according to section type - we're talking over 40 section types!
|
||||
/// This way, we get basic information with minimal computational costs.
|
||||
/// </remarks>
|
||||
public void ExtractProperties(string sectionName, Dictionary<string, object?> properties)
|
||||
{
|
||||
// Get all frame properties
|
||||
int numberOfNames = 0;
|
||||
string[] names = [];
|
||||
eFramePropType[] propTypes = [];
|
||||
double[] t3 = [],
|
||||
t2 = [],
|
||||
tf = [],
|
||||
tw = [],
|
||||
t2b = [],
|
||||
tfb = [],
|
||||
area = [];
|
||||
|
||||
_settingsStore.Current.SapModel.PropFrame.GetAllFrameProperties_2(
|
||||
ref numberOfNames,
|
||||
ref names,
|
||||
ref propTypes,
|
||||
ref t3,
|
||||
ref t2,
|
||||
ref tf,
|
||||
ref tw,
|
||||
ref t2b,
|
||||
ref tfb,
|
||||
ref area
|
||||
);
|
||||
|
||||
// Find the index of the current section
|
||||
int sectionIndex = Array.IndexOf(names, sectionName);
|
||||
|
||||
if (sectionIndex != -1)
|
||||
{
|
||||
// General Data
|
||||
var generalData = DictionaryUtils.EnsureNestedDictionary(properties, SectionPropertyCategory.GENERAL_DATA);
|
||||
generalData["type"] = propTypes[sectionIndex].ToString();
|
||||
|
||||
// Section Dimensions
|
||||
var sectionDimensions = DictionaryUtils.EnsureNestedDictionary(
|
||||
properties,
|
||||
SectionPropertyCategory.SECTION_DIMENSIONS
|
||||
);
|
||||
sectionDimensions["t3"] = t3[sectionIndex];
|
||||
sectionDimensions["t2"] = t2[sectionIndex];
|
||||
sectionDimensions["tf"] = tf[sectionIndex];
|
||||
sectionDimensions["tw"] = tw[sectionIndex];
|
||||
sectionDimensions["t2b"] = t2b[sectionIndex];
|
||||
sectionDimensions["tfb"] = tfb[sectionIndex];
|
||||
sectionDimensions["area"] = area[sectionIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
using Speckle.Connectors.CSiShared.HostApp.Helpers;
|
||||
|
||||
namespace Speckle.Connectors.ETABSShared.HostApp.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Coordinates property extraction combining base CSi and ETABS-specific properties.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Mirrors property extraction system pattern used in EtabsPropertiesExtractor.
|
||||
/// Composition handled at coordinator level rather than individual extractors.
|
||||
/// </remarks>
|
||||
public class EtabsSectionPropertyExtractor
|
||||
{
|
||||
private readonly IFrameSectionPropertyExtractor _csiFrameExtractor;
|
||||
private readonly IShellSectionPropertyExtractor _csiShellExtractor;
|
||||
private readonly IApplicationFrameSectionPropertyExtractor _etabsFrameExtractor;
|
||||
private readonly IApplicationShellSectionPropertyExtractor _etabsShellExtractor;
|
||||
|
||||
public EtabsSectionPropertyExtractor(
|
||||
IFrameSectionPropertyExtractor csiFrameExtractor,
|
||||
IShellSectionPropertyExtractor csiShellExtractor,
|
||||
IApplicationFrameSectionPropertyExtractor etabsFrameExtractor,
|
||||
IApplicationShellSectionPropertyExtractor etabsShellExtractor
|
||||
)
|
||||
{
|
||||
_csiFrameExtractor = csiFrameExtractor;
|
||||
_csiShellExtractor = csiShellExtractor;
|
||||
_etabsFrameExtractor = etabsFrameExtractor;
|
||||
_etabsShellExtractor = etabsShellExtractor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract the frame section properties on both a Csi and app-specific level
|
||||
/// </summary>
|
||||
public Dictionary<string, object?> ExtractFrameSectionProperties(string sectionName)
|
||||
{
|
||||
Dictionary<string, object?> properties = new();
|
||||
_csiFrameExtractor.ExtractProperties(sectionName, properties);
|
||||
_etabsFrameExtractor.ExtractProperties(sectionName, properties);
|
||||
return properties;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract the shell section properties on both a Csi and app-specific level
|
||||
/// </summary>
|
||||
public Dictionary<string, object?> ExtractShellSectionProperties(string sectionName)
|
||||
{
|
||||
Dictionary<string, object?> properties = new();
|
||||
_csiShellExtractor.ExtractProperties(sectionName, properties);
|
||||
_etabsShellExtractor.ExtractProperties(sectionName, properties);
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.CSiShared.HostApp.Helpers;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.CSiShared;
|
||||
using Speckle.Converters.CSiShared.Utils;
|
||||
|
||||
namespace Speckle.Connectors.ETABSShared.HostApp.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Extracts ETABS-specific shell section properties.
|
||||
/// </summary>
|
||||
public class EtabsShellSectionPropertyExtractor : IApplicationShellSectionPropertyExtractor
|
||||
{
|
||||
private readonly IConverterSettingsStore<CsiConversionSettings> _settingsStore;
|
||||
private readonly ILogger<EtabsShellSectionPropertyExtractor> _logger;
|
||||
private readonly EtabsShellSectionResolver _etabsShellSectionResolver;
|
||||
|
||||
public EtabsShellSectionPropertyExtractor(
|
||||
IConverterSettingsStore<CsiConversionSettings> settingsStore,
|
||||
ILogger<EtabsShellSectionPropertyExtractor> logger,
|
||||
EtabsShellSectionResolver etabsShellSectionResolver
|
||||
)
|
||||
{
|
||||
_settingsStore = settingsStore;
|
||||
_logger = logger;
|
||||
_etabsShellSectionResolver = etabsShellSectionResolver;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract shell section properties
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// sectionName is unique across all types (Wall, Slab and Deck)
|
||||
/// There is no general query such as PropArea.GetShell() - rather we have to be specific on the type, for example
|
||||
/// PropArea.GetWall() or PropArea.GetDeck() BUT we can't get the building type given a SectionName.
|
||||
/// Hence the introduction of ResolveSection.
|
||||
/// </remarks>
|
||||
public void ExtractProperties(string sectionName, Dictionary<string, object?> properties)
|
||||
{
|
||||
// Step 01: Finding the appropriate api query for the unknown section type (wall, deck or slab)
|
||||
Dictionary<string, object?> resolvedProperties = _etabsShellSectionResolver.ResolveSection(sectionName);
|
||||
|
||||
// Step 02: Mutate properties dictionary with resolved properties
|
||||
foreach (var nestedDictionary in resolvedProperties)
|
||||
{
|
||||
if (nestedDictionary.Value is not Dictionary<string, object?> nestedValues)
|
||||
{
|
||||
_logger.LogWarning(
|
||||
"Unexpected value type for key {Key} in section {SectionName}. Expected Dictionary<string, object?>, got {ActualType}",
|
||||
nestedDictionary.Key,
|
||||
sectionName,
|
||||
nestedDictionary.Value?.GetType().Name ?? "null"
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
var nestedProperties = DictionaryUtils.EnsureNestedDictionary(properties, nestedDictionary.Key);
|
||||
foreach (var kvp in nestedValues)
|
||||
{
|
||||
nestedProperties[kvp.Key] = kvp.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.CSiShared;
|
||||
using Speckle.Converters.CSiShared.Utils;
|
||||
|
||||
namespace Speckle.Connectors.ETABSShared.HostApp.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to resolve the section type and retrieve its properties by trying different section resolvers.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This service focuses solely on determining the correct section type and returning its properties.
|
||||
/// Since section names are unique across different types (Wall, Slab, Deck), it uses a try-and-fail approach
|
||||
/// rather than attempting to predetermine the type. The first successful resolution is returned.
|
||||
/// </remarks>
|
||||
public record AreaSectionResult
|
||||
{
|
||||
public bool Success { get; init; }
|
||||
public Dictionary<string, object?> Properties { get; init; }
|
||||
}
|
||||
|
||||
public interface IAreaSectionResolver
|
||||
{
|
||||
AreaSectionResult TryResolveSection(string sectionName);
|
||||
}
|
||||
|
||||
public class EtabsShellSectionResolver
|
||||
{
|
||||
private readonly IConverterSettingsStore<CsiConversionSettings> _settingsStore;
|
||||
private readonly IEnumerable<IAreaSectionResolver> _resolvers;
|
||||
|
||||
public EtabsShellSectionResolver(IConverterSettingsStore<CsiConversionSettings> settingsStore)
|
||||
{
|
||||
_settingsStore = settingsStore;
|
||||
_resolvers =
|
||||
[
|
||||
new WallSectionResolver(_settingsStore),
|
||||
new SlabSectionResolver(_settingsStore),
|
||||
new DeckSectionResolver(_settingsStore)
|
||||
];
|
||||
}
|
||||
|
||||
public Dictionary<String, object?> ResolveSection(string sectionName)
|
||||
{
|
||||
foreach (var resolver in _resolvers)
|
||||
{
|
||||
var result = resolver.TryResolveSection(sectionName);
|
||||
if (result.Success)
|
||||
{
|
||||
return result.Properties;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"Section '{sectionName}' could not be resolved to any known type.");
|
||||
}
|
||||
}
|
||||
|
||||
public class WallSectionResolver(IConverterSettingsStore<CsiConversionSettings> settingsStore) : IAreaSectionResolver
|
||||
{
|
||||
public AreaSectionResult TryResolveSection(string sectionName)
|
||||
{
|
||||
eWallPropType wallPropType = default;
|
||||
eShellType shellType = default;
|
||||
string matProp = string.Empty;
|
||||
double thickness = 0.0;
|
||||
int color = 0;
|
||||
string notes = string.Empty;
|
||||
string guid = string.Empty;
|
||||
|
||||
var result = settingsStore.Current.SapModel.PropArea.GetWall(
|
||||
sectionName,
|
||||
ref wallPropType,
|
||||
ref shellType,
|
||||
ref matProp,
|
||||
ref thickness,
|
||||
ref color,
|
||||
ref notes,
|
||||
ref guid
|
||||
);
|
||||
|
||||
Dictionary<string, object?> generalData = [];
|
||||
generalData["name"] = sectionName;
|
||||
generalData["type"] = wallPropType.ToString();
|
||||
generalData["material"] = matProp;
|
||||
generalData["modelingType"] = shellType.ToString();
|
||||
generalData["color"] = color;
|
||||
generalData["notes"] = notes;
|
||||
|
||||
Dictionary<string, object?> propertyData = [];
|
||||
propertyData["type"] = "Wall";
|
||||
propertyData["thickness"] = thickness;
|
||||
|
||||
Dictionary<string, object?> properties = [];
|
||||
properties[SectionPropertyCategory.GENERAL_DATA] = generalData;
|
||||
properties[SectionPropertyCategory.PROPERTY_DATA] = propertyData;
|
||||
|
||||
return new AreaSectionResult { Success = result == 0, Properties = properties };
|
||||
}
|
||||
}
|
||||
|
||||
public class SlabSectionResolver(IConverterSettingsStore<CsiConversionSettings> settingsStore) : IAreaSectionResolver
|
||||
{
|
||||
public AreaSectionResult TryResolveSection(string sectionName)
|
||||
{
|
||||
eSlabType slabType = default;
|
||||
eShellType shellType = default;
|
||||
string matProp = string.Empty;
|
||||
double thickness = 0.0;
|
||||
int color = 0;
|
||||
string notes = string.Empty;
|
||||
string guid = string.Empty;
|
||||
|
||||
var result = settingsStore.Current.SapModel.PropArea.GetSlab(
|
||||
sectionName,
|
||||
ref slabType,
|
||||
ref shellType,
|
||||
ref matProp,
|
||||
ref thickness,
|
||||
ref color,
|
||||
ref notes,
|
||||
ref guid
|
||||
);
|
||||
|
||||
Dictionary<string, object?> generalData = [];
|
||||
generalData["name"] = sectionName;
|
||||
generalData["material"] = matProp;
|
||||
generalData["modelingType"] = shellType.ToString();
|
||||
generalData["color"] = color;
|
||||
generalData["notes"] = notes;
|
||||
|
||||
Dictionary<string, object?> propertyData = [];
|
||||
propertyData["type"] = slabType.ToString();
|
||||
propertyData["thickness"] = thickness;
|
||||
|
||||
Dictionary<string, object?> properties = [];
|
||||
properties[SectionPropertyCategory.GENERAL_DATA] = generalData;
|
||||
properties[SectionPropertyCategory.PROPERTY_DATA] = propertyData;
|
||||
|
||||
return new AreaSectionResult { Success = result == 0, Properties = properties };
|
||||
}
|
||||
}
|
||||
|
||||
public class DeckSectionResolver(IConverterSettingsStore<CsiConversionSettings> settingsStore) : IAreaSectionResolver
|
||||
{
|
||||
public AreaSectionResult TryResolveSection(string sectionName)
|
||||
{
|
||||
eDeckType deckType = default;
|
||||
eShellType shellType = default;
|
||||
string deckMatProp = string.Empty;
|
||||
double thickness = 0.0;
|
||||
int color = 0;
|
||||
string notes = string.Empty;
|
||||
string guid = string.Empty;
|
||||
|
||||
var result = settingsStore.Current.SapModel.PropArea.GetDeck(
|
||||
sectionName,
|
||||
ref deckType,
|
||||
ref shellType,
|
||||
ref deckMatProp,
|
||||
ref thickness,
|
||||
ref color,
|
||||
ref notes,
|
||||
ref guid
|
||||
);
|
||||
|
||||
Dictionary<string, object?> generalData = [];
|
||||
generalData["name"] = sectionName;
|
||||
generalData["type"] = deckType.ToString();
|
||||
generalData["material"] = deckMatProp;
|
||||
generalData["modelingType"] = shellType.ToString();
|
||||
generalData["color"] = color;
|
||||
generalData["notes"] = notes;
|
||||
|
||||
Dictionary<string, object?> propertyData = [];
|
||||
propertyData["thickness"] = thickness;
|
||||
|
||||
Dictionary<string, object?> properties = [];
|
||||
properties[SectionPropertyCategory.GENERAL_DATA] = generalData;
|
||||
properties[SectionPropertyCategory.PROPERTY_DATA] = propertyData;
|
||||
|
||||
return new AreaSectionResult { Success = result == 0, Properties = properties };
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Speckle.Connectors.CSiShared.HostApp;
|
||||
using Speckle.Connectors.CSiShared.HostApp.Helpers;
|
||||
using Speckle.Connectors.ETABSShared.HostApp;
|
||||
using Speckle.Connectors.ETABSShared.HostApp.Helpers;
|
||||
using Speckle.Converters.ETABSShared;
|
||||
|
||||
namespace Speckle.Connectors.ETABSShared;
|
||||
@@ -10,7 +12,12 @@ public static class ServiceRegistration
|
||||
public static IServiceCollection AddEtabs(this IServiceCollection services)
|
||||
{
|
||||
services.AddEtabsConverters();
|
||||
services.AddScoped<IApplicationFrameSectionPropertyExtractor, EtabsFrameSectionPropertyExtractor>();
|
||||
services.AddScoped<IApplicationShellSectionPropertyExtractor, EtabsShellSectionPropertyExtractor>();
|
||||
services.AddScoped<EtabsSectionPropertyExtractor>();
|
||||
services.AddScoped<EtabsShellSectionResolver>();
|
||||
services.AddScoped<CsiSendCollectionManager, EtabsSendCollectionManager>();
|
||||
services.AddScoped<ISectionUnpacker, EtabsSectionUnpacker>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,12 @@
|
||||
<Import_RootNamespace>Speckle.Connectors.ETABSShared</Import_RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\EtabsSectionUnpacker.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\EtabsSendCollectionManager.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Helpers\EtabsFrameSectionPropertyExtractor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Helpers\EtabsSectionPropertyExtractor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Helpers\EtabsShellSectionPropertyExtractor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\Helpers\EtabsShellSectionResolver.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\EtabsPluginBase.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\EtabsSpeckleFormBase.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ServiceRegistration.cs" />
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<UseWpf>true</UseWpf>
|
||||
|
||||
<Description>NextGen Speckle Connector for Autodesk Navisworks Manage</Description>
|
||||
<Authors>$(Authors) jonathon@speckle.systems</Authors>
|
||||
<PackageTags>$(PackageTags) connector nwd nwc nwf navisworks manage</PackageTags>
|
||||
|
||||
<PluginBundleTarget>$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Navisworks.bundle</PluginBundleTarget>
|
||||
<PluginVersionContentTarget>$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Navisworks.bundle\Contents\$(NavisworksVersion)</PluginVersionContentTarget>
|
||||
<RootNamespace>Speckle.Connector.Navisworks</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Post Builds -->
|
||||
<ItemGroup>
|
||||
<RibbonFiles Include="$(OutDir)Plugin\NavisworksRibbon.*"/>
|
||||
<ResourceFiles Include="$(OutDir)Resources\**\*.png"/>
|
||||
<ResourceFiles Include="$(OutDir)Resources\**\*.ico"/>
|
||||
<AllFiles Include="$(OutDir)*"/>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="Build">
|
||||
<Message Text="Navisworks Version $(NavisworksVersion)" Importance="high"/>
|
||||
<RemoveDir Directories="$(PluginVersionContentTarget)" Condition="Exists('$(PluginVersionContentTarget)')"/>
|
||||
|
||||
<Copy SourceFiles="$(OutDir)Plugin\PackageContents.xml" DestinationFolder="$(PluginBundleTarget)\"/>
|
||||
<Copy SourceFiles="@(RibbonFiles)" DestinationFolder="$(PluginVersionContentTarget)\en-US\"/>
|
||||
<Copy SourceFiles="@(ResourceFiles)" DestinationFolder="$(PluginVersionContentTarget)\Resources\"/>
|
||||
|
||||
<Copy SourceFiles="@(AllFiles)" DestinationFolder="$(PluginVersionContentTarget)\" />
|
||||
</Target>
|
||||
</Project>
|
||||
-29
@@ -8,16 +8,7 @@
|
||||
<NavisworksBuildNumber>v17</NavisworksBuildNumber>
|
||||
<NavisworksVersion>2020</NavisworksVersion>
|
||||
|
||||
<UseWpf>true</UseWpf>
|
||||
<DefineConstants>$(DefineConstants);TRACE;NAVIS2020;NAVIS</DefineConstants>
|
||||
|
||||
<Description>NextGen Speckle Connector for Autodesk Navisworks Manage</Description>
|
||||
<Authors>$(Authors) jonathon@speckle.systems</Authors>
|
||||
<PackageTags>$(PackageTags) connector nwd nwc nwf navisworks manage</PackageTags>
|
||||
|
||||
<PluginBundleTarget>$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Navisworksv3.bundle</PluginBundleTarget>
|
||||
<PluginVersionContentTarget>$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Navisworksv3.bundle\Contents\$(NavisworksVersion)</PluginVersionContentTarget>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\Speckle.Connectors.NavisworksShared\Speckle.Connectors.NavisworksShared.projitems" Label="Shared"/>
|
||||
@@ -32,25 +23,5 @@
|
||||
<ProjectReference Include="..\..\..\Converters\Navisworks\Speckle.Converters.Navisworks2020\Speckle.Converters.Navisworks2020.csproj" />
|
||||
<ProjectReference Include="..\..\..\Sdk\Speckle.Connectors.Common\Speckle.Connectors.Common.csproj"/>
|
||||
<ProjectReference Include="..\..\..\DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj"/>
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Post Builds -->
|
||||
<ItemGroup>
|
||||
<RibbonFiles Include="$(OutDir)Plugin\NavisworksRibbon.*"/>
|
||||
<ResourceFiles Include="$(OutDir)Resources\**\*.png"/>
|
||||
<ResourceFiles Include="$(OutDir)Resources\**\*.ico"/>
|
||||
<AllFiles Include="$(OutDir)*"/>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="Build">
|
||||
<RemoveDir Directories="$(PluginVersionContentTarget)" Condition="Exists('$(PluginVersionContentTarget)')"/>
|
||||
|
||||
<Copy SourceFiles="$(OutDir)Plugin\PackageContents.xml" DestinationFolder="$(PluginBundleTarget)\"/>
|
||||
<Copy SourceFiles="@(RibbonFiles)" DestinationFolder="$(PluginVersionContentTarget)\en-US\"/>
|
||||
<Copy SourceFiles="@(ResourceFiles)" DestinationFolder="$(PluginVersionContentTarget)\Resources\"/>
|
||||
|
||||
<Copy SourceFiles="@(AllFiles)" DestinationFolder="$(PluginVersionContentTarget)\" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -41,11 +41,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "Direct",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client": {
|
||||
@@ -273,9 +273,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -283,9 +283,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -302,7 +301,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2020": {
|
||||
@@ -348,32 +347,26 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
-29
@@ -8,16 +8,7 @@
|
||||
<NavisworksBuildNumber>v18</NavisworksBuildNumber>
|
||||
<NavisworksVersion>2021</NavisworksVersion>
|
||||
|
||||
<UseWpf>true</UseWpf>
|
||||
<DefineConstants>$(DefineConstants);TRACE;NAVIS2021;NAVIS</DefineConstants>
|
||||
|
||||
<Description>NextGen Speckle Connector for Autodesk Navisworks Manage</Description>
|
||||
<Authors>$(Authors) jonathon@speckle.systems</Authors>
|
||||
<PackageTags>$(PackageTags) connector nwd nwc nwf navisworks manage</PackageTags>
|
||||
|
||||
<PluginBundleTarget>$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Navisworksv3.bundle</PluginBundleTarget>
|
||||
<PluginVersionContentTarget>$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Navisworksv3.bundle\Contents\$(NavisworksVersion)</PluginVersionContentTarget>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\Speckle.Connectors.NavisworksShared\Speckle.Connectors.NavisworksShared.projitems" Label="Shared"/>
|
||||
@@ -32,25 +23,5 @@
|
||||
<ProjectReference Include="..\..\..\Converters\Navisworks\Speckle.Converters.Navisworks2021\Speckle.Converters.Navisworks2021.csproj" />
|
||||
<ProjectReference Include="..\..\..\Sdk\Speckle.Connectors.Common\Speckle.Connectors.Common.csproj"/>
|
||||
<ProjectReference Include="..\..\..\DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj"/>
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Post Builds -->
|
||||
<ItemGroup>
|
||||
<RibbonFiles Include="$(OutDir)Plugin\NavisworksRibbon.*"/>
|
||||
<ResourceFiles Include="$(OutDir)Resources\**\*.png"/>
|
||||
<ResourceFiles Include="$(OutDir)Resources\**\*.ico"/>
|
||||
<AllFiles Include="$(OutDir)*"/>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="Build">
|
||||
<RemoveDir Directories="$(PluginVersionContentTarget)" Condition="Exists('$(PluginVersionContentTarget)')"/>
|
||||
|
||||
<Copy SourceFiles="$(OutDir)Plugin\PackageContents.xml" DestinationFolder="$(PluginBundleTarget)\"/>
|
||||
<Copy SourceFiles="@(RibbonFiles)" DestinationFolder="$(PluginVersionContentTarget)\en-US\"/>
|
||||
<Copy SourceFiles="@(ResourceFiles)" DestinationFolder="$(PluginVersionContentTarget)\Resources\"/>
|
||||
|
||||
<Copy SourceFiles="@(AllFiles)" DestinationFolder="$(PluginVersionContentTarget)\" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -41,11 +41,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "Direct",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client": {
|
||||
@@ -273,9 +273,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -283,9 +283,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -302,7 +301,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2021": {
|
||||
@@ -348,32 +347,26 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
-30
@@ -1,5 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
@@ -9,16 +8,7 @@
|
||||
<NavisworksBuildNumber>v19</NavisworksBuildNumber>
|
||||
<NavisworksVersion>2022</NavisworksVersion>
|
||||
|
||||
<UseWpf>true</UseWpf>
|
||||
<DefineConstants>$(DefineConstants);TRACE;NAVIS2022;NAVIS</DefineConstants>
|
||||
|
||||
<Description>NextGen Speckle Connector for Autodesk Navisworks Manage</Description>
|
||||
<Authors>$(Authors) jonathon@speckle.systems</Authors>
|
||||
<PackageTags>$(PackageTags) connector nwd nwc nwf navisworks manage</PackageTags>
|
||||
|
||||
<PluginBundleTarget>$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Navisworksv3.bundle</PluginBundleTarget>
|
||||
<PluginVersionContentTarget>$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Navisworksv3.bundle\Contents\$(NavisworksVersion)</PluginVersionContentTarget>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\Speckle.Connectors.NavisworksShared\Speckle.Connectors.NavisworksShared.projitems" Label="Shared"/>
|
||||
@@ -33,25 +23,5 @@
|
||||
<ProjectReference Include="..\..\..\Converters\Navisworks\Speckle.Converters.Navisworks2022\Speckle.Converters.Navisworks2022.csproj" />
|
||||
<ProjectReference Include="..\..\..\Sdk\Speckle.Connectors.Common\Speckle.Connectors.Common.csproj"/>
|
||||
<ProjectReference Include="..\..\..\DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj"/>
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Post Builds -->
|
||||
<ItemGroup>
|
||||
<RibbonFiles Include="$(OutDir)Plugin\NavisworksRibbon.*"/>
|
||||
<ResourceFiles Include="$(OutDir)Resources\**\*.png"/>
|
||||
<ResourceFiles Include="$(OutDir)Resources\**\*.ico"/>
|
||||
<AllFiles Include="$(OutDir)*"/>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="Build">
|
||||
<RemoveDir Directories="$(PluginVersionContentTarget)" Condition="Exists('$(PluginVersionContentTarget)')"/>
|
||||
|
||||
<Copy SourceFiles="$(OutDir)Plugin\PackageContents.xml" DestinationFolder="$(PluginBundleTarget)\"/>
|
||||
<Copy SourceFiles="@(RibbonFiles)" DestinationFolder="$(PluginVersionContentTarget)\en-US\"/>
|
||||
<Copy SourceFiles="@(ResourceFiles)" DestinationFolder="$(PluginVersionContentTarget)\Resources\"/>
|
||||
|
||||
<Copy SourceFiles="@(AllFiles)" DestinationFolder="$(PluginVersionContentTarget)\" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -41,11 +41,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "Direct",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client": {
|
||||
@@ -273,9 +273,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -283,9 +283,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -302,7 +301,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2022": {
|
||||
@@ -348,32 +347,26 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
-32
@@ -1,5 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
@@ -9,20 +8,9 @@
|
||||
<NavisworksBuildNumber>v20</NavisworksBuildNumber>
|
||||
<NavisworksVersion>2023</NavisworksVersion>
|
||||
|
||||
<UseWpf>true</UseWpf>
|
||||
<DefineConstants>$(DefineConstants);TRACE;NAVIS2023;NAVIS</DefineConstants>
|
||||
|
||||
<Description>NextGen Speckle Connector for Autodesk Navisworks Manage</Description>
|
||||
<Authors>$(Authors) jonathon@speckle.systems</Authors>
|
||||
<PackageTags>$(PackageTags) connector nwd nwc nwf navisworks manage</PackageTags>
|
||||
|
||||
<PluginBundleTarget>$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Navisworksv3.bundle</PluginBundleTarget>
|
||||
<PluginVersionContentTarget>$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Navisworksv3.bundle\Contents\$(NavisworksVersion)</PluginVersionContentTarget>
|
||||
<RootNamespace>Speckle.Connector.Navisworks</RootNamespace>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Includes -->
|
||||
<Import Project="..\Speckle.Connectors.NavisworksShared\Speckle.Connectors.NavisworksShared.projitems" Label="Shared"/>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -35,25 +23,5 @@
|
||||
<ProjectReference Include="..\..\..\Converters\Navisworks\Speckle.Converters.Navisworks2023\Speckle.Converters.Navisworks2023.csproj" />
|
||||
<ProjectReference Include="..\..\..\Sdk\Speckle.Connectors.Common\Speckle.Connectors.Common.csproj"/>
|
||||
<ProjectReference Include="..\..\..\DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj"/>
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Post Builds -->
|
||||
<ItemGroup>
|
||||
<RibbonFiles Include="$(OutDir)Plugin\NavisworksRibbon.*"/>
|
||||
<ResourceFiles Include="$(OutDir)Resources\**\*.png"/>
|
||||
<ResourceFiles Include="$(OutDir)Resources\**\*.ico"/>
|
||||
<AllFiles Include="$(OutDir)*"/>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="Build">
|
||||
<RemoveDir Directories="$(PluginVersionContentTarget)" Condition="Exists('$(PluginVersionContentTarget)')"/>
|
||||
|
||||
<Copy SourceFiles="$(OutDir)Plugin\PackageContents.xml" DestinationFolder="$(PluginBundleTarget)\"/>
|
||||
<Copy SourceFiles="@(RibbonFiles)" DestinationFolder="$(PluginVersionContentTarget)\en-US\"/>
|
||||
<Copy SourceFiles="@(ResourceFiles)" DestinationFolder="$(PluginVersionContentTarget)\Resources\"/>
|
||||
|
||||
<Copy SourceFiles="@(AllFiles)" DestinationFolder="$(PluginVersionContentTarget)\" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -41,11 +41,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "Direct",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client": {
|
||||
@@ -273,9 +273,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -283,9 +283,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -302,7 +301,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2023": {
|
||||
@@ -348,32 +347,26 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
+1
-32
@@ -1,5 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
@@ -9,19 +8,9 @@
|
||||
<NavisworksBuildNumber>v21</NavisworksBuildNumber>
|
||||
<NavisworksVersion>2024</NavisworksVersion>
|
||||
|
||||
<UseWpf>true</UseWpf>
|
||||
<DefineConstants>$(DefineConstants);TRACE;NAVIS2024;NAVIS</DefineConstants>
|
||||
|
||||
<Description>NextGen Speckle Connector for Autodesk Navisworks Manage</Description>
|
||||
<Authors>$(Authors) jonathon@speckle.systems</Authors>
|
||||
<PackageTags>$(PackageTags) connector nwd nwc nwf navisworks manage</PackageTags>
|
||||
|
||||
<PluginBundleTarget>$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Navisworksv3.bundle</PluginBundleTarget>
|
||||
<PluginVersionContentTarget>$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Navisworksv3.bundle\Contents\$(NavisworksVersion)</PluginVersionContentTarget>
|
||||
<RootNamespace>Speckle.Connector.Navisworks</RootNamespace>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<Import Project="..\Speckle.Connectors.NavisworksShared\Speckle.Connectors.NavisworksShared.projitems" Label="Shared"/>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -34,25 +23,5 @@
|
||||
<ProjectReference Include="..\..\..\Converters\Navisworks\Speckle.Converters.Navisworks2024\Speckle.Converters.Navisworks2024.csproj" />
|
||||
<ProjectReference Include="..\..\..\Sdk\Speckle.Connectors.Common\Speckle.Connectors.Common.csproj"/>
|
||||
<ProjectReference Include="..\..\..\DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj"/>
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Post Builds -->
|
||||
<ItemGroup>
|
||||
<RibbonFiles Include="$(OutDir)Plugin\NavisworksRibbon.*"/>
|
||||
<ResourceFiles Include="$(OutDir)Resources\**\*.png"/>
|
||||
<ResourceFiles Include="$(OutDir)Resources\**\*.ico"/>
|
||||
<AllFiles Include="$(OutDir)*"/>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="Build">
|
||||
<RemoveDir Directories="$(PluginVersionContentTarget)" Condition="Exists('$(PluginVersionContentTarget)')"/>
|
||||
|
||||
<Copy SourceFiles="$(OutDir)Plugin\PackageContents.xml" DestinationFolder="$(PluginBundleTarget)\"/>
|
||||
<Copy SourceFiles="@(RibbonFiles)" DestinationFolder="$(PluginVersionContentTarget)\en-US\"/>
|
||||
<Copy SourceFiles="@(ResourceFiles)" DestinationFolder="$(PluginVersionContentTarget)\Resources\"/>
|
||||
|
||||
<Copy SourceFiles="@(AllFiles)" DestinationFolder="$(PluginVersionContentTarget)\" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -41,11 +41,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "Direct",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client": {
|
||||
@@ -273,9 +273,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -283,9 +283,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -302,7 +301,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2024": {
|
||||
@@ -348,32 +347,26 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
-28
@@ -8,16 +8,7 @@
|
||||
<NavisworksBuildNumber>v22</NavisworksBuildNumber>
|
||||
<NavisworksVersion>2025</NavisworksVersion>
|
||||
|
||||
<UseWpf>true</UseWpf>
|
||||
<DefineConstants>$(DefineConstants);TRACE;NAVIS2025;NAVIS</DefineConstants>
|
||||
|
||||
<Description>NextGen Speckle Connector for Autodesk Navisworks Manage</Description>
|
||||
<Authors>$(Authors) jonathon@speckle.systems</Authors>
|
||||
<PackageTags>$(PackageTags) connector nwd nwc nwf navisworks manage</PackageTags>
|
||||
|
||||
<PluginBundleTarget>$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Navisworksv3.bundle</PluginBundleTarget>
|
||||
<PluginVersionContentTarget>$(AppData)\Autodesk\ApplicationPlugins\Speckle.Connectors.Navisworksv3.bundle\Contents\$(NavisworksVersion)</PluginVersionContentTarget>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\Speckle.Connectors.NavisworksShared\Speckle.Connectors.NavisworksShared.projitems" Label="Shared"/>
|
||||
@@ -34,23 +25,4 @@
|
||||
<ProjectReference Include="..\..\..\Sdk\Speckle.Connectors.Common\Speckle.Connectors.Common.csproj"/>
|
||||
<ProjectReference Include="..\..\..\DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Post Builds -->
|
||||
<ItemGroup>
|
||||
<RibbonFiles Include="$(OutDir)Plugin\NavisworksRibbon.*"/>
|
||||
<ResourceFiles Include="$(OutDir)Resources\**\*.png"/>
|
||||
<ResourceFiles Include="$(OutDir)Resources\**\*.ico"/>
|
||||
<AllFiles Include="$(OutDir)*"/>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="Build">
|
||||
<RemoveDir Directories="$(PluginVersionContentTarget)" Condition="Exists('$(PluginVersionContentTarget)')"/>
|
||||
|
||||
<Copy SourceFiles="$(OutDir)Plugin\PackageContents.xml" DestinationFolder="$(PluginBundleTarget)\"/>
|
||||
<Copy SourceFiles="@(RibbonFiles)" DestinationFolder="$(PluginVersionContentTarget)\en-US\"/>
|
||||
<Copy SourceFiles="@(ResourceFiles)" DestinationFolder="$(PluginVersionContentTarget)\Resources\"/>
|
||||
|
||||
<Copy SourceFiles="@(AllFiles)" DestinationFolder="$(PluginVersionContentTarget)\" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -47,11 +47,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "Direct",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client": {
|
||||
@@ -279,9 +279,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -289,9 +289,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -308,7 +307,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2025": {
|
||||
@@ -348,32 +347,26 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
+9
-21
@@ -42,20 +42,13 @@ public class NavisworksBasicConnectorBinding : IBasicConnectorBinding
|
||||
public string GetConnectorVersion() => _speckleApplication.SpeckleVersion;
|
||||
|
||||
public DocumentInfo? GetDocumentInfo() =>
|
||||
Parent
|
||||
.RunOnMainThreadAsync(
|
||||
() =>
|
||||
Task.FromResult(
|
||||
NavisworksApp.ActiveDocument is null || NavisworksApp.ActiveDocument.Models.Count == 0
|
||||
? null
|
||||
: new DocumentInfo(
|
||||
NavisworksApp.ActiveDocument.CurrentFileName,
|
||||
NavisworksApp.ActiveDocument.Title,
|
||||
NavisworksApp.ActiveDocument.GetHashCode().ToString()
|
||||
)
|
||||
)
|
||||
)
|
||||
.Result;
|
||||
NavisworksApp.ActiveDocument is null || NavisworksApp.ActiveDocument.Models.Count == 0
|
||||
? null
|
||||
: new DocumentInfo(
|
||||
NavisworksApp.ActiveDocument.CurrentFileName,
|
||||
NavisworksApp.ActiveDocument.Title,
|
||||
NavisworksApp.ActiveDocument.GetHashCode().ToString()
|
||||
);
|
||||
|
||||
public DocumentModelStore GetDocumentState() => _store;
|
||||
|
||||
@@ -68,11 +61,6 @@ public class NavisworksBasicConnectorBinding : IBasicConnectorBinding
|
||||
public Task HighlightModel(string modelCardId) => Task.CompletedTask;
|
||||
|
||||
public async Task HighlightObjects(IReadOnlyList<string> objectIds) =>
|
||||
await Parent
|
||||
.RunOnMainThreadAsync(async () =>
|
||||
{
|
||||
// TODO: Implement highlighting logic on main thread
|
||||
await Task.CompletedTask.ConfigureAwait(false);
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
// TODO: Implement highlighting logic on main thread
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
+3
-15
@@ -26,24 +26,12 @@ public class NavisworksSelectionBinding : ISelectionBinding
|
||||
}
|
||||
|
||||
private void OnSelectionChange(object? o, EventArgs eventArgs) =>
|
||||
_appIdleManager.SubscribeToIdle(
|
||||
nameof(NavisworksSelectionBinding),
|
||||
async () => await UpdateSelectionAsync().ConfigureAwait(false)
|
||||
);
|
||||
|
||||
private void UpdateSelection()
|
||||
{
|
||||
SelectionInfo selInfo = GetSelection();
|
||||
Parent.Send(SELECTION_EVENT, selInfo);
|
||||
}
|
||||
_appIdleManager.SubscribeToIdle(nameof(NavisworksSelectionBinding), async () => await UpdateSelectionAsync());
|
||||
|
||||
private async Task UpdateSelectionAsync()
|
||||
{
|
||||
var selInfo = await Parent
|
||||
.RunOnMainThreadAsync<SelectionInfo>(() => Task.FromResult(GetSelection()))
|
||||
.ConfigureAwait(false);
|
||||
|
||||
await Parent.Send<SelectionInfo>(SELECTION_EVENT, selInfo).ConfigureAwait(false);
|
||||
var selInfo = GetSelection();
|
||||
await Parent.Send<SelectionInfo>(SELECTION_EVENT, selInfo);
|
||||
}
|
||||
|
||||
public SelectionInfo GetSelection()
|
||||
|
||||
+10
-19
@@ -87,27 +87,19 @@ public class NavisworksSendBinding : ISendBinding
|
||||
using var activity = _activityFactory.Start();
|
||||
try
|
||||
{
|
||||
await Parent
|
||||
.RunOnMainThreadAsync(async () =>
|
||||
{
|
||||
var modelCard = GetModelCard(modelCardId);
|
||||
var modelCard = GetModelCard(modelCardId);
|
||||
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
|
||||
InitializeConverterSettings(scope, modelCard);
|
||||
InitializeConverterSettings(scope, modelCard);
|
||||
|
||||
CancellationToken token = _cancellationManager.InitCancellationTokenSource(modelCardId);
|
||||
CancellationToken token = _cancellationManager.InitCancellationTokenSource(modelCardId);
|
||||
|
||||
var navisworksModelItems = GetNavisworksModelItems(modelCard);
|
||||
var navisworksModelItems = GetNavisworksModelItems(modelCard);
|
||||
|
||||
var sendResult = await ExecuteSendOperation(scope, modelCard, navisworksModelItems, token)
|
||||
.ConfigureAwait(false);
|
||||
var sendResult = await ExecuteSendOperation(scope, modelCard, navisworksModelItems, token);
|
||||
|
||||
await Commands
|
||||
.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults)
|
||||
.ConfigureAwait(false);
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
await Commands.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -118,7 +110,7 @@ public class NavisworksSendBinding : 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);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
await Commands.SetModelError(modelCardId, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,10 +163,9 @@ public class NavisworksSendBinding : ISendBinding
|
||||
.Execute(
|
||||
navisworksModelItems,
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCard.ModelCardId!, token),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCard.ModelCardId.NotNull(), token),
|
||||
token
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
);
|
||||
|
||||
public void CancelSend(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
|
||||
|
||||
|
||||
+3
-2
@@ -9,6 +9,7 @@ using Speckle.Connectors.Common;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
@@ -27,7 +28,7 @@ public static class NavisworksConnectorServiceRegistration
|
||||
{
|
||||
// Register Core functionality
|
||||
serviceCollection.AddConnectorUtils();
|
||||
serviceCollection.AddDUI<NavisworksDocumentModelStore>();
|
||||
serviceCollection.AddDUI<DefaultThreadContext, NavisworksDocumentModelStore>();
|
||||
serviceCollection.AddDUIView();
|
||||
|
||||
// Register bindings
|
||||
@@ -50,6 +51,7 @@ public static class NavisworksConnectorServiceRegistration
|
||||
>();
|
||||
|
||||
serviceCollection.AddScoped<NavisworksMaterialUnpacker>();
|
||||
serviceCollection.AddScoped<NavisworksColorUnpacker>();
|
||||
|
||||
// Sending operations
|
||||
serviceCollection.AddScoped<IRootObjectBuilder<NAV.ModelItem>, NavisworksRootObjectBuilder>();
|
||||
@@ -58,7 +60,6 @@ public static class NavisworksConnectorServiceRegistration
|
||||
serviceCollection.AddSingleton<IOperationProgressManager, OperationProgressManager>();
|
||||
|
||||
// Register Intercom/interop
|
||||
serviceCollection.RegisterTopLevelExceptionHandler();
|
||||
serviceCollection.AddTransient<CancellationManager>();
|
||||
serviceCollection.AddSingleton<IAppIdleManager, NavisworksIdleManager>();
|
||||
serviceCollection.AddSingleton<NavisworksDocumentModelStore>();
|
||||
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connector.Navisworks.Services;
|
||||
using Speckle.Converter.Navisworks.Helpers;
|
||||
using Speckle.Converter.Navisworks.Settings;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Models.Proxies;
|
||||
using ComApi = Autodesk.Navisworks.Api.Interop.ComApi;
|
||||
using ComBridge = Autodesk.Navisworks.Api.ComApi.ComApiBridge;
|
||||
|
||||
namespace Speckle.Connector.Navisworks.HostApp;
|
||||
|
||||
public class NavisworksColorUnpacker(
|
||||
ILogger<NavisworksColorUnpacker> logger,
|
||||
IConverterSettingsStore<NavisworksConversionSettings> converterSettings,
|
||||
IElementSelectionService selectionService
|
||||
)
|
||||
{
|
||||
private static T Select<T>(RepresentationMode mode, T active, T permanent, T original, T defaultValue) =>
|
||||
mode switch
|
||||
{
|
||||
RepresentationMode.Active => active,
|
||||
RepresentationMode.Permanent => permanent,
|
||||
RepresentationMode.Original => original,
|
||||
_ => defaultValue,
|
||||
};
|
||||
|
||||
internal List<ColorProxy> UnpackColor(
|
||||
IReadOnlyList<NAV.ModelItem> navisworksObjects,
|
||||
Dictionary<string, List<NAV.ModelItem>> groupedNodes
|
||||
)
|
||||
{
|
||||
if (navisworksObjects == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(navisworksObjects));
|
||||
}
|
||||
|
||||
if (groupedNodes == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(groupedNodes));
|
||||
}
|
||||
|
||||
Dictionary<string, ColorProxy> colorProxies = [];
|
||||
Dictionary<string, string> mergedIds = [];
|
||||
|
||||
// Build mergedIds map once
|
||||
foreach (var group in groupedNodes)
|
||||
{
|
||||
foreach (var node in group.Value)
|
||||
{
|
||||
mergedIds[selectionService.GetModelItemPath(node)] = group.Key;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (NAV.ModelItem navisworksObject in navisworksObjects)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Skip non-2D elements
|
||||
if (!Is2DElement(navisworksObject))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var navisworksObjectId = selectionService.GetModelItemPath(navisworksObject);
|
||||
var finalId = mergedIds.TryGetValue(navisworksObjectId, out var mergedId) ? mergedId : navisworksObjectId;
|
||||
|
||||
var geometry = navisworksObject.Geometry;
|
||||
var mode = converterSettings.Current.User.VisualRepresentationMode;
|
||||
|
||||
using var defaultColor = new NAV.Color(1.0, 1.0, 1.0);
|
||||
|
||||
var representationColor = Select(
|
||||
mode,
|
||||
geometry.ActiveColor,
|
||||
geometry.PermanentColor,
|
||||
geometry.OriginalColor,
|
||||
defaultColor
|
||||
);
|
||||
|
||||
var colorId = Select(
|
||||
mode,
|
||||
$"{geometry.ActiveColor.GetHashCode()}_{geometry.ActiveTransparency}".GetHashCode(),
|
||||
$"{geometry.PermanentColor.GetHashCode()}_{geometry.PermanentTransparency}".GetHashCode(),
|
||||
$"{geometry.OriginalColor.GetHashCode()}_{geometry.OriginalTransparency}".GetHashCode(),
|
||||
0
|
||||
);
|
||||
|
||||
var colorName = ColorConverter.NavisworksColorToColor(representationColor).Name;
|
||||
|
||||
if (colorProxies.TryGetValue(colorId.ToString(), out ColorProxy? colorProxy))
|
||||
{
|
||||
colorProxy.objects.Add(finalId);
|
||||
}
|
||||
else
|
||||
{
|
||||
colorProxies[colorId.ToString()] = new ColorProxy
|
||||
{
|
||||
value = ColorConverter.NavisworksColorToColor(representationColor).ToArgb(),
|
||||
name = colorName,
|
||||
applicationId = colorId.ToString(),
|
||||
objects = [finalId]
|
||||
};
|
||||
}
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
logger.LogError(ex, "Failed to unpack color for Navisworks object");
|
||||
}
|
||||
}
|
||||
|
||||
return colorProxies.Values.ToList();
|
||||
}
|
||||
|
||||
private static bool Is2DElement(NAV.ModelItem modelItem)
|
||||
{
|
||||
if (!modelItem.HasGeometry)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var primitiveChecker = new PrimitiveChecker();
|
||||
|
||||
var comSelection = ComBridge.ToInwOpSelection([modelItem]);
|
||||
try
|
||||
{
|
||||
foreach (ComApi.InwOaPath path in comSelection.Paths())
|
||||
{
|
||||
GC.KeepAlive(path);
|
||||
|
||||
foreach (ComApi.InwOaFragment3 fragment in path.Fragments())
|
||||
{
|
||||
GC.KeepAlive(fragment);
|
||||
|
||||
fragment.GenerateSimplePrimitives(ComApi.nwEVertexProperty.eNORMAL, primitiveChecker);
|
||||
|
||||
// Exit early if triangles are found
|
||||
if (primitiveChecker.HasTriangles)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return true if any 2D primitives are found
|
||||
return primitiveChecker.HasLines || primitiveChecker.HasPoints || primitiveChecker.HasSnapPoints;
|
||||
}
|
||||
finally
|
||||
{
|
||||
System.Runtime.InteropServices.Marshal.ReleaseComObject(comSelection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PrimitiveChecker : ComApi.InwSimplePrimitivesCB
|
||||
{
|
||||
public bool HasTriangles { get; private set; }
|
||||
public bool HasLines { get; private set; }
|
||||
public bool HasPoints { get; private set; }
|
||||
public bool HasSnapPoints { get; private set; }
|
||||
|
||||
public void Line(ComApi.InwSimpleVertex v1, ComApi.InwSimpleVertex v2) => HasLines = true;
|
||||
|
||||
public void Point(ComApi.InwSimpleVertex v1) => HasPoints = true;
|
||||
|
||||
public void SnapPoint(ComApi.InwSimpleVertex v1) => HasSnapPoints = true;
|
||||
|
||||
public void Triangle(ComApi.InwSimpleVertex v1, ComApi.InwSimpleVertex v2, ComApi.InwSimpleVertex v3) =>
|
||||
HasTriangles = true;
|
||||
}
|
||||
+18
-26
@@ -84,10 +84,7 @@ public sealed class NavisworksDocumentEvents : IDisposable
|
||||
|
||||
_topLevelExceptionHandler.CatchUnhandled(
|
||||
() =>
|
||||
_idleManager.SubscribeToIdle(
|
||||
nameof(NavisworksDocumentEvents),
|
||||
async () => await ProcessModelStateChangeAsync().ConfigureAwait(false)
|
||||
)
|
||||
_idleManager.SubscribeToIdle(nameof(NavisworksDocumentEvents), async () => await ProcessModelStateChangeAsync())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -102,29 +99,24 @@ public sealed class NavisworksDocumentEvents : IDisposable
|
||||
|
||||
try
|
||||
{
|
||||
await _parent
|
||||
.RunOnMainThreadAsync(async () =>
|
||||
{
|
||||
var store = _serviceProvider.GetRequiredService<NavisworksDocumentModelStore>();
|
||||
var basicBinding = _serviceProvider.GetRequiredService<IBasicConnectorBinding>();
|
||||
var commands = (basicBinding as NavisworksBasicConnectorBinding)?.Commands;
|
||||
var store = _serviceProvider.GetRequiredService<NavisworksDocumentModelStore>();
|
||||
var basicBinding = _serviceProvider.GetRequiredService<IBasicConnectorBinding>();
|
||||
var commands = (basicBinding as NavisworksBasicConnectorBinding)?.Commands;
|
||||
|
||||
switch (_finalModelCount)
|
||||
{
|
||||
case 0 when _priorModelCount > 0:
|
||||
store.ClearAndSave();
|
||||
break;
|
||||
case > 0 when _priorModelCount == 0:
|
||||
store.ReloadState();
|
||||
break;
|
||||
}
|
||||
switch (_finalModelCount)
|
||||
{
|
||||
case 0 when _priorModelCount > 0:
|
||||
store.ClearAndSave();
|
||||
break;
|
||||
case > 0 when _priorModelCount == 0:
|
||||
store.ReloadState();
|
||||
break;
|
||||
}
|
||||
|
||||
if (commands != null)
|
||||
{
|
||||
await commands.NotifyDocumentChanged().ConfigureAwait(false);
|
||||
}
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
if (commands != null)
|
||||
{
|
||||
await commands.NotifyDocumentChanged();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -164,7 +156,7 @@ public sealed class NavisworksDocumentEvents : IDisposable
|
||||
|
||||
if (commands != null)
|
||||
{
|
||||
await commands.NotifyDocumentChanged().ConfigureAwait(false);
|
||||
await commands.NotifyDocumentChanged();
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
||||
+56
-38
@@ -2,6 +2,7 @@ using System.Data;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
using Database = Autodesk.Navisworks.Api.DocumentParts.DocumentDatabase;
|
||||
|
||||
namespace Speckle.Connector.Navisworks.HostApp;
|
||||
|
||||
@@ -15,6 +16,7 @@ public sealed class NavisworksDocumentModelStore : DocumentModelStore
|
||||
private const string KEY_NAME = "Speckle_DUI3";
|
||||
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private string _lastSavedState = string.Empty;
|
||||
|
||||
public NavisworksDocumentModelStore(
|
||||
IJsonSerializer jsonSerializer,
|
||||
@@ -33,9 +35,16 @@ public sealed class NavisworksDocumentModelStore : DocumentModelStore
|
||||
return;
|
||||
}
|
||||
|
||||
// Compare current state with last saved state
|
||||
if (modelCardState == _lastSavedState)
|
||||
{
|
||||
return; // Skip save if states match
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
SaveStateToDatabase(modelCardState);
|
||||
_lastSavedState = modelCardState; // Update last saved state after successful save
|
||||
}
|
||||
catch (NAV.Data.DatabaseException ex)
|
||||
{
|
||||
@@ -54,7 +63,7 @@ public sealed class NavisworksDocumentModelStore : DocumentModelStore
|
||||
{
|
||||
if (!IsActiveDocumentValid())
|
||||
{
|
||||
ClearAndSave();
|
||||
ClearAndSaveThisState();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -62,16 +71,23 @@ public sealed class NavisworksDocumentModelStore : DocumentModelStore
|
||||
{
|
||||
string serializedState = RetrieveStateFromDatabase();
|
||||
LoadFromString(serializedState);
|
||||
_lastSavedState = serializedState; // Store initial state after loading
|
||||
}
|
||||
catch (NAV.Data.DatabaseException ex)
|
||||
{
|
||||
ClearAndSave(); // Clear models on failure to avoid stale data
|
||||
ClearAndSaveThisState(); // Clear models on failure to avoid stale data
|
||||
_topLevelExceptionHandler.CatchUnhandled(
|
||||
() => throw new InvalidOperationException("Failed to read Speckle state from database", ex)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearAndSaveThisState()
|
||||
{
|
||||
ClearAndSave();
|
||||
_lastSavedState = string.Empty; // Reset last saved state when clearing
|
||||
}
|
||||
|
||||
private static bool IsActiveDocumentValid()
|
||||
{
|
||||
try
|
||||
@@ -99,46 +115,55 @@ public sealed class NavisworksDocumentModelStore : DocumentModelStore
|
||||
|
||||
var database = activeDoc.Database;
|
||||
|
||||
using (var transaction = database.BeginTransaction(NAV.Data.DatabaseChangedAction.Reset))
|
||||
if (!DoesTableExist(database))
|
||||
{
|
||||
EnsureDatabaseTableExists(transaction);
|
||||
CreateTable(database);
|
||||
}
|
||||
|
||||
using (var transaction = database.BeginTransaction(NAV.Data.DatabaseChangedAction.Edited))
|
||||
using var transaction = database.BeginTransaction(NAV.Data.DatabaseChangedAction.Edited);
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
ReplaceStateInDatabase(transaction, modelCardState);
|
||||
transaction.Commit();
|
||||
}
|
||||
catch
|
||||
{
|
||||
transaction.Rollback(); // Roll back transaction on failure
|
||||
throw;
|
||||
}
|
||||
ReplaceStateInDatabase(transaction, modelCardState);
|
||||
transaction.Commit();
|
||||
}
|
||||
catch
|
||||
{
|
||||
transaction.Rollback(); // Roll back transaction on failure
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureDatabaseTableExists(NAV.Data.NavisworksTransaction transaction)
|
||||
private static void ReplaceStateInDatabase(NAV.Data.NavisworksTransaction transaction, string modelCardState)
|
||||
{
|
||||
var command = transaction.Connection.CreateCommand();
|
||||
command.CommandText = $"CREATE TABLE IF NOT EXISTS {TABLE_NAME}(key TEXT PRIMARY KEY, value TEXT)";
|
||||
command.CommandText = $"REPLACE INTO {TABLE_NAME}(key, value) VALUES(@key, @value)";
|
||||
command.Parameters.AddWithValue("@key", KEY_NAME);
|
||||
command.Parameters.AddWithValue("@value", modelCardState);
|
||||
command.ExecuteNonQuery();
|
||||
transaction.Commit(); // Ensure table exists before proceeding
|
||||
}
|
||||
|
||||
private static void ReplaceStateInDatabase(NAV.Data.NavisworksTransaction transaction, string serializedState)
|
||||
private static bool DoesTableExist(Database database)
|
||||
{
|
||||
var command = transaction.Connection.CreateCommand();
|
||||
var checkCommand = database.Value.CreateCommand();
|
||||
checkCommand.CommandText = $"SELECT name FROM sqlite_master WHERE type='table' AND name='{TABLE_NAME}'";
|
||||
return checkCommand.ExecuteScalar() != null;
|
||||
}
|
||||
|
||||
command.CommandText = $"DELETE FROM {TABLE_NAME} WHERE key = @key";
|
||||
command.Parameters.AddWithValue("@key", KEY_NAME);
|
||||
command.ExecuteNonQuery();
|
||||
|
||||
command.CommandText = $"INSERT INTO {TABLE_NAME}(key, value) VALUES(@key, @value)";
|
||||
command.Parameters.AddWithValue("@key", KEY_NAME);
|
||||
command.Parameters.AddWithValue("@value", serializedState);
|
||||
command.ExecuteNonQuery();
|
||||
private static void CreateTable(Database database)
|
||||
{
|
||||
using var transaction = database.BeginTransaction(NAV.Data.DatabaseChangedAction.Edited);
|
||||
try
|
||||
{
|
||||
var command = transaction.Connection.CreateCommand();
|
||||
command.CommandText = $"CREATE TABLE {TABLE_NAME}(key TEXT PRIMARY KEY, value TEXT)";
|
||||
command.ExecuteNonQuery();
|
||||
transaction.Commit();
|
||||
}
|
||||
catch
|
||||
{
|
||||
transaction.Rollback();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private static string RetrieveStateFromDatabase()
|
||||
@@ -146,9 +171,9 @@ public sealed class NavisworksDocumentModelStore : DocumentModelStore
|
||||
var database = NavisworksApp.ActiveDocument!.Database;
|
||||
using var table = new DataTable();
|
||||
|
||||
using (var transaction = database.BeginTransaction(NAV.Data.DatabaseChangedAction.Reset))
|
||||
if (!DoesTableExist(database))
|
||||
{
|
||||
EnsureDatabaseTableExists(transaction);
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
using var dataAdapter = new NAV.Data.NavisworksDataAdapter(
|
||||
@@ -158,13 +183,6 @@ public sealed class NavisworksDocumentModelStore : DocumentModelStore
|
||||
dataAdapter.SelectCommand.Parameters.AddWithValue("@key", KEY_NAME);
|
||||
dataAdapter.Fill(table);
|
||||
|
||||
if (table.Rows.Count <= 0)
|
||||
{
|
||||
return string.Empty; // Return an empty collection if no state is found
|
||||
}
|
||||
|
||||
string stateString = table.Rows[0]["value"] as string ?? string.Empty;
|
||||
|
||||
return stateString;
|
||||
return table.Rows.Count <= 0 ? string.Empty : table.Rows[0]["value"] as string ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
+32
-24
@@ -1,5 +1,6 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connector.Navisworks.Services;
|
||||
using Speckle.Converter.Navisworks.Helpers;
|
||||
using Speckle.Converter.Navisworks.Settings;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Objects.Other;
|
||||
@@ -24,14 +25,32 @@ public class NavisworksMaterialUnpacker(
|
||||
_ => defaultValue,
|
||||
};
|
||||
|
||||
internal List<RenderMaterialProxy> UnpackRenderMaterial(IReadOnlyList<NAV.ModelItem> navisworksObjects)
|
||||
internal List<RenderMaterialProxy> UnpackRenderMaterial(
|
||||
IReadOnlyList<NAV.ModelItem> navisworksObjects,
|
||||
Dictionary<string, List<NAV.ModelItem>> groupedNodes
|
||||
)
|
||||
{
|
||||
if (navisworksObjects == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(navisworksObjects));
|
||||
}
|
||||
|
||||
if (groupedNodes == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(groupedNodes));
|
||||
}
|
||||
|
||||
Dictionary<string, RenderMaterialProxy> renderMaterialProxies = [];
|
||||
Dictionary<string, string> mergedIds = [];
|
||||
|
||||
// Build mergedIds map once
|
||||
foreach (var group in groupedNodes)
|
||||
{
|
||||
foreach (var node in group.Value)
|
||||
{
|
||||
mergedIds[selectionService.GetModelItemPath(node)] = group.Key;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (NAV.ModelItem navisworksObject in navisworksObjects)
|
||||
{
|
||||
@@ -43,15 +62,13 @@ public class NavisworksMaterialUnpacker(
|
||||
}
|
||||
|
||||
var navisworksObjectId = selectionService.GetModelItemPath(navisworksObject);
|
||||
var finalId = mergedIds.TryGetValue(navisworksObjectId, out var mergedId) ? mergedId : navisworksObjectId;
|
||||
|
||||
var geometry = navisworksObject.Geometry;
|
||||
|
||||
// Extract the current visual representation mode
|
||||
var mode = converterSettings.Current.User.VisualRepresentationMode;
|
||||
|
||||
using var defaultColor = new NAV.Color(1.0, 1.0, 1.0);
|
||||
|
||||
// Assign properties using the selector
|
||||
var renderColor = Select(
|
||||
mode,
|
||||
geometry.ActiveColor,
|
||||
@@ -70,15 +87,16 @@ public class NavisworksMaterialUnpacker(
|
||||
|
||||
var renderMaterialId = Select(
|
||||
mode,
|
||||
geometry.ActiveColor.GetHashCode(),
|
||||
geometry.PermanentColor.GetHashCode(),
|
||||
geometry.OriginalColor.GetHashCode(),
|
||||
$"{geometry.ActiveColor.GetHashCode()}_{geometry.ActiveTransparency}".GetHashCode(),
|
||||
$"{geometry.PermanentColor.GetHashCode()}_{geometry.PermanentTransparency}".GetHashCode(),
|
||||
$"{geometry.OriginalColor.GetHashCode()}_{geometry.OriginalTransparency}".GetHashCode(),
|
||||
0
|
||||
);
|
||||
|
||||
var materialName = $"NavisworksMaterial_{Math.Abs(NavisworksColorToColor(renderColor).ToArgb())}";
|
||||
var materialName =
|
||||
$"NavisworksMaterial_{Math.Abs(ColorConverter.NavisworksColorToColor(renderColor).ToArgb())}";
|
||||
|
||||
// Alternatively the material could be stored on the Item property
|
||||
// Check Item category for material name
|
||||
var itemCategory = navisworksObject.PropertyCategories.FindCategoryByDisplayName("Item");
|
||||
if (itemCategory != null)
|
||||
{
|
||||
@@ -90,7 +108,7 @@ public class NavisworksMaterialUnpacker(
|
||||
}
|
||||
}
|
||||
|
||||
// Or in a Material property
|
||||
// Check Material category for material name
|
||||
var materialPropertyCategory = navisworksObject.PropertyCategories.FindCategoryByDisplayName("Material");
|
||||
if (materialPropertyCategory != null)
|
||||
{
|
||||
@@ -104,22 +122,19 @@ public class NavisworksMaterialUnpacker(
|
||||
|
||||
if (renderMaterialProxies.TryGetValue(renderMaterialId.ToString(), out RenderMaterialProxy? value))
|
||||
{
|
||||
value.objects.Add(navisworksObjectId);
|
||||
value.objects.Add(finalId);
|
||||
}
|
||||
else
|
||||
{
|
||||
renderMaterialProxies[renderMaterialId.ToString()] = new RenderMaterialProxy()
|
||||
{
|
||||
// For now, we will just use the color and transparency to create a new material
|
||||
// There is more information that is in the Material object that could be used to create a more accurate material
|
||||
// But is constant regardless of the user settings
|
||||
value = ConvertRenderColorAndTransparencyToSpeckle(
|
||||
materialName,
|
||||
renderTransparency,
|
||||
renderColor,
|
||||
renderMaterialId
|
||||
),
|
||||
objects = [navisworksObjectId]
|
||||
objects = [finalId]
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -139,7 +154,7 @@ public class NavisworksMaterialUnpacker(
|
||||
int applicationId
|
||||
)
|
||||
{
|
||||
var color = NavisworksColorToColor(navisworksColor);
|
||||
var color = ColorConverter.NavisworksColorToColor(navisworksColor);
|
||||
|
||||
var speckleRenderMaterial = new RenderMaterial()
|
||||
{
|
||||
@@ -154,11 +169,4 @@ public class NavisworksMaterialUnpacker(
|
||||
|
||||
return speckleRenderMaterial;
|
||||
}
|
||||
|
||||
private static System.Drawing.Color NavisworksColorToColor(NAV.Color color) =>
|
||||
System.Drawing.Color.FromArgb(
|
||||
Convert.ToInt32(color.R * 255),
|
||||
Convert.ToInt32(color.G * 255),
|
||||
Convert.ToInt32(color.B * 255)
|
||||
);
|
||||
}
|
||||
|
||||
+182
-72
@@ -23,49 +23,101 @@ public class NavisworksRootObjectBuilder(
|
||||
ILogger<NavisworksRootObjectBuilder> logger,
|
||||
ISdkActivityFactory activityFactory,
|
||||
NavisworksMaterialUnpacker materialUnpacker,
|
||||
NavisworksColorUnpacker colorUnpacker,
|
||||
IElementSelectionService elementSelectionService
|
||||
) : IRootObjectBuilder<NAV.ModelItem>
|
||||
{
|
||||
private bool SkipNodeMerging { get; set; }
|
||||
|
||||
internal NavisworksConversionSettings GetCurrentSettings() => converterSettings.Current;
|
||||
|
||||
public Task<RootObjectBuilderResult> Build(
|
||||
/// <summary>
|
||||
/// Asynchronously builds a Speckle object hierarchy from Navisworks model items.
|
||||
/// </summary>
|
||||
/// <param name="navisworksModelItems">The list of Navisworks items to convert.</param>
|
||||
/// <param name="sendInfo">Information about the send operation.</param>
|
||||
/// <param name="onOperationProgressed">Progress reporting callback.</param>
|
||||
/// <param name="cancellationToken">Token to cancel the operation.</param>
|
||||
/// <returns>A result containing the root collection and conversion results.</returns>
|
||||
/// <exception cref="SpeckleException">Thrown when no objects can be converted.</exception>
|
||||
public async Task<RootObjectBuilderResult> BuildAsync(
|
||||
IReadOnlyList<NAV.ModelItem> navisworksModelItems,
|
||||
SendInfo sendInfo,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken = default
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
#if DEBUG
|
||||
// This is a temporary workaround to disable node merging for debugging purposes - false is default, true is for debugging
|
||||
SkipNodeMerging = false;
|
||||
#endif
|
||||
using var activity = activityFactory.Start("Build");
|
||||
|
||||
// 1. Validate input
|
||||
ValidateInputs(navisworksModelItems, sendInfo, onOperationProgressed);
|
||||
|
||||
// 2. Initialize root collection
|
||||
var rootCollection = InitializeRootCollection();
|
||||
|
||||
// 3. Convert all model items and store results
|
||||
var (convertedElements, conversionResults) = await ConvertModelItemsAsync(
|
||||
navisworksModelItems,
|
||||
sendInfo,
|
||||
onOperationProgressed,
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
ValidateConversionResults(conversionResults);
|
||||
|
||||
var groupedNodes = SkipNodeMerging ? [] : GroupSiblingGeometryNodes(navisworksModelItems);
|
||||
var finalElements = BuildFinalElements(convertedElements, groupedNodes);
|
||||
|
||||
await AddProxiesToCollection(rootCollection, navisworksModelItems, groupedNodes);
|
||||
|
||||
rootCollection.elements = finalElements;
|
||||
return new RootObjectBuilderResult(rootCollection, conversionResults);
|
||||
}
|
||||
|
||||
private static void ValidateInputs(
|
||||
IReadOnlyList<NAV.ModelItem> navisworksModelItems,
|
||||
SendInfo sendInfo,
|
||||
IProgress<CardProgress> onOperationProgressed
|
||||
)
|
||||
{
|
||||
if (!navisworksModelItems.Any())
|
||||
{
|
||||
throw new SpeckleException("No objects to convert");
|
||||
}
|
||||
|
||||
// 2. Initialize root collection
|
||||
var rootObjectCollection = new Collection
|
||||
{
|
||||
name = NavisworksApp.ActiveDocument.Title ?? "Unnamed model",
|
||||
["units"] = converterSettings.Current.Derived.SpeckleUnits
|
||||
};
|
||||
|
||||
// 3. Convert all model items and store results
|
||||
if (navisworksModelItems == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(navisworksModelItems));
|
||||
}
|
||||
|
||||
List<SendConversionResult> results = new(navisworksModelItems.Count);
|
||||
if (onOperationProgressed == null || sendInfo == null)
|
||||
{
|
||||
throw new ArgumentNullException(onOperationProgressed == null ? nameof(onOperationProgressed) : nameof(sendInfo));
|
||||
}
|
||||
}
|
||||
|
||||
private Collection InitializeRootCollection() =>
|
||||
new()
|
||||
{
|
||||
name = NavisworksApp.ActiveDocument.Title ?? "Unnamed model",
|
||||
["units"] = converterSettings.Current.Derived.SpeckleUnits
|
||||
};
|
||||
|
||||
private Task<(Dictionary<string, Base?> converted, List<SendConversionResult> results)> ConvertModelItemsAsync(
|
||||
IReadOnlyList<NAV.ModelItem> navisworksModelItems,
|
||||
SendInfo sendInfo,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var results = new List<SendConversionResult>(navisworksModelItems.Count);
|
||||
var convertedBases = new Dictionary<string, Base?>();
|
||||
int processedCount = 0;
|
||||
int totalCount = navisworksModelItems.Count;
|
||||
|
||||
if (onOperationProgressed == null || sendInfo == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(onOperationProgressed));
|
||||
}
|
||||
|
||||
foreach (var item in navisworksModelItems)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
@@ -75,85 +127,143 @@ public class NavisworksRootObjectBuilder(
|
||||
onOperationProgressed.Report(new CardProgress("Converting", (double)processedCount / totalCount));
|
||||
}
|
||||
|
||||
return Task.FromResult((convertedBases, results));
|
||||
}
|
||||
|
||||
private static void ValidateConversionResults(List<SendConversionResult> results)
|
||||
{
|
||||
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.
|
||||
throw new SpeckleException("Failed to convert all objects.");
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Initialize final elements list and group nodes
|
||||
private List<Base> BuildFinalElements(
|
||||
Dictionary<string, Base?> convertedBases,
|
||||
Dictionary<string, List<NAV.ModelItem>> groupedNodes
|
||||
)
|
||||
{
|
||||
var finalElements = new List<Base>();
|
||||
var groupedNodes = GroupSiblingGeometryNodes(navisworksModelItems);
|
||||
var processedPaths = new HashSet<string>();
|
||||
|
||||
// 5. Process and merge grouped nodes
|
||||
AddGroupedElements(finalElements, convertedBases, groupedNodes, processedPaths);
|
||||
AddRemainingElements(finalElements, convertedBases, processedPaths);
|
||||
|
||||
return finalElements;
|
||||
}
|
||||
|
||||
private void AddGroupedElements(
|
||||
List<Base> finalElements,
|
||||
Dictionary<string, Base?> convertedBases,
|
||||
Dictionary<string, List<NAV.ModelItem>> groupedNodes,
|
||||
HashSet<string> processedPaths
|
||||
)
|
||||
{
|
||||
foreach (var group in groupedNodes)
|
||||
{
|
||||
var siblingBases = new List<Base>();
|
||||
foreach (var itemPath in group.Value.Select(elementSelectionService.GetModelItemPath))
|
||||
{
|
||||
processedPaths.Add(itemPath);
|
||||
|
||||
if (convertedBases.TryGetValue(itemPath, out var convertedBase) && convertedBase != null)
|
||||
{
|
||||
siblingBases.Add(convertedBase);
|
||||
}
|
||||
}
|
||||
|
||||
if (siblingBases.Count == 0)
|
||||
if (siblingBases.Count > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var navisworksObject = new NavisworksObject
|
||||
{
|
||||
name = elementSelectionService.GetModelItemFromPath(group.Key).DisplayName ?? string.Empty,
|
||||
displayValue = siblingBases.SelectMany(b => b["displayValue"] as List<Base> ?? []).ToList(),
|
||||
properties = siblingBases.First()["properties"] as Dictionary<string, object?> ?? [],
|
||||
units = converterSettings.Current.Derived.SpeckleUnits,
|
||||
applicationId = group.Key
|
||||
};
|
||||
|
||||
finalElements.Add(navisworksObject);
|
||||
}
|
||||
|
||||
// 6. Add remaining non-grouped nodes
|
||||
foreach (var result in results.Where(result => !processedPaths.Contains(result.SourceId)))
|
||||
{
|
||||
if (!convertedBases.TryGetValue(result.SourceId, out var convertedBase) || convertedBase == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// TODO: check if converted base is a collection when full tree sending is implemented
|
||||
|
||||
if (convertedBase is Collection convertedCollection)
|
||||
{
|
||||
finalElements.Add(convertedCollection);
|
||||
}
|
||||
else
|
||||
{
|
||||
var navisworksObject = new NavisworksObject
|
||||
{
|
||||
name = convertedBase["name"] as string ?? string.Empty,
|
||||
displayValue = convertedBase["displayValue"] as List<Base> ?? [],
|
||||
properties = convertedBase["properties"] as Dictionary<string, object?> ?? [],
|
||||
units = converterSettings.Current.Derived.SpeckleUnits,
|
||||
applicationId = convertedBase.applicationId
|
||||
};
|
||||
finalElements.Add(navisworksObject);
|
||||
finalElements.Add(CreateNavisworksObject(group.Key, siblingBases));
|
||||
}
|
||||
}
|
||||
|
||||
using (var _ = activityFactory.Start("UnpackRenderMaterials"))
|
||||
{
|
||||
// 7. - Unpack the render material proxies
|
||||
rootObjectCollection[ProxyKeys.RENDER_MATERIAL] = materialUnpacker.UnpackRenderMaterial(navisworksModelItems);
|
||||
}
|
||||
|
||||
// 8. Finalize and return
|
||||
rootObjectCollection.elements = finalElements;
|
||||
return Task.FromResult(new RootObjectBuilderResult(rootObjectCollection, results));
|
||||
}
|
||||
|
||||
private void AddRemainingElements(
|
||||
List<Base> finalElements,
|
||||
Dictionary<string, Base?> convertedBases,
|
||||
HashSet<string> processedPaths
|
||||
)
|
||||
{
|
||||
foreach (var kvp in convertedBases.Where(kvp => !processedPaths.Contains(kvp.Key)))
|
||||
{
|
||||
switch (kvp.Value)
|
||||
{
|
||||
case null:
|
||||
continue;
|
||||
case Collection collection:
|
||||
finalElements.Add(collection);
|
||||
break;
|
||||
default:
|
||||
finalElements.Add(CreateNavisworksObject(kvp.Value));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes and adds any remaining non-grouped elements.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Handles both Collection and Base type elements differently.
|
||||
/// Only processes elements that weren't handled in grouped processing.
|
||||
/// </remarks>
|
||||
private NavisworksObject CreateNavisworksObject(string groupKey, List<Base> siblingBases) =>
|
||||
new()
|
||||
{
|
||||
name = elementSelectionService.GetModelItemFromPath(groupKey).DisplayName ?? string.Empty,
|
||||
displayValue = siblingBases.SelectMany(b => b["displayValue"] as List<Base> ?? []).ToList(),
|
||||
properties = siblingBases.First()["properties"] as Dictionary<string, object?> ?? [],
|
||||
units = converterSettings.Current.Derived.SpeckleUnits,
|
||||
applicationId = groupKey
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Creates a NavisworksObject from a single converted base.
|
||||
/// </summary>
|
||||
/// <param name="convertedBase">The converted Speckle Base object.</param>
|
||||
/// <returns>A new NavisworksObject containing the converted data.</returns>
|
||||
private NavisworksObject CreateNavisworksObject(Base convertedBase) =>
|
||||
new()
|
||||
{
|
||||
name = convertedBase["name"] as string ?? string.Empty,
|
||||
displayValue = convertedBase["displayValue"] as List<Base> ?? [],
|
||||
properties = convertedBase["properties"] as Dictionary<string, object?> ?? [],
|
||||
units = converterSettings.Current.Derived.SpeckleUnits,
|
||||
applicationId = convertedBase.applicationId
|
||||
};
|
||||
|
||||
private Task AddProxiesToCollection(
|
||||
Collection rootCollection,
|
||||
IReadOnlyList<NAV.ModelItem> navisworksModelItems,
|
||||
Dictionary<string, List<NAV.ModelItem>> groupedNodes
|
||||
)
|
||||
{
|
||||
using var _ = activityFactory.Start("UnpackProxies");
|
||||
|
||||
var renderMaterials = materialUnpacker.UnpackRenderMaterial(navisworksModelItems, groupedNodes);
|
||||
if (renderMaterials.Count > 0)
|
||||
{
|
||||
rootCollection[ProxyKeys.RENDER_MATERIAL] = renderMaterials;
|
||||
}
|
||||
|
||||
var colors = colorUnpacker.UnpackColor(navisworksModelItems, groupedNodes);
|
||||
if (colors.Count > 0)
|
||||
{
|
||||
rootCollection[ProxyKeys.COLOR] = colors;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a single Navisworks item to a Speckle object.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Attempts to retrieve from cache first.
|
||||
/// Falls back to fresh conversion if not cached.
|
||||
/// Logs errors but doesn't throw exceptions.
|
||||
/// </remarks>
|
||||
/// <returns>A SendConversionResult indicating success or failure.</returns>
|
||||
private SendConversionResult ConvertNavisworksItem(
|
||||
NAV.ModelItem navisworksItem,
|
||||
Dictionary<string, Base?> convertedBases,
|
||||
|
||||
+2
-1
@@ -33,6 +33,8 @@ internal sealed class Connector : NAV.Plugins.DockPanePlugin
|
||||
|
||||
public override Control CreateControlPane()
|
||||
{
|
||||
AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolver.OnAssemblyResolve<Connector>;
|
||||
|
||||
var services = new ServiceCollection();
|
||||
|
||||
services.Initialize(HostApplications.Navisworks, HostAppVersion.v2024);
|
||||
@@ -41,7 +43,6 @@ internal sealed class Connector : NAV.Plugins.DockPanePlugin
|
||||
services.AddNavisworksConverter();
|
||||
|
||||
Container = services.BuildServiceProvider();
|
||||
|
||||
Container.UseDUI();
|
||||
|
||||
var u = Container.GetRequiredService<DUI3ControlWebView>();
|
||||
|
||||
+1
-3
@@ -15,6 +15,7 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)DependencyInjection\NavisworksConnectorServiceRegistration.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ElementSelectionService.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)GlobalUsing.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\NavisworksColorUnpacker.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\NavisworksDocumentEvents.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\NavisworksDocumentModelStore.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\NavisworksIdleManager.cs" />
|
||||
@@ -54,7 +55,4 @@
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Operations\_Receive\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project>
|
||||
<Target AfterTargets="Clean" Name="CleanAddinsRevit" Condition="'$(RevitVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
|
||||
<RemoveDir Directories="$(TargetDir);$(ProjectDir)\..\Release\Release$(RevitVersion);$(AppData)\Autodesk\Revit\Addins\$(RevitVersion)\Speckle.Connectors.Revit$(RevitVersion);" />
|
||||
<Delete Files="$(AppData)\Autodesk\Revit\Addins\$(RevitVersion)\Speckle.Connectors.Revit$(RevitVersion).addin" />
|
||||
</Target>
|
||||
|
||||
<Target AfterTargets="Build" Name="AfterBuildRevit" Condition="'$(RevitVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
|
||||
<ItemGroup>
|
||||
<RevitDLLs Include="$(TargetDir)\**\*.*" Exclude="$(TargetDir)*.addin" />
|
||||
<SourceManifest Include="$(TargetDir)\Plugin\Speckle.Connectors.Revit$(RevitVersion).addin" />
|
||||
</ItemGroup>
|
||||
<Message Text="Revit Version $(RevitVersion)" Importance="high"/>
|
||||
<Copy DestinationFolder="$(AppData)\Autodesk\REVIT\Addins\$(RevitVersion)\Speckle.Connectors.Revit$(RevitVersion)\%(RecursiveDir)" SourceFiles="@(RevitDLLs)" />
|
||||
<Copy DestinationFolder="$(AppData)\Autodesk\REVIT\Addins\$(RevitVersion)\" SourceFiles="@(SourceManifest)" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -292,9 +292,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -302,9 +302,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
@@ -314,7 +313,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2022": {
|
||||
@@ -353,11 +352,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -368,32 +367,26 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,9 +292,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -302,9 +302,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
@@ -314,7 +313,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2023": {
|
||||
@@ -353,11 +352,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -368,32 +367,26 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,9 +292,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -302,9 +302,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
@@ -314,7 +313,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2024": {
|
||||
@@ -353,11 +352,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -368,32 +367,26 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.0.0]",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,9 +242,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -252,9 +252,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.219, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.219, )",
|
||||
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
|
||||
"Speckle.Sdk": "[3.1.0-dev.234, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
@@ -264,7 +263,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.219, )"
|
||||
"Speckle.Objects": "[3.1.0-dev.234, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2025": {
|
||||
@@ -303,11 +302,11 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "2thsMUDkRr7lR0PXZJ8k3KWZLWjz/aBY0KaO2SuXM0lIKyJw1APMJ7lXJ89e6JAjBzEbK8yLHBb0qtfcc4bNRw==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "vM/aRt+t3yB6JOk+2UdgD40yLiZRFlc5+bUf2dQLbgN4AciSMge3vU6cYnfeV/gMPnQM3XR3Lv9UP/VaLYDwkA==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.219"
|
||||
"Speckle.Sdk": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -318,31 +317,25 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "UTgz9UgkMFGqRLmCq1HPo74MngvKbSZOFWaMRzASHrrnsBtzZatBXjoJBlvVoeBCoiea5Jj+BgZg6RvlV2m3sg==",
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "9MRVpu0bFWeAWE5BFqc+W3eDFmRJPe46TcSFguYcBGebJzdWPgwqyZt4O0vNBXOuM3NSOz8UpZXe1H0vjX4jRg==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5]",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0]",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0]",
|
||||
"Speckle.DoubleNumerics": "4.0.1",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.219"
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.234"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.219, )",
|
||||
"resolved": "3.1.0-dev.219",
|
||||
"contentHash": "5hqBd9whAs5cC8S/6YUgKFOivjntAkVutKhz06XD/f3Kj6xScT3hwcUaWBxiwK3Mw7FLtiVuU1uG777pjn0PKQ=="
|
||||
},
|
||||
"System.Threading.Tasks.Dataflow": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
|
||||
"requested": "[3.1.0-dev.234, )",
|
||||
"resolved": "3.1.0-dev.234",
|
||||
"contentHash": "wx++uIHVTiFEiAYoqhsTfN3yJOBiaV2doXP4pttPC52eWwvhOjThKrcRW/Lx2uWlUC8HcyBA3mBV9GaIl7n+1A=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
|
||||
@@ -13,15 +13,9 @@ public partial class CefSharpPanel : Page, Autodesk.Revit.UI.IDockablePaneProvid
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public Task ExecuteScriptAsyncMethod(string script, CancellationToken cancellationToken)
|
||||
public void ExecuteScript(string script)
|
||||
{
|
||||
Browser.Dispatcher.Invoke(
|
||||
() => Browser.ExecuteScriptAsync(script),
|
||||
DispatcherPriority.Background,
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
return Task.CompletedTask;
|
||||
Browser.Dispatcher.Invoke(() => Browser.ExecuteScriptAsync(script), DispatcherPriority.Background);
|
||||
}
|
||||
|
||||
public bool IsBrowserInitialized => Browser.IsBrowserInitialized;
|
||||
|
||||
+27
-47
@@ -1,9 +1,8 @@
|
||||
using Autodesk.Revit.DB;
|
||||
using Revit.Async;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Eventing;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Connectors.Revit.HostApp;
|
||||
using Speckle.Connectors.RevitShared;
|
||||
using Speckle.Connectors.RevitShared.Operations.Send.Filters;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
@@ -20,35 +19,30 @@ 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;
|
||||
|
||||
public BasicConnectorBindingRevit(
|
||||
APIContext apiContext,
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
RevitContext revitContext,
|
||||
ISpeckleApplication speckleApplication
|
||||
ISpeckleApplication speckleApplication,
|
||||
IEventAggregator eventAggregator
|
||||
)
|
||||
{
|
||||
Name = "baseBinding";
|
||||
Parent = parent;
|
||||
_apiContext = apiContext;
|
||||
_store = store;
|
||||
_revitContext = revitContext;
|
||||
_speckleApplication = speckleApplication;
|
||||
Commands = new BasicConnectorBindingCommands(parent);
|
||||
|
||||
// POC: event binding?
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
parent.TopLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await Commands.NotifyDocumentChanged().ConfigureAwait(false);
|
||||
});
|
||||
eventAggregator.GetEvent<DocumentStoreChangedEvent>().Subscribe(OnDocumentStoreChangedEvent);
|
||||
}
|
||||
|
||||
private async Task OnDocumentStoreChangedEvent(object _) => await Commands.NotifyDocumentChanged();
|
||||
|
||||
public string GetConnectorVersion() => _speckleApplication.SpeckleVersion;
|
||||
|
||||
public string GetSourceApplicationName() => _speckleApplication.Slug;
|
||||
@@ -97,21 +91,16 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
{
|
||||
if (senderModelCard.SendFilter is IRevitSendFilter revitFilter)
|
||||
{
|
||||
revitFilter.SetContext(_revitContext, _apiContext);
|
||||
revitFilter.SetContext(_revitContext);
|
||||
}
|
||||
|
||||
if (senderModelCard.SendFilter is RevitViewsFilter revitViewsFilter)
|
||||
{
|
||||
await _apiContext
|
||||
.Run(() =>
|
||||
{
|
||||
var view = revitViewsFilter.GetView();
|
||||
if (view is not null)
|
||||
{
|
||||
_revitContext.UIApplication.ActiveUIDocument.ActiveView = view;
|
||||
}
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
var view = revitViewsFilter.GetView();
|
||||
if (view is not null)
|
||||
{
|
||||
_revitContext.UIApplication.ActiveUIDocument.ActiveView = view;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -128,7 +117,7 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
{
|
||||
elementIds = receiverModelCard
|
||||
.BakedObjectIds.NotNull()
|
||||
.Select(uid => ElementIdHelper.GetElementIdFromUniqueId(activeUIDoc.Document, uid))
|
||||
.Select(uid => ElementIdHelper.GetElementIdFromUniqueId(activeUIDoc.Document, uid.Value))
|
||||
.Where(el => el is not null)
|
||||
.Cast<ElementId>()
|
||||
.ToList();
|
||||
@@ -136,51 +125,42 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
|
||||
if (elementIds.Count == 0)
|
||||
{
|
||||
await Commands
|
||||
.SetModelError(modelCardId, new InvalidOperationException("No objects found to highlight."))
|
||||
.ConfigureAwait(false);
|
||||
await Commands.SetModelError(modelCardId, new InvalidOperationException("No objects found to highlight."));
|
||||
return;
|
||||
}
|
||||
|
||||
await HighlightObjectsOnView(elementIds).ConfigureAwait(false);
|
||||
HighlightObjectsOnView(elementIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Highlights the objects from the given ids.
|
||||
/// </summary>
|
||||
/// <param name="objectIds"> UniqueId's of the DB.Elements.</param>
|
||||
public async Task HighlightObjects(IReadOnlyList<string> objectIds)
|
||||
public Task HighlightObjects(IReadOnlyList<string> objectIds)
|
||||
{
|
||||
var activeUIDoc =
|
||||
_revitContext.UIApplication?.ActiveUIDocument
|
||||
?? throw new SpeckleException("Unable to retrieve active UI document");
|
||||
|
||||
await HighlightObjectsOnView(
|
||||
objectIds
|
||||
.Select(uid => ElementIdHelper.GetElementIdFromUniqueId(activeUIDoc.Document, uid))
|
||||
.Where(el => el is not null)
|
||||
.Cast<ElementId>()
|
||||
.ToList()
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
;
|
||||
HighlightObjectsOnView(
|
||||
objectIds
|
||||
.Select(uid => ElementIdHelper.GetElementIdFromUniqueId(activeUIDoc.Document, uid))
|
||||
.Where(el => el is not null)
|
||||
.Cast<ElementId>()
|
||||
.ToList()
|
||||
);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task HighlightObjectsOnView(List<ElementId> objectIds)
|
||||
private void HighlightObjectsOnView(List<ElementId> objectIds)
|
||||
{
|
||||
// POC: don't know if we can rely on storing the ActiveUIDocument, hence getting it each time
|
||||
var activeUIDoc =
|
||||
_revitContext.UIApplication?.ActiveUIDocument
|
||||
?? throw new SpeckleException("Unable to retrieve active UI document");
|
||||
|
||||
// UiDocument operations should be wrapped into RevitTask, otherwise doesn't work on other tasks.
|
||||
await RevitTask
|
||||
.RunAsync(() =>
|
||||
{
|
||||
activeUIDoc.Selection.SetElementIds(objectIds);
|
||||
activeUIDoc.ShowElements(objectIds);
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
activeUIDoc.Selection.SetElementIds(objectIds);
|
||||
activeUIDoc.ShowElements(objectIds);
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,13 +83,14 @@ internal sealed class RevitReceiveBinding : IReceiveBinding
|
||||
modelCard.GetReceiveInfo(_speckleApplication.Slug),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationToken),
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
);
|
||||
|
||||
modelCard.BakedObjectIds = conversionResults.BakedObjectIds.ToList();
|
||||
await Commands
|
||||
.SetModelReceiveResult(modelCardId, conversionResults.BakedObjectIds, conversionResults.ConversionResults)
|
||||
.ConfigureAwait(false);
|
||||
modelCard.BakedObjectIds = conversionResults.BakedObjectIds;
|
||||
await Commands.SetModelReceiveResult(
|
||||
modelCardId,
|
||||
conversionResults.BakedObjectIds,
|
||||
conversionResults.ConversionResults
|
||||
);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -100,7 +101,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);
|
||||
await Commands.SetModelError(modelCardId, ex).ConfigureAwait(false);
|
||||
await Commands.SetModelError(modelCardId, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user